Compare commits

...

1 Commits

Author SHA1 Message Date
Bilal Elmoussaoui
b800a5ea2d gdk/wayland: Implement toplevel tag protocol
The toplevel tag would an application developer to tag a toplevel
surface with a tag.

When combined with the application-id, the compositor can use that
information to identify specific windows and use it for
configurability/scriptability.

The protocol:
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/238
2024-11-13 13:33:10 +01:00
7 changed files with 135 additions and 1 deletions

View File

@@ -63,6 +63,7 @@
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "presentation-time-client-protocol.h"
#include "xx-color-management-v4-client-protocol.h"
#include "xdg-toplevel-tag-v1-client-protocol.h"
#include "wm-button-layout-translation.h"
@@ -554,6 +555,12 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry, id,
&xdg_system_bell_v1_interface, 1);
}
else if (strcmp (interface, xdg_toplevel_tag_manager_v1_interface.name) == 0)
{
display_wayland->xdg_toplevel_tag =
wl_registry_bind (display_wayland->wl_registry, id,
&xdg_toplevel_tag_manager_v1_interface, 1);
}
g_hash_table_insert (display_wayland->known_globals,
GUINT_TO_POINTER (id), g_strdup (interface));
@@ -770,6 +777,7 @@ gdk_wayland_display_dispose (GObject *object)
g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free);
g_clear_pointer (&display_wayland->color, gdk_wayland_color_free);
g_clear_pointer (&display_wayland->system_bell, xdg_system_bell_v1_destroy);
g_clear_pointer (&display_wayland->xdg_toplevel_tag, xdg_toplevel_tag_manager_v1_destroy);
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);

View File

@@ -126,6 +126,7 @@ struct _GdkWaylandDisplay
struct wp_viewporter *viewporter;
struct wp_presentation *presentation;
struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer;
struct xdg_toplevel_tag_manager_v1 *xdg_toplevel_tag;
GdkWaylandColor *color;
GList *async_roundtrips;

View File

@@ -38,6 +38,7 @@
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include <wayland/xdg-dialog-v1-client-protocol.h>
#include "xdg-toplevel-tag-v1-client-protocol.h"
#include <stdlib.h>
#include <stdio.h>
@@ -1257,7 +1258,7 @@ gdk_wayland_toplevel_set_transient_for (GdkWaylandToplevel *toplevel,
#define LAST_PROP 1
static void
static void
gdk_wayland_toplevel_set_decorated (GdkWaylandToplevel *self,
gboolean decorated)
{
@@ -2480,6 +2481,50 @@ gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
}
}
/**
* gdk_wayland_toplevel_set_tag:
* @toplevel: (type GdkWaylandToplevel): a `GdkToplevel` to set the tag for
* @tag: A preferably human-readable tag
*
* Set a tag to the toplevel allowing to uniquely identify it from the compositor
* side.
*
* The tag along with the application ID can be used to create a unique identifier
* per app / window.
*
* The tag may be shown to the user in UI, so it's preferable for
* it to be human readable. Suitable tags would for example be
* “main window”, “settings”, “e-mail composer” or similar.
*
* The tag does not need to be unique across applications.
* Returns: whether the tag was set.
*
* Since: 4.18
*/
gboolean
gdk_wayland_toplevel_set_tag (GdkToplevel *toplevel,
const char *tag)
{
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
if (!display_wayland->xdg_toplevel_tag)
{
g_warning ("Server is missing xdg_toplevel_tag support");
return FALSE;
}
xdg_toplevel_tag_manager_v1_set_toplevel_tag (display_wayland->xdg_toplevel_tag,
wayland_toplevel->display_server.xdg_toplevel,
tag);
return TRUE;
}
gboolean
gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
{

View File

@@ -67,4 +67,8 @@ GDK_AVAILABLE_IN_ALL
void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
const char *application_id);
GDK_AVAILABLE_IN_4_18
gboolean gdk_wayland_toplevel_set_tag (GdkToplevel *toplevel,
const char *tag);
G_END_DECLS

View File

@@ -156,6 +156,11 @@ proto_sources = [
'stability': 'private',
'version': 1,
},
{
'name': 'xdg-toplevel-tag',
'stability': 'private',
'version': 1,
},
]
gdk_wayland_gen_headers = []

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xdg_toplevel_tag_v1">
<copyright>
Copyright © 2024 Xaver Hugl
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="xdg_toplevel_tag_manager_v1" version="1">
<description summary="protocol for setting toplevel tags">
In order to make some window properties like position, size, "always on top"
or user defined rules for window behavior persistent, the compositor needs
some way to identify windows even after the application has been restarted.
This protocol allows clients to make this possible by setting a tag for
toplevels.
Warning! The protocol described in this file is currently in the testing
phase. Backward compatible changes may be added together with the
corresponding interface version bump. Backward incompatible changes can
only be done by creating a new major version of the extension.
</description>
<request name="destroy" type="destructor">
<description summary="destroy toplevel tag object">
Destroy this toplevel tag factory object. This request has no other effects.
</description>
</request>
<enum name="error">
<entry name="tag_on_mapped" value="0"
summary="attempted to tag an already mapped toplevel"/>
</enum>
<request name="set_toplevel_tag">
<description summary="set tag">
Set a tag for a toplevel. The tag may be shown to the user in UI, so it's preferable for
it to be human readable. Suitable tags would for example be "main window", "settings",
"e-mail composer" or similar.
The tag does not need to be unique across applications, and the client may set the same
tag for multiple windows, for example if the user has opened the same UI twice.
How the potentially resulting conflicts are handled is compositor policy.
If a tag is set at all, the client must set the tag as part of the initial commit on the
associated toplevel. If the toplevel is already mapped, or the following wl_surface.commit
after this request maps the surface, the tag_on_mapped error is emitted.
</description>
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
<arg name="tag" type="string"/>
</request>
</interface>
</protocol>

View File

@@ -743,6 +743,7 @@ add_wayland_protocols (GdkDisplay *display,
append_wayland_protocol_row (gen, (struct wl_proxy *)d->single_pixel_buffer);
append_wayland_protocol_row (gen, d->color ? gdk_wayland_color_get_color_manager (d->color) : NULL);
append_wayland_protocol_row (gen, (struct wl_proxy *)d->system_bell);
append_wayland_protocol_row (gen, (struct wl_proxy *)d->xdg_toplevel_tag);
}
}
#endif