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 /src/drivers/Wayland | |
| 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.
Diffstat (limited to 'src/drivers/Wayland')
| -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); + } } |
