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>
This commit is contained in:
parent
6fbe4286ea
commit
2a600ac98e
@ -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)));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user