aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h8
-rw-r--r--sway/commands/move.c12
-rw-r--r--sway/tree/arrange.c14
-rw-r--r--sway/tree/container.c22
-rw-r--r--sway/tree/root.c27
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);
196void floating_calculate_constraints(int *min_width, int *max_width, 201void 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
204void floating_fix_coordinates(struct sway_container *con,
205 struct wlr_box *old, struct wlr_box *new);
206
199void container_floating_resize_and_center(struct sway_container *con); 207void container_floating_resize_and_center(struct sway_container *con);
200 208
201void container_floating_set_default_size(struct sway_container *con); 209void 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
715void 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
715static void floating_natural_resize(struct sway_container *con) { 730static 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
59static 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
59void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) { 69void 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);