summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h10
-rw-r--r--include/sway/tree/view.h1
-rw-r--r--sway/commands/move.c1
-rw-r--r--sway/desktop/transaction.c3
-rw-r--r--sway/tree/container.c113
-rw-r--r--sway/tree/layout.c8
-rw-r--r--sway/tree/view.c58
7 files changed, 93 insertions, 101 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 5eccedc1..e0cda17c 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -138,6 +138,9 @@ struct sway_container {
138 138
139 struct sway_container *parent; 139 struct sway_container *parent;
140 140
141 // Outputs currently being intersected
142 list_t *outputs; // struct sway_output
143
141 // Indicates that the container is a scratchpad container. 144 // Indicates that the container is a scratchpad container.
142 // Both hidden and visible scratchpad containers have scratchpad=true. 145 // Both hidden and visible scratchpad containers have scratchpad=true.
143 // Hidden scratchpad containers have a NULL parent. 146 // Hidden scratchpad containers have a NULL parent.
@@ -166,12 +169,7 @@ struct sway_container {
166 169
167 struct { 170 struct {
168 struct wl_signal destroy; 171 struct wl_signal destroy;
169 // Raised after the tree updates, but before arrange_windows
170 // Passed the previous parent
171 struct wl_signal reparent;
172 } events; 172 } events;
173
174 struct wl_listener reparent;
175}; 173};
176 174
177struct sway_container *container_create(enum sway_container_type type); 175struct sway_container *container_create(enum sway_container_type type);
@@ -353,4 +351,6 @@ bool container_is_floating_or_child(struct sway_container *container);
353 */ 351 */
354bool container_is_fullscreen_or_child(struct sway_container *container); 352bool container_is_fullscreen_or_child(struct sway_container *container);
355 353
354void container_discover_outputs(struct sway_container *con);
355
356#endif 356#endif
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 2747e7c4..5fdecc2b 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -120,7 +120,6 @@ struct sway_view {
120 } events; 120 } events;
121 121
122 struct wl_listener surface_new_subsurface; 122 struct wl_listener surface_new_subsurface;
123 struct wl_listener container_reparent;
124}; 123};
125 124
126struct sway_xdg_shell_v6_view { 125struct sway_xdg_shell_v6_view {
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 d77a2afd..53ecc1f0 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -193,6 +193,9 @@ static void transaction_apply(struct sway_transaction *transaction) {
193 } 193 }
194 194
195 container->instruction = NULL; 195 container->instruction = NULL;
196 if (container->type == C_CONTAINER || container->type == C_VIEW) {
197 container_discover_outputs(container);
198 }
196 } 199 }
197} 200}
198 201
diff --git a/sway/tree/container.c b/sway/tree/container.c
index ea20991c..80d3f524 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
79static 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
104struct sway_container *container_create(enum sway_container_type type) { 79struct 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:
@@ -777,13 +750,25 @@ void container_damage_whole(struct sway_container *container) {
777 } 750 }
778} 751}
779 752
753/**
754 * Return the output which will be used for scale purposes.
755 * This is the most recently entered output.
756 */
757static struct sway_output *container_get_effective_output(
758 struct sway_container *con) {
759 if (con->outputs->length == 0) {
760 return NULL;
761 }
762 return con->outputs->items[con->outputs->length - 1];
763}
764
780static void update_title_texture(struct sway_container *con, 765static void update_title_texture(struct sway_container *con,
781 struct wlr_texture **texture, struct border_colors *class) { 766 struct wlr_texture **texture, struct border_colors *class) {
782 if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW, 767 if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW,
783 "Unexpected type %s", container_type_to_str(con->type))) { 768 "Unexpected type %s", container_type_to_str(con->type))) {
784 return; 769 return;
785 } 770 }
786 struct sway_container *output = container_parent(con, C_OUTPUT); 771 struct sway_output *output = container_get_effective_output(con);
787 if (!output) { 772 if (!output) {
788 return; 773 return;
789 } 774 }
@@ -795,7 +780,7 @@ static void update_title_texture(struct sway_container *con,
795 return; 780 return;
796 } 781 }
797 782
798 double scale = output->sway_output->wlr_output->scale; 783 double scale = output->wlr_output->scale;
799 int width = 0; 784 int width = 0;
800 int height = con->title_height * scale; 785 int height = con->title_height * scale;
801 786
@@ -823,7 +808,7 @@ static void update_title_texture(struct sway_container *con,
823 unsigned char *data = cairo_image_surface_get_data(surface); 808 unsigned char *data = cairo_image_surface_get_data(surface);
824 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); 809 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
825 struct wlr_renderer *renderer = wlr_backend_get_renderer( 810 struct wlr_renderer *renderer = wlr_backend_get_renderer(
826 output->sway_output->wlr_output->backend); 811 output->wlr_output->backend);
827 *texture = wlr_texture_from_pixels( 812 *texture = wlr_texture_from_pixels(
828 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); 813 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
829 cairo_surface_destroy(surface); 814 cairo_surface_destroy(surface);
@@ -1272,3 +1257,67 @@ bool container_is_fullscreen_or_child(struct sway_container *container) {
1272 1257
1273 return false; 1258 return false;
1274} 1259}
1260
1261static void surface_send_enter_iterator(struct wlr_surface *surface,
1262 int x, int y, void *data) {
1263 struct wlr_output *wlr_output = data;
1264 wlr_surface_send_enter(surface, wlr_output);
1265}
1266
1267static void surface_send_leave_iterator(struct wlr_surface *surface,
1268 int x, int y, void *data) {
1269 struct wlr_output *wlr_output = data;
1270 wlr_surface_send_leave(surface, wlr_output);
1271}
1272
1273void container_discover_outputs(struct sway_container *con) {
1274 if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW,
1275 "Expected a container or view")) {
1276 return;
1277 }
1278 struct wlr_box con_box = {
1279 .x = con->current.swayc_x,
1280 .y = con->current.swayc_y,
1281 .width = con->current.swayc_width,
1282 .height = con->current.swayc_height,
1283 };
1284 struct sway_output *old_output = container_get_effective_output(con);
1285
1286 for (int i = 0; i < root_container.children->length; ++i) {
1287 struct sway_container *output = root_container.children->items[i];
1288 struct sway_output *sway_output = output->sway_output;
1289 struct wlr_box output_box;
1290 container_get_box(output, &output_box);
1291 struct wlr_box intersection;
1292 bool intersects =
1293 wlr_box_intersection(&con_box, &output_box, &intersection);
1294 int index = list_find(con->outputs, sway_output);
1295
1296 if (intersects && index == -1) {
1297 // Send enter
1298 wlr_log(WLR_DEBUG, "Con %p entered output %p", con, sway_output);
1299 if (con->type == C_VIEW) {
1300 view_for_each_surface(con->sway_view,
1301 surface_send_enter_iterator, sway_output->wlr_output);
1302 }
1303 list_add(con->outputs, sway_output);
1304 } else if (!intersects && index != -1) {
1305 // Send leave
1306 wlr_log(WLR_DEBUG, "Con %p left output %p", con, sway_output);
1307 if (con->type == C_VIEW) {
1308 view_for_each_surface(con->sway_view,
1309 surface_send_leave_iterator, sway_output->wlr_output);
1310 }
1311 list_del(con->outputs, index);
1312 }
1313 }
1314 struct sway_output *new_output = container_get_effective_output(con);
1315 double old_scale = old_output ? old_output->wlr_output->scale : -1;
1316 double new_scale = new_output ? new_output->wlr_output->scale : -1;
1317 if (old_scale != new_scale) {
1318 container_update_title_textures(con);
1319 if (con->type == C_VIEW) {
1320 view_update_marks_textures(con->sway_view);
1321 }
1322 }
1323}
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
81struct sway_container *container_add_sibling(struct sway_container *fixed, 80struct 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..4abf1abb 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
367static 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
373static 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
379static 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
409static bool view_has_executed_criteria(struct sway_view *view, 367static 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
594void view_unmap(struct sway_view *view) { 547void 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,10 +889,8 @@ void view_add_mark(struct sway_view *view, char *mark) {
937 889
938static void update_marks_texture(struct sway_view *view, 890static 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 =
941 if (!output) { 893 view->swayc->outputs->items[view->swayc->outputs->length - 1];
942 return;
943 }
944 if (*texture) { 894 if (*texture) {
945 wlr_texture_destroy(*texture); 895 wlr_texture_destroy(*texture);
946 *texture = NULL; 896 *texture = NULL;
@@ -973,7 +923,7 @@ static void update_marks_texture(struct sway_view *view,
973 } 923 }
974 free(part); 924 free(part);
975 925
976 double scale = output->sway_output->wlr_output->scale; 926 double scale = output->wlr_output->scale;
977 int width = 0; 927 int width = 0;
978 int height = view->swayc->title_height * scale; 928 int height = view->swayc->title_height * scale;
979 929
@@ -999,7 +949,7 @@ static void update_marks_texture(struct sway_view *view,
999 unsigned char *data = cairo_image_surface_get_data(surface); 949 unsigned char *data = cairo_image_surface_get_data(surface);
1000 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); 950 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1001 struct wlr_renderer *renderer = wlr_backend_get_renderer( 951 struct wlr_renderer *renderer = wlr_backend_get_renderer(
1002 output->sway_output->wlr_output->backend); 952 output->wlr_output->backend);
1003 *texture = wlr_texture_from_pixels( 953 *texture = wlr_texture_from_pixels(
1004 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); 954 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
1005 cairo_surface_destroy(surface); 955 cairo_surface_destroy(surface);