From 1c6a0c1a8fb254945179276ecbd359cc1926fbb1 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:57:54 +0200 Subject: [PATCH] Wayland: fix interactive moving and resizing of a subwindow - cont'd (#987) This fix requires to be able to recognize whether Fl_Wayland_Window_Driver::resize() is called by a resize operation of an encompassing widget or not. To do that, private static int variable group_resize_depth_ is added to class Fl_Group and an accessor to this variable is added to class Fl_Window_Driver. --- FL/Fl_Group.H | 3 ++- src/Fl_Group.cxx | 4 ++++ src/Fl_Window_Driver.H | 1 + src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 16 ++++++---------- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/FL/Fl_Group.H b/FL/Fl_Group.H index 173f8754bb..9f76b4fd13 100644 --- a/FL/Fl_Group.H +++ b/FL/Fl_Group.H @@ -54,7 +54,7 @@ class Fl_Rect; reason \p FL_REASON_CLOSED. */ class FL_EXPORT Fl_Group : public Fl_Widget { - + friend class Fl_Window_Driver; union { Fl_Widget** array_; // used if group has two or more children or NULL Fl_Widget* child1_; // used if group has one child or NULL @@ -67,6 +67,7 @@ class FL_EXPORT Fl_Group : public Fl_Widget { int navigation(int); static Fl_Group *current_; + static int group_resize_depth_; // unimplemented copy ctor and assignment operator Fl_Group(const Fl_Group&); diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index 2576efea74..e6d942e32f 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -809,6 +809,8 @@ int* Fl_Group::sizes() return sizes_; } +int Fl_Group::group_resize_depth_ = 0; + /** Resizes the Fl_Group widget and all of its children. @@ -857,6 +859,7 @@ void Fl_Group::resize(int X, int Y, int W, int H) { // Part 2: here we definitely have a resizable() widget, resize children else if (children_) { + group_resize_depth_++; // get changes in size/position from the initial size: dx = X - p->x(); @@ -905,6 +908,7 @@ void Fl_Group::resize(int X, int Y, int W, int H) { o->resize(L+dx, T+dy, R-L, B-T); } + group_resize_depth_--; } // End of part 2: we have a resizable() widget } diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index cec60a2dae..9df4c99e8c 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -58,6 +58,7 @@ private: protected: Fl_Window *pWindow; int screen_num_; // number of screen where window is mapped + static int group_resize_depth() { return Fl_Group::group_resize_depth_; } public: Fl_Window_Driver(Fl_Window *); virtual ~Fl_Window_Driver(); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 5c0ff38dff..21a02c8f46 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -1770,7 +1770,6 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { - static int depth = 0; struct wld_window *fl_win = fl_wl_xid(pWindow); if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) { pWindow->wait_for_expose(); @@ -1788,14 +1787,13 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { int is_a_resize = (W != w() || H != h() || true_rescale); if (is_a_move) force_position(1); else if (!is_a_resize && !is_a_move) return; - depth++; if (shown() && !(parent() || popup_window())) { X = Y = 0; } struct wld_window *parent_xid = parent() ? fl_wl_xid(pWindow->window()) : NULL; // This condition excludes moving or resizing a subwindow while not changing its parent // and delays application of new X,Y,W,H values if the parent is being committed. - if (!parent_xid || depth > 1 || !parent_xid->frame_cb) { + if (true_rescale || !parent_xid || group_resize_depth() >= 1 || !parent_xid->frame_cb) { if (is_a_resize) { if (pWindow->parent()) { if (W < 1) W = 1; @@ -1866,18 +1864,16 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { } if (fl_win && parent_xid) { - if (depth == 1) { + if (group_resize_depth() < 1 && !parent_xid->frame_cb) { // Interactive move or resize of a subwindow requires to commit the parent surface // and requires to make sure the parent surface is ready to accept a new commit (#987). - if (!parent_xid->frame_cb) { - parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface); - wl_callback_add_listener(parent_xid->frame_cb, Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid); - wl_surface_commit(parent_xid->wl_surface); - } + parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface); + wl_callback_add_listener(parent_xid->frame_cb, + Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid); + wl_surface_commit(parent_xid->wl_surface); } checkSubwindowFrame(); // make sure subwindow doesn't leak outside parent } - depth--; }