diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-12-28 09:59:51 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-12-28 09:59:51 +0100 |
| commit | 614376488568e3eae2289e7d15e453ad6d7285af (patch) | |
| tree | 011760c3feead3ea35092ab8aae21cae0874f5fc | |
| parent | 73bd4a53dd54c300ffa539f23a521083172d6253 (diff) | |
Fix for bug in Mutter Wayland compositor (#878)
Mutter implements too strictly this rule expected from compositors about "frame callbacks" :
"A server should avoid signaling the frame callbacks if the surface is not visible in any way,
e.g. the surface is off-screen, or completely obscured by other opaque surfaces."
When a window is being interactively resized, it makes no sense to create a frame callback
for an entirely covered surface but then never signal the surface can be redrawn,
because this blocks the resize operation.
Neither KWin nor Weston have this problem.
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 6 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 28 |
3 files changed, 33 insertions, 2 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index b2def3703..3ec0ffd38 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -176,8 +176,10 @@ void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, struct wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0); wl_surface_set_buffer_scale( window->wl_surface, Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale() ); - window->buffer->cb = wl_surface_frame(window->wl_surface); - wl_callback_add_listener(window->buffer->cb, &surface_frame_listener, window); + if (!window->covered) { // see issue #878 + window->buffer->cb = wl_surface_frame(window->wl_surface); + wl_callback_add_listener(window->buffer->cb, &surface_frame_listener, window); + } wl_surface_commit(window->wl_surface); window->buffer->draw_buffer_needs_commit = false; } diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H index 30e19e184..b3d530f00 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H @@ -163,6 +163,7 @@ struct wld_window { int floating_width; int floating_height; int state; + bool covered; }; diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 1345c17a2..637d47486 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -1790,6 +1790,29 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx } +// does win entirely cover its parent ? +static void does_window_cover_parent(Fl_Window *win) { + if (win->parent()) { + Fl_Window *parent = win->window(); + if (win->x() <= 0 && win->y() <= 0 && win->w() >= parent->w() && + win->h() >= parent->h()) { + struct wld_window *xid = fl_wl_xid(parent); + xid->covered = true; + } + } +} + + +// recursively explore all subwindows in a window +static void scan_subwindows(Fl_Group *g, void (*f)(Fl_Window *)) { + for (int i = 0; i < g->children(); i++) { + Fl_Widget *o = g->child(i); + if (o->as_window()) f(o->as_window()); + if (o->as_group()) scan_subwindows(o->as_group(), f); + } +} + + void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { struct wld_window *fl_win = fl_wl_xid(pWindow); if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) { @@ -1885,6 +1908,11 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { if (fl_win && fl_win->kind == SUBWINDOW && fl_win->subsurface) checkSubwindowFrame(); // make sure subwindow doesn't leak outside parent + + if (Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::MUTTER && + !pWindow->parent()) { // fix for MUTTER bug described in issue #878 + scan_subwindows(pWindow, does_window_cover_parent); + } } |
