Skip to content

Commit

Permalink
Implement xdg-decoration
Browse files Browse the repository at this point in the history
This commit adds a commandline switch (-d) to disable client side
decorations, if possible. In this case, Cage will not draw any
decorations of its own, in order to maximize screen real estate.

The default behavior remains the same, i.e., if -d is not passed,
clients will draw their client side decorations, if any.

Fixes #32
  • Loading branch information
Hjdskes committed Feb 17, 2019
1 parent 996f641 commit f96e507
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 6 deletions.
20 changes: 16 additions & 4 deletions cage.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Cage: A Wayland kiosk.
*
*
* Copyright (C) 2018-2019 Jente Hidskes
*
* See the LICENSE file accompanying this file.
Expand All @@ -27,6 +27,7 @@
#if CAGE_HAS_XWAYLAND
#include <wlr/types/wlr_xcursor_manager.h>
#endif
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
#if CAGE_HAS_XWAYLAND
Expand Down Expand Up @@ -84,6 +85,7 @@ usage(FILE *file, const char *cage)
{
fprintf(file, "Usage: %s APPLICATION\n"
"\n"
" -d\t Don't draw client side decorations, when possible"
" -D\t Turn on damage tracking debugging\n"
" -h\t Display this help message\n",
cage);
Expand All @@ -93,8 +95,11 @@ static bool
parse_args(struct cg_server *server, int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "hD")) != -1) {
while ((c = getopt(argc, argv, "dDh")) != -1) {
switch (c) {
case 'd':
server->xdg_decoration = true;
break;
case 'D':
server->debug_damage_tracking = true;
break;
Expand Down Expand Up @@ -123,6 +128,7 @@ main(int argc, char *argv[])
struct wlr_renderer *renderer = NULL;
struct wlr_compositor *compositor = NULL;
struct wlr_data_device_manager *data_device_mgr = NULL;
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager = NULL;
struct wlr_xdg_shell *xdg_shell = NULL;
#if CAGE_HAS_XWAYLAND
struct wlr_xwayland *xwayland = NULL;
Expand Down Expand Up @@ -160,6 +166,8 @@ main(int argc, char *argv[])
renderer = wlr_backend_get_renderer(server.backend);
wlr_renderer_init_wl_display(renderer, server.wl_display);

wl_list_init(&server.views);

server.output_layout = wlr_output_layout_create();
if (!server.output_layout) {
wlr_log(WLR_ERROR, "Unable to create output layout");
Expand Down Expand Up @@ -210,17 +218,20 @@ main(int argc, char *argv[])
server.new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1_new;
wl_signal_add(&server.idle_inhibit_v1->events.new_inhibitor, &server.new_idle_inhibitor_v1);
wl_list_init(&server.inhibitors);

xdg_shell = wlr_xdg_shell_create(server.wl_display);
if (!xdg_shell) {
wlr_log(WLR_ERROR, "Unable to create the XDG shell interface");
ret = 1;
goto end;
}
wl_list_init(&server.views);
server.new_xdg_shell_surface.notify = handle_xdg_shell_surface_new;
wl_signal_add(&xdg_shell->events.new_surface, &server.new_xdg_shell_surface);

xdg_decoration_manager = wlr_xdg_decoration_manager_v1_create(server.wl_display);
wl_signal_add(&xdg_decoration_manager->events.new_toplevel_decoration, &server.xdg_toplevel_decoration);
server.xdg_toplevel_decoration.notify = handle_xdg_toplevel_decoration;

#if CAGE_HAS_XWAYLAND
xwayland = wlr_xwayland_create(server.wl_display, compositor, true);
if (!xwayland) {
Expand Down Expand Up @@ -293,6 +304,7 @@ main(int argc, char *argv[])

end:
seat_destroy(server.seat);
wlr_xdg_decoration_manager_v1_destroy(xdg_decoration_manager);
wlr_xdg_shell_destroy(xdg_shell);
wlr_idle_inhibit_v1_destroy(server.idle_inhibit_v1);
if (server.idle) {
Expand Down
6 changes: 4 additions & 2 deletions server.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#if CAGE_HAS_XWAYLAND
#include <wlr/xwayland.h>
#endif
Expand All @@ -19,8 +20,6 @@
struct cg_server {
struct wl_display *wl_display;
struct wlr_backend *backend;

struct wl_listener new_xdg_shell_surface;
struct wl_list views;

struct cg_seat *seat;
Expand All @@ -33,10 +32,13 @@ struct cg_server {
struct cg_output *output;
struct wl_listener new_output;

struct wl_listener xdg_toplevel_decoration;
struct wl_listener new_xdg_shell_surface;
#if CAGE_HAS_XWAYLAND
struct wl_listener new_xwayland_surface;
#endif

bool xdg_decoration;
#ifdef DEBUG
bool debug_damage_tracking;
#endif
Expand Down
1 change: 1 addition & 0 deletions view.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ void view_damage_surface(struct cg_view *view);
void view_damage_whole(struct cg_view *view);
void view_activate(struct cg_view *view, bool activate);
void view_position(struct cg_view *view);
// TODO: abstract wlr_surface_iterator_func_t
void view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data);
void view_unmap(struct cg_view *view);
void view_map(struct cg_view *view, struct wlr_surface *surface);
Expand Down
46 changes: 46 additions & 0 deletions xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@
#include "view.h"
#include "xdg_shell.h"

static void
xdg_decoration_handle_destroy(struct wl_listener *listener, void *data)
{
struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, destroy);

wl_list_remove(&xdg_decoration->destroy.link);
wl_list_remove(&xdg_decoration->request_mode.link);
free(xdg_decoration);
}

static void
xdg_decoration_handle_request_mode(struct wl_listener *listener, void *data)
{
struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, request_mode);
enum wlr_xdg_toplevel_decoration_v1_mode mode;

if (xdg_decoration->server->xdg_decoration) {
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
} else {
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
}
wlr_xdg_toplevel_decoration_v1_set_mode(xdg_decoration->wlr_decoration, mode);
}

static void
xdg_popup_destroy(struct cg_view_child *child)
{
Expand Down Expand Up @@ -304,3 +328,25 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data)
xdg_shell_view->new_popup.notify = handle_new_xdg_popup;
wl_signal_add(&xdg_surface->events.new_popup, &xdg_shell_view->new_popup);
}

void
handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data)
{
struct cg_server *server = wl_container_of(listener, server, xdg_toplevel_decoration);
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration = data;

struct cg_xdg_decoration *xdg_decoration = calloc(1, sizeof(struct cg_xdg_decoration));
if (!xdg_decoration) {
return;
}

xdg_decoration->wlr_decoration = wlr_decoration;
xdg_decoration->server = server;

xdg_decoration->destroy.notify = xdg_decoration_handle_destroy;
wl_signal_add(&wlr_decoration->events.destroy, &xdg_decoration->destroy);
xdg_decoration->request_mode.notify = xdg_decoration_handle_request_mode;
wl_signal_add(&wlr_decoration->events.request_mode, &xdg_decoration->request_mode);

xdg_decoration_handle_request_mode(&xdg_decoration->request_mode, wlr_decoration);
}
10 changes: 10 additions & 0 deletions xdg_shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CG_XDG_SHELL_H

#include <wayland-server.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_shell.h>

#include "view.h"
Expand All @@ -28,6 +29,15 @@ struct cg_xdg_popup {
struct wl_listener new_popup;
};

struct cg_xdg_decoration {
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
struct cg_server *server;
struct wl_listener destroy;
struct wl_listener request_mode;
};

void handle_xdg_shell_surface_new(struct wl_listener *listener, void *data);

void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data);

#endif

0 comments on commit f96e507

Please sign in to comment.