frames: Notify borders on first content resize

This addresses the following race condition:
1. Window+MetaFrame are created non-fullscreen, _MUTTER_FRAME_EXTENTS
   is initialized through widget measuring, accounting for frame.
2. Window and MetaFrame become fullscreen.
3. MetaFrameContent gets first size allocation, already fullscreen.
4. Borders were initialized to 0,0,0,0, become set to 0,0,0,0 correctly
   reflecting fullscreen, however notify::borders is not emitted.
5. _MUTTER_FRAME_EXTENTS stays accounting for the frame extents.

It sounds sensible to have the borders initialized to a meaningful value,
so account for the first time the border would be set due to the content
being (re)sized, and let this first value trigger notify::borders resulting
in _MUTTER_FRAME_EXTENTS updates.

Since all later _MUTTER_FRAME_EXTENTS changes happen through content
resizes, we only have to cater for this initial handover between the
frame/content initialization paths done through widget measuring and
the later paths done through MetaFrameContent resizes.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2937
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3476>
This commit is contained in:
Carlos Garnacho 2024-01-02 13:42:57 +01:00 committed by Marge Bot
parent 5964ccb385
commit 4f68713020

View File

@ -26,6 +26,7 @@ struct _MetaFrameContent
GtkWidget parent_instance; GtkWidget parent_instance;
Window window; Window window;
GtkBorder border; GtkBorder border;
gboolean border_initialized;
}; };
enum { enum {
@ -100,13 +101,15 @@ static void
meta_frame_content_update_border (MetaFrameContent *content, meta_frame_content_update_border (MetaFrameContent *content,
GtkBorder border) GtkBorder border)
{ {
if (content->border.left == border.left && if (content->border_initialized &&
content->border.left == border.left &&
content->border.right == border.right && content->border.right == border.right &&
content->border.top == border.top && content->border.top == border.top &&
content->border.bottom == border.bottom) content->border.bottom == border.bottom)
return; return;
content->border = border; content->border = border;
content->border_initialized = TRUE;
g_object_notify (G_OBJECT (content), "border"); g_object_notify (G_OBJECT (content), "border");
} }