diff --git a/.gitignore b/.gitignore index 1a1c0af878d1..52d8e6ef7471 100644 --- a/.gitignore +++ b/.gitignore @@ -242,6 +242,8 @@ gfx/common/wayland/single-pixel-buffer-v1.h gfx/common/wayland/single-pixel-buffer-v1.c gfx/common/wayland/xdg-toplevel-icon-v1.h gfx/common/wayland/xdg-toplevel-icon-v1.c +gfx/common/wayland/xdg-toplevel-tag-v1.h +gfx/common/wayland/xdg-toplevel-tag-v1.c # libretro-common samples libretro-common/samples/streams/rzip/rzip diff --git a/Makefile.common b/Makefile.common index 411f959f392e..da7f9f1a945b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1272,6 +1272,7 @@ ifeq ($(HAVE_WAYLAND), 1) gfx/common/wayland/fractional-scale-v1.o \ gfx/common/wayland/viewporter.o \ gfx/common/wayland/xdg-toplevel-icon-v1.o \ + gfx/common/wayland/xdg-toplevel-tag-v1.o \ gfx/common/wayland/xdg-shell.o \ gfx/common/wayland/idle-inhibit-unstable-v1.o \ gfx/common/wayland/xdg-decoration-unstable-v1.o \ diff --git a/deps/wayland-protocols/staging/xdg-toplevel-tag/README b/deps/wayland-protocols/staging/xdg-toplevel-tag/README new file mode 100644 index 000000000000..b4910eef486f --- /dev/null +++ b/deps/wayland-protocols/staging/xdg-toplevel-tag/README @@ -0,0 +1,4 @@ +Toplevel tag protocol + +Maintainers: +Xaver Hugl diff --git a/deps/wayland-protocols/staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml b/deps/wayland-protocols/staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml new file mode 100644 index 000000000000..5e20bdf45f81 --- /dev/null +++ b/deps/wayland-protocols/staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml @@ -0,0 +1,85 @@ + + + + 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. + + + + + 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. + + + + + Destroy this toplevel tag manager object. This request has no other + effects. + + + + + + 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, but it must be suitable + for configuration files and should not be translated. + 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. + + The client should set the tag as part of the initial commit on the + associated toplevel, but it may set it at any time afterwards as well, + for example if the purpose of the toplevel changes. + + + + + + + + Set a description for a toplevel. This description may be shown to the + user in UI or read by a screen reader for accessibility purposes, and + should be translated. + It is recommended to make the description the translation of the tag. + + The client should set the description as part of the initial commit on + the associated toplevel, but it may set it at any time afterwards as + well, for example if the purpose of the toplevel changes. + + + + + + + diff --git a/gfx/common/wayland/generate_wayland_protos.sh b/gfx/common/wayland/generate_wayland_protos.sh index d45de792189f..bd560c54c253 100755 --- a/gfx/common/wayland/generate_wayland_protos.sh +++ b/gfx/common/wayland/generate_wayland_protos.sh @@ -74,3 +74,4 @@ generate_source 'unstable/tablet' 'tablet-unstable-v2' generate_source 'staging/content-type' 'content-type-v1' generate_source 'staging/single-pixel-buffer' 'single-pixel-buffer-v1' generate_source 'staging/xdg-toplevel-icon' 'xdg-toplevel-icon-v1' +generate_source 'staging/xdg-toplevel-tag' 'xdg-toplevel-tag-v1' diff --git a/gfx/common/wayland_common.c b/gfx/common/wayland_common.c index b5647a11ccee..aa4c12ebfd50 100644 --- a/gfx/common/wayland_common.c +++ b/gfx/common/wayland_common.c @@ -34,7 +34,7 @@ #define SPLASH_SHM_NAME "retroarch-wayland-vk-splash" -#define WINDOW_TITLE "RetroArch" +#define DEFAULT_WINDOW_TITLE "RetroArch" #ifdef HAVE_LIBDECOR_H #include @@ -280,10 +280,10 @@ void gfx_ctx_wl_destroy_resources_common(gfx_ctx_wayland_data_t *wl) if (wl->wl_touch) wl_touch_destroy(wl->wl_touch); - if (wl->cursor.theme) - wl_cursor_theme_destroy(wl->cursor.theme); if (wl->cursor.surface) wl_surface_destroy(wl->cursor.surface); + if (wl->cursor.theme) + wl_cursor_theme_destroy(wl->cursor.theme); if (wl->viewport) wp_viewport_destroy(wl->viewport); @@ -293,12 +293,10 @@ void gfx_ctx_wl_destroy_resources_common(gfx_ctx_wayland_data_t *wl) zwp_idle_inhibitor_v1_destroy(wl->idle_inhibitor); if (wl->deco) zxdg_toplevel_decoration_v1_destroy(wl->deco); - if (wl->xdg_toplevel) - xdg_toplevel_destroy(wl->xdg_toplevel); - if (wl->xdg_toplevel_icon_manager) - xdg_toplevel_icon_manager_v1_destroy(wl->xdg_toplevel_icon_manager); if (wl->xdg_toplevel_icon) xdg_toplevel_icon_v1_destroy(wl->xdg_toplevel_icon); + if (wl->xdg_toplevel) + xdg_toplevel_destroy(wl->xdg_toplevel); if (wl->xdg_surface) xdg_surface_destroy(wl->xdg_surface); if (wl->surface) @@ -306,6 +304,10 @@ void gfx_ctx_wl_destroy_resources_common(gfx_ctx_wayland_data_t *wl) if (wl->deco_manager) zxdg_decoration_manager_v1_destroy(wl->deco_manager); + if (wl->xdg_toplevel_icon_manager) + xdg_toplevel_icon_manager_v1_destroy(wl->xdg_toplevel_icon_manager); + if (wl->xdg_toplevel_tag_manager) + xdg_toplevel_tag_manager_v1_destroy(wl->xdg_toplevel_tag_manager); if (wl->idle_inhibit_manager) zwp_idle_inhibit_manager_v1_destroy(wl->idle_inhibit_manager); else @@ -388,6 +390,7 @@ void gfx_ctx_wl_destroy_resources_common(gfx_ctx_wayland_data_t *wl) wl->xdg_toplevel = NULL; wl->xdg_toplevel_icon = NULL; wl->xdg_toplevel_icon_manager = NULL; + wl->xdg_toplevel_tag_manager = NULL; wl->deco = NULL; wl->idle_inhibitor = NULL; wl->wl_touch = NULL; @@ -831,6 +834,11 @@ bool gfx_ctx_wl_init_common( RARCH_LOG("[Wayland] Compositor doesn't support the %s protocol.\n", xdg_toplevel_icon_manager_v1_interface.name); } + if (!wl->xdg_toplevel_tag_manager) + { + RARCH_LOG("[Wayland] Compositor doesn't support the %s protocol.\n", xdg_toplevel_tag_manager_v1_interface.name); + } + wl->surface = wl_compositor_create_surface(wl->compositor); if (wl->viewporter) wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface); @@ -869,7 +877,7 @@ bool gfx_ctx_wl_init_common( } wl->libdecor_frame_set_app_id(wl->libdecor_frame, WAYLAND_APP_ID); - wl->libdecor_frame_set_title(wl->libdecor_frame, WINDOW_TITLE); + wl->libdecor_frame_set_title(wl->libdecor_frame, DEFAULT_WINDOW_TITLE); wl->libdecor_frame_map(wl->libdecor_frame); /* Waiting for libdecor to be configured before starting to draw */ @@ -895,7 +903,7 @@ bool gfx_ctx_wl_init_common( xdg_toplevel_add_listener(wl->xdg_toplevel, &toplevel_listener->xdg_toplevel_listener, wl); xdg_toplevel_set_app_id(wl->xdg_toplevel, WAYLAND_APP_ID); - xdg_toplevel_set_title(wl->xdg_toplevel, WINDOW_TITLE); + xdg_toplevel_set_title(wl->xdg_toplevel, DEFAULT_WINDOW_TITLE); if (wl->deco_manager) wl->deco = zxdg_decoration_manager_v1_get_toplevel_decoration( @@ -904,6 +912,14 @@ bool gfx_ctx_wl_init_common( if (wl->xdg_toplevel_icon_manager) wl_create_toplevel_icon(wl, wl->xdg_toplevel); + if (wl->xdg_toplevel_tag_manager) + { + xdg_toplevel_tag_manager_v1_set_toplevel_tag( + wl->xdg_toplevel_tag_manager, wl->xdg_toplevel, "main window"); + xdg_toplevel_tag_manager_v1_set_toplevel_description( + wl->xdg_toplevel_tag_manager, wl->xdg_toplevel, DEFAULT_WINDOW_TITLE " main window"); + } + /* Waiting for xdg_toplevel to be configured before starting to draw */ wl_surface_commit(wl->surface); wl->configured = true; diff --git a/input/common/wayland_common.c b/input/common/wayland_common.c index e39626bd1a50..c9b60bfec07a 100644 --- a/input/common/wayland_common.c +++ b/input/common/wayland_common.c @@ -809,6 +809,10 @@ static void wl_registry_handle_global(void *data, struct wl_registry *reg, wl->xdg_toplevel_icon_manager = (struct xdg_toplevel_icon_manager_v1*) wl_registry_bind( reg, id, &xdg_toplevel_icon_manager_v1_interface, MIN(version, 1)); + else if (string_is_equal(interface, xdg_toplevel_tag_manager_v1_interface.name) && found++) + wl->xdg_toplevel_tag_manager = (struct xdg_toplevel_tag_manager_v1*) + wl_registry_bind( + reg, id, &xdg_toplevel_tag_manager_v1_interface, MIN(version, 1)); if (found > 1) RARCH_LOG("[Wayland] Registered interface %s at version %u.\n", diff --git a/input/common/wayland_common.h b/input/common/wayland_common.h index 7f685b61e6d9..88ed8c88567a 100644 --- a/input/common/wayland_common.h +++ b/input/common/wayland_common.h @@ -45,6 +45,7 @@ #include "../../gfx/common/wayland/xdg-decoration-unstable-v1.h" #include "../../gfx/common/wayland/xdg-shell.h" #include "../../gfx/common/wayland/xdg-toplevel-icon-v1.h" +#include "../../gfx/common/wayland/xdg-toplevel-tag-v1.h" #define FRACTIONAL_SCALE_V1_DEN 120 #define FRACTIONAL_SCALE_MULT(v, scale_num) \ @@ -162,6 +163,7 @@ typedef struct gfx_ctx_wayland_data struct xdg_toplevel *xdg_toplevel; struct xdg_toplevel_icon_v1 *xdg_toplevel_icon; struct xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager; + struct xdg_toplevel_tag_manager_v1 *xdg_toplevel_tag_manager; struct wl_keyboard *wl_keyboard; struct wl_pointer *wl_pointer; struct zwp_relative_pointer_v1 *wl_relative_pointer; diff --git a/qb/config.libs.sh b/qb/config.libs.sh index d5315b83acc9..c2086c441e1b 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -564,7 +564,7 @@ check_header '' XSHM X11/Xlib.h X11/extensions/XShm.h check_val '' XKBCOMMON -lxkbcommon '' xkbcommon 0.3.2 '' false check_val '' WAYLAND '-lwayland-egl -lwayland-client' '' wayland-egl 10.1.0 '' false check_val '' WAYLAND_CURSOR -lwayland-cursor '' wayland-cursor 1.12 '' false -check_pkgconf WAYLAND_PROTOS wayland-protocols 1.37 +check_pkgconf WAYLAND_PROTOS wayland-protocols 1.43 check_pkgconf WAYLAND_SCANNER wayland-scanner '1.15 1.12' if [ "$HAVE_WAYLAND_SCANNER" = yes ] &&