diff options
author | Kirill Primak <vyivel@eclair.cafe> | 2023-07-11 15:09:14 +0300 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2023-11-23 19:41:57 +0100 |
commit | 47e6a1164c25b5b49bfb919a681b88641d2ce37c (patch) | |
tree | 7d801aeea31eef9ab2f60cbaaa52d2b9d55289b3 | |
parent | Pass wl_display to wlr_output_layout (diff) | |
download | sway-47e6a1164c25b5b49bfb919a681b88641d2ce37c.tar.gz sway-47e6a1164c25b5b49bfb919a681b88641d2ce37c.tar.zst sway-47e6a1164c25b5b49bfb919a681b88641d2ce37c.zip |
xdg-shell: chase events update
-rw-r--r-- | include/sway/server.h | 4 | ||||
-rw-r--r-- | include/sway/tree/view.h | 1 | ||||
-rw-r--r-- | include/sway/xdg_decoration.h | 2 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 45 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 87 | ||||
-rw-r--r-- | sway/server.c | 6 | ||||
-rw-r--r-- | sway/xdg_decoration.c | 59 |
7 files changed, 114 insertions, 90 deletions
diff --git a/include/sway/server.h b/include/sway/server.h index be5c8d72..1b3166ce 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -59,7 +59,7 @@ struct sway_server { | |||
59 | struct wl_listener layer_shell_surface; | 59 | struct wl_listener layer_shell_surface; |
60 | 60 | ||
61 | struct wlr_xdg_shell *xdg_shell; | 61 | struct wlr_xdg_shell *xdg_shell; |
62 | struct wl_listener xdg_shell_surface; | 62 | struct wl_listener xdg_shell_toplevel; |
63 | 63 | ||
64 | struct wlr_tablet_manager_v2 *tablet_v2; | 64 | struct wlr_tablet_manager_v2 *tablet_v2; |
65 | 65 | ||
@@ -176,7 +176,7 @@ void handle_new_output(struct wl_listener *listener, void *data); | |||
176 | void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data); | 176 | void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data); |
177 | void handle_layer_shell_surface(struct wl_listener *listener, void *data); | 177 | void handle_layer_shell_surface(struct wl_listener *listener, void *data); |
178 | void sway_session_lock_init(void); | 178 | void sway_session_lock_init(void); |
179 | void handle_xdg_shell_surface(struct wl_listener *listener, void *data); | 179 | void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data); |
180 | #if HAVE_XWAYLAND | 180 | #if HAVE_XWAYLAND |
181 | void handle_xwayland_surface(struct wl_listener *listener, void *data); | 181 | void handle_xwayland_surface(struct wl_listener *listener, void *data); |
182 | #endif | 182 | #endif |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 960f9d71..856651a5 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -226,6 +226,7 @@ struct sway_xdg_popup { | |||
226 | 226 | ||
227 | struct wlr_xdg_popup *wlr_xdg_popup; | 227 | struct wlr_xdg_popup *wlr_xdg_popup; |
228 | 228 | ||
229 | struct wl_listener surface_commit; | ||
229 | struct wl_listener new_popup; | 230 | struct wl_listener new_popup; |
230 | struct wl_listener destroy; | 231 | struct wl_listener destroy; |
231 | }; | 232 | }; |
diff --git a/include/sway/xdg_decoration.h b/include/sway/xdg_decoration.h index 8bef4c6d..2388ebcb 100644 --- a/include/sway/xdg_decoration.h +++ b/include/sway/xdg_decoration.h | |||
@@ -16,4 +16,6 @@ struct sway_xdg_decoration { | |||
16 | struct sway_xdg_decoration *xdg_decoration_from_surface( | 16 | struct sway_xdg_decoration *xdg_decoration_from_surface( |
17 | struct wlr_surface *surface); | 17 | struct wlr_surface *surface); |
18 | 18 | ||
19 | void set_xdg_decoration_mode(struct sway_xdg_decoration *deco); | ||
20 | |||
19 | #endif | 21 | #endif |
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 8c6cedfe..979c4449 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -542,6 +542,26 @@ static void popup_damage(struct sway_layer_popup *layer_popup, bool whole) { | |||
542 | output_damage_surface(output, ox, oy, surface, whole); | 542 | output_damage_surface(output, ox, oy, surface, whole); |
543 | } | 543 | } |
544 | 544 | ||
545 | static void popup_unconstrain(struct sway_layer_popup *popup) { | ||
546 | struct sway_layer_surface *layer = popup_get_layer(popup); | ||
547 | struct wlr_xdg_popup *wlr_popup = popup->wlr_popup; | ||
548 | |||
549 | struct wlr_output *wlr_output = layer->layer_surface->output; | ||
550 | sway_assert(wlr_output, "wlr_layer_surface_v1 has null output"); | ||
551 | struct sway_output *output = wlr_output->data; | ||
552 | |||
553 | // the output box expressed in the coordinate system of the toplevel parent | ||
554 | // of the popup | ||
555 | struct wlr_box output_toplevel_sx_box = { | ||
556 | .x = -layer->geo.x, | ||
557 | .y = -layer->geo.y, | ||
558 | .width = output->width, | ||
559 | .height = output->height, | ||
560 | }; | ||
561 | |||
562 | wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); | ||
563 | } | ||
564 | |||
545 | static void popup_handle_map(struct wl_listener *listener, void *data) { | 565 | static void popup_handle_map(struct wl_listener *listener, void *data) { |
546 | struct sway_layer_popup *popup = wl_container_of(listener, popup, map); | 566 | struct sway_layer_popup *popup = wl_container_of(listener, popup, map); |
547 | struct sway_layer_surface *layer = popup_get_layer(popup); | 567 | struct sway_layer_surface *layer = popup_get_layer(popup); |
@@ -558,6 +578,9 @@ static void popup_handle_unmap(struct wl_listener *listener, void *data) { | |||
558 | 578 | ||
559 | static void popup_handle_commit(struct wl_listener *listener, void *data) { | 579 | static void popup_handle_commit(struct wl_listener *listener, void *data) { |
560 | struct sway_layer_popup *popup = wl_container_of(listener, popup, commit); | 580 | struct sway_layer_popup *popup = wl_container_of(listener, popup, commit); |
581 | if (popup->wlr_popup->base->initial_commit) { | ||
582 | popup_unconstrain(popup); | ||
583 | } | ||
561 | popup_damage(popup, false); | 584 | popup_damage(popup, false); |
562 | } | 585 | } |
563 | 586 | ||
@@ -572,26 +595,6 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { | |||
572 | free(popup); | 595 | free(popup); |
573 | } | 596 | } |
574 | 597 | ||
575 | static void popup_unconstrain(struct sway_layer_popup *popup) { | ||
576 | struct sway_layer_surface *layer = popup_get_layer(popup); | ||
577 | struct wlr_xdg_popup *wlr_popup = popup->wlr_popup; | ||
578 | |||
579 | struct wlr_output *wlr_output = layer->layer_surface->output; | ||
580 | sway_assert(wlr_output, "wlr_layer_surface_v1 has null output"); | ||
581 | struct sway_output *output = wlr_output->data; | ||
582 | |||
583 | // the output box expressed in the coordinate system of the toplevel parent | ||
584 | // of the popup | ||
585 | struct wlr_box output_toplevel_sx_box = { | ||
586 | .x = -layer->geo.x, | ||
587 | .y = -layer->geo.y, | ||
588 | .width = output->width, | ||
589 | .height = output->height, | ||
590 | }; | ||
591 | |||
592 | wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); | ||
593 | } | ||
594 | |||
595 | static void popup_handle_new_popup(struct wl_listener *listener, void *data); | 598 | static void popup_handle_new_popup(struct wl_listener *listener, void *data); |
596 | 599 | ||
597 | static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, | 600 | static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, |
@@ -617,8 +620,6 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, | |||
617 | popup->new_popup.notify = popup_handle_new_popup; | 620 | popup->new_popup.notify = popup_handle_new_popup; |
618 | wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); | 621 | wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); |
619 | 622 | ||
620 | popup_unconstrain(popup); | ||
621 | |||
622 | return popup; | 623 | return popup; |
623 | } | 624 | } |
624 | 625 | ||
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 4c59b42a..63a0835b 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -38,6 +38,7 @@ static void popup_destroy(struct sway_view_child *child) { | |||
38 | return; | 38 | return; |
39 | } | 39 | } |
40 | struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child; | 40 | struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child; |
41 | wl_list_remove(&popup->surface_commit.link); | ||
41 | wl_list_remove(&popup->new_popup.link); | 42 | wl_list_remove(&popup->new_popup.link); |
42 | wl_list_remove(&popup->destroy.link); | 43 | wl_list_remove(&popup->destroy.link); |
43 | free(popup); | 44 | free(popup); |
@@ -51,18 +52,6 @@ static const struct sway_view_child_impl popup_impl = { | |||
51 | static struct sway_xdg_popup *popup_create( | 52 | static struct sway_xdg_popup *popup_create( |
52 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view); | 53 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view); |
53 | 54 | ||
54 | static void popup_handle_new_popup(struct wl_listener *listener, void *data) { | ||
55 | struct sway_xdg_popup *popup = | ||
56 | wl_container_of(listener, popup, new_popup); | ||
57 | struct wlr_xdg_popup *wlr_popup = data; | ||
58 | popup_create(wlr_popup, popup->child.view); | ||
59 | } | ||
60 | |||
61 | static void popup_handle_destroy(struct wl_listener *listener, void *data) { | ||
62 | struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy); | ||
63 | view_child_destroy(&popup->child); | ||
64 | } | ||
65 | |||
66 | static void popup_unconstrain(struct sway_xdg_popup *popup) { | 55 | static void popup_unconstrain(struct sway_xdg_popup *popup) { |
67 | struct sway_view *view = popup->child.view; | 56 | struct sway_view *view = popup->child.view; |
68 | struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup; | 57 | struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup; |
@@ -87,6 +76,25 @@ static void popup_unconstrain(struct sway_xdg_popup *popup) { | |||
87 | wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); | 76 | wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); |
88 | } | 77 | } |
89 | 78 | ||
79 | static void popup_handle_surface_commit(struct wl_listener *listener, void *data) { | ||
80 | struct sway_xdg_popup *popup = wl_container_of(listener, popup, surface_commit); | ||
81 | if (popup->wlr_xdg_popup->base->initial_commit) { | ||
82 | popup_unconstrain(popup); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | static void popup_handle_new_popup(struct wl_listener *listener, void *data) { | ||
87 | struct sway_xdg_popup *popup = | ||
88 | wl_container_of(listener, popup, new_popup); | ||
89 | struct wlr_xdg_popup *wlr_popup = data; | ||
90 | popup_create(wlr_popup, popup->child.view); | ||
91 | } | ||
92 | |||
93 | static void popup_handle_destroy(struct wl_listener *listener, void *data) { | ||
94 | struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy); | ||
95 | view_child_destroy(&popup->child); | ||
96 | } | ||
97 | |||
90 | static struct sway_xdg_popup *popup_create( | 98 | static struct sway_xdg_popup *popup_create( |
91 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { | 99 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { |
92 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; | 100 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; |
@@ -97,22 +105,21 @@ static struct sway_xdg_popup *popup_create( | |||
97 | return NULL; | 105 | return NULL; |
98 | } | 106 | } |
99 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); | 107 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); |
100 | popup->wlr_xdg_popup = xdg_surface->popup; | 108 | popup->wlr_xdg_popup = wlr_popup; |
101 | 109 | ||
110 | wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit); | ||
111 | popup->surface_commit.notify = popup_handle_surface_commit; | ||
102 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 112 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); |
103 | popup->new_popup.notify = popup_handle_new_popup; | 113 | popup->new_popup.notify = popup_handle_new_popup; |
104 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 114 | wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); |
105 | popup->destroy.notify = popup_handle_destroy; | 115 | popup->destroy.notify = popup_handle_destroy; |
106 | 116 | ||
107 | wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map); | 117 | wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map); |
108 | wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap); | 118 | wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap); |
109 | 119 | ||
110 | popup_unconstrain(popup); | ||
111 | |||
112 | return popup; | 120 | return popup; |
113 | } | 121 | } |
114 | 122 | ||
115 | |||
116 | static struct sway_xdg_shell_view *xdg_shell_view_from_view( | 123 | static struct sway_xdg_shell_view *xdg_shell_view_from_view( |
117 | struct sway_view *view) { | 124 | struct sway_view *view) { |
118 | if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL, | 125 | if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL, |
@@ -286,6 +293,19 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
286 | struct sway_view *view = &xdg_shell_view->view; | 293 | struct sway_view *view = &xdg_shell_view->view; |
287 | struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_toplevel->base; | 294 | struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_toplevel->base; |
288 | 295 | ||
296 | if (xdg_surface->initial_commit) { | ||
297 | if (view->xdg_decoration != NULL) { | ||
298 | set_xdg_decoration_mode(view->xdg_decoration); | ||
299 | } | ||
300 | // XXX: https://github.com/swaywm/sway/issues/2176 | ||
301 | wlr_xdg_surface_schedule_configure(xdg_surface); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | if (!xdg_surface->surface->mapped) { | ||
306 | return; | ||
307 | } | ||
308 | |||
289 | struct wlr_box new_geo; | 309 | struct wlr_box new_geo; |
290 | wlr_xdg_surface_get_geometry(xdg_surface, &new_geo); | 310 | wlr_xdg_surface_get_geometry(xdg_surface, &new_geo); |
291 | bool new_size = new_geo.width != view->geometry.width || | 311 | bool new_size = new_geo.width != view->geometry.width || |
@@ -421,7 +441,6 @@ static void handle_unmap(struct wl_listener *listener, void *data) { | |||
421 | 441 | ||
422 | view_unmap(view); | 442 | view_unmap(view); |
423 | 443 | ||
424 | wl_list_remove(&xdg_shell_view->commit.link); | ||
425 | wl_list_remove(&xdg_shell_view->new_popup.link); | 444 | wl_list_remove(&xdg_shell_view->new_popup.link); |
426 | wl_list_remove(&xdg_shell_view->request_maximize.link); | 445 | wl_list_remove(&xdg_shell_view->request_maximize.link); |
427 | wl_list_remove(&xdg_shell_view->request_fullscreen.link); | 446 | wl_list_remove(&xdg_shell_view->request_fullscreen.link); |
@@ -464,10 +483,6 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
464 | 483 | ||
465 | transaction_commit_dirty(); | 484 | transaction_commit_dirty(); |
466 | 485 | ||
467 | xdg_shell_view->commit.notify = handle_commit; | ||
468 | wl_signal_add(&toplevel->base->surface->events.commit, | ||
469 | &xdg_shell_view->commit); | ||
470 | |||
471 | xdg_shell_view->new_popup.notify = handle_new_popup; | 486 | xdg_shell_view->new_popup.notify = handle_new_popup; |
472 | wl_signal_add(&toplevel->base->events.new_popup, | 487 | wl_signal_add(&toplevel->base->events.new_popup, |
473 | &xdg_shell_view->new_popup); | 488 | &xdg_shell_view->new_popup); |
@@ -507,6 +522,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
507 | wl_list_remove(&xdg_shell_view->destroy.link); | 522 | wl_list_remove(&xdg_shell_view->destroy.link); |
508 | wl_list_remove(&xdg_shell_view->map.link); | 523 | wl_list_remove(&xdg_shell_view->map.link); |
509 | wl_list_remove(&xdg_shell_view->unmap.link); | 524 | wl_list_remove(&xdg_shell_view->unmap.link); |
525 | wl_list_remove(&xdg_shell_view->commit.link); | ||
510 | view->wlr_xdg_toplevel = NULL; | 526 | view->wlr_xdg_toplevel = NULL; |
511 | if (view->xdg_decoration) { | 527 | if (view->xdg_decoration) { |
512 | view->xdg_decoration->view = NULL; | 528 | view->xdg_decoration->view = NULL; |
@@ -519,17 +535,12 @@ struct sway_view *view_from_wlr_xdg_surface( | |||
519 | return xdg_surface->data; | 535 | return xdg_surface->data; |
520 | } | 536 | } |
521 | 537 | ||
522 | void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { | 538 | void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) { |
523 | struct wlr_xdg_surface *xdg_surface = data; | 539 | struct wlr_xdg_toplevel *xdg_toplevel = data; |
524 | |||
525 | if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
526 | sway_log(SWAY_DEBUG, "New xdg_shell popup"); | ||
527 | return; | ||
528 | } | ||
529 | 540 | ||
530 | sway_log(SWAY_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", | 541 | sway_log(SWAY_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", |
531 | xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); | 542 | xdg_toplevel->title, xdg_toplevel->app_id); |
532 | wlr_xdg_surface_ping(xdg_surface); | 543 | wlr_xdg_surface_ping(xdg_toplevel->base); |
533 | 544 | ||
534 | struct sway_xdg_shell_view *xdg_shell_view = | 545 | struct sway_xdg_shell_view *xdg_shell_view = |
535 | calloc(1, sizeof(struct sway_xdg_shell_view)); | 546 | calloc(1, sizeof(struct sway_xdg_shell_view)); |
@@ -538,16 +549,20 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { | |||
538 | } | 549 | } |
539 | 550 | ||
540 | view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl); | 551 | view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl); |
541 | xdg_shell_view->view.wlr_xdg_toplevel = xdg_surface->toplevel; | 552 | xdg_shell_view->view.wlr_xdg_toplevel = xdg_toplevel; |
542 | 553 | ||
543 | xdg_shell_view->map.notify = handle_map; | 554 | xdg_shell_view->map.notify = handle_map; |
544 | wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map); | 555 | wl_signal_add(&xdg_toplevel->base->surface->events.map, &xdg_shell_view->map); |
545 | 556 | ||
546 | xdg_shell_view->unmap.notify = handle_unmap; | 557 | xdg_shell_view->unmap.notify = handle_unmap; |
547 | wl_signal_add(&xdg_surface->surface->events.unmap, &xdg_shell_view->unmap); | 558 | wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &xdg_shell_view->unmap); |
559 | |||
560 | xdg_shell_view->commit.notify = handle_commit; | ||
561 | wl_signal_add(&xdg_toplevel->base->surface->events.commit, | ||
562 | &xdg_shell_view->commit); | ||
548 | 563 | ||
549 | xdg_shell_view->destroy.notify = handle_destroy; | 564 | xdg_shell_view->destroy.notify = handle_destroy; |
550 | wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy); | 565 | wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy); |
551 | 566 | ||
552 | xdg_surface->data = xdg_shell_view; | 567 | xdg_toplevel->base->data = xdg_shell_view; |
553 | } | 568 | } |
diff --git a/sway/server.c b/sway/server.c index e4f8a7c8..be521621 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -185,9 +185,9 @@ bool server_init(struct sway_server *server) { | |||
185 | 185 | ||
186 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display, | 186 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display, |
187 | SWAY_XDG_SHELL_VERSION); | 187 | SWAY_XDG_SHELL_VERSION); |
188 | wl_signal_add(&server->xdg_shell->events.new_surface, | 188 | wl_signal_add(&server->xdg_shell->events.new_toplevel, |
189 | &server->xdg_shell_surface); | 189 | &server->xdg_shell_toplevel); |
190 | server->xdg_shell_surface.notify = handle_xdg_shell_surface; | 190 | server->xdg_shell_toplevel.notify = handle_xdg_shell_toplevel; |
191 | 191 | ||
192 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); | 192 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); |
193 | 193 | ||
diff --git a/sway/xdg_decoration.c b/sway/xdg_decoration.c index f7f5f5ed..fa8c6279 100644 --- a/sway/xdg_decoration.c +++ b/sway/xdg_decoration.c | |||
@@ -23,32 +23,7 @@ static void xdg_decoration_handle_request_mode(struct wl_listener *listener, | |||
23 | void *data) { | 23 | void *data) { |
24 | struct sway_xdg_decoration *deco = | 24 | struct sway_xdg_decoration *deco = |
25 | wl_container_of(listener, deco, request_mode); | 25 | wl_container_of(listener, deco, request_mode); |
26 | struct sway_view *view = deco->view; | 26 | set_xdg_decoration_mode(deco); |
27 | enum wlr_xdg_toplevel_decoration_v1_mode mode = | ||
28 | WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; | ||
29 | enum wlr_xdg_toplevel_decoration_v1_mode client_mode = | ||
30 | deco->wlr_xdg_decoration->requested_mode; | ||
31 | |||
32 | bool floating; | ||
33 | if (view->container) { | ||
34 | floating = container_is_floating(view->container); | ||
35 | bool csd = false; | ||
36 | csd = client_mode == | ||
37 | WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; | ||
38 | view_update_csd_from_client(view, csd); | ||
39 | arrange_container(view->container); | ||
40 | transaction_commit_dirty(); | ||
41 | } else { | ||
42 | floating = view->impl->wants_floating && | ||
43 | view->impl->wants_floating(view); | ||
44 | } | ||
45 | |||
46 | if (floating && client_mode) { | ||
47 | mode = client_mode; | ||
48 | } | ||
49 | |||
50 | wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, | ||
51 | mode); | ||
52 | } | 27 | } |
53 | 28 | ||
54 | void handle_xdg_decoration(struct wl_listener *listener, void *data) { | 29 | void handle_xdg_decoration(struct wl_listener *listener, void *data) { |
@@ -72,7 +47,7 @@ void handle_xdg_decoration(struct wl_listener *listener, void *data) { | |||
72 | 47 | ||
73 | wl_list_insert(&server.xdg_decorations, &deco->link); | 48 | wl_list_insert(&server.xdg_decorations, &deco->link); |
74 | 49 | ||
75 | xdg_decoration_handle_request_mode(&deco->request_mode, wlr_deco); | 50 | set_xdg_decoration_mode(deco); |
76 | } | 51 | } |
77 | 52 | ||
78 | struct sway_xdg_decoration *xdg_decoration_from_surface( | 53 | struct sway_xdg_decoration *xdg_decoration_from_surface( |
@@ -85,3 +60,33 @@ struct sway_xdg_decoration *xdg_decoration_from_surface( | |||
85 | } | 60 | } |
86 | return NULL; | 61 | return NULL; |
87 | } | 62 | } |
63 | |||
64 | void set_xdg_decoration_mode(struct sway_xdg_decoration *deco) { | ||
65 | struct sway_view *view = deco->view; | ||
66 | enum wlr_xdg_toplevel_decoration_v1_mode mode = | ||
67 | WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; | ||
68 | enum wlr_xdg_toplevel_decoration_v1_mode client_mode = | ||
69 | deco->wlr_xdg_decoration->requested_mode; | ||
70 | |||
71 | bool floating; | ||
72 | if (view->container) { | ||
73 | floating = container_is_floating(view->container); | ||
74 | bool csd = false; | ||
75 | csd = client_mode == | ||
76 | WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; | ||
77 | view_update_csd_from_client(view, csd); | ||
78 | arrange_container(view->container); | ||
79 | transaction_commit_dirty(); | ||
80 | } else { | ||
81 | floating = view->impl->wants_floating && | ||
82 | view->impl->wants_floating(view); | ||
83 | } | ||
84 | |||
85 | if (floating && client_mode) { | ||
86 | mode = client_mode; | ||
87 | } | ||
88 | |||
89 | if (view->wlr_xdg_toplevel->base->initialized) { | ||
90 | wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, mode); | ||
91 | } | ||
92 | } | ||