summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2023-04-14 14:40:28 +0200
committerMarge Bot <marge-bot@gnome.org>2023-04-14 13:55:23 +0000
commit2a600ac98e5d47f68a3e39dc12801a5e1c7bb7fa (patch)
treead41ca28843ca008cf12fcc4224c9b23c802448c
parent6fbe4286eab576168b7f83b46207ad672de14de7 (diff)
downloadmutter-2a600ac98e5d47f68a3e39dc12801a5e1c7bb7fa.tar.gz
frames: Forward _NET_WM_STATE during frame initialization
Ensure the frame window is created at the right fullscreen state before showing it and assigning it to the client window. A peculiarity of this property on frame windows is that it is typically single-handedly updated from the Mutter side, in synchronization with client window state. It can only differ during creation, since GTK still likes to apply its own state. Also, the only relevant property seems to be _NET_WM_STATE_FULLSCREEN, since the others are less relevant to the role of the frames client, and get applied to the MetaWindow as a whole, instead. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2712 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2961>
-rw-r--r--src/frames/meta-frame.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/src/frames/meta-frame.c b/src/frames/meta-frame.c
index 73ac90d92..21be7c140 100644
--- a/src/frames/meta-frame.c
+++ b/src/frames/meta-frame.c
@@ -34,6 +34,8 @@ struct _MetaFrame
Atom atom__NET_WM_VISIBLE_NAME;
Atom atom__NET_WM_NAME;
Atom atom__MOTIF_WM_HINTS;
+ Atom atom__NET_WM_STATE;
+ Atom atom__NET_WM_STATE_FULLSCREEN;
char *net_wm_visible_name;
char *net_wm_name;
@@ -73,6 +75,10 @@ meta_frame_constructed (GObject *object)
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME");
frame->atom__MOTIF_WM_HINTS =
gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_WM_HINTS");
+ frame->atom__NET_WM_STATE =
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
+ frame->atom__NET_WM_STATE_FULLSCREEN =
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
G_OBJECT_CLASS (meta_frame_parent_class)->constructed (object);
}
@@ -463,12 +469,44 @@ frame_sync_wm_normal_hints (GtkWindow *frame,
gtk_window_set_resizable (frame, resizable);
}
+static void
+frame_sync_wm_state (MetaFrame *frame,
+ Window client_window)
+{
+ GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (frame));
+ Display *xdisplay = gdk_x11_display_get_xdisplay (display);
+ Atom *data = NULL, type;
+ int format;
+ unsigned long i, nitems, bytes_after;
+
+ gdk_x11_display_error_trap_push (display);
+
+ XGetWindowProperty (xdisplay,
+ client_window,
+ frame->atom__NET_WM_STATE,
+ 0, 32,
+ False, XA_ATOM,
+ &type, &format,
+ &nitems, &bytes_after,
+ (unsigned char **) &data);
+
+ for (i = 0; i < nitems; i++)
+ {
+ if (data[i] == frame->atom__NET_WM_STATE_FULLSCREEN)
+ gtk_window_fullscreen (GTK_WINDOW (frame));
+ }
+
+ gdk_x11_display_error_trap_pop_ignored (display);
+
+ XFree (data);
+}
+
GtkWidget *
meta_frame_new (Window window)
{
GtkWidget *frame, *header, *content;
GdkSurface *surface;
- int frame_height;
+ int frame_height = 0;
double scale;
frame = g_object_new (META_TYPE_FRAME, NULL);
@@ -487,10 +525,15 @@ meta_frame_new (Window window)
surface = gtk_native_get_surface (GTK_NATIVE (frame));
gdk_x11_surface_set_frame_sync_enabled (surface, TRUE);
- gtk_widget_measure (header,
- GTK_ORIENTATION_VERTICAL, 1,
- &frame_height,
- NULL, NULL, NULL);
+ frame_sync_wm_state (META_FRAME (frame), window);
+
+ if (!gtk_window_is_fullscreen (GTK_WINDOW (frame)))
+ {
+ gtk_widget_measure (header,
+ GTK_ORIENTATION_VERTICAL, 1,
+ &frame_height,
+ NULL, NULL, NULL);
+ }
scale = gdk_surface_get_scale_factor (gtk_native_get_surface (GTK_NATIVE (frame)));