Skip to content

Commit 82885a1

Browse files
authored
[Wayland] Bump gtk-shell-v1 protocol to version 6 (#736)
* [Wayland] gtk-shell: Fix MetaWaylandGtkSurface leak on surface destroy The MetaWaylandSurface corresponding to a MetaWaylandGtkSurface can be destroyed before the MetaWaylandGtkSurface is destroyed. In its destroy function MetaWaylandSurface however was unsetting the destructor of the correspnding resource along with the gtk_surface1 interface implementation. This was done to prevent further gtk_surface1 requests on a NULLed MetaWaylandSurface, if it has been destroyed before the MetaWaylandGtkSurface. It would be enough to just unset the resource implementation, while keeping the destructor to fix this leak. However the following commit will rely on the implementation being available after the MetaWaylandSurface has been destroyed. So instead introduce NULL checks for all functions that can be called on the gtk_surface1 interface and do not unset the implementation. Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1307/diffs?commit_id=b41c4aec2677a48e30a54f731b3d7ef9924b48ea * [Wayland] gtk-shell: Add an explicit gtk-shell surface release request Previously the wl_resource and MetaWaylandGtkSurface corresponding to any client gtk_surface have been kept around until the exit of the client due to the client side destroy method not signaling the destruction to the server. Ideally the protocol would have specified a destroy request marked as destructor to handle this automatically, however this is no longer possible due to the destroy method being implicitly generated in the absence of an explicit request in the protocol. Adding a destroy request marked as destructor now would generate a new destroy method that unconditionally would send the request to the server, which would break clients running on servers not supporting that request. So instead of modifying the destroy request add a new "release" destructor, that indicates to the server that it can release the resource. This can be optionally be used by clients depending on the server protocol version. Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1307/diffs?commit_id=c9aa43aa7a40bb0a74c9d98836599825441fc154 * [Wayland] Bump gtk-shell-v1 protocol to version 5 Added titlebar_gesture request. This allows client to delegate titlebar gestures to the compositor, which allows for better consistency with server-side decorations, and a wider range of actions (including lower-on-middle-click). Original Mutter MR: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1944 * [Wayland] Bump gtk-shell-v1 protocol to version 6 No actual changes. We will use this version to hint GTK about the availability of non broken wl_surface.offset support for pointer cursors. * Replace all G_DESKTOP with C_DESKTOP * debian: update libmuffin0.symbols
1 parent 6607c1a commit 82885a1

File tree

7 files changed

+207
-54
lines changed

7 files changed

+207
-54
lines changed

debian/libmuffin0.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ libmuffin-clutter-0.so.0 libmuffin0 #MINVER#
879879
clutter_modifier_type_get_type@Base 5.3.0
880880
clutter_offscreen_effect_create_texture@Base 5.3.0
881881
clutter_offscreen_effect_get_pipeline@Base 6.6.0
882+
clutter_offscreen_effect_get_pipeline@Base 6.4.1
882883
clutter_offscreen_effect_get_target@Base 5.3.0
883884
clutter_offscreen_effect_get_target_rect@Base 5.3.0
884885
clutter_offscreen_effect_get_target_size@Base 5.3.0
@@ -2670,6 +2671,7 @@ libmuffin.so.0 libmuffin0 #MINVER#
26702671
meta_window_kill@Base 5.3.0
26712672
meta_window_located_on_workspace@Base 5.3.0
26722673
meta_window_lower@Base 5.3.0
2674+
meta_window_lower_with_transients@Base 6.4.1
26732675
meta_window_make_above@Base 5.3.0
26742676
meta_window_make_fullscreen@Base 5.3.0
26752677
meta_window_maximize@Base 5.3.0

src/core/window.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5624,6 +5624,62 @@ meta_window_lower (MetaWindow *window)
56245624
meta_stack_lower (window->display->stack, window);
56255625
}
56265626

5627+
static gboolean
5628+
lower_window_and_transients (MetaWindow *window,
5629+
gpointer user_data)
5630+
{
5631+
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
5632+
5633+
meta_window_lower (window);
5634+
5635+
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
5636+
5637+
if (meta_prefs_get_raise_on_click ())
5638+
{
5639+
/* Move window to the back of the focusing workspace's MRU list.
5640+
* Do extra sanity checks to avoid possible race conditions.
5641+
* (Borrowed from window.c.)
5642+
*/
5643+
if (workspace_manager->active_workspace &&
5644+
meta_window_located_on_workspace (window,
5645+
workspace_manager->active_workspace))
5646+
{
5647+
GList *link;
5648+
link = g_list_find (workspace_manager->active_workspace->mru_list,
5649+
window);
5650+
g_assert (link);
5651+
5652+
workspace_manager->active_workspace->mru_list =
5653+
g_list_remove_link (workspace_manager->active_workspace->mru_list,
5654+
link);
5655+
g_list_free (link);
5656+
5657+
workspace_manager->active_workspace->mru_list =
5658+
g_list_append (workspace_manager->active_workspace->mru_list,
5659+
window);
5660+
}
5661+
}
5662+
5663+
return FALSE;
5664+
}
5665+
5666+
void
5667+
meta_window_lower_with_transients (MetaWindow *window,
5668+
uint32_t timestamp)
5669+
{
5670+
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
5671+
5672+
lower_window_and_transients (window, NULL);
5673+
5674+
/* Rather than try to figure that out whether we just lowered
5675+
* the focus window, assume that's always the case. (Typically,
5676+
* this will be invoked via keyboard action or by a mouse action;
5677+
* in either case the window or a modal child will have been focused.) */
5678+
meta_workspace_focus_default_window (workspace_manager->active_workspace,
5679+
NULL,
5680+
timestamp);
5681+
}
5682+
56275683
/*
56285684
* Move window to the requested workspace; append controls whether new WS
56295685
* should be created if one does not exist.

src/meta/window.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ void meta_window_raise (MetaWindow *window);
317317
META_EXPORT
318318
void meta_window_lower (MetaWindow *window);
319319

320+
META_EXPORT
321+
void meta_window_lower_with_transients (MetaWindow *window,
322+
uint32_t timestamp);
323+
320324
META_EXPORT
321325
const char *meta_window_get_title (MetaWindow *window);
322326

src/wayland/meta-wayland-gtk-shell.c

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ gtk_surface_set_dbus_properties (struct wl_client *client,
8383
MetaWaylandSurface *surface = gtk_surface->surface;
8484
MetaWindow *window;
8585

86+
if (!surface)
87+
return;
88+
8689
window = meta_wayland_surface_get_window (surface);
8790
if (!window)
8891
return;
@@ -104,6 +107,9 @@ gtk_surface_set_modal (struct wl_client *client,
104107
MetaWaylandSurface *surface = gtk_surface->surface;
105108
MetaWindow *window;
106109

110+
if (!surface)
111+
return;
112+
107113
window = meta_wayland_surface_get_window (surface);
108114
if (!window)
109115
return;
@@ -123,6 +129,9 @@ gtk_surface_unset_modal (struct wl_client *client,
123129
MetaWaylandSurface *surface = gtk_surface->surface;
124130
MetaWindow *window;
125131

132+
if (!surface)
133+
return;
134+
126135
window = meta_wayland_surface_get_window (surface);
127136
if (!window)
128137
return;
@@ -143,6 +152,9 @@ gtk_surface_present (struct wl_client *client,
143152
MetaWaylandSurface *surface = gtk_surface->surface;
144153
MetaWindow *window;
145154

155+
if (!surface)
156+
return;
157+
146158
window = meta_wayland_surface_get_window (surface);
147159
if (!window)
148160
return;
@@ -162,6 +174,9 @@ gtk_surface_request_focus (struct wl_client *client,
162174
MetaStartupSequence *sequence = NULL;
163175
MetaWindow *window;
164176

177+
if (!surface)
178+
return;
179+
165180
window = meta_wayland_surface_get_window (surface);
166181
if (!window)
167182
return;
@@ -193,19 +208,119 @@ gtk_surface_request_focus (struct wl_client *client,
193208
}
194209
}
195210

211+
static void
212+
gtk_surface_titlebar_gesture (struct wl_client *client,
213+
struct wl_resource *resource,
214+
uint32_t serial,
215+
struct wl_resource *seat_resource,
216+
uint32_t gesture)
217+
{
218+
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
219+
MetaWaylandSurface *surface = gtk_surface->surface;
220+
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
221+
CDesktopTitlebarAction action = C_DESKTOP_TITLEBAR_ACTION_NONE;
222+
MetaWindow *window;
223+
float x, y;
224+
225+
if (!surface)
226+
return;
227+
228+
window = meta_wayland_surface_get_window (surface);
229+
if (!window)
230+
return;
231+
232+
233+
234+
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, &x, &y))
235+
return;
236+
237+
switch (gesture)
238+
{
239+
case GTK_SURFACE1_GESTURE_DOUBLE_CLICK:
240+
action = meta_prefs_get_action_double_click_titlebar ();
241+
break;
242+
case GTK_SURFACE1_GESTURE_RIGHT_CLICK:
243+
action = meta_prefs_get_action_right_click_titlebar ();
244+
break;
245+
case GTK_SURFACE1_GESTURE_MIDDLE_CLICK:
246+
action = meta_prefs_get_action_middle_click_titlebar ();
247+
break;
248+
default:
249+
wl_resource_post_error (resource,
250+
GTK_SURFACE1_ERROR_INVALID_GESTURE,
251+
"Invalid gesture passed");
252+
break;
253+
254+
}
255+
256+
switch (action)
257+
{
258+
case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE:
259+
if (META_WINDOW_MAXIMIZED (window))
260+
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
261+
else
262+
meta_window_maximize (window, META_MAXIMIZE_BOTH);
263+
break;
264+
265+
case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY:
266+
if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window))
267+
meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
268+
else
269+
meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
270+
break;
271+
272+
case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY:
273+
if (META_WINDOW_MAXIMIZED_VERTICALLY (window))
274+
meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
275+
else
276+
meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
277+
break;
278+
279+
case C_DESKTOP_TITLEBAR_ACTION_MINIMIZE:
280+
meta_window_minimize (window);
281+
break;
282+
283+
case C_DESKTOP_TITLEBAR_ACTION_LOWER:
284+
{
285+
uint32_t timestamp;
286+
287+
timestamp = meta_display_get_current_time_roundtrip (window->display);
288+
meta_window_lower_with_transients (window, timestamp);
289+
}
290+
break;
291+
292+
case C_DESKTOP_TITLEBAR_ACTION_MENU:
293+
meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y);
294+
break;
295+
296+
case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
297+
g_warning ("No shade! The library is closed.");
298+
G_GNUC_FALLTHROUGH;
299+
default:
300+
return;
301+
}
302+
}
303+
304+
static void
305+
gtk_surface_release (struct wl_client *client,
306+
struct wl_resource *resource)
307+
{
308+
wl_resource_destroy (resource);
309+
}
310+
196311
static const struct gtk_surface1_interface meta_wayland_gtk_surface_interface = {
197312
gtk_surface_set_dbus_properties,
198313
gtk_surface_set_modal,
199314
gtk_surface_unset_modal,
200315
gtk_surface_present,
201316
gtk_surface_request_focus,
317+
gtk_surface_release,
318+
gtk_surface_titlebar_gesture
202319
};
203320

204321
static void
205322
gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface)
206323
{
207-
wl_resource_set_implementation (gtk_surface->resource,
208-
NULL, NULL, NULL);
209324
gtk_surface->surface = NULL;
210325
}
211326

src/wayland/meta-wayland-versions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#define META_WL_SEAT_VERSION 5
4242
#define META_WL_OUTPUT_VERSION 4
4343
#define META_XSERVER_VERSION 1
44-
#define META_GTK_SHELL1_VERSION 3
44+
#define META_GTK_SHELL1_VERSION 6
4545
#define META_WL_SUBCOMPOSITOR_VERSION 1
4646
#define META_ZWP_POINTER_GESTURES_V1_VERSION 3
4747
#define META_ZXDG_EXPORTER_V1_VERSION 1

src/wayland/protocol/gtk-shell.xml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<protocol name="gtk">
22

3-
<interface name="gtk_shell1" version="3">
3+
<interface name="gtk_shell1" version="6">
44
<description summary="gtk specific extensions">
55
gtk_shell is a protocol extension providing additional features for
66
clients implementing it.
@@ -33,9 +33,11 @@
3333
<request name="notify_launch" since="3">
3434
<arg name="startup_id" type="string"/>
3535
</request>
36+
37+
<!-- Version 6 does not add new API, but asserts that surface offsets are implemented -->
3638
</interface>
3739

38-
<interface name="gtk_surface1" version="3">
40+
<interface name="gtk_surface1" version="6">
3941
<request name="set_dbus_properties">
4042
<arg name="application_id" type="string" allow-null="true"/>
4143
<arg name="app_menu_path" type="string" allow-null="true"/>
@@ -82,6 +84,28 @@
8284
<request name="request_focus" since="3">
8385
<arg name="startup_id" type="string" allow-null="true"/>
8486
</request>
87+
88+
<!-- Version 4 additions -->
89+
<request name="release" type="destructor" since="4"/>
90+
91+
<!-- Version 5 additions -->
92+
<enum name="gesture" since="5">
93+
<entry name="double_click" value="1"/>
94+
<entry name="right_click" value="2"/>
95+
<entry name="middle_click" value="3"/>
96+
</enum>
97+
98+
<enum name="error" since="5">
99+
<entry name="invalid_gesture" value="0"/>
100+
</enum>
101+
102+
<request name="titlebar_gesture" since="5">
103+
<arg name="serial" type="uint"/>
104+
<arg name="seat" type="object" interface="wl_seat"/>
105+
<arg name="gesture" type="uint" enum="gesture"/>
106+
</request>
107+
108+
<!-- Version 6 does not add new API, but asserts that surface offsets are implemented -->
85109
</interface>
86110

87111
</protocol>

src/x11/meta-x11-window-control.c

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -61,62 +61,14 @@ meta_x11_wm_queue_frame_resize (MetaX11Display *x11_display,
6161
meta_window_frame_size_changed (window);
6262
}
6363

64-
static gboolean
65-
lower_window_and_transients (MetaWindow *window,
66-
gpointer data)
67-
{
68-
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
69-
70-
meta_window_lower (window);
71-
72-
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
73-
74-
if (meta_prefs_get_raise_on_click ())
75-
{
76-
/* Move window to the back of the focusing workspace's MRU list.
77-
* Do extra sanity checks to avoid possible race conditions.
78-
* (Borrowed from window.c.)
79-
*/
80-
if (workspace_manager->active_workspace &&
81-
meta_window_located_on_workspace (window,
82-
workspace_manager->active_workspace))
83-
{
84-
GList* link;
85-
link = g_list_find (workspace_manager->active_workspace->mru_list,
86-
window);
87-
g_assert (link);
88-
89-
workspace_manager->active_workspace->mru_list =
90-
g_list_remove_link (workspace_manager->active_workspace->mru_list,
91-
link);
92-
g_list_free (link);
93-
94-
workspace_manager->active_workspace->mru_list =
95-
g_list_append (workspace_manager->active_workspace->mru_list,
96-
window);
97-
}
98-
}
99-
100-
return FALSE;
101-
}
102-
10364
void
10465
meta_x11_wm_user_lower_and_unfocus (MetaX11Display *x11_display,
10566
Window frame_xwindow,
10667
uint32_t timestamp)
10768
{
10869
MetaWindow *window = window_from_frame (x11_display, frame_xwindow);
109-
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
110-
111-
lower_window_and_transients (window, NULL);
11270

113-
/* Rather than try to figure that out whether we just lowered
114-
* the focus window, assume that's always the case. (Typically,
115-
* this will be invoked via keyboard action or by a mouse action;
116-
* in either case the window or a modal child will have been focused.) */
117-
meta_workspace_focus_default_window (workspace_manager->active_workspace,
118-
NULL,
119-
timestamp);
71+
meta_window_lower_with_transients (window, timestamp);
12072
}
12173

12274
void

0 commit comments

Comments
 (0)