summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2023-12-28 09:59:51 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2023-12-28 09:59:51 +0100
commit614376488568e3eae2289e7d15e453ad6d7285af (patch)
tree011760c3feead3ea35092ab8aae21cae0874f5fc /src
parent73bd4a53dd54c300ffa539f23a521083172d6253 (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')
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx6
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.H1
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx28
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);
+ }
}