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.
This commit is contained in:
parent
73bd4a53dd
commit
6143764885
@ -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;
|
||||
}
|
||||
|
@ -163,6 +163,7 @@ struct wld_window {
|
||||
int floating_width;
|
||||
int floating_height;
|
||||
int state;
|
||||
bool covered;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user