diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands/move.c | 1 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 3 | ||||
-rw-r--r-- | sway/tree/container.c | 122 | ||||
-rw-r--r-- | sway/tree/layout.c | 8 | ||||
-rw-r--r-- | sway/tree/view.c | 54 |
5 files changed, 96 insertions, 92 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c index e788d32f..c6dc0775 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -236,7 +236,6 @@ static void workspace_move_to_output(struct sway_container *workspace, | |||
236 | seat_get_focus_inactive(seat, output); | 236 | seat_get_focus_inactive(seat, output); |
237 | 237 | ||
238 | container_add_child(output, workspace); | 238 | container_add_child(output, workspace); |
239 | wl_signal_emit(&workspace->events.reparent, old_output); | ||
240 | 239 | ||
241 | // If moving the last workspace from the old output, create a new workspace | 240 | // If moving the last workspace from the old output, create a new workspace |
242 | // on the old output | 241 | // on the old output |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 3b626cb7..f82e5ef2 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -195,6 +195,9 @@ static void transaction_apply(struct sway_transaction *transaction) { | |||
195 | } | 195 | } |
196 | 196 | ||
197 | container->instruction = NULL; | 197 | container->instruction = NULL; |
198 | if (container->type == C_CONTAINER || container->type == C_VIEW) { | ||
199 | container_discover_outputs(container); | ||
200 | } | ||
198 | } | 201 | } |
199 | } | 202 | } |
200 | 203 | ||
diff --git a/sway/tree/container.c b/sway/tree/container.c index ea20991c..6ea0cc94 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -76,31 +76,6 @@ void container_update_textures_recursive(struct sway_container *con) { | |||
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | static void handle_reparent(struct wl_listener *listener, | ||
80 | void *data) { | ||
81 | struct sway_container *container = | ||
82 | wl_container_of(listener, container, reparent); | ||
83 | struct sway_container *old_parent = data; | ||
84 | |||
85 | struct sway_container *old_output = old_parent; | ||
86 | if (old_output != NULL && old_output->type != C_OUTPUT) { | ||
87 | old_output = container_parent(old_output, C_OUTPUT); | ||
88 | } | ||
89 | |||
90 | struct sway_container *new_output = container->parent; | ||
91 | if (new_output != NULL && new_output->type != C_OUTPUT) { | ||
92 | new_output = container_parent(new_output, C_OUTPUT); | ||
93 | } | ||
94 | |||
95 | if (old_output && new_output) { | ||
96 | float old_scale = old_output->sway_output->wlr_output->scale; | ||
97 | float new_scale = new_output->sway_output->wlr_output->scale; | ||
98 | if (old_scale != new_scale) { | ||
99 | container_update_textures_recursive(container); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | struct sway_container *container_create(enum sway_container_type type) { | 79 | struct sway_container *container_create(enum sway_container_type type) { |
105 | // next id starts at 1 because 0 is assigned to root_container in layout.c | 80 | // next id starts at 1 because 0 is assigned to root_container in layout.c |
106 | static size_t next_id = 1; | 81 | static size_t next_id = 1; |
@@ -117,12 +92,9 @@ struct sway_container *container_create(enum sway_container_type type) { | |||
117 | c->children = create_list(); | 92 | c->children = create_list(); |
118 | c->current.children = create_list(); | 93 | c->current.children = create_list(); |
119 | } | 94 | } |
95 | c->outputs = create_list(); | ||
120 | 96 | ||
121 | wl_signal_init(&c->events.destroy); | 97 | wl_signal_init(&c->events.destroy); |
122 | wl_signal_init(&c->events.reparent); | ||
123 | |||
124 | wl_signal_add(&c->events.reparent, &c->reparent); | ||
125 | c->reparent.notify = handle_reparent; | ||
126 | 98 | ||
127 | c->has_gaps = false; | 99 | c->has_gaps = false; |
128 | c->gaps_inner = 0; | 100 | c->gaps_inner = 0; |
@@ -156,6 +128,7 @@ void container_free(struct sway_container *cont) { | |||
156 | wlr_texture_destroy(cont->title_urgent); | 128 | wlr_texture_destroy(cont->title_urgent); |
157 | list_free(cont->children); | 129 | list_free(cont->children); |
158 | list_free(cont->current.children); | 130 | list_free(cont->current.children); |
131 | list_free(cont->outputs); | ||
159 | 132 | ||
160 | switch (cont->type) { | 133 | switch (cont->type) { |
161 | case C_ROOT: | 134 | case C_ROOT: |
@@ -238,6 +211,14 @@ static struct sway_container *container_workspace_destroy( | |||
238 | return output; | 211 | return output; |
239 | } | 212 | } |
240 | 213 | ||
214 | static void untrack_output(struct sway_container *con, void *data) { | ||
215 | struct sway_output *output = data; | ||
216 | int index = list_find(con->outputs, output); | ||
217 | if (index != -1) { | ||
218 | list_del(con->outputs, index); | ||
219 | } | ||
220 | } | ||
221 | |||
241 | static struct sway_container *container_output_destroy( | 222 | static struct sway_container *container_output_destroy( |
242 | struct sway_container *output) { | 223 | struct sway_container *output) { |
243 | if (!sway_assert(output, "cannot destroy null output")) { | 224 | if (!sway_assert(output, "cannot destroy null output")) { |
@@ -279,6 +260,8 @@ static struct sway_container *container_output_destroy( | |||
279 | } | 260 | } |
280 | } | 261 | } |
281 | 262 | ||
263 | root_for_each_container(untrack_output, output->sway_output); | ||
264 | |||
282 | wl_list_remove(&output->sway_output->mode.link); | 265 | wl_list_remove(&output->sway_output->mode.link); |
283 | wl_list_remove(&output->sway_output->transform.link); | 266 | wl_list_remove(&output->sway_output->transform.link); |
284 | wl_list_remove(&output->sway_output->scale.link); | 267 | wl_list_remove(&output->sway_output->scale.link); |
@@ -777,13 +760,24 @@ void container_damage_whole(struct sway_container *container) { | |||
777 | } | 760 | } |
778 | } | 761 | } |
779 | 762 | ||
763 | /** | ||
764 | * Return the output which will be used for scale purposes. | ||
765 | * This is the most recently entered output. | ||
766 | */ | ||
767 | struct sway_output *container_get_effective_output(struct sway_container *con) { | ||
768 | if (con->outputs->length == 0) { | ||
769 | return NULL; | ||
770 | } | ||
771 | return con->outputs->items[con->outputs->length - 1]; | ||
772 | } | ||
773 | |||
780 | static void update_title_texture(struct sway_container *con, | 774 | static void update_title_texture(struct sway_container *con, |
781 | struct wlr_texture **texture, struct border_colors *class) { | 775 | struct wlr_texture **texture, struct border_colors *class) { |
782 | if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW, | 776 | if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW, |
783 | "Unexpected type %s", container_type_to_str(con->type))) { | 777 | "Unexpected type %s", container_type_to_str(con->type))) { |
784 | return; | 778 | return; |
785 | } | 779 | } |
786 | struct sway_container *output = container_parent(con, C_OUTPUT); | 780 | struct sway_output *output = container_get_effective_output(con); |
787 | if (!output) { | 781 | if (!output) { |
788 | return; | 782 | return; |
789 | } | 783 | } |
@@ -795,7 +789,7 @@ static void update_title_texture(struct sway_container *con, | |||
795 | return; | 789 | return; |
796 | } | 790 | } |
797 | 791 | ||
798 | double scale = output->sway_output->wlr_output->scale; | 792 | double scale = output->wlr_output->scale; |
799 | int width = 0; | 793 | int width = 0; |
800 | int height = con->title_height * scale; | 794 | int height = con->title_height * scale; |
801 | 795 | ||
@@ -823,7 +817,7 @@ static void update_title_texture(struct sway_container *con, | |||
823 | unsigned char *data = cairo_image_surface_get_data(surface); | 817 | unsigned char *data = cairo_image_surface_get_data(surface); |
824 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | 818 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); |
825 | struct wlr_renderer *renderer = wlr_backend_get_renderer( | 819 | struct wlr_renderer *renderer = wlr_backend_get_renderer( |
826 | output->sway_output->wlr_output->backend); | 820 | output->wlr_output->backend); |
827 | *texture = wlr_texture_from_pixels( | 821 | *texture = wlr_texture_from_pixels( |
828 | renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | 822 | renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); |
829 | cairo_surface_destroy(surface); | 823 | cairo_surface_destroy(surface); |
@@ -1272,3 +1266,67 @@ bool container_is_fullscreen_or_child(struct sway_container *container) { | |||
1272 | 1266 | ||
1273 | return false; | 1267 | return false; |
1274 | } | 1268 | } |
1269 | |||
1270 | static void surface_send_enter_iterator(struct wlr_surface *surface, | ||
1271 | int x, int y, void *data) { | ||
1272 | struct wlr_output *wlr_output = data; | ||
1273 | wlr_surface_send_enter(surface, wlr_output); | ||
1274 | } | ||
1275 | |||
1276 | static void surface_send_leave_iterator(struct wlr_surface *surface, | ||
1277 | int x, int y, void *data) { | ||
1278 | struct wlr_output *wlr_output = data; | ||
1279 | wlr_surface_send_leave(surface, wlr_output); | ||
1280 | } | ||
1281 | |||
1282 | void container_discover_outputs(struct sway_container *con) { | ||
1283 | if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW, | ||
1284 | "Expected a container or view")) { | ||
1285 | return; | ||
1286 | } | ||
1287 | struct wlr_box con_box = { | ||
1288 | .x = con->current.swayc_x, | ||
1289 | .y = con->current.swayc_y, | ||
1290 | .width = con->current.swayc_width, | ||
1291 | .height = con->current.swayc_height, | ||
1292 | }; | ||
1293 | struct sway_output *old_output = container_get_effective_output(con); | ||
1294 | |||
1295 | for (int i = 0; i < root_container.children->length; ++i) { | ||
1296 | struct sway_container *output = root_container.children->items[i]; | ||
1297 | struct sway_output *sway_output = output->sway_output; | ||
1298 | struct wlr_box output_box; | ||
1299 | container_get_box(output, &output_box); | ||
1300 | struct wlr_box intersection; | ||
1301 | bool intersects = | ||
1302 | wlr_box_intersection(&con_box, &output_box, &intersection); | ||
1303 | int index = list_find(con->outputs, sway_output); | ||
1304 | |||
1305 | if (intersects && index == -1) { | ||
1306 | // Send enter | ||
1307 | wlr_log(WLR_DEBUG, "Con %p entered output %p", con, sway_output); | ||
1308 | if (con->type == C_VIEW) { | ||
1309 | view_for_each_surface(con->sway_view, | ||
1310 | surface_send_enter_iterator, sway_output->wlr_output); | ||
1311 | } | ||
1312 | list_add(con->outputs, sway_output); | ||
1313 | } else if (!intersects && index != -1) { | ||
1314 | // Send leave | ||
1315 | wlr_log(WLR_DEBUG, "Con %p left output %p", con, sway_output); | ||
1316 | if (con->type == C_VIEW) { | ||
1317 | view_for_each_surface(con->sway_view, | ||
1318 | surface_send_leave_iterator, sway_output->wlr_output); | ||
1319 | } | ||
1320 | list_del(con->outputs, index); | ||
1321 | } | ||
1322 | } | ||
1323 | struct sway_output *new_output = container_get_effective_output(con); | ||
1324 | double old_scale = old_output ? old_output->wlr_output->scale : -1; | ||
1325 | double new_scale = new_output ? new_output->wlr_output->scale : -1; | ||
1326 | if (old_scale != new_scale) { | ||
1327 | container_update_title_textures(con); | ||
1328 | if (con->type == C_VIEW) { | ||
1329 | view_update_marks_textures(con->sway_view); | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 2f22a3dd..ee7d7418 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -75,7 +75,6 @@ void container_insert_child(struct sway_container *parent, | |||
75 | list_insert(parent->children, i, child); | 75 | list_insert(parent->children, i, child); |
76 | child->parent = parent; | 76 | child->parent = parent; |
77 | container_handle_fullscreen_reparent(child, old_parent); | 77 | container_handle_fullscreen_reparent(child, old_parent); |
78 | wl_signal_emit(&child->events.reparent, old_parent); | ||
79 | } | 78 | } |
80 | 79 | ||
81 | struct sway_container *container_add_sibling(struct sway_container *fixed, | 80 | struct sway_container *container_add_sibling(struct sway_container *fixed, |
@@ -91,7 +90,6 @@ struct sway_container *container_add_sibling(struct sway_container *fixed, | |||
91 | list_insert(parent->children, i + 1, active); | 90 | list_insert(parent->children, i + 1, active); |
92 | active->parent = parent; | 91 | active->parent = parent; |
93 | container_handle_fullscreen_reparent(active, old_parent); | 92 | container_handle_fullscreen_reparent(active, old_parent); |
94 | wl_signal_emit(&active->events.reparent, old_parent); | ||
95 | return active->parent; | 93 | return active->parent; |
96 | } | 94 | } |
97 | 95 | ||
@@ -181,8 +179,6 @@ void container_move_to(struct sway_container *container, | |||
181 | } | 179 | } |
182 | } | 180 | } |
183 | 181 | ||
184 | wl_signal_emit(&container->events.reparent, old_parent); | ||
185 | |||
186 | if (container->type == C_VIEW) { | 182 | if (container->type == C_VIEW) { |
187 | ipc_event_window(container, "move"); | 183 | ipc_event_window(container, "move"); |
188 | } | 184 | } |
@@ -307,7 +303,6 @@ static void workspace_rejigger(struct sway_container *ws, | |||
307 | 303 | ||
308 | container_flatten(ws); | 304 | container_flatten(ws); |
309 | container_reap_empty_recursive(original_parent); | 305 | container_reap_empty_recursive(original_parent); |
310 | wl_signal_emit(&child->events.reparent, original_parent); | ||
311 | container_create_notify(new_parent); | 306 | container_create_notify(new_parent); |
312 | } | 307 | } |
313 | 308 | ||
@@ -859,7 +854,6 @@ struct sway_container *container_split(struct sway_container *child, | |||
859 | struct sway_container *ws_child = workspace->children->items[0]; | 854 | struct sway_container *ws_child = workspace->children->items[0]; |
860 | container_remove_child(ws_child); | 855 | container_remove_child(ws_child); |
861 | container_add_child(cont, ws_child); | 856 | container_add_child(cont, ws_child); |
862 | wl_signal_emit(&ws_child->events.reparent, workspace); | ||
863 | } | 857 | } |
864 | 858 | ||
865 | container_add_child(workspace, cont); | 859 | container_add_child(workspace, cont); |
@@ -867,11 +861,9 @@ struct sway_container *container_split(struct sway_container *child, | |||
867 | workspace->layout = layout; | 861 | workspace->layout = layout; |
868 | cont->layout = old_layout; | 862 | cont->layout = old_layout; |
869 | } else { | 863 | } else { |
870 | struct sway_container *old_parent = child->parent; | ||
871 | cont->layout = layout; | 864 | cont->layout = layout; |
872 | container_replace_child(child, cont); | 865 | container_replace_child(child, cont); |
873 | container_add_child(cont, child); | 866 | container_add_child(cont, child); |
874 | wl_signal_emit(&child->events.reparent, old_parent); | ||
875 | } | 867 | } |
876 | 868 | ||
877 | if (set_focus) { | 869 | if (set_focus) { |
diff --git a/sway/tree/view.c b/sway/tree/view.c index b77a9bb2..2c0c1aa9 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -364,48 +364,6 @@ static void view_handle_surface_new_subsurface(struct wl_listener *listener, | |||
364 | view_subsurface_create(view, subsurface); | 364 | view_subsurface_create(view, subsurface); |
365 | } | 365 | } |
366 | 366 | ||
367 | static void surface_send_enter_iterator(struct wlr_surface *surface, | ||
368 | int x, int y, void *data) { | ||
369 | struct wlr_output *wlr_output = data; | ||
370 | wlr_surface_send_enter(surface, wlr_output); | ||
371 | } | ||
372 | |||
373 | static void surface_send_leave_iterator(struct wlr_surface *surface, | ||
374 | int x, int y, void *data) { | ||
375 | struct wlr_output *wlr_output = data; | ||
376 | wlr_surface_send_leave(surface, wlr_output); | ||
377 | } | ||
378 | |||
379 | static void view_handle_container_reparent(struct wl_listener *listener, | ||
380 | void *data) { | ||
381 | struct sway_view *view = | ||
382 | wl_container_of(listener, view, container_reparent); | ||
383 | struct sway_container *old_parent = data; | ||
384 | |||
385 | struct sway_container *old_output = old_parent; | ||
386 | if (old_output != NULL && old_output->type != C_OUTPUT) { | ||
387 | old_output = container_parent(old_output, C_OUTPUT); | ||
388 | } | ||
389 | |||
390 | struct sway_container *new_output = view->swayc->parent; | ||
391 | if (new_output != NULL && new_output->type != C_OUTPUT) { | ||
392 | new_output = container_parent(new_output, C_OUTPUT); | ||
393 | } | ||
394 | |||
395 | if (old_output == new_output) { | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | if (old_output != NULL) { | ||
400 | view_for_each_surface(view, surface_send_leave_iterator, | ||
401 | old_output->sway_output->wlr_output); | ||
402 | } | ||
403 | if (new_output != NULL) { | ||
404 | view_for_each_surface(view, surface_send_enter_iterator, | ||
405 | new_output->sway_output->wlr_output); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | static bool view_has_executed_criteria(struct sway_view *view, | 367 | static bool view_has_executed_criteria(struct sway_view *view, |
410 | struct criteria *criteria) { | 368 | struct criteria *criteria) { |
411 | for (int i = 0; i < view->executed_criteria->length; ++i) { | 369 | for (int i = 0; i < view->executed_criteria->length; ++i) { |
@@ -567,9 +525,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
567 | &view->surface_new_subsurface); | 525 | &view->surface_new_subsurface); |
568 | view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; | 526 | view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; |
569 | 527 | ||
570 | wl_signal_add(&view->swayc->events.reparent, &view->container_reparent); | ||
571 | view->container_reparent.notify = view_handle_container_reparent; | ||
572 | |||
573 | if (view->impl->wants_floating && view->impl->wants_floating(view)) { | 528 | if (view->impl->wants_floating && view->impl->wants_floating(view)) { |
574 | view->border = config->floating_border; | 529 | view->border = config->floating_border; |
575 | view->border_thickness = config->floating_border_thickness; | 530 | view->border_thickness = config->floating_border_thickness; |
@@ -587,15 +542,12 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
587 | view_update_title(view, false); | 542 | view_update_title(view, false); |
588 | container_notify_subtree_changed(view->swayc->parent); | 543 | container_notify_subtree_changed(view->swayc->parent); |
589 | view_execute_criteria(view); | 544 | view_execute_criteria(view); |
590 | |||
591 | view_handle_container_reparent(&view->container_reparent, NULL); | ||
592 | } | 545 | } |
593 | 546 | ||
594 | void view_unmap(struct sway_view *view) { | 547 | void view_unmap(struct sway_view *view) { |
595 | wl_signal_emit(&view->events.unmap, view); | 548 | wl_signal_emit(&view->events.unmap, view); |
596 | 549 | ||
597 | wl_list_remove(&view->surface_new_subsurface.link); | 550 | wl_list_remove(&view->surface_new_subsurface.link); |
598 | wl_list_remove(&view->container_reparent.link); | ||
599 | 551 | ||
600 | if (view->urgent_timer) { | 552 | if (view->urgent_timer) { |
601 | wl_event_source_remove(view->urgent_timer); | 553 | wl_event_source_remove(view->urgent_timer); |
@@ -937,7 +889,7 @@ void view_add_mark(struct sway_view *view, char *mark) { | |||
937 | 889 | ||
938 | static void update_marks_texture(struct sway_view *view, | 890 | static void update_marks_texture(struct sway_view *view, |
939 | struct wlr_texture **texture, struct border_colors *class) { | 891 | struct wlr_texture **texture, struct border_colors *class) { |
940 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 892 | struct sway_output *output = container_get_effective_output(view->swayc); |
941 | if (!output) { | 893 | if (!output) { |
942 | return; | 894 | return; |
943 | } | 895 | } |
@@ -973,7 +925,7 @@ static void update_marks_texture(struct sway_view *view, | |||
973 | } | 925 | } |
974 | free(part); | 926 | free(part); |
975 | 927 | ||
976 | double scale = output->sway_output->wlr_output->scale; | 928 | double scale = output->wlr_output->scale; |
977 | int width = 0; | 929 | int width = 0; |
978 | int height = view->swayc->title_height * scale; | 930 | int height = view->swayc->title_height * scale; |
979 | 931 | ||
@@ -999,7 +951,7 @@ static void update_marks_texture(struct sway_view *view, | |||
999 | unsigned char *data = cairo_image_surface_get_data(surface); | 951 | unsigned char *data = cairo_image_surface_get_data(surface); |
1000 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | 952 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); |
1001 | struct wlr_renderer *renderer = wlr_backend_get_renderer( | 953 | struct wlr_renderer *renderer = wlr_backend_get_renderer( |
1002 | output->sway_output->wlr_output->backend); | 954 | output->wlr_output->backend); |
1003 | *texture = wlr_texture_from_pixels( | 955 | *texture = wlr_texture_from_pixels( |
1004 | renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | 956 | renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); |
1005 | cairo_surface_destroy(surface); | 957 | cairo_surface_destroy(surface); |