aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2018-01-15 10:19:49 -0500
committerGitHub <noreply@github.com>2018-01-15 10:19:49 -0500
commiteb0f432a840dbe860b8c20f7a16e0281f9026326 (patch)
treea8b8e1a5a92a4203503ead496d8d50fd72fcf850 /sway/desktop/xwayland.c
parent5a23959242419169fa4af032d85ee3f65e7041e4 (diff)
parentddc49ede4636b01dad8d8bfb7d0314bf1eb88258 (diff)
Merge pull request #1566 from acrisci/render-loop
Subsurfaces and popups
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c87
1 files changed, 74 insertions, 13 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 43bb2e00..a4d9687d 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -93,13 +93,68 @@ 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);
+ if (xsurface->override_redirect) {
+ if (xsurface->mapped) {
+ wl_list_remove(&sway_surface->view->unmanaged_view_link);
+ }
+ }
+
swayc_t *parent = destroy_view(sway_surface->view->swayc);
+ if (parent) {
+ 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) {
+ 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);
+ }
+
+ // take it out of the tree
+ swayc_t *parent = destroy_view(sway_surface->view->swayc);
+ if (parent) {
+ arrange_windows(parent, -1, -1);
+ }
+
+ sway_surface->view->swayc = NULL;
+ 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;
+
+ sway_surface->view->surface = xsurface->surface;
+
+ // put it back into the tree
+ if (xsurface->override_redirect) {
+ wl_list_insert(&root_container.sway_root->unmanaged_views,
+ &sway_surface->view->unmanaged_view_link);
+ } else {
+ struct sway_view *view = sway_surface->view;
+ destroy_view(view->swayc);
+
+ swayc_t *parent = root_container.children->items[0];
+ parent = parent->children->items[0]; // workspace
+
+ swayc_t *cont = new_view(parent, view);
+ view->swayc = cont;
+
+ arrange_windows(cont->parent, -1, -1);
+ sway_input_manager_set_focus(input_manager, cont);
+ }
}
static void handle_configure_request(struct wl_listener *listener, void *data) {
@@ -119,11 +174,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);
@@ -144,26 +194,37 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
sway_view->iface.set_activated = set_activated;
sway_view->wlr_xwayland_surface = xsurface;
sway_view->sway_xwayland_surface = sway_surface;
- // TODO remove from the tree when the surface goes away (unmapped)
sway_view->surface = xsurface->surface;
sway_surface->view = sway_view;
// TODO:
- // - Wire up listeners
- // - Handle popups
// - Look up pid and open on appropriate workspace
// - 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