aboutsummaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c14
-rw-r--r--sway/tree/container.c22
-rw-r--r--sway/tree/root.c27
3 files changed, 50 insertions, 13 deletions
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) {
area->width, area->height, area->x, area->y);
bool first_arrange = workspace->width == 0 && workspace->height == 0;
+ struct wlr_box prev_box;
+ workspace_get_box(workspace, &prev_box);
+
double prev_x = workspace->x - workspace->current_gaps.left;
double prev_y = workspace->y - workspace->current_gaps.top;
workspace->width = area->width;
@@ -277,13 +280,14 @@ void arrange_workspace(struct sway_workspace *workspace) {
if (!first_arrange && (diff_x != 0 || diff_y != 0)) {
for (int i = 0; i < workspace->floating->length; ++i) {
struct sway_container *floater = workspace->floating->items[i];
- container_floating_translate(floater, diff_x, diff_y);
- double center_x = floater->pending.x + floater->pending.width / 2;
- double center_y = floater->pending.y + floater->pending.height / 2;
struct wlr_box workspace_box;
workspace_get_box(workspace, &workspace_box);
- if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) {
- container_floating_move_to_center(floater);
+ floating_fix_coordinates(floater, &prev_box, &workspace_box);
+ // Set transformation for scratchpad windows.
+ if (floater->scratchpad) {
+ struct wlr_box output_box;
+ output_get_box(output, &output_box);
+ floater->transform = output_box;
}
}
}
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,
}
+void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new) {
+ if (!old->width || !old->height) {
+ // Fall back to centering on the workspace.
+ container_floating_move_to_center(con);
+ } else {
+ int rel_x = con->pending.x - old->x + (con->pending.width / 2);
+ int rel_y = con->pending.y - old->y + (con->pending.height / 2);
+
+ con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->pending.width / 2);
+ con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->pending.height / 2);
+
+ sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y);
+ }
+}
+
static void floating_natural_resize(struct sway_container *con) {
int min_width, max_width, min_height, max_height;
floating_calculate_constraints(&min_width, &max_width,
@@ -1025,6 +1040,13 @@ void container_floating_move_to(struct sway_container *con,
workspace_add_floating(new_workspace, con);
arrange_workspace(old_workspace);
arrange_workspace(new_workspace);
+ // If the moved container was a visible scratchpad container, then
+ // update its transform.
+ if (con->scratchpad) {
+ struct wlr_box output_box;
+ output_get_box(new_output, &output_box);
+ con->transform = output_box;
+ }
workspace_detect_urgent(old_workspace);
workspace_detect_urgent(new_workspace);
}
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) {
free(root);
}
+static void set_container_transform(struct sway_workspace *ws,
+ struct sway_container *con) {
+ struct sway_output *output = ws->output;
+ struct wlr_box box = {0};
+ if (output) {
+ output_get_box(output, &box);
+ }
+ con->transform = box;
+}
+
void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
return;
@@ -64,6 +74,8 @@ void root_scratchpad_add_container(struct sway_container *con, struct sway_works
struct sway_container *parent = con->pending.parent;
struct sway_workspace *workspace = con->pending.workspace;
+ set_container_transform(workspace, con);
+
// Clear the fullscreen mode when sending to the scratchpad
if (con->pending.fullscreen_mode != FULLSCREEN_NONE) {
container_fullscreen_disable(con);
@@ -142,15 +154,12 @@ void root_scratchpad_show(struct sway_container *con) {
}
workspace_add_floating(new_ws, con);
- // Make sure the container's center point overlaps this workspace
- double center_lx = con->pending.x + con->pending.width / 2;
- double center_ly = con->pending.y + con->pending.height / 2;
-
- struct wlr_box workspace_box;
- workspace_get_box(new_ws, &workspace_box);
- if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
- container_floating_resize_and_center(con);
+ if (new_ws->output) {
+ struct wlr_box output_box;
+ output_get_box(new_ws->output, &output_box);
+ floating_fix_coordinates(con, &con->transform, &output_box);
}
+ set_container_transform(new_ws, con);
arrange_workspace(new_ws);
seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node));
@@ -173,6 +182,8 @@ void root_scratchpad_hide(struct sway_container *con) {
return;
}
+ set_container_transform(con->pending.workspace, con);
+
disable_fullscreen(con, NULL);
container_for_each_child(con, disable_fullscreen, NULL);
container_detach(con);