frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2022 Red Hat Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author: Carlos Garnacho <carlosg@gnome.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "meta-frame.h"
|
|
|
|
|
|
|
|
#include "meta-frame-content.h"
|
|
|
|
#include "meta-frame-header.h"
|
|
|
|
|
|
|
|
#include <gdk/x11/gdkx.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
|
|
|
|
struct _MetaFrame
|
|
|
|
{
|
|
|
|
GtkWindow parent_instance;
|
|
|
|
GtkWidget *content;
|
2023-02-27 12:51:30 +00:00
|
|
|
Atom atom__NET_WM_NAME;
|
|
|
|
Atom atom__MOTIF_WM_HINTS;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
};
|
|
|
|
|
2022-12-05 23:02:19 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
unsigned long functions;
|
|
|
|
unsigned long decorations;
|
|
|
|
long input_mode;
|
|
|
|
unsigned long status;
|
|
|
|
} MotifWmHints;
|
|
|
|
|
|
|
|
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
|
|
|
|
|
|
|
#define MWM_FUNC_ALL (1L << 0)
|
|
|
|
#define MWM_FUNC_RESIZE (1L << 1)
|
|
|
|
#define MWM_FUNC_MINIMIZE (1L << 3)
|
|
|
|
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
|
|
|
#define MWM_FUNC_CLOSE (1L << 5)
|
|
|
|
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
G_DEFINE_TYPE (MetaFrame, meta_frame, GTK_TYPE_WINDOW)
|
|
|
|
|
2023-02-27 12:51:30 +00:00
|
|
|
static void
|
|
|
|
meta_frame_constructed (GObject *object)
|
|
|
|
{
|
|
|
|
MetaFrame *frame = META_FRAME (object);
|
|
|
|
GdkDisplay *display;
|
|
|
|
|
|
|
|
display = gtk_widget_get_display (GTK_WIDGET (object));
|
|
|
|
|
|
|
|
frame->atom__NET_WM_NAME =
|
|
|
|
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");
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (meta_frame_parent_class)->constructed (object);
|
|
|
|
}
|
|
|
|
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
static void
|
|
|
|
meta_frame_class_init (MetaFrameClass *klass)
|
|
|
|
{
|
2023-02-27 12:51:30 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->constructed = meta_frame_constructed;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
}
|
|
|
|
|
2022-12-10 00:51:59 +00:00
|
|
|
static gboolean
|
|
|
|
client_window_has_wm_protocol (MetaFrame *frame,
|
|
|
|
Window client_window,
|
|
|
|
Atom protocol)
|
|
|
|
{
|
|
|
|
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (frame));
|
|
|
|
Atom *wm_protocols, wm_protocols_atom;
|
|
|
|
int format;
|
|
|
|
Atom type;
|
|
|
|
unsigned long i, nitems, bytes_after;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
|
|
|
gdk_x11_display_error_trap_push (display);
|
|
|
|
|
|
|
|
wm_protocols_atom =
|
|
|
|
gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
|
|
|
|
|
|
|
|
if (XGetWindowProperty (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_window,
|
|
|
|
wm_protocols_atom,
|
|
|
|
0, G_MAXLONG, False,
|
|
|
|
XA_ATOM,
|
|
|
|
&type, &format,
|
|
|
|
&nitems, &bytes_after,
|
|
|
|
(unsigned char **) &wm_protocols) != Success)
|
|
|
|
{
|
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gdk_x11_display_error_trap_pop (display))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (i = 0; i < nitems; i++)
|
|
|
|
{
|
|
|
|
if (wm_protocols[i] == protocol)
|
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XFree (wm_protocols);
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
static gboolean
|
|
|
|
on_frame_close_request (GtkWindow *window,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (window));
|
|
|
|
GtkWidget *content;
|
|
|
|
XClientMessageEvent ev;
|
|
|
|
Window client_xwindow;
|
2022-12-10 00:51:59 +00:00
|
|
|
Atom delete_window_atom;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
|
|
|
|
content = gtk_window_get_child (window);
|
|
|
|
if (!content)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
client_xwindow =
|
|
|
|
meta_frame_content_get_window (META_FRAME_CONTENT (content));
|
|
|
|
|
2022-12-10 00:51:59 +00:00
|
|
|
delete_window_atom =
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
|
|
|
|
|
|
|
|
gdk_x11_display_error_trap_push (display);
|
2022-12-10 00:51:59 +00:00
|
|
|
|
|
|
|
if (client_window_has_wm_protocol (META_FRAME (window),
|
|
|
|
client_xwindow,
|
|
|
|
delete_window_atom))
|
|
|
|
{
|
|
|
|
ev.type = ClientMessage;
|
|
|
|
ev.window = client_xwindow;
|
|
|
|
ev.message_type =
|
|
|
|
gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
|
|
|
|
ev.format = 32;
|
|
|
|
ev.data.l[0] = delete_window_atom;
|
|
|
|
ev.data.l[1] = 0; /* FIXME: missing timestamp */
|
|
|
|
|
|
|
|
XSendEvent (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_xwindow, False, 0, (XEvent*) &ev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XKillClient (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_xwindow);
|
|
|
|
}
|
|
|
|
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_frame_init (MetaFrame *frame)
|
|
|
|
{
|
|
|
|
g_signal_connect (frame, "close-request",
|
|
|
|
G_CALLBACK (on_frame_close_request), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_frame_update_extents (MetaFrame *frame,
|
|
|
|
GtkBorder border)
|
|
|
|
{
|
|
|
|
GtkWindow *window = GTK_WINDOW (frame);
|
|
|
|
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (frame));
|
|
|
|
GdkSurface *surface;
|
|
|
|
Window xframe;
|
|
|
|
unsigned long data[4];
|
|
|
|
|
|
|
|
surface = gtk_native_get_surface (GTK_NATIVE (window));
|
|
|
|
if (!surface)
|
|
|
|
return;
|
|
|
|
|
|
|
|
data[0] = border.left;
|
|
|
|
data[1] = border.right;
|
|
|
|
data[2] = border.top;
|
|
|
|
data[3] = border.bottom;
|
|
|
|
|
|
|
|
xframe = gdk_x11_surface_get_xid (surface);
|
2022-12-06 14:29:41 +00:00
|
|
|
|
|
|
|
gdk_x11_display_error_trap_push (display);
|
|
|
|
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
XChangeProperty (gdk_x11_display_get_xdisplay (display),
|
|
|
|
xframe,
|
|
|
|
gdk_x11_get_xatom_by_name_for_display (display, "_MUTTER_FRAME_EXTENTS"),
|
|
|
|
XA_CARDINAL,
|
|
|
|
32,
|
|
|
|
PropModeReplace,
|
|
|
|
(guchar *) &data, 4);
|
2022-12-06 14:29:41 +00:00
|
|
|
|
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
meta_frame_update_extents (frame, border);
|
|
|
|
}
|
|
|
|
|
2023-02-27 13:12:19 +00:00
|
|
|
static char *
|
|
|
|
get_utf8_string_prop (GtkWindow *window,
|
|
|
|
Window client_window,
|
|
|
|
Atom prop)
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
{
|
2023-02-27 12:51:30 +00:00
|
|
|
MetaFrame *frame = META_FRAME (window);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
GdkDisplay *display;
|
2023-02-27 13:12:19 +00:00
|
|
|
char *str = NULL;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
int format;
|
|
|
|
Atom type;
|
|
|
|
unsigned long nitems, bytes_after;
|
|
|
|
|
|
|
|
display = gtk_widget_get_display (GTK_WIDGET (frame));
|
|
|
|
|
2022-12-06 14:29:41 +00:00
|
|
|
gdk_x11_display_error_trap_push (display);
|
|
|
|
|
|
|
|
if (XGetWindowProperty (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_window,
|
2023-02-27 13:12:19 +00:00
|
|
|
prop,
|
2022-12-06 14:29:41 +00:00
|
|
|
0, G_MAXLONG, False,
|
|
|
|
gdk_x11_get_xatom_by_name_for_display (display,
|
|
|
|
"UTF8_STRING"),
|
|
|
|
&type, &format,
|
|
|
|
&nitems, &bytes_after,
|
2023-02-27 13:12:19 +00:00
|
|
|
(unsigned char **) &str) != Success)
|
2022-12-06 14:29:41 +00:00
|
|
|
{
|
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
2023-02-27 13:12:19 +00:00
|
|
|
return NULL;
|
2022-12-06 14:29:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gdk_x11_display_error_trap_pop (display))
|
2023-02-27 13:12:19 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
frame_sync_net_wm_name (GtkWindow *window,
|
|
|
|
Window client_window)
|
|
|
|
{
|
|
|
|
MetaFrame *frame = META_FRAME (window);
|
|
|
|
char *title;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
|
2023-02-27 13:12:19 +00:00
|
|
|
title = get_utf8_string_prop (window, client_window,
|
|
|
|
frame->atom__NET_WM_NAME);
|
2023-02-27 12:51:30 +00:00
|
|
|
gtk_window_set_title (window, title ? title : "");
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
g_free (title);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-02-27 12:51:30 +00:00
|
|
|
frame_sync_motif_wm_hints (GtkWindow *window,
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
Window client_window)
|
|
|
|
{
|
2023-02-27 12:51:30 +00:00
|
|
|
MetaFrame *frame = META_FRAME (window);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
GdkDisplay *display;
|
|
|
|
MotifWmHints *mwm_hints = NULL;
|
|
|
|
int format;
|
|
|
|
Atom type;
|
|
|
|
unsigned long nitems, bytes_after;
|
|
|
|
gboolean deletable = TRUE;
|
|
|
|
|
|
|
|
display = gtk_widget_get_display (GTK_WIDGET (frame));
|
|
|
|
|
2022-12-06 14:29:41 +00:00
|
|
|
gdk_x11_display_error_trap_push (display);
|
|
|
|
|
|
|
|
if (XGetWindowProperty (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_window,
|
2023-02-27 12:51:30 +00:00
|
|
|
frame->atom__MOTIF_WM_HINTS,
|
2022-12-06 14:29:41 +00:00
|
|
|
0, sizeof (MotifWmHints) / sizeof (long),
|
|
|
|
False, AnyPropertyType,
|
|
|
|
&type, &format,
|
|
|
|
&nitems, &bytes_after,
|
|
|
|
(unsigned char **) &mwm_hints) != Success)
|
|
|
|
{
|
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gdk_x11_display_error_trap_pop (display))
|
|
|
|
return;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
|
2022-12-04 11:03:44 +00:00
|
|
|
if (mwm_hints &&
|
|
|
|
(mwm_hints->flags & MWM_HINTS_FUNCTIONS) != 0)
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
{
|
|
|
|
if ((mwm_hints->functions & MWM_FUNC_ALL) == 0)
|
|
|
|
deletable = (mwm_hints->functions & MWM_FUNC_CLOSE) != 0;
|
|
|
|
else
|
|
|
|
deletable = (mwm_hints->functions & MWM_FUNC_CLOSE) == 0;
|
|
|
|
}
|
|
|
|
|
2023-02-27 12:51:30 +00:00
|
|
|
gtk_window_set_deletable (window, deletable);
|
2022-12-04 11:03:44 +00:00
|
|
|
g_free (mwm_hints);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
frame_sync_wm_normal_hints (GtkWindow *frame,
|
|
|
|
Window client_window)
|
|
|
|
{
|
|
|
|
GdkDisplay *display;
|
|
|
|
XSizeHints size_hints;
|
|
|
|
long nitems;
|
|
|
|
gboolean resizable = TRUE;
|
|
|
|
|
|
|
|
display = gtk_widget_get_display (GTK_WIDGET (frame));
|
|
|
|
|
2022-12-06 14:29:41 +00:00
|
|
|
gdk_x11_display_error_trap_push (display);
|
|
|
|
|
|
|
|
if (XGetWMNormalHints (gdk_x11_display_get_xdisplay (display),
|
|
|
|
client_window,
|
|
|
|
&size_hints,
|
|
|
|
&nitems) != Success)
|
|
|
|
{
|
|
|
|
gdk_x11_display_error_trap_pop_ignored (display);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gdk_x11_display_error_trap_pop (display))
|
|
|
|
return;
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
|
|
|
|
if (nitems > 0)
|
|
|
|
{
|
|
|
|
resizable = ((size_hints.flags & PMinSize) == 0 ||
|
|
|
|
(size_hints.flags & PMaxSize) == 0 ||
|
|
|
|
size_hints.min_width != size_hints.max_width ||
|
|
|
|
size_hints.min_height != size_hints.max_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_window_set_resizable (frame, resizable);
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget *
|
|
|
|
meta_frame_new (Window window)
|
|
|
|
{
|
|
|
|
GtkWidget *frame, *header, *content;
|
|
|
|
GdkSurface *surface;
|
|
|
|
int frame_height;
|
|
|
|
double scale;
|
|
|
|
|
|
|
|
frame = g_object_new (META_TYPE_FRAME, NULL);
|
|
|
|
|
|
|
|
header = meta_frame_header_new ();
|
|
|
|
|
|
|
|
gtk_window_set_titlebar (GTK_WINDOW (frame), header);
|
|
|
|
|
|
|
|
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));
|
2022-09-09 13:54:28 +00:00
|
|
|
gdk_x11_surface_set_frame_sync_enabled (surface, TRUE);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
|
|
|
|
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)));
|
|
|
|
|
|
|
|
meta_frame_update_extents (META_FRAME (frame),
|
|
|
|
(GtkBorder) {
|
|
|
|
0, 0,
|
|
|
|
frame_height * scale, 0,
|
|
|
|
});
|
|
|
|
|
2023-02-27 12:53:43 +00:00
|
|
|
frame_sync_net_wm_name (GTK_WINDOW (frame), window);
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
frame_sync_motif_wm_hints (GTK_WINDOW (frame), window);
|
|
|
|
frame_sync_wm_normal_hints (GTK_WINDOW (frame), window);
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_frame_handle_xevent (MetaFrame *frame,
|
|
|
|
Window window,
|
|
|
|
XEvent *xevent)
|
|
|
|
{
|
|
|
|
GtkWidget *content;
|
|
|
|
gboolean is_frame, is_content;
|
|
|
|
GdkSurface *surface;
|
|
|
|
|
|
|
|
surface = gtk_native_get_surface (GTK_NATIVE (frame));
|
|
|
|
if (!surface)
|
|
|
|
return;
|
|
|
|
|
|
|
|
content = gtk_window_get_child (GTK_WINDOW (frame));
|
|
|
|
if (!content)
|
|
|
|
return;
|
|
|
|
|
|
|
|
is_frame = window == gdk_x11_surface_get_xid (surface);
|
|
|
|
is_content =
|
|
|
|
window == meta_frame_content_get_window (META_FRAME_CONTENT (content));
|
|
|
|
|
|
|
|
if (!is_frame && !is_content)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (is_content && xevent->type == PropertyNotify)
|
|
|
|
{
|
2023-02-27 12:51:30 +00:00
|
|
|
if (xevent->xproperty.atom == frame->atom__NET_WM_NAME)
|
2023-02-27 12:53:43 +00:00
|
|
|
frame_sync_net_wm_name (GTK_WINDOW (frame), xevent->xproperty.window);
|
2023-02-27 12:51:30 +00:00
|
|
|
else if (xevent->xproperty.atom == frame->atom__MOTIF_WM_HINTS)
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
frame_sync_motif_wm_hints (GTK_WINDOW (frame), xevent->xproperty.window);
|
2023-02-27 12:51:30 +00:00
|
|
|
else if (xevent->xproperty.atom == XA_WM_NORMAL_HINTS)
|
frames: Add new X11 frames client
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
2021-12-21 20:11:05 +00:00
|
|
|
frame_sync_wm_normal_hints (GTK_WINDOW (frame), xevent->xproperty.window);
|
|
|
|
}
|
|
|
|
}
|