diff --git a/modules/highgui/src/window_wayland.cpp b/modules/highgui/src/window_wayland.cpp index ee1d50207d..3bf87c06ec 100644 --- a/modules/highgui/src/window_wayland.cpp +++ b/modules/highgui/src/window_wayland.cpp @@ -623,6 +623,9 @@ private: cv::Rect last_img_area_; bool image_changed_ = false; + int real_img_width = 0; + cv::Scalar const outarea_color_ = CV_RGB(0, 0, 0); + void *param_ = nullptr; CvMouseCallback callback_ = nullptr; }; @@ -1582,6 +1585,28 @@ cv_wl_viewer::cv_wl_viewer(cv_wl_window *window, int flags) void cv_wl_viewer::set_image(cv::Mat const &image) { image_ = image.clone(); image_changed_ = true; + + // See https://github.com/opencv/opencv/issues/25560 + // If image_ width is too small enough to show title and buttons, expand it. + + // Keep real image width to limit x position for callback functions + real_img_width = image_.size().width; + + // Minimum width of title is not defined, so use button width * 3 instead of it. + const int view_min_width = cv_wl_titlebar::btn_width * 3 + cv_wl_titlebar::titlebar_min_width; + + const int margin = view_min_width - real_img_width; + if(margin > 0) + { + copyMakeBorder(image_, // src + image_, // dst + 0, // top + 0, // bottom + 0, // left + margin, // right + cv::BORDER_CONSTANT, // borderType + outarea_color_ ); // value(color) + } } void cv_wl_viewer::set_mouse_callback(CvMouseCallback callback, void *param) { @@ -1634,6 +1659,8 @@ void cv_wl_viewer::on_mouse(int event, cv::Point const &p, int flag) { int x = static_cast((p.x - last_img_area_.x) * ((double) image_.size().width / last_img_area_.width)); int y = static_cast((p.y - last_img_area_.y) * ((double) image_.size().height / last_img_area_.height)); + + x = cv::min(x, real_img_width); callback_(event, x, y, flag, param_); } } diff --git a/modules/highgui/test/test_gui.cpp b/modules/highgui/test/test_gui.cpp index 41304ddf43..96ecbb9341 100644 --- a/modules/highgui/test/test_gui.cpp +++ b/modules/highgui/test/test_gui.cpp @@ -215,6 +215,21 @@ TEST(Highgui_GUI, trackbar) EXPECT_NO_THROW(destroyAllWindows()); } +// See https://github.com/opencv/opencv/issues/25560 +#if !defined(ENABLE_PLUGINS) +TEST(Highgui_GUI, DISABLED_small_width_image) +#else +TEST(Highgui_GUI, small_width_image) +#endif +{ + const std::string window_name("trackbar_test_window"); + cv::Mat src(1,1,CV_8UC3,cv::Scalar(0)); + EXPECT_NO_THROW(destroyAllWindows()); + ASSERT_NO_THROW(namedWindow(window_name)); + ASSERT_NO_THROW(imshow(window_name, src)); + EXPECT_NO_THROW(waitKey(10)); + EXPECT_NO_THROW(destroyAllWindows()); +} TEST(Highgui_GUI, currentUIFramework) {