aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-18 12:42:09 -0700
committerLibravatar GitHub <noreply@github.com>2018-07-18 12:42:09 -0700
commit4931d0ddc5d9de1f823af7efd931702b2fa80260 (patch)
treeb486f3576982ab0f94183323d44bc4bbb3a456e3 /sway
parentMerge pull request #2292 from emersion/update-cursor-on-focus (diff)
parentDon't unfocus when an override redirect window is mapped (diff)
downloadsway-4931d0ddc5d9de1f823af7efd931702b2fa80260.tar.gz
sway-4931d0ddc5d9de1f823af7efd931702b2fa80260.tar.zst
sway-4931d0ddc5d9de1f823af7efd931702b2fa80260.zip
Merge pull request #2300 from emersion/override-redirect-updates
Handle xwayland override_redirect flag change
Diffstat (limited to 'sway')
-rw-r--r--sway/desktop/xwayland.c91
-rw-r--r--sway/input/seat.c6
2 files changed, 49 insertions, 48 deletions
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
84static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { 79static 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
299static 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
306static void handle_unmap(struct wl_listener *listener, void *data) { 320static 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
347static 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
368static void handle_request_configure(struct wl_listener *listener, void *data) { 370static 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
755void seat_set_focus_surface(struct sway_seat *seat, 755void 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 }