aboutsummaryrefslogtreecommitdiff
path: root/sway
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
parent2ce1d8d6cd0ae1520ea191678e3c39d555c66b58 (diff)
downloadsway-83ddd2d9dbee1b77993f5cc45427854e18aae6f1.tar.xz
render override redirect
Diffstat (limited to 'sway')
-rw-r--r--sway/desktop/output.c13
-rw-r--r--sway/desktop/xwayland.c61
-rw-r--r--sway/input/cursor.c25
-rw-r--r--sway/tree/container.c2
-rw-r--r--sway/tree/layout.c1
5 files changed, 90 insertions, 12 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
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index c51b59f9..e6a4eca8 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -24,6 +24,31 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor,
struct wlr_seat *seat = cursor->seat->wlr_seat;
struct wlr_surface *surface = NULL;
double sx, sy;
+
+ // check for unmanaged views first
+ struct sway_view *view;
+ wl_list_for_each_reverse(view, &root_container.sway_root->unmanaged_views,
+ unmanaged_view_link) {
+ if (view->type == SWAY_XWAYLAND_VIEW) {
+ struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
+ struct wlr_box box = {
+ .x = xsurface->x,
+ .y = xsurface->y,
+ .width = xsurface->width,
+ .height = xsurface->height,
+ };
+
+ if (wlr_box_contains_point(&box, cursor->x, cursor->y)) {
+ surface = xsurface->surface;
+ sx = cursor->x - box.x;
+ sy = cursor->y - box.y;
+ wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
+ wlr_seat_pointer_notify_motion(seat, time, sx, sy);
+ return;
+ }
+ }
+ }
+
swayc_t *swayc =
swayc_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy);
if (swayc) {
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 862406cf..d241f69a 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -207,7 +207,7 @@ swayc_t *destroy_output(swayc_t *output) {
}
swayc_t *destroy_view(swayc_t *view) {
- if (!sway_assert(view, "null view passed to destroy_view")) {
+ if (!view) {
return NULL;
}
wlr_log(L_DEBUG, "Destroying view '%s'", view->name);
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 13b8a395..01535f2d 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -51,6 +51,7 @@ void init_layout(void) {
root_container.sway_root = calloc(1, sizeof(*root_container.sway_root));
root_container.sway_root->output_layout = wlr_output_layout_create();
+ wl_list_init(&root_container.sway_root->unmanaged_views);
root_container.sway_root->output_layout_change.notify =
output_layout_change_notify;