aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-07-29 18:31:10 +0100
committeremersion <contact@emersion.fr>2018-08-06 15:20:30 +0100
commit9d578e0a0f08e053dfc1982e32d9fda172b0087f (patch)
tree941f76c80794a5665264bd65ea1467490b1d615e
parent700941dde8d270b7986bd592fcb42333e7626718 (diff)
Handle views created after decoration mode is sent for xdg-shell
-rw-r--r--include/sway/decoration.h4
-rw-r--r--include/sway/server.h1
-rw-r--r--include/sway/tree/view.h4
-rw-r--r--sway/decoration.c34
-rw-r--r--sway/desktop/xdg_shell.c19
-rw-r--r--sway/server.c3
6 files changed, 61 insertions, 4 deletions
diff --git a/include/sway/decoration.h b/include/sway/decoration.h
index c77c04c7..7916746e 100644
--- a/include/sway/decoration.h
+++ b/include/sway/decoration.h
@@ -5,9 +5,13 @@
struct sway_server_decoration {
struct wlr_server_decoration *wlr_server_decoration;
+ struct wl_list link;
struct wl_listener destroy;
struct wl_listener mode;
};
+struct sway_server_decoration *decoration_from_surface(
+ struct wlr_surface *surface);
+
#endif
diff --git a/include/sway/server.h b/include/sway/server.h
index 7e73fb4f..b93584b6 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -52,6 +52,7 @@ struct sway_server {
struct wlr_server_decoration_manager *server_decoration_manager;
struct wl_listener server_decoration;
+ struct wl_list decorations; // sway_server_decoration::link
bool debug_txn_timings;
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 37fd02bc..e91d2a20 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -118,6 +118,8 @@ struct sway_view {
struct sway_xdg_shell_v6_view {
struct sway_view view;
+ enum wlr_server_decoration_manager_mode deco_mode;
+
struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;
@@ -134,6 +136,8 @@ struct sway_xdg_shell_v6_view {
struct sway_xdg_shell_view {
struct sway_view view;
+ enum wlr_server_decoration_manager_mode deco_mode;
+
struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;
diff --git a/sway/decoration.c b/sway/decoration.c
index 73b3f45d..0e3e67ac 100644
--- a/sway/decoration.c
+++ b/sway/decoration.c
@@ -9,6 +9,8 @@ static void server_decoration_handle_destroy(struct wl_listener *listener,
struct sway_server_decoration *deco =
wl_container_of(listener, deco, destroy);
wl_list_remove(&deco->destroy.link);
+ wl_list_remove(&deco->mode.link);
+ wl_list_remove(&deco->link);
free(deco);
}
@@ -18,9 +20,24 @@ static void server_decoration_handle_mode(struct wl_listener *listener,
wl_container_of(listener, deco, mode);
struct sway_view *view =
view_from_wlr_surface(deco->wlr_server_decoration->surface);
+ if (view == NULL || view->surface != deco->wlr_server_decoration->surface) {
+ return;
+ }
- // TODO
- wlr_log(WLR_ERROR, "%p %d", view, deco->wlr_server_decoration->mode);
+ switch (view->type) {
+ case SWAY_VIEW_XDG_SHELL_V6:;
+ struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
+ (struct sway_xdg_shell_v6_view *)view;
+ xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode;
+ break;
+ case SWAY_VIEW_XDG_SHELL:;
+ struct sway_xdg_shell_view *xdg_shell_view =
+ (struct sway_xdg_shell_view *)view;
+ xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode;
+ break;
+ default:
+ break;
+ }
}
void handle_server_decoration(struct wl_listener *listener, void *data) {
@@ -38,4 +55,17 @@ void handle_server_decoration(struct wl_listener *listener, void *data) {
wl_signal_add(&wlr_deco->events.mode, &deco->mode);
deco->mode.notify = server_decoration_handle_mode;
+
+ wl_list_insert(&server.decorations, &deco->link);
+}
+
+struct sway_server_decoration *decoration_from_surface(
+ struct wlr_surface *surface) {
+ struct sway_server_decoration *deco;
+ wl_list_for_each(deco, &server.decorations, link) {
+ if (deco->wlr_server_decoration->surface == surface) {
+ return deco;
+ }
+ }
+ return NULL;
}
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index b364663d..3b73f99c 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -6,6 +6,7 @@
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/edges.h>
#include "log.h"
+#include "sway/decoration.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/server.h"
@@ -170,6 +171,15 @@ static bool wants_floating(struct sway_view *view) {
|| toplevel->parent;
}
+static bool has_client_side_decorations(struct sway_view *view) {
+ struct sway_xdg_shell_view *xdg_shell_view =
+ xdg_shell_view_from_view(view);
+ if (xdg_shell_view == NULL) {
+ return true;
+ }
+ return xdg_shell_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER;
+}
+
static void for_each_surface(struct sway_view *view,
wlr_surface_iterator_func_t iterator, void *user_data) {
if (xdg_shell_view_from_view(view) == NULL) {
@@ -226,6 +236,7 @@ static const struct sway_view_impl view_impl = {
.set_tiled = set_tiled,
.set_fullscreen = set_fullscreen,
.wants_floating = wants_floating,
+ .has_client_side_decorations = has_client_side_decorations,
.for_each_surface = for_each_surface,
.for_each_popup = for_each_popup,
.close = _close,
@@ -357,6 +368,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_height = view->wlr_xdg_surface->surface->current.height;
}
+ struct sway_server_decoration *deco =
+ decoration_from_surface(xdg_surface->surface);
+ if (deco != NULL) {
+ xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode;
+ } else {
+ xdg_shell_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;
+ }
+
view_map(view, view->wlr_xdg_surface->surface);
if (xdg_surface->toplevel->client_pending.fullscreen) {
diff --git a/sway/server.c b/sway/server.c
index bf6255bc..e8dc63be 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -19,7 +19,6 @@
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_output.h>
#include <wlr/util/log.h>
-// TODO WLR: make Xwayland optional
#include "list.h"
#include "sway/config.h"
#include "sway/desktop/idle_inhibit_v1.h"
@@ -85,7 +84,6 @@ bool server_init(struct sway_server *server) {
&server->xdg_shell_surface);
server->xdg_shell_surface.notify = handle_xdg_shell_surface;
- // TODO make xwayland optional
#ifdef HAVE_XWAYLAND
server->xwayland.wlr_xwayland =
wlr_xwayland_create(server->wl_display, server->compositor, true);
@@ -117,6 +115,7 @@ bool server_init(struct sway_server *server) {
wl_signal_add(&server->server_decoration_manager->events.new_decoration,
&server->server_decoration);
server->server_decoration.notify = handle_server_decoration;
+ wl_list_init(&server->decorations);
wlr_linux_dmabuf_v1_create(server->wl_display, renderer);
wlr_export_dmabuf_manager_v1_create(server->wl_display);