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:
Carlos Garnacho 2023-08-17 12:13:47 +02:00 committed by Marge Bot
parent c3eb819564
commit 630f13db78
2 changed files with 38 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;