diff options
-rw-r--r-- | include/sway/tree/container.h | 8 | ||||
-rw-r--r-- | sway/commands/move.c | 12 | ||||
-rw-r--r-- | sway/tree/arrange.c | 14 | ||||
-rw-r--r-- | sway/tree/container.c | 22 | ||||
-rw-r--r-- | sway/tree/root.c | 27 |
5 files changed, 68 insertions, 15 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 751612e2..fe3ee8a8 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -113,6 +113,11 @@ struct sway_container { | |||
113 | // Hidden scratchpad containers have a NULL parent. | 113 | // Hidden scratchpad containers have a NULL parent. |
114 | bool scratchpad; | 114 | bool scratchpad; |
115 | 115 | ||
116 | // Stores last output size and position for adjusting coordinates of | ||
117 | // scratchpad windows. | ||
118 | // Unused for non-scratchpad windows. | ||
119 | struct wlr_box transform; | ||
120 | |||
116 | float alpha; | 121 | float alpha; |
117 | 122 | ||
118 | struct wlr_texture *title_focused; | 123 | struct wlr_texture *title_focused; |
@@ -196,6 +201,9 @@ size_t container_titlebar_height(void); | |||
196 | void floating_calculate_constraints(int *min_width, int *max_width, | 201 | void floating_calculate_constraints(int *min_width, int *max_width, |
197 | int *min_height, int *max_height); | 202 | int *min_height, int *max_height); |
198 | 203 | ||
204 | void floating_fix_coordinates(struct sway_container *con, | ||
205 | struct wlr_box *old, struct wlr_box *new); | ||
206 | |||
199 | void container_floating_resize_and_center(struct sway_container *con); | 207 | void container_floating_resize_and_center(struct sway_container *con); |
200 | 208 | ||
201 | void container_floating_set_default_size(struct sway_container *con); | 209 | void container_floating_set_default_size(struct sway_container *con); |
diff --git a/sway/commands/move.c b/sway/commands/move.c index 7bd1fe3e..9e40a3b4 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -206,9 +206,17 @@ static void container_move_to_workspace(struct sway_container *container, | |||
206 | container_detach(container); | 206 | container_detach(container); |
207 | workspace_add_floating(workspace, container); | 207 | workspace_add_floating(workspace, container); |
208 | container_handle_fullscreen_reparent(container); | 208 | container_handle_fullscreen_reparent(container); |
209 | // If changing output, center it within the workspace | 209 | // If changing output, adjust the coordinates of the window. |
210 | if (old_output != workspace->output && !container->pending.fullscreen_mode) { | 210 | if (old_output != workspace->output && !container->pending.fullscreen_mode) { |
211 | container_floating_move_to_center(container); | 211 | struct wlr_box workspace_box, old_workspace_box; |
212 | workspace_get_box(workspace, &workspace_box); | ||
213 | workspace_get_box(old_workspace, &old_workspace_box); | ||
214 | floating_fix_coordinates(container, &old_workspace_box, &workspace_box); | ||
215 | if (container->scratchpad && workspace->output) { | ||
216 | struct wlr_box output_box; | ||
217 | output_get_box(workspace->output, &output_box); | ||
218 | container->transform = workspace_box; | ||
219 | } | ||
212 | } | 220 | } |
213 | } else { | 221 | } else { |
214 | container_detach(container); | 222 | container_detach(container); |
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 9c1a11e5..af925d05 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c | |||
@@ -264,6 +264,9 @@ void arrange_workspace(struct sway_workspace *workspace) { | |||
264 | area->width, area->height, area->x, area->y); | 264 | area->width, area->height, area->x, area->y); |
265 | 265 | ||
266 | bool first_arrange = workspace->width == 0 && workspace->height == 0; | 266 | bool first_arrange = workspace->width == 0 && workspace->height == 0; |
267 | struct wlr_box prev_box; | ||
268 | workspace_get_box(workspace, &prev_box); | ||
269 | |||
267 | double prev_x = workspace->x - workspace->current_gaps.left; | 270 | double prev_x = workspace->x - workspace->current_gaps.left; |
268 | double prev_y = workspace->y - workspace->current_gaps.top; | 271 | double prev_y = workspace->y - workspace->current_gaps.top; |
269 | workspace->width = area->width; | 272 | workspace->width = area->width; |
@@ -277,13 +280,14 @@ void arrange_workspace(struct sway_workspace *workspace) { | |||
277 | if (!first_arrange && (diff_x != 0 || diff_y != 0)) { | 280 | if (!first_arrange && (diff_x != 0 || diff_y != 0)) { |
278 | for (int i = 0; i < workspace->floating->length; ++i) { | 281 | for (int i = 0; i < workspace->floating->length; ++i) { |
279 | struct sway_container *floater = workspace->floating->items[i]; | 282 | struct sway_container *floater = workspace->floating->items[i]; |
280 | container_floating_translate(floater, diff_x, diff_y); | ||
281 | double center_x = floater->pending.x + floater->pending.width / 2; | ||
282 | double center_y = floater->pending.y + floater->pending.height / 2; | ||
283 | struct wlr_box workspace_box; | 283 | struct wlr_box workspace_box; |
284 | workspace_get_box(workspace, &workspace_box); | 284 | workspace_get_box(workspace, &workspace_box); |
285 | if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) { | 285 | floating_fix_coordinates(floater, &prev_box, &workspace_box); |
286 | container_floating_move_to_center(floater); | 286 | // Set transformation for scratchpad windows. |
287 | if (floater->scratchpad) { | ||
288 | struct wlr_box output_box; | ||
289 | output_get_box(output, &output_box); | ||
290 | floater->transform = output_box; | ||
287 | } | 291 | } |
288 | } | 292 | } |
289 | } | 293 | } |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 8222a506..d2c4ffc4 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -712,6 +712,21 @@ void floating_calculate_constraints(int *min_width, int *max_width, | |||
712 | 712 | ||
713 | } | 713 | } |
714 | 714 | ||
715 | void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new) { | ||
716 | if (!old->width || !old->height) { | ||
717 | // Fall back to centering on the workspace. | ||
718 | container_floating_move_to_center(con); | ||
719 | } else { | ||
720 | int rel_x = con->pending.x - old->x + (con->pending.width / 2); | ||
721 | int rel_y = con->pending.y - old->y + (con->pending.height / 2); | ||
722 | |||
723 | con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->pending.width / 2); | ||
724 | con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->pending.height / 2); | ||
725 | |||
726 | sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y); | ||
727 | } | ||
728 | } | ||
729 | |||
715 | static void floating_natural_resize(struct sway_container *con) { | 730 | static void floating_natural_resize(struct sway_container *con) { |
716 | int min_width, max_width, min_height, max_height; | 731 | int min_width, max_width, min_height, max_height; |
717 | floating_calculate_constraints(&min_width, &max_width, | 732 | floating_calculate_constraints(&min_width, &max_width, |
@@ -1025,6 +1040,13 @@ void container_floating_move_to(struct sway_container *con, | |||
1025 | workspace_add_floating(new_workspace, con); | 1040 | workspace_add_floating(new_workspace, con); |
1026 | arrange_workspace(old_workspace); | 1041 | arrange_workspace(old_workspace); |
1027 | arrange_workspace(new_workspace); | 1042 | arrange_workspace(new_workspace); |
1043 | // If the moved container was a visible scratchpad container, then | ||
1044 | // update its transform. | ||
1045 | if (con->scratchpad) { | ||
1046 | struct wlr_box output_box; | ||
1047 | output_get_box(new_output, &output_box); | ||
1048 | con->transform = output_box; | ||
1049 | } | ||
1028 | workspace_detect_urgent(old_workspace); | 1050 | workspace_detect_urgent(old_workspace); |
1029 | workspace_detect_urgent(new_workspace); | 1051 | workspace_detect_urgent(new_workspace); |
1030 | } | 1052 | } |
diff --git a/sway/tree/root.c b/sway/tree/root.c index 95129a88..233358d2 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c | |||
@@ -56,6 +56,16 @@ void root_destroy(struct sway_root *root) { | |||
56 | free(root); | 56 | free(root); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void set_container_transform(struct sway_workspace *ws, | ||
60 | struct sway_container *con) { | ||
61 | struct sway_output *output = ws->output; | ||
62 | struct wlr_box box = {0}; | ||
63 | if (output) { | ||
64 | output_get_box(output, &box); | ||
65 | } | ||
66 | con->transform = box; | ||
67 | } | ||
68 | |||
59 | void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) { | 69 | void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) { |
60 | if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) { | 70 | if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) { |
61 | return; | 71 | return; |
@@ -64,6 +74,8 @@ void root_scratchpad_add_container(struct sway_container *con, struct sway_works | |||
64 | struct sway_container *parent = con->pending.parent; | 74 | struct sway_container *parent = con->pending.parent; |
65 | struct sway_workspace *workspace = con->pending.workspace; | 75 | struct sway_workspace *workspace = con->pending.workspace; |
66 | 76 | ||
77 | set_container_transform(workspace, con); | ||
78 | |||
67 | // Clear the fullscreen mode when sending to the scratchpad | 79 | // Clear the fullscreen mode when sending to the scratchpad |
68 | if (con->pending.fullscreen_mode != FULLSCREEN_NONE) { | 80 | if (con->pending.fullscreen_mode != FULLSCREEN_NONE) { |
69 | container_fullscreen_disable(con); | 81 | container_fullscreen_disable(con); |
@@ -142,15 +154,12 @@ void root_scratchpad_show(struct sway_container *con) { | |||
142 | } | 154 | } |
143 | workspace_add_floating(new_ws, con); | 155 | workspace_add_floating(new_ws, con); |
144 | 156 | ||
145 | // Make sure the container's center point overlaps this workspace | 157 | if (new_ws->output) { |
146 | double center_lx = con->pending.x + con->pending.width / 2; | 158 | struct wlr_box output_box; |
147 | double center_ly = con->pending.y + con->pending.height / 2; | 159 | output_get_box(new_ws->output, &output_box); |
148 | 160 | floating_fix_coordinates(con, &con->transform, &output_box); | |
149 | struct wlr_box workspace_box; | ||
150 | workspace_get_box(new_ws, &workspace_box); | ||
151 | if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { | ||
152 | container_floating_resize_and_center(con); | ||
153 | } | 161 | } |
162 | set_container_transform(new_ws, con); | ||
154 | 163 | ||
155 | arrange_workspace(new_ws); | 164 | arrange_workspace(new_ws); |
156 | seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node)); | 165 | seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node)); |
@@ -173,6 +182,8 @@ void root_scratchpad_hide(struct sway_container *con) { | |||
173 | return; | 182 | return; |
174 | } | 183 | } |
175 | 184 | ||
185 | set_container_transform(con->pending.workspace, con); | ||
186 | |||
176 | disable_fullscreen(con, NULL); | 187 | disable_fullscreen(con, NULL); |
177 | container_for_each_child(con, disable_fullscreen, NULL); | 188 | container_for_each_child(con, disable_fullscreen, NULL); |
178 | container_detach(con); | 189 | container_detach(con); |