mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 05:12:15 +00:00
x11: Handle ConfigureRequest events in frames
Under strange timings, the GTK frames client may implicitly queue relayouts that end up disagreeing with the latest frame size as given by Mutter, this results in GTK calling XResizeWindow, and Mutter plain out ignoring the resulting XConfigureRequestEvent received. This however makes GTK think there's pending resize operations, so at the next resize it will freeze the window, until enough resizes happened to thaw it again. This is seen as temporary loss of frame-sync ness (e.g. frozen frame, and other weird behavior). In order to make GTK happy and balanced, reply to this XConfigureRequest, even if just to ignore it in a more polite way (we simply re-apply the size Mutter thinks the frame should have, not GTK), this results in the right amount of ConfigureNotify received on the frames client side, and the surface to be thawed more timely, while enforcing the size as managed by Mutter. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2837 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3189>
This commit is contained in:
parent
c3eb819564
commit
630f13db78
@ -440,6 +440,34 @@ meta_frame_get_xwindow (MetaFrame *frame)
|
||||
return frame->xwindow;
|
||||
}
|
||||
|
||||
static void
|
||||
send_configure_notify (MetaFrame *frame)
|
||||
{
|
||||
MetaX11Display *x11_display = frame->window->display->x11_display;
|
||||
XEvent event = { 0 };
|
||||
|
||||
/* We never get told by the frames client, just reassert the
|
||||
* current frame size.
|
||||
*/
|
||||
event.type = ConfigureNotify;
|
||||
event.xconfigure.display = x11_display->xdisplay;
|
||||
event.xconfigure.event = frame->xwindow;
|
||||
event.xconfigure.window = frame->xwindow;
|
||||
event.xconfigure.x = frame->rect.x;
|
||||
event.xconfigure.y = frame->rect.y;
|
||||
event.xconfigure.width = frame->rect.width;
|
||||
event.xconfigure.height = frame->rect.height;
|
||||
event.xconfigure.border_width = 0;
|
||||
event.xconfigure.above = None;
|
||||
event.xconfigure.override_redirect = False;
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (x11_display->xdisplay,
|
||||
frame->xwindow,
|
||||
False, StructureNotifyMask, &event);
|
||||
meta_x11_error_trap_pop (x11_display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_frame_handle_xevent (MetaFrame *frame,
|
||||
XEvent *xevent)
|
||||
@ -465,6 +493,12 @@ meta_frame_handle_xevent (MetaFrame *frame,
|
||||
xevent->xproperty.atom, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (xevent->xany.type == ConfigureRequest &&
|
||||
xevent->xconfigurerequest.window == frame->xwindow)
|
||||
{
|
||||
send_configure_notify (frame);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1601,6 +1601,10 @@ handle_other_xevent (MetaX11Display *x11_display,
|
||||
{
|
||||
meta_window_x11_configure_request (window, event);
|
||||
}
|
||||
else if (frame_was_receiver && window->frame)
|
||||
{
|
||||
meta_frame_handle_xevent (window->frame, event);
|
||||
}
|
||||
break;
|
||||
case GravityNotify:
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user