Skip to content

Commit

Permalink
wl: Prefer SSD via zxdg_decoration_manager_v1
Browse files Browse the repository at this point in the history
Ask compositors that support the zxdg_decoration_manager_v1_interface
protocol to provide server-side decorations (SSD). This way it is more
likely that the Cog surfaces will have window decorations. Note that
compositors will still hide the decorations of fullscreen surfaces,
but maximized ones will keep them, and this is the expected behaviour.
Tested on Sway and Labwc, and should work in most (if not all) wlroots
based compositors.
  • Loading branch information
aperezdc committed Mar 27, 2024
1 parent ecf0d3a commit d93a55a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
8 changes: 8 additions & 0 deletions platform/wayland/cog-platform-wl.c
Expand Up @@ -212,6 +212,10 @@ registry_on_global(void *data, struct wl_registry *registry, uint32_t name, cons
} else if (strcmp(interface, weston_content_protection_interface.name) == 0) {
display->protection = wl_registry_bind(registry, name, &weston_content_protection_interface, 1);
#endif /* COG_ENABLE_WESTON_CONTENT_PROTECTION */
#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
} else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) {
display->xdg_decoration = wl_registry_bind(registry, name, &zxdg_decoration_manager_v1_interface, 1);
#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */
} else if (strcmp(interface, wl_output_interface.name) == 0) {
/* Version 2 introduced the wl_output_listener::scale. */
CogWlOutput *item = g_new0(CogWlOutput, 1);
Expand Down Expand Up @@ -1181,6 +1185,10 @@ init_wayland(CogWlPlatform *platform, GError **error)
static void
clear_wayland(CogWlPlatform *platform)
{
#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
g_clear_pointer(&platform->display->xdg_decoration, zxdg_decoration_manager_v1_destroy);
#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */

cog_wl_display_destroy(platform->display);
}

Expand Down
12 changes: 12 additions & 0 deletions platform/wayland/cog-utils-wl.h
Expand Up @@ -15,6 +15,10 @@
# include "cog-xdp-parent-wl.h"
#endif

#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
# include "xdg-decoration-unstable-v1-client.h"
#endif

#include <wayland-server.h>
#include <wayland-util.h>
#include <xkbcommon/xkbcommon.h>
Expand Down Expand Up @@ -116,6 +120,10 @@ struct _CogWlWindow {
struct xdg_toplevel *xdg_toplevel;
struct wl_shell_surface *shell_surface;

#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
struct zxdg_toplevel_decoration_v1 *xdg_decoration;
#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */

#if COG_HAVE_LIBPORTAL
struct xdp_parent_wl_data xdp_parent_wl_data;
#endif /* COG_HAVE_LIBPORTAL */
Expand Down Expand Up @@ -231,6 +239,10 @@ struct _CogWlDisplay {
struct zwp_fullscreen_shell_v1 *fshell;
struct wl_shell *shell;

#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
struct zxdg_decoration_manager_v1 *xdg_decoration;
#endif

CogWlSeat *seat_default;
struct wl_list seats; /* wl_list<CogWlSeat> */

Expand Down
21 changes: 21 additions & 0 deletions platform/wayland/cog-viewport-wl.c
Expand Up @@ -16,6 +16,10 @@
#include "fullscreen-shell-unstable-v1-client.h"
#include "xdg-shell-client.h"

#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
# include "xdg-decoration-unstable-v1-client.h"
#endif

G_DEFINE_DYNAMIC_TYPE(CogWlViewport, cog_wl_viewport, COG_TYPE_VIEWPORT)

static void cog_wl_viewport_dispose(GObject *);
Expand All @@ -41,6 +45,10 @@ destroy_video_surface(gpointer data)
static void
destroy_window(CogWlViewport *viewport)
{
#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
g_clear_pointer(&viewport->window.xdg_decoration, zxdg_toplevel_decoration_v1_destroy);
#endif

g_clear_pointer(&viewport->window.xdg_toplevel, xdg_toplevel_destroy);
g_clear_pointer(&viewport->window.xdg_surface, xdg_surface_destroy);
g_clear_pointer(&viewport->window.shell_surface, wl_shell_surface_destroy);
Expand Down Expand Up @@ -265,6 +273,19 @@ cog_wl_viewport_create_window(CogWlViewport *viewport, GError **error)
viewport->window.xdg_toplevel = xdg_surface_get_toplevel(viewport->window.xdg_surface);
g_assert(viewport->window.xdg_toplevel);

#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1
/*
* Ask the compositor for server-side decorations. The compositor may
* still prefer client-side decorations, but do not attach a listener
* because knowing the compositor's preference is pointless because
* there is no support for painting client-side decorations.
*/
viewport->window.xdg_decoration =
zxdg_decoration_manager_v1_get_toplevel_decoration(display->xdg_decoration, viewport->window.xdg_toplevel);
zxdg_toplevel_decoration_v1_set_mode(viewport->window.xdg_decoration,
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */

xdg_toplevel_add_listener(viewport->window.xdg_toplevel, &xdg_toplevel_listener, viewport);
xdg_toplevel_set_title(viewport->window.xdg_toplevel, COG_DEFAULT_APPNAME);

Expand Down
15 changes: 14 additions & 1 deletion platform/wayland/meson.build
Expand Up @@ -38,6 +38,7 @@ wayland_platform_protocols = {
['text-input', 1],
['text-input', 3],
['xdg-foreign', 2],
['xdg-decoration', 1, 'optional'],
],
'weston': wayland_platform_weston_protocols,
}
Expand Down Expand Up @@ -78,22 +79,34 @@ fs = import('fs')
wayland_platform_sources = []
foreach kind, proto_list : wayland_platform_protocols
foreach item : proto_list
proto_optional = false
if kind == 'stable'
proto_name = item
proto_dir = join_paths(wayland_protocols_path, 'stable', item)
elif kind == 'unstable' or kind == 'staging'
proto_name = '@0@-@1@-v@2@'.format(item[0], kind, item[1])
proto_dir = join_paths(wayland_protocols_path, 'unstable', item[0])
proto_optional = item.length() == 3 and item[2] == 'optional'
elif kind == 'weston'
proto_name = item
proto_dir = weston_protocols_path
else
error('Unknown Wayland protocol type: @0@'.format(kind))
endif
proto_macro = proto_name.underscorify().to_upper()

xml_path = join_paths(proto_dir, '@0@.xml'.format(proto_name))
if not fs.is_file(xml_path)
error('Cannot find protocol @0@, file does not exist: @1@'.format(proto_name, xml_path))
if proto_optional
wayland_platform_c_args += ['-DHAVE_@0@=0'.format(proto_macro)]
continue
else
error('Cannot find protocol @0@, file does not exist: @1@'.format(proto_name, xml_path))
endif
endif

if proto_optional
wayland_platform_c_args += ['-DCOG_HAVE_@0@=1'.format(proto_macro)]
endif

wayland_platform_sources += [custom_target(
Expand Down

0 comments on commit d93a55a

Please sign in to comment.