aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2018-01-14 13:19:21 -0500
committerTony Crisci <tony@dubstepdish.com>2018-01-14 13:19:21 -0500
commit83ddd2d9dbee1b77993f5cc45427854e18aae6f1 (patch)
treef2ec5fbc8b47b66f85978aa7feb1a09e34aaf569 /sway/desktop
parent2ce1d8d6cd0ae1520ea191678e3c39d555c66b58 (diff)
render override redirect
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/output.c13
-rw-r--r--sway/desktop/xwayland.c61
2 files changed, 63 insertions, 11 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index ec204c6f..21c8513f 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -218,6 +218,19 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
swayc_descendants_of_type(
&root_container, C_VIEW, output_frame_view, soutput);
+ // render unmanaged views on top
+ struct sway_view *view;
+ wl_list_for_each(view, &root_container.sway_root->unmanaged_views,
+ unmanaged_view_link) {
+ if (view->type == SWAY_XWAYLAND_VIEW) {
+ // the only kind of unamanged view right now is xwayland override redirect
+ int view_x = view->wlr_xwayland_surface->x;
+ int view_y = view->wlr_xwayland_surface->y;
+ render_surface(view->surface, wlr_output, &soutput->last_frame,
+ view_x, view_y, 0);
+ }
+ }
+
wlr_renderer_end(server->renderer);
wlr_output_swap_buffers(wlr_output);
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 43bb2e00..0c0dbfff 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -93,13 +93,43 @@ static void handle_commit(struct wl_listener *listener, void *data) {
static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_xwayland_surface *sway_surface =
wl_container_of(listener, sway_surface, destroy);
+ struct wlr_xwayland_surface *xsurface = data;
wl_list_remove(&sway_surface->commit.link);
wl_list_remove(&sway_surface->destroy.link);
wl_list_remove(&sway_surface->request_configure.link);
- swayc_t *parent = destroy_view(sway_surface->view->swayc);
+ if (xsurface->override_redirect) {
+ if (xsurface->mapped) {
+ wl_list_remove(&sway_surface->view->unmanaged_view_link);
+ }
+ } else {
+ swayc_t *parent = destroy_view(sway_surface->view->swayc);
+ arrange_windows(parent, -1, -1);
+ }
free(sway_surface->view);
free(sway_surface);
- arrange_windows(parent, -1, -1);
+}
+
+static void handle_unmap_notify(struct wl_listener *listener, void *data) {
+ // TODO take the view out of the tree
+ struct sway_xwayland_surface *sway_surface =
+ wl_container_of(listener, sway_surface, unmap_notify);
+ struct wlr_xwayland_surface *xsurface = data;
+ if (xsurface->override_redirect) {
+ wl_list_remove(&sway_surface->view->unmanaged_view_link);
+ }
+ sway_surface->view->surface = NULL;
+}
+
+static void handle_map_notify(struct wl_listener *listener, void *data) {
+ // TODO put the view back into the tree
+ struct sway_xwayland_surface *sway_surface =
+ wl_container_of(listener, sway_surface, map_notify);
+ struct wlr_xwayland_surface *xsurface = data;
+ if (xsurface->override_redirect) {
+ wl_list_insert(&root_container.sway_root->unmanaged_views,
+ &sway_surface->view->unmanaged_view_link);
+ }
+ sway_surface->view->surface = xsurface->surface;
}
static void handle_configure_request(struct wl_listener *listener, void *data) {
@@ -119,11 +149,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
listener, server, xwayland_surface);
struct wlr_xwayland_surface *xsurface = data;
- if (xsurface->override_redirect) {
- // TODO: floating popups
- return;
- }
-
wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
xsurface->title, xsurface->class);
@@ -155,15 +180,29 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
// - Set new view to maximized so it behaves nicely
// - Criteria
- sway_surface->commit.notify = handle_commit;
wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit);
- sway_surface->destroy.notify = handle_destroy;
+ sway_surface->commit.notify = handle_commit;
+
wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy);
- sway_surface->request_configure.notify = handle_configure_request;
+ sway_surface->destroy.notify = handle_destroy;
+
wl_signal_add(&xsurface->events.request_configure,
&sway_surface->request_configure);
+ sway_surface->request_configure.notify = handle_configure_request;
+
+ wl_signal_add(&xsurface->events.unmap_notify, &sway_surface->unmap_notify);
+ sway_surface->unmap_notify.notify = handle_unmap_notify;
+
+ wl_signal_add(&xsurface->events.map_notify, &sway_surface->map_notify);
+ sway_surface->map_notify.notify = handle_map_notify;
+
+ if (xsurface->override_redirect) {
+ // these don't get a container in the tree
+ wl_list_insert(&root_container.sway_root->unmanaged_views,
+ &sway_view->unmanaged_view_link);
+ return;
+ }
- // TODO: actual focus semantics
swayc_t *parent = root_container.children->items[0];
parent = parent->children->items[0]; // workspace