diff options
-rw-r--r-- | include/sway/input/seat.h | 2 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 91 | ||||
-rw-r--r-- | sway/input/seat.c | 6 |
3 files changed, 50 insertions, 49 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 1f7792ba..eac1626b 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h | |||
@@ -83,7 +83,7 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
83 | struct sway_container *container, bool warp); | 83 | struct sway_container *container, bool warp); |
84 | 84 | ||
85 | void seat_set_focus_surface(struct sway_seat *seat, | 85 | void seat_set_focus_surface(struct sway_seat *seat, |
86 | struct wlr_surface *surface); | 86 | struct wlr_surface *surface, bool unfocus); |
87 | 87 | ||
88 | void seat_set_focus_layer(struct sway_seat *seat, | 88 | void seat_set_focus_layer(struct sway_seat *seat, |
89 | struct wlr_layer_surface *layer); | 89 | struct wlr_layer_surface *layer); |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 9df7977d..7737a33a 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -69,16 +69,11 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { | |||
69 | surface->ly = xsurface->y; | 69 | surface->ly = xsurface->y; |
70 | desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); | 70 | desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); |
71 | 71 | ||
72 | if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { | 72 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
73 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 73 | struct wlr_xwayland *xwayland = |
74 | struct wlr_xwayland *xwayland = | 74 | seat->input->server->xwayland.wlr_xwayland; |
75 | seat->input->server->xwayland.wlr_xwayland; | 75 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); |
76 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); | 76 | seat_set_focus_surface(seat, xsurface->surface, false); |
77 | seat_set_focus_surface(seat, xsurface->surface); | ||
78 | } | ||
79 | |||
80 | // TODO: we don't send surface enter/leave events to xwayland unmanaged | ||
81 | // surfaces, but xwayland doesn't support HiDPI anyway | ||
82 | } | 77 | } |
83 | 78 | ||
84 | static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { | 79 | static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { |
@@ -89,18 +84,16 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { | |||
89 | wl_list_remove(&surface->link); | 84 | wl_list_remove(&surface->link); |
90 | wl_list_remove(&surface->commit.link); | 85 | wl_list_remove(&surface->commit.link); |
91 | 86 | ||
92 | if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { | 87 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
93 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 88 | if (seat->wlr_seat->keyboard_state.focused_surface == |
94 | if (seat->wlr_seat->keyboard_state.focused_surface == | 89 | xsurface->surface) { |
95 | xsurface->surface) { | 90 | // Restore focus |
96 | // Restore focus | 91 | struct sway_container *previous = |
97 | struct sway_container *previous = | 92 | seat_get_focus_inactive(seat, &root_container); |
98 | seat_get_focus_inactive(seat, &root_container); | 93 | if (previous) { |
99 | if (previous) { | 94 | // Hack to get seat to re-focus the return value of get_focus |
100 | // Hack to get seat to re-focus the return value of get_focus | 95 | seat_set_focus(seat, previous->parent); |
101 | seat_set_focus(seat, previous->parent); | 96 | seat_set_focus(seat, previous); |
102 | seat_set_focus(seat, previous); | ||
103 | } | ||
104 | } | 97 | } |
105 | } | 98 | } |
106 | } | 99 | } |
@@ -303,6 +296,27 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
303 | } | 296 | } |
304 | } | 297 | } |
305 | 298 | ||
299 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
300 | struct sway_xwayland_view *xwayland_view = | ||
301 | wl_container_of(listener, xwayland_view, destroy); | ||
302 | struct sway_view *view = &xwayland_view->view; | ||
303 | |||
304 | if (view->surface) { | ||
305 | view_unmap(view); | ||
306 | wl_list_remove(&xwayland_view->commit.link); | ||
307 | } | ||
308 | |||
309 | wl_list_remove(&xwayland_view->destroy.link); | ||
310 | wl_list_remove(&xwayland_view->request_configure.link); | ||
311 | wl_list_remove(&xwayland_view->request_fullscreen.link); | ||
312 | wl_list_remove(&xwayland_view->set_title.link); | ||
313 | wl_list_remove(&xwayland_view->set_class.link); | ||
314 | wl_list_remove(&xwayland_view->set_window_type.link); | ||
315 | wl_list_remove(&xwayland_view->map.link); | ||
316 | wl_list_remove(&xwayland_view->unmap.link); | ||
317 | view_destroy(&xwayland_view->view); | ||
318 | } | ||
319 | |||
306 | static void handle_unmap(struct wl_listener *listener, void *data) { | 320 | static void handle_unmap(struct wl_listener *listener, void *data) { |
307 | struct sway_xwayland_view *xwayland_view = | 321 | struct sway_xwayland_view *xwayland_view = |
308 | wl_container_of(listener, xwayland_view, unmap); | 322 | wl_container_of(listener, xwayland_view, unmap); |
@@ -323,6 +337,15 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
323 | struct wlr_xwayland_surface *xsurface = data; | 337 | struct wlr_xwayland_surface *xsurface = data; |
324 | struct sway_view *view = &xwayland_view->view; | 338 | struct sway_view *view = &xwayland_view->view; |
325 | 339 | ||
340 | if (xsurface->override_redirect) { | ||
341 | // This window used not to have the override redirect flag and has it | ||
342 | // now. Switch to unmanaged. | ||
343 | handle_destroy(&xwayland_view->destroy, view); | ||
344 | struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface); | ||
345 | unmanaged_handle_map(&unmanaged->map, xsurface); | ||
346 | return; | ||
347 | } | ||
348 | |||
326 | view->natural_width = xsurface->width; | 349 | view->natural_width = xsurface->width; |
327 | view->natural_height = xsurface->height; | 350 | view->natural_height = xsurface->height; |
328 | 351 | ||
@@ -344,27 +367,6 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
344 | transaction_commit_dirty(); | 367 | transaction_commit_dirty(); |
345 | } | 368 | } |
346 | 369 | ||
347 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
348 | struct sway_xwayland_view *xwayland_view = | ||
349 | wl_container_of(listener, xwayland_view, destroy); | ||
350 | struct sway_view *view = &xwayland_view->view; | ||
351 | |||
352 | if (view->surface) { | ||
353 | view_unmap(view); | ||
354 | wl_list_remove(&xwayland_view->commit.link); | ||
355 | } | ||
356 | |||
357 | wl_list_remove(&xwayland_view->destroy.link); | ||
358 | wl_list_remove(&xwayland_view->request_configure.link); | ||
359 | wl_list_remove(&xwayland_view->request_fullscreen.link); | ||
360 | wl_list_remove(&xwayland_view->set_title.link); | ||
361 | wl_list_remove(&xwayland_view->set_class.link); | ||
362 | wl_list_remove(&xwayland_view->set_window_type.link); | ||
363 | wl_list_remove(&xwayland_view->map.link); | ||
364 | wl_list_remove(&xwayland_view->unmap.link); | ||
365 | view_destroy(&xwayland_view->view); | ||
366 | } | ||
367 | |||
368 | static void handle_request_configure(struct wl_listener *listener, void *data) { | 370 | static void handle_request_configure(struct wl_listener *listener, void *data) { |
369 | struct sway_xwayland_view *xwayland_view = | 371 | struct sway_xwayland_view *xwayland_view = |
370 | wl_container_of(listener, xwayland_view, request_configure); | 372 | wl_container_of(listener, xwayland_view, request_configure); |
@@ -445,8 +447,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
445 | xwayland_surface); | 447 | xwayland_surface); |
446 | struct wlr_xwayland_surface *xsurface = data; | 448 | struct wlr_xwayland_surface *xsurface = data; |
447 | 449 | ||
448 | if (wlr_xwayland_surface_is_unmanaged(xsurface) || | 450 | if (xsurface->override_redirect) { |
449 | xsurface->override_redirect) { | ||
450 | wlr_log(WLR_DEBUG, "New xwayland unmanaged surface"); | 451 | wlr_log(WLR_DEBUG, "New xwayland unmanaged surface"); |
451 | create_unmanaged(xsurface); | 452 | create_unmanaged(xsurface); |
452 | return; | 453 | return; |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 8ed4a3fe..eadf3b26 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -753,11 +753,11 @@ void seat_set_focus(struct sway_seat *seat, | |||
753 | } | 753 | } |
754 | 754 | ||
755 | void seat_set_focus_surface(struct sway_seat *seat, | 755 | void seat_set_focus_surface(struct sway_seat *seat, |
756 | struct wlr_surface *surface) { | 756 | struct wlr_surface *surface, bool unfocus) { |
757 | if (seat->focused_layer != NULL) { | 757 | if (seat->focused_layer != NULL) { |
758 | return; | 758 | return; |
759 | } | 759 | } |
760 | if (seat->has_focus) { | 760 | if (seat->has_focus && unfocus) { |
761 | struct sway_container *focus = seat_get_focus(seat); | 761 | struct sway_container *focus = seat_get_focus(seat); |
762 | seat_send_unfocus(focus, seat); | 762 | seat_send_unfocus(focus, seat); |
763 | seat->has_focus = false; | 763 | seat->has_focus = false; |
@@ -789,7 +789,7 @@ void seat_set_focus_layer(struct sway_seat *seat, | |||
789 | } else if (!layer || seat->focused_layer == layer) { | 789 | } else if (!layer || seat->focused_layer == layer) { |
790 | return; | 790 | return; |
791 | } | 791 | } |
792 | seat_set_focus_surface(seat, layer->surface); | 792 | seat_set_focus_surface(seat, layer->surface, true); |
793 | if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { | 793 | if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { |
794 | seat->focused_layer = layer; | 794 | seat->focused_layer = layer; |
795 | } | 795 | } |