Skip to content

Commit 825d03c

Browse files
authored
[Wayland] Add support for xdg-toplevel-tag-v1 protocol (#745)
* [Wayland] Add support for xdg-toplevel-tag-v1 protocol Implementation of the https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/238 wayland protocol. It allows to identify unique toplevels (windows) in order to set their initial size and position * include xdg-toplevel-tag protocol as private until we have more recent wayland-protocols version in Mint * Update libmuffin0.symbols * remove some whitespaces
1 parent fbf7541 commit 825d03c

File tree

12 files changed

+279
-0
lines changed

12 files changed

+279
-0
lines changed

debian/libmuffin0.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,6 +2637,7 @@ libmuffin.so.0 libmuffin0 #MINVER#
26372637
meta_window_get_sandboxed_app_id@Base 5.3.0
26382638
meta_window_get_stable_sequence@Base 5.3.0
26392639
meta_window_get_startup_id@Base 5.3.0
2640+
meta_window_get_tag@Base 6.4.1
26402641
meta_window_get_tile_match@Base 5.3.0
26412642
meta_window_get_title@Base 5.3.0
26422643
meta_window_get_transient_for@Base 5.3.0

src/core/window-private.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ struct _MetaWindow
203203
char *sm_client_id;
204204
char *wm_client_machine;
205205

206+
char *tag;
207+
206208
char *startup_id;
207209
char *muffin_hints;
208210
char *sandboxed_app_id;
@@ -912,4 +914,7 @@ gboolean meta_window_is_focus_async (MetaWindow *window);
912914
gboolean meta_window_calculate_bounds (MetaWindow *window,
913915
int *bounds_width,
914916
int *bounds_height);
917+
918+
void meta_window_set_tag (MetaWindow *window,
919+
const char *tag);
915920
#endif

src/core/window.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ enum
219219
PROP_PROGRESS_PULSE,
220220
PROP_TILE_MODE,
221221
PROP_OPACITY,
222+
PROP_TAG,
222223
PROP_LAST,
223224
};
224225

@@ -352,6 +353,7 @@ meta_window_finalize (GObject *object)
352353
g_free (window->gtk_app_menu_object_path);
353354
g_free (window->gtk_menubar_object_path);
354355
g_free (window->placement.rule);
356+
g_free (window->tag);
355357

356358
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
357359
}
@@ -453,6 +455,9 @@ meta_window_get_property(GObject *object,
453455
case PROP_OPACITY:
454456
g_value_set_uint (value, win->opacity);
455457
break;
458+
case PROP_TAG:
459+
g_value_set_string (value, win->tag);
460+
break;
456461
default:
457462
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
458463
break;
@@ -674,6 +679,12 @@ meta_window_class_init (MetaWindowClass *klass)
674679
0xFF,
675680
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
676681

682+
obj_props[PROP_TAG] =
683+
g_param_spec_string ("tag", NULL, NULL,
684+
NULL,
685+
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY |
686+
G_PARAM_STATIC_STRINGS);
687+
677688
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
678689

679690
window_signals[WORKSPACE_CHANGED] =
@@ -9534,3 +9545,29 @@ meta_window_calculate_bounds (MetaWindow *window,
95349545
return FALSE;
95359546
}
95369547
}
9548+
9549+
void
9550+
meta_window_set_tag (MetaWindow *window,
9551+
const char *tag)
9552+
{
9553+
if (g_set_str (&window->tag, tag))
9554+
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TAG]);
9555+
}
9556+
9557+
/**
9558+
* meta_window_get_tag:
9559+
* @window: A #MetaWindow
9560+
*
9561+
* Get a tag associated to the window.
9562+
* Under wayland the tag can be set using the toplevel tag protocol,
9563+
* and under x11 it falls back to using `NET_WM_WINDOW_TAG` atom.
9564+
*
9565+
* Returns: (nullable): An associated toplevel tag
9566+
*/
9567+
const char *
9568+
meta_window_get_tag (MetaWindow *window)
9569+
{
9570+
g_return_val_if_fail (META_IS_WINDOW (window), NULL);
9571+
9572+
return window->tag;
9573+
}

src/meson.build

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,8 @@ if have_wayland
591591
'wayland/meta-wayland-xdg-shell.h',
592592
'wayland/meta-wayland-xdg-dialog.c',
593593
'wayland/meta-wayland-xdg-dialog.h',
594+
'wayland/meta-wayland-xdg-toplevel-tag.c',
595+
'wayland/meta-wayland-xdg-toplevel-tag.h',
594596
'wayland/meta-window-wayland.c',
595597
'wayland/meta-window-wayland.h',
596598
'wayland/meta-window-xwayland.c',
@@ -817,6 +819,7 @@ if have_wayland
817819
['xdg-foreign', 'unstable', 'v2', ],
818820
['xdg-output', 'unstable', 'v1', ],
819821
['xdg-shell', 'stable', ],
822+
['xdg-toplevel-tag-v1', 'private', ],
820823
['xwayland-keyboard-grab', 'unstable', 'v1', ],
821824
]
822825
if have_wayland_eglstream

src/meta/window.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,7 @@ void meta_window_set_opacity (MetaWindow *window,
469469
META_EXPORT
470470
guint8 meta_window_get_opacity (MetaWindow *window);
471471

472+
META_EXPORT
473+
const char * meta_window_get_tag (MetaWindow *window);
474+
472475
#endif

src/wayland/meta-wayland-versions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@
5858
#define META_XDG_ACTIVATION_V1_VERSION 1
5959
#define META_XDG_DIALOG_VERSION 1
6060
#define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1
61+
#define META_XDG_TOPLEVEL_TAG_V1_VERSION 1
6162

6263
#endif
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (C) 2024 Red Hat
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License as
6+
* published by the Free Software Foundation; either version 2 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but
10+
* WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, see <http://www.gnu.org/licenses/>.
16+
*
17+
* Written by:
18+
* Bilal Elmoussaoui <[email protected]>
19+
*/
20+
21+
#include "config.h"
22+
23+
#include "wayland/meta-wayland-xdg-toplevel-tag.h"
24+
25+
#include <wayland-server.h>
26+
27+
#include "wayland/meta-wayland-private.h"
28+
#include "wayland/meta-wayland-versions.h"
29+
#include "wayland/meta-wayland-xdg-shell.h"
30+
31+
#include "xdg-toplevel-tag-v1-server-protocol.h"
32+
33+
static void
34+
xdg_toplevel_tag_manager_destroy (struct wl_client *client,
35+
struct wl_resource *resource)
36+
{
37+
wl_resource_destroy (resource);
38+
}
39+
40+
static void
41+
xdg_toplevel_tag_manager_set_toplevel_tag (struct wl_client *client,
42+
struct wl_resource *resource,
43+
struct wl_resource *toplevel_resource,
44+
const char *tag)
45+
{
46+
MetaWaylandXdgToplevel *xdg_toplevel;
47+
MetaWaylandSurfaceRole *surface_role;
48+
MetaWaylandSurface *surface;
49+
MetaWindow *window;
50+
51+
if (!toplevel_resource)
52+
return;
53+
54+
xdg_toplevel = wl_resource_get_user_data (toplevel_resource);
55+
surface_role = META_WAYLAND_SURFACE_ROLE (xdg_toplevel);
56+
surface = meta_wayland_surface_role_get_surface (surface_role);
57+
window = meta_wayland_surface_get_window (surface);
58+
59+
meta_window_set_tag (window, tag);
60+
}
61+
62+
static void
63+
xdg_toplevel_tag_manager_set_toplevel_tag_description (struct wl_client *client,
64+
struct wl_resource *resource,
65+
struct wl_resource *toplevel,
66+
const char *tag_description)
67+
{
68+
/* We don't make use of the toplevel tag description */
69+
}
70+
71+
static const struct xdg_toplevel_tag_manager_v1_interface meta_xdg_toplevel_tag_interface = {
72+
xdg_toplevel_tag_manager_destroy,
73+
xdg_toplevel_tag_manager_set_toplevel_tag,
74+
xdg_toplevel_tag_manager_set_toplevel_tag_description,
75+
};
76+
77+
78+
static void
79+
bind_xdg_toplevel_tag (struct wl_client *client,
80+
void *data,
81+
uint32_t version,
82+
uint32_t id)
83+
{
84+
struct wl_resource *resource;
85+
86+
resource = wl_resource_create (client,
87+
&xdg_toplevel_tag_manager_v1_interface,
88+
META_XDG_TOPLEVEL_TAG_V1_VERSION,
89+
id);
90+
91+
wl_resource_set_implementation (resource,
92+
&meta_xdg_toplevel_tag_interface,
93+
NULL, NULL);
94+
}
95+
96+
void
97+
meta_wayland_xdg_toplevel_tag_init (MetaWaylandCompositor *compositor)
98+
{
99+
if (wl_global_create (compositor->wayland_display,
100+
&xdg_toplevel_tag_manager_v1_interface,
101+
META_XDG_TOPLEVEL_TAG_V1_VERSION,
102+
NULL,
103+
bind_xdg_toplevel_tag) == NULL)
104+
g_error ("Failed to register a global xdg-toplevel-tag object");
105+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (C) 2024 Red Hat
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License as
6+
* published by the Free Software Foundation; either version 2 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but
10+
* WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, see <http://www.gnu.org/licenses/>.
16+
*
17+
* Written by:
18+
* Bilal Elmoussaoui <[email protected]>
19+
*/
20+
21+
#pragma once
22+
23+
#include <glib.h>
24+
25+
#include "wayland/meta-wayland-types.h"
26+
27+
void meta_wayland_xdg_toplevel_tag_init (MetaWaylandCompositor *compositor);

src/wayland/meta-wayland.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "wayland/meta-wayland-tablet-manager.h"
4848
#include "wayland/meta-wayland-xdg-dialog.h"
4949
#include "wayland/meta-wayland-xdg-foreign.h"
50+
#include "wayland/meta-wayland-xdg-toplevel-tag.h"
5051
#include "wayland/meta-xwayland-grab-keyboard.h"
5152
#include "wayland/meta-xwayland-private.h"
5253
#include "wayland/meta-xwayland.h"
@@ -444,6 +445,7 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *wayland_compositor)
444445
meta_wayland_activation_init (compositor);
445446
meta_wayland_idle_inhibit_init (compositor);
446447
meta_wayland_init_xdg_wm_dialog (compositor);
448+
meta_wayland_xdg_toplevel_tag_init (compositor);
447449

448450
/* Xwayland specific protocol, needs to be filtered out for all other clients */
449451
if (meta_xwayland_grab_keyboard_init (compositor))
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<protocol name="xdg_toplevel_tag_v1">
3+
<copyright>
4+
Copyright © 2024 Xaver Hugl
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a
7+
copy of this software and associated documentation files (the "Software"),
8+
to deal in the Software without restriction, including without limitation
9+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
and/or sell copies of the Software, and to permit persons to whom the
11+
Software is furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice (including the next
14+
paragraph) shall be included in all copies or substantial portions of the
15+
Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23+
DEALINGS IN THE SOFTWARE.
24+
</copyright>
25+
26+
<interface name="xdg_toplevel_tag_manager_v1" version="1">
27+
<description summary="protocol for setting toplevel tags">
28+
In order to make some window properties like position, size,
29+
"always on top" or user defined rules for window behavior persistent, the
30+
compositor needs some way to identify windows even after the application
31+
has been restarted.
32+
This protocol allows clients to make this possible by setting a tag for
33+
toplevels.
34+
35+
Warning! The protocol described in this file is currently in the testing
36+
phase. Backward compatible changes may be added together with the
37+
corresponding interface version bump. Backward incompatible changes can
38+
only be done by creating a new major version of the extension.
39+
</description>
40+
41+
<request name="destroy" type="destructor">
42+
<description summary="destroy toplevel tag object">
43+
Destroy this toplevel tag manager object. This request has no other
44+
effects.
45+
</description>
46+
</request>
47+
48+
<request name="set_toplevel_tag">
49+
<description summary="set tag">
50+
Set a tag for a toplevel. The tag may be shown to the user in UI, so
51+
it's preferable for it to be human readable, but it must be suitable
52+
for configuration files and should not be translated.
53+
Suitable tags would for example be "main window", "settings",
54+
"e-mail composer" or similar.
55+
56+
The tag does not need to be unique across applications, and the client
57+
may set the same tag for multiple windows, for example if the user has
58+
opened the same UI twice. How the potentially resulting conflicts are
59+
handled is compositor policy.
60+
61+
The client should set the tag as part of the initial commit on the
62+
associated toplevel, but it may set it at any time afterwards as well,
63+
for example if the purpose of the toplevel changes.
64+
</description>
65+
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
66+
<arg name="tag" type="string" summary="untranslated tag"/>
67+
</request>
68+
69+
<request name="set_toplevel_description">
70+
<description summary="set description">
71+
Set a description for a toplevel. This description may be shown to the
72+
user in UI or read by a screen reader for accessibility purposes, and
73+
should be translated.
74+
It is recommended to make the description the translation of the tag.
75+
76+
The client should set the description as part of the initial commit on
77+
the associated toplevel, but it may set it at any time afterwards as
78+
well, for example if the purpose of the toplevel changes.
79+
</description>
80+
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
81+
<arg name="description" type="string" summary="translated description"/>
82+
</request>
83+
</interface>
84+
85+
</protocol>

0 commit comments

Comments
 (0)