diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2023-04-14 14:40:28 +0200 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2023-04-14 13:55:23 +0000 |
commit | 2a600ac98e5d47f68a3e39dc12801a5e1c7bb7fa (patch) | |
tree | ad41ca28843ca008cf12fcc4224c9b23c802448c | |
parent | 6fbe4286eab576168b7f83b46207ad672de14de7 (diff) | |
download | mutter-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.c | 53 |
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))); |