aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorLibravatar Tobias Langendorf <junglerobba@jngl.one>2020-08-29 17:14:55 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2020-10-10 09:53:41 +0200
commit657587964e5d8e444ac64829a0aab309c25ff50f (patch)
treeb0991a49d72f845a5783d5c642ccc72326b312c4 /sway/desktop/xwayland.c
parentcommands/move: fix single-split escaping on move (diff)
downloadsway-657587964e5d8e444ac64829a0aab309c25ff50f.tar.gz
sway-657587964e5d8e444ac64829a0aab309c25ff50f.tar.zst
sway-657587964e5d8e444ac64829a0aab309c25ff50f.zip
xwayland: support views that change override-redirect status
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 3b42013b..e35473bf 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -118,12 +118,36 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
118static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { 118static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
119 struct sway_xwayland_unmanaged *surface = 119 struct sway_xwayland_unmanaged *surface =
120 wl_container_of(listener, surface, destroy); 120 wl_container_of(listener, surface, destroy);
121 wl_list_remove(&surface->request_configure.link);
121 wl_list_remove(&surface->map.link); 122 wl_list_remove(&surface->map.link);
122 wl_list_remove(&surface->unmap.link); 123 wl_list_remove(&surface->unmap.link);
123 wl_list_remove(&surface->destroy.link); 124 wl_list_remove(&surface->destroy.link);
125 wl_list_remove(&surface->override_redirect.link);
124 free(surface); 126 free(surface);
125} 127}
126 128
129static void handle_map(struct wl_listener *listener, void *data);
130
131struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsurface);
132
133static void unmanaged_handle_override_redirect(struct wl_listener *listener, void *data) {
134 struct sway_xwayland_unmanaged *surface =
135 wl_container_of(listener, surface, override_redirect);
136 struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
137
138 bool mapped = xsurface->mapped;
139 if (mapped) {
140 unmanaged_handle_unmap(&surface->unmap, NULL);
141 }
142
143 unmanaged_handle_destroy(&surface->destroy, NULL);
144 xsurface->data = NULL;
145 struct sway_xwayland_view *xwayland_view = create_xwayland_view(xsurface);
146 if (mapped) {
147 handle_map(&xwayland_view->map, xsurface);
148 }
149}
150
127static struct sway_xwayland_unmanaged *create_unmanaged( 151static struct sway_xwayland_unmanaged *create_unmanaged(
128 struct wlr_xwayland_surface *xsurface) { 152 struct wlr_xwayland_surface *xsurface) {
129 struct sway_xwayland_unmanaged *surface = 153 struct sway_xwayland_unmanaged *surface =
@@ -144,6 +168,8 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
144 surface->unmap.notify = unmanaged_handle_unmap; 168 surface->unmap.notify = unmanaged_handle_unmap;
145 wl_signal_add(&xsurface->events.destroy, &surface->destroy); 169 wl_signal_add(&xsurface->events.destroy, &surface->destroy);
146 surface->destroy.notify = unmanaged_handle_destroy; 170 surface->destroy.notify = unmanaged_handle_destroy;
171 wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect);
172 surface->override_redirect.notify = unmanaged_handle_override_redirect;
147 173
148 return surface; 174 return surface;
149} 175}
@@ -418,6 +444,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
418 wl_list_remove(&xwayland_view->set_decorations.link); 444 wl_list_remove(&xwayland_view->set_decorations.link);
419 wl_list_remove(&xwayland_view->map.link); 445 wl_list_remove(&xwayland_view->map.link);
420 wl_list_remove(&xwayland_view->unmap.link); 446 wl_list_remove(&xwayland_view->unmap.link);
447 wl_list_remove(&xwayland_view->override_redirect.link);
421 view_begin_destroy(&xwayland_view->view); 448 view_begin_destroy(&xwayland_view->view);
422} 449}
423 450
@@ -441,16 +468,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
441 struct wlr_xwayland_surface *xsurface = data; 468 struct wlr_xwayland_surface *xsurface = data;
442 struct sway_view *view = &xwayland_view->view; 469 struct sway_view *view = &xwayland_view->view;
443 470
444 if (xsurface->override_redirect) {
445 // This window used not to have the override redirect flag and has it
446 // now. Switch to unmanaged.
447 handle_destroy(&xwayland_view->destroy, view);
448 xsurface->data = NULL;
449 struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface);
450 unmanaged_handle_map(&unmanaged->map, xsurface);
451 return;
452 }
453
454 view->natural_width = xsurface->width; 471 view->natural_width = xsurface->width;
455 view->natural_height = xsurface->height; 472 view->natural_height = xsurface->height;
456 473
@@ -465,6 +482,25 @@ static void handle_map(struct wl_listener *listener, void *data) {
465 transaction_commit_dirty(); 482 transaction_commit_dirty();
466} 483}
467 484
485static void handle_override_redirect(struct wl_listener *listener, void *data) {
486 struct sway_xwayland_view *xwayland_view =
487 wl_container_of(listener, xwayland_view, override_redirect);
488 struct wlr_xwayland_surface *xsurface = data;
489 struct sway_view *view = &xwayland_view->view;
490
491 bool mapped = xsurface->mapped;
492 if (mapped) {
493 handle_unmap(&xwayland_view->unmap, NULL);
494 }
495
496 handle_destroy(&xwayland_view->destroy, view);
497 xsurface->data = NULL;
498 struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface);
499 if (mapped) {
500 unmanaged_handle_map(&unmanaged->map, xsurface);
501 }
502}
503
468static void handle_request_configure(struct wl_listener *listener, void *data) { 504static void handle_request_configure(struct wl_listener *listener, void *data) {
469 struct sway_xwayland_view *xwayland_view = 505 struct sway_xwayland_view *xwayland_view =
470 wl_container_of(listener, xwayland_view, request_configure); 506 wl_container_of(listener, xwayland_view, request_configure);
@@ -637,22 +673,14 @@ struct sway_view *view_from_wlr_xwayland_surface(
637 return xsurface->data; 673 return xsurface->data;
638} 674}
639 675
640void handle_xwayland_surface(struct wl_listener *listener, void *data) { 676struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsurface) {
641 struct wlr_xwayland_surface *xsurface = data;
642
643 if (xsurface->override_redirect) {
644 sway_log(SWAY_DEBUG, "New xwayland unmanaged surface");
645 create_unmanaged(xsurface);
646 return;
647 }
648
649 sway_log(SWAY_DEBUG, "New xwayland surface title='%s' class='%s'", 677 sway_log(SWAY_DEBUG, "New xwayland surface title='%s' class='%s'",
650 xsurface->title, xsurface->class); 678 xsurface->title, xsurface->class);
651 679
652 struct sway_xwayland_view *xwayland_view = 680 struct sway_xwayland_view *xwayland_view =
653 calloc(1, sizeof(struct sway_xwayland_view)); 681 calloc(1, sizeof(struct sway_xwayland_view));
654 if (!sway_assert(xwayland_view, "Failed to allocate view")) { 682 if (!sway_assert(xwayland_view, "Failed to allocate view")) {
655 return; 683 return NULL;
656 } 684 }
657 685
658 view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl); 686 view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl);
@@ -711,7 +739,25 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
711 wl_signal_add(&xsurface->events.map, &xwayland_view->map); 739 wl_signal_add(&xsurface->events.map, &xwayland_view->map);
712 xwayland_view->map.notify = handle_map; 740 xwayland_view->map.notify = handle_map;
713 741
742 wl_signal_add(&xsurface->events.set_override_redirect,
743 &xwayland_view->override_redirect);
744 xwayland_view->override_redirect.notify = handle_override_redirect;
745
714 xsurface->data = xwayland_view; 746 xsurface->data = xwayland_view;
747
748 return xwayland_view;
749}
750
751void handle_xwayland_surface(struct wl_listener *listener, void *data) {
752 struct wlr_xwayland_surface *xsurface = data;
753
754 if (xsurface->override_redirect) {
755 sway_log(SWAY_DEBUG, "New xwayland unmanaged surface");
756 create_unmanaged(xsurface);
757 return;
758 }
759
760 create_xwayland_view(xsurface);
715} 761}
716 762
717void handle_xwayland_ready(struct wl_listener *listener, void *data) { 763void handle_xwayland_ready(struct wl_listener *listener, void *data) {