Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scratchpad doesn't remember window size when moving to another monitor #6561

Open
Zeioth opened this issue Sep 29, 2021 · 7 comments
Open

Scratchpad doesn't remember window size when moving to another monitor #6561

Zeioth opened this issue Sep 29, 2021 · 7 comments
Labels
bug Not working as intended

Comments

@Zeioth
Copy link

Zeioth commented Sep 29, 2021

How to reproduce:

  • Send a window to the scratchpad.
  • Move the cursor to another monitor and bring back the window from scratchpad.
  • The size of the window changed, and is now super small.

This issue only seem to happen in multi monitor setups. If you always work in the same monitor, it does't happen.

https://x0.at/R4rM.png
https://x0.at/Dls8.png

@boredland
Copy link

What are the screen resolutions of the different monitors? Are they identical or different?

@Zeioth
Copy link
Author

Zeioth commented Oct 1, 2021

5 monitors, all of them UHD (3840 x 2160).

My config, if relevant:

output $screen2 mode 3840x2160@70.981Hz pos 0 0 scale 1
output $screen3 mode 3840x2160@70.981Hz pos 3840 0 scale 1
output $screen4 mode 3840x2160@70.981Hz pos 0 -2160 scale 1
output $screen5 mode 3840x2160@70.981Hz pos -3840 -2160 scale 1
output $screen6 mode 3840x2160@70.981Hz pos 3840 -2160 scale 1

@boredland
Copy link

So this is different from the problem I experienced in the past, I think, when switching from a high-res display to a lower-res one.

@PolyMeilex
Copy link

It's the same for me, but for me they get huge, rather than super small.
I have two FHD monitors

  1. Send a window to the scratchpad.
  2. Move the cursor to another monitor
  3. Bring back the window from scratchpad.
  4. The size of the window changed, and is now approximately the size of the monitor (FHD)

It does not happen in i3 btw

@Shfty
Copy link

Shfty commented Mar 21, 2022

I'm also seeing this on my 3-monitor setup - a central 2560x1440 monitor flanked by a pair of 1920x1200 ones.

In my case, restoring a foot terminal from the scratchpad on a different monitor causes it to briefly appear at its original size (i.e. the size it was hidden at), then shrink down to 69 columns x 24 rows.

I note that the window doesn't move during this process - when appearing at the original size, it's center-aligned as if it's already 69x24, after which the resize occurs.

It's also not specific to foot - the same behavior occurs when running st via xwayland.

@paulodiovani
Copy link

I handle this issue by resizing the window after showing scratchpad. E.g.

bindsym Ctrl+Escape exec swaymsg 'scratchpad show' \
  && sleep .1 \
  && swaymsg 'resize set 100ppt 40ppt, move position 0 0'

The sleep .1 is necessary due to the time the window takes to render, otherwise, it could try resizing the underlying window, if any.
It is not pretty, as the window will flick before resizing/moving, due to the latency of using exec swaymsg instead of calling from sway process. I supposed it can be made better with use of sway-ipc, but it solves my issue for now.

I currently use this for my dropdown terminal.
Full config: https://github.com/paulodiovani/dot-files/blob/feature/sway/home/user/.config/sway/config.d/50-dropdownterminal

@anpandey
Copy link
Contributor

This happens because sway resets the window back to the default floating size and position if it finds that the center of the container doesn't overlap with the current workspace. On the other hand, i3 uses floating_fix_coordinates to adjust the coordinates of floating windows moved between workspaces of possibly different sizes.

Here's a hackish way of saving coordinates across outputs in sway, which works well enough for me. This still resets the window if e.g. the output the window is on is disconnected.

diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 05761150..f2674dc7 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -196,6 +196,8 @@ size_t container_titlebar_height(void);
 void floating_calculate_constraints(int *min_width, int *max_width,
 		int *min_height, int *max_height);
 
+void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new);
+
 void container_floating_resize_and_center(struct sway_container *con);
 
 void container_floating_set_default_size(struct sway_container *con);
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 79e04ec0..a34f752f 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -731,6 +731,22 @@ static void floating_natural_resize(struct sway_container *con) {
 	}
 }
 
+void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new) {
+	int rel_x = con->current.x - old->x + (con->current.width / 2);
+	int rel_y = con->current.y - old->y + (con->current.height / 2);
+
+	sway_log(SWAY_DEBUG, "old = (%d, %d), %d x %d",
+			 old->x, old->y, old->width, old->height);
+	sway_log(SWAY_DEBUG, "new = (%d, %d), %d x %d",
+			 new->x, new->y, new->width, new->height);
+
+	con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->current.width / 2);
+	con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->current.height / 2);
+
+	sway_log(SWAY_DEBUG, "fixed container coords to (%.2f, %.2f)",
+			 con->pending.x, con->pending.y);
+}
+
 void container_floating_resize_and_center(struct sway_container *con) {
 	struct sway_workspace *ws = con->pending.workspace;
 	if (!ws) {
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 73f3993c..a58584f9 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -140,6 +140,15 @@ void root_scratchpad_show(struct sway_container *con) {
 	}
 	workspace_add_floating(new_ws, con);
 
+	// Try to fix the coords of the container.
+	if (new_ws->output) {
+		struct wlr_box new_output_box, closest_box;
+		struct sway_output *closest = container_floating_find_output(con);
+		output_get_box(new_ws->output, &new_output_box);
+		output_get_box(closest, &closest_box);
+		floating_fix_coordinates(con, &closest_box, &new_output_box);
+	}
+
 	// 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;

It would be nice if we could replicate i3's behavior in adjusting coordinates for all floating window movements. I think that would require storing some additional state for scratchpad windows (where the previous workspace is unknown).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not working as intended
Development

No branches or pull requests

6 participants