diff options
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index bcefc4fd..bb4340f1 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -128,7 +128,7 @@ static void unmanaged_handle_request_activate(struct wl_listener *listener, void | |||
128 | struct sway_xwayland_unmanaged *surface = | 128 | struct sway_xwayland_unmanaged *surface = |
129 | wl_container_of(listener, surface, request_activate); | 129 | wl_container_of(listener, surface, request_activate); |
130 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | 130 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
131 | if (!xsurface->mapped) { | 131 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
132 | return; | 132 | return; |
133 | } | 133 | } |
134 | struct sway_seat *seat = input_manager_current_seat(); | 134 | struct sway_seat *seat = input_manager_current_seat(); |
@@ -140,12 +140,29 @@ static void unmanaged_handle_request_activate(struct wl_listener *listener, void | |||
140 | seat_set_focus_surface(seat, xsurface->surface, false); | 140 | seat_set_focus_surface(seat, xsurface->surface, false); |
141 | } | 141 | } |
142 | 142 | ||
143 | static void unmanaged_handle_associate(struct wl_listener *listener, void *data) { | ||
144 | struct sway_xwayland_unmanaged *surface = | ||
145 | wl_container_of(listener, surface, associate); | ||
146 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | ||
147 | wl_signal_add(&xsurface->surface->events.map, &surface->map); | ||
148 | surface->map.notify = unmanaged_handle_map; | ||
149 | wl_signal_add(&xsurface->surface->events.unmap, &surface->unmap); | ||
150 | surface->unmap.notify = unmanaged_handle_unmap; | ||
151 | } | ||
152 | |||
153 | static void unmanaged_handle_dissociate(struct wl_listener *listener, void *data) { | ||
154 | struct sway_xwayland_unmanaged *surface = | ||
155 | wl_container_of(listener, surface, dissociate); | ||
156 | wl_list_remove(&surface->map.link); | ||
157 | wl_list_remove(&surface->unmap.link); | ||
158 | } | ||
159 | |||
143 | static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { | 160 | static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { |
144 | struct sway_xwayland_unmanaged *surface = | 161 | struct sway_xwayland_unmanaged *surface = |
145 | wl_container_of(listener, surface, destroy); | 162 | wl_container_of(listener, surface, destroy); |
146 | wl_list_remove(&surface->request_configure.link); | 163 | wl_list_remove(&surface->request_configure.link); |
147 | wl_list_remove(&surface->map.link); | 164 | wl_list_remove(&surface->associate.link); |
148 | wl_list_remove(&surface->unmap.link); | 165 | wl_list_remove(&surface->dissociate.link); |
149 | wl_list_remove(&surface->destroy.link); | 166 | wl_list_remove(&surface->destroy.link); |
150 | wl_list_remove(&surface->override_redirect.link); | 167 | wl_list_remove(&surface->override_redirect.link); |
151 | wl_list_remove(&surface->request_activate.link); | 168 | wl_list_remove(&surface->request_activate.link); |
@@ -161,7 +178,7 @@ static void unmanaged_handle_override_redirect(struct wl_listener *listener, voi | |||
161 | wl_container_of(listener, surface, override_redirect); | 178 | wl_container_of(listener, surface, override_redirect); |
162 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | 179 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
163 | 180 | ||
164 | bool mapped = xsurface->mapped; | 181 | bool mapped = xsurface->surface != NULL || xsurface->surface->mapped; |
165 | if (mapped) { | 182 | if (mapped) { |
166 | unmanaged_handle_unmap(&surface->unmap, NULL); | 183 | unmanaged_handle_unmap(&surface->unmap, NULL); |
167 | } | 184 | } |
@@ -188,10 +205,10 @@ static struct sway_xwayland_unmanaged *create_unmanaged( | |||
188 | wl_signal_add(&xsurface->events.request_configure, | 205 | wl_signal_add(&xsurface->events.request_configure, |
189 | &surface->request_configure); | 206 | &surface->request_configure); |
190 | surface->request_configure.notify = unmanaged_handle_request_configure; | 207 | surface->request_configure.notify = unmanaged_handle_request_configure; |
191 | wl_signal_add(&xsurface->events.map, &surface->map); | 208 | wl_signal_add(&xsurface->events.associate, &surface->associate); |
192 | surface->map.notify = unmanaged_handle_map; | 209 | surface->associate.notify = unmanaged_handle_associate; |
193 | wl_signal_add(&xsurface->events.unmap, &surface->unmap); | 210 | wl_signal_add(&xsurface->events.dissociate, &surface->dissociate); |
194 | surface->unmap.notify = unmanaged_handle_unmap; | 211 | surface->dissociate.notify = unmanaged_handle_dissociate; |
195 | wl_signal_add(&xsurface->events.destroy, &surface->destroy); | 212 | wl_signal_add(&xsurface->events.destroy, &surface->destroy); |
196 | surface->destroy.notify = unmanaged_handle_destroy; | 213 | surface->destroy.notify = unmanaged_handle_destroy; |
197 | wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect); | 214 | wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect); |
@@ -474,8 +491,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
474 | wl_list_remove(&xwayland_view->set_window_type.link); | 491 | wl_list_remove(&xwayland_view->set_window_type.link); |
475 | wl_list_remove(&xwayland_view->set_hints.link); | 492 | wl_list_remove(&xwayland_view->set_hints.link); |
476 | wl_list_remove(&xwayland_view->set_decorations.link); | 493 | wl_list_remove(&xwayland_view->set_decorations.link); |
477 | wl_list_remove(&xwayland_view->map.link); | 494 | wl_list_remove(&xwayland_view->associate.link); |
478 | wl_list_remove(&xwayland_view->unmap.link); | 495 | wl_list_remove(&xwayland_view->dissociate.link); |
479 | wl_list_remove(&xwayland_view->override_redirect.link); | 496 | wl_list_remove(&xwayland_view->override_redirect.link); |
480 | view_begin_destroy(&xwayland_view->view); | 497 | view_begin_destroy(&xwayland_view->view); |
481 | } | 498 | } |
@@ -520,7 +537,7 @@ static void handle_override_redirect(struct wl_listener *listener, void *data) { | |||
520 | struct sway_view *view = &xwayland_view->view; | 537 | struct sway_view *view = &xwayland_view->view; |
521 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 538 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
522 | 539 | ||
523 | bool mapped = xsurface->mapped; | 540 | bool mapped = xsurface->surface != NULL || xsurface->surface->mapped; |
524 | if (mapped) { | 541 | if (mapped) { |
525 | handle_unmap(&xwayland_view->unmap, NULL); | 542 | handle_unmap(&xwayland_view->unmap, NULL); |
526 | } | 543 | } |
@@ -539,7 +556,7 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { | |||
539 | struct wlr_xwayland_surface_configure_event *ev = data; | 556 | struct wlr_xwayland_surface_configure_event *ev = data; |
540 | struct sway_view *view = &xwayland_view->view; | 557 | struct sway_view *view = &xwayland_view->view; |
541 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 558 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
542 | if (!xsurface->mapped) { | 559 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
543 | wlr_xwayland_surface_configure(xsurface, ev->x, ev->y, | 560 | wlr_xwayland_surface_configure(xsurface, ev->x, ev->y, |
544 | ev->width, ev->height); | 561 | ev->width, ev->height); |
545 | return; | 562 | return; |
@@ -568,7 +585,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
568 | wl_container_of(listener, xwayland_view, request_fullscreen); | 585 | wl_container_of(listener, xwayland_view, request_fullscreen); |
569 | struct sway_view *view = &xwayland_view->view; | 586 | struct sway_view *view = &xwayland_view->view; |
570 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 587 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
571 | if (!xsurface->mapped) { | 588 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
572 | return; | 589 | return; |
573 | } | 590 | } |
574 | container_set_fullscreen(view->container, xsurface->fullscreen); | 591 | container_set_fullscreen(view->container, xsurface->fullscreen); |
@@ -582,7 +599,7 @@ static void handle_request_minimize(struct wl_listener *listener, void *data) { | |||
582 | wl_container_of(listener, xwayland_view, request_minimize); | 599 | wl_container_of(listener, xwayland_view, request_minimize); |
583 | struct sway_view *view = &xwayland_view->view; | 600 | struct sway_view *view = &xwayland_view->view; |
584 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 601 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
585 | if (!xsurface->mapped) { | 602 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
586 | return; | 603 | return; |
587 | } | 604 | } |
588 | 605 | ||
@@ -597,7 +614,7 @@ static void handle_request_move(struct wl_listener *listener, void *data) { | |||
597 | wl_container_of(listener, xwayland_view, request_move); | 614 | wl_container_of(listener, xwayland_view, request_move); |
598 | struct sway_view *view = &xwayland_view->view; | 615 | struct sway_view *view = &xwayland_view->view; |
599 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 616 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
600 | if (!xsurface->mapped) { | 617 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
601 | return; | 618 | return; |
602 | } | 619 | } |
603 | if (!container_is_floating(view->container) || | 620 | if (!container_is_floating(view->container) || |
@@ -613,7 +630,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { | |||
613 | wl_container_of(listener, xwayland_view, request_resize); | 630 | wl_container_of(listener, xwayland_view, request_resize); |
614 | struct sway_view *view = &xwayland_view->view; | 631 | struct sway_view *view = &xwayland_view->view; |
615 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 632 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
616 | if (!xsurface->mapped) { | 633 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
617 | return; | 634 | return; |
618 | } | 635 | } |
619 | if (!container_is_floating(view->container)) { | 636 | if (!container_is_floating(view->container)) { |
@@ -629,7 +646,7 @@ static void handle_request_activate(struct wl_listener *listener, void *data) { | |||
629 | wl_container_of(listener, xwayland_view, request_activate); | 646 | wl_container_of(listener, xwayland_view, request_activate); |
630 | struct sway_view *view = &xwayland_view->view; | 647 | struct sway_view *view = &xwayland_view->view; |
631 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 648 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
632 | if (!xsurface->mapped) { | 649 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
633 | return; | 650 | return; |
634 | } | 651 | } |
635 | view_request_activate(view, NULL); | 652 | view_request_activate(view, NULL); |
@@ -642,7 +659,7 @@ static void handle_set_title(struct wl_listener *listener, void *data) { | |||
642 | wl_container_of(listener, xwayland_view, set_title); | 659 | wl_container_of(listener, xwayland_view, set_title); |
643 | struct sway_view *view = &xwayland_view->view; | 660 | struct sway_view *view = &xwayland_view->view; |
644 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 661 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
645 | if (!xsurface->mapped) { | 662 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
646 | return; | 663 | return; |
647 | } | 664 | } |
648 | view_update_title(view, false); | 665 | view_update_title(view, false); |
@@ -654,7 +671,7 @@ static void handle_set_class(struct wl_listener *listener, void *data) { | |||
654 | wl_container_of(listener, xwayland_view, set_class); | 671 | wl_container_of(listener, xwayland_view, set_class); |
655 | struct sway_view *view = &xwayland_view->view; | 672 | struct sway_view *view = &xwayland_view->view; |
656 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 673 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
657 | if (!xsurface->mapped) { | 674 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
658 | return; | 675 | return; |
659 | } | 676 | } |
660 | view_execute_criteria(view); | 677 | view_execute_criteria(view); |
@@ -665,7 +682,7 @@ static void handle_set_role(struct wl_listener *listener, void *data) { | |||
665 | wl_container_of(listener, xwayland_view, set_role); | 682 | wl_container_of(listener, xwayland_view, set_role); |
666 | struct sway_view *view = &xwayland_view->view; | 683 | struct sway_view *view = &xwayland_view->view; |
667 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 684 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
668 | if (!xsurface->mapped) { | 685 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
669 | return; | 686 | return; |
670 | } | 687 | } |
671 | view_execute_criteria(view); | 688 | view_execute_criteria(view); |
@@ -701,7 +718,7 @@ static void handle_set_window_type(struct wl_listener *listener, void *data) { | |||
701 | wl_container_of(listener, xwayland_view, set_window_type); | 718 | wl_container_of(listener, xwayland_view, set_window_type); |
702 | struct sway_view *view = &xwayland_view->view; | 719 | struct sway_view *view = &xwayland_view->view; |
703 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 720 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
704 | if (!xsurface->mapped) { | 721 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
705 | return; | 722 | return; |
706 | } | 723 | } |
707 | view_execute_criteria(view); | 724 | view_execute_criteria(view); |
@@ -712,7 +729,7 @@ static void handle_set_hints(struct wl_listener *listener, void *data) { | |||
712 | wl_container_of(listener, xwayland_view, set_hints); | 729 | wl_container_of(listener, xwayland_view, set_hints); |
713 | struct sway_view *view = &xwayland_view->view; | 730 | struct sway_view *view = &xwayland_view->view; |
714 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 731 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
715 | if (!xsurface->mapped) { | 732 | if (xsurface->surface == NULL || !xsurface->surface->mapped) { |
716 | return; | 733 | return; |
717 | } | 734 | } |
718 | const bool hints_urgency = xcb_icccm_wm_hints_get_urgency(xsurface->hints); | 735 | const bool hints_urgency = xcb_icccm_wm_hints_get_urgency(xsurface->hints); |
@@ -727,6 +744,24 @@ static void handle_set_hints(struct wl_listener *listener, void *data) { | |||
727 | } | 744 | } |
728 | } | 745 | } |
729 | 746 | ||
747 | static void handle_associate(struct wl_listener *listener, void *data) { | ||
748 | struct sway_xwayland_view *xwayland_view = | ||
749 | wl_container_of(listener, xwayland_view, associate); | ||
750 | struct wlr_xwayland_surface *xsurface = | ||
751 | xwayland_view->view.wlr_xwayland_surface; | ||
752 | wl_signal_add(&xsurface->surface->events.unmap, &xwayland_view->unmap); | ||
753 | xwayland_view->unmap.notify = handle_unmap; | ||
754 | wl_signal_add(&xsurface->surface->events.map, &xwayland_view->map); | ||
755 | xwayland_view->map.notify = handle_map; | ||
756 | } | ||
757 | |||
758 | static void handle_dissociate(struct wl_listener *listener, void *data) { | ||
759 | struct sway_xwayland_view *xwayland_view = | ||
760 | wl_container_of(listener, xwayland_view, dissociate); | ||
761 | wl_list_remove(&xwayland_view->map.link); | ||
762 | wl_list_remove(&xwayland_view->unmap.link); | ||
763 | } | ||
764 | |||
730 | struct sway_view *view_from_wlr_xwayland_surface( | 765 | struct sway_view *view_from_wlr_xwayland_surface( |
731 | struct wlr_xwayland_surface *xsurface) { | 766 | struct wlr_xwayland_surface *xsurface) { |
732 | return xsurface->data; | 767 | return xsurface->data; |
@@ -796,11 +831,11 @@ struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsu | |||
796 | &xwayland_view->set_decorations); | 831 | &xwayland_view->set_decorations); |
797 | xwayland_view->set_decorations.notify = handle_set_decorations; | 832 | xwayland_view->set_decorations.notify = handle_set_decorations; |
798 | 833 | ||
799 | wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); | 834 | wl_signal_add(&xsurface->events.associate, &xwayland_view->associate); |
800 | xwayland_view->unmap.notify = handle_unmap; | 835 | xwayland_view->associate.notify = handle_associate; |
801 | 836 | ||
802 | wl_signal_add(&xsurface->events.map, &xwayland_view->map); | 837 | wl_signal_add(&xsurface->events.dissociate, &xwayland_view->dissociate); |
803 | xwayland_view->map.notify = handle_map; | 838 | xwayland_view->dissociate.notify = handle_dissociate; |
804 | 839 | ||
805 | wl_signal_add(&xsurface->events.set_override_redirect, | 840 | wl_signal_add(&xsurface->events.set_override_redirect, |
806 | &xwayland_view->override_redirect); | 841 | &xwayland_view->override_redirect); |