mirror of
https://github.com/brl/mutter.git
synced 2025-01-07 10:12:14 +00:00
frames: Update _MUTTER_FRAME_EXTENTS from frame size_allocate
Relying on the content size_allocate() to determine the content position can fail in situations where the position of the content has changed, but not its size. This happens for example when the window initially is sized fullscreen height + headerbar height while not considered fullscreen yet. Then when the window is resized to just the fullscreen height and marked as fullscreen, the content size has not changed and size_allocate() is not called on the content. Thus the previous position which assumes the presence of a headerbar still applies. As a result the window is shifted down, revealing a headerbar sized area showing the gtk window background color. This issue can be avoided by using the frame's size_allocate(), which gets called in response to all relevant events, such as any headerbar size changes, headerbar visibility changes, window resizes and fullscreen status changes. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2937 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3608>
This commit is contained in:
parent
87c43ad15e
commit
bcdd282e9c
@ -30,6 +30,8 @@
|
||||
struct _MetaFrame
|
||||
{
|
||||
GtkWindow parent_instance;
|
||||
GtkBorder extents;
|
||||
|
||||
Atom atom__NET_WM_VISIBLE_NAME;
|
||||
Atom atom__NET_WM_NAME;
|
||||
Atom atom__MOTIF_WM_HINTS;
|
||||
@ -187,20 +189,8 @@ update_extents (MetaFrame *frame,
|
||||
(guchar *) &data, 4);
|
||||
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
}
|
||||
|
||||
static void
|
||||
on_border_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaFrame *frame = user_data;
|
||||
GtkWidget *content;
|
||||
GtkBorder border;
|
||||
|
||||
content = gtk_window_get_child (GTK_WINDOW (frame));
|
||||
border = meta_frame_content_get_border (META_FRAME_CONTENT (content));
|
||||
update_extents (frame, border);
|
||||
frame->extents = border;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -484,11 +474,47 @@ meta_frame_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_frame_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frame_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
MetaFrame *frame = META_FRAME (widget);
|
||||
GtkWidget *content;
|
||||
GtkBorder extents;
|
||||
graphene_point_t point = {};
|
||||
double scale;
|
||||
|
||||
GTK_WIDGET_CLASS (meta_frame_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
|
||||
content = gtk_window_get_child (GTK_WINDOW (frame));
|
||||
if (!content)
|
||||
return;
|
||||
|
||||
if (!gtk_widget_compute_point (content, widget, &point, &point))
|
||||
return;
|
||||
|
||||
scale = gdk_surface_get_scale_factor (gtk_native_get_surface (GTK_NATIVE (widget)));
|
||||
/* FIXME: right/bottom are broken, if they are ever other than 0. */
|
||||
extents = (GtkBorder) { point.x * scale, 0, point.y * scale, 0 };
|
||||
|
||||
if (frame->extents.left == extents.left &&
|
||||
frame->extents.right == extents.right &&
|
||||
frame->extents.top == extents.top &&
|
||||
frame->extents.bottom == extents.bottom)
|
||||
return;
|
||||
|
||||
update_extents (frame, extents);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frame_class_init (MetaFrameClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
widget_class->size_allocate = meta_frame_size_allocate;
|
||||
object_class->constructed = meta_frame_constructed;
|
||||
object_class->finalize = meta_frame_finalize;
|
||||
}
|
||||
@ -518,9 +544,6 @@ meta_frame_new (Window window)
|
||||
content = meta_frame_content_new (window);
|
||||
gtk_window_set_child (GTK_WINDOW (frame), content);
|
||||
|
||||
g_signal_connect (content, "notify::border",
|
||||
G_CALLBACK (on_border_changed), frame);
|
||||
|
||||
gtk_widget_realize (GTK_WIDGET (frame));
|
||||
surface = gtk_native_get_surface (GTK_NATIVE (frame));
|
||||
gdk_x11_surface_set_frame_sync_enabled (surface, TRUE);
|
||||
|
Loading…
Reference in New Issue
Block a user