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

Moving containers around #7

Open
korreman opened this issue Feb 15, 2022 · 14 comments
Open

Moving containers around #7

korreman opened this issue Feb 15, 2022 · 14 comments
Labels
enhancement New feature or request

Comments

@korreman
Copy link
Owner

It'd be nice to support moving containers using the same logic they are focused with.

My initial idea is that sway_bfocus move <targets> should find the container that would be focused, then place the currently focused container right before or after it. This wouldn't be as powerful as the builtin directional movement, but it would be more consistent. The lacking functionality could then be achieved with an additional move to parent command.

@korreman korreman added the enhancement New feature or request label Feb 15, 2022
@korreman
Copy link
Owner Author

korreman commented Feb 15, 2022

This seems non-trivial to implement with the commands provided by sway. There is no move to after container <con_id> command. The closest is move to mark <mark>, but it dynamically decides to insert into containers instead of next to as it does with windows.

Edit: The dynamic behavior can be dealt with. The real issue is that the command does nothing when the focused container is already a descendant of the marked one.

@korreman
Copy link
Owner Author

korreman commented Feb 17, 2022

Apparently, only sway decides to ignore the command if the focused container is already a child of the target. There is an open issue to bring the behavior in line with i3, swaywm/sway#6818. If fixed, custom container movement should be possible.

@laur89
Copy link

laur89 commented Mar 3, 2022

If/when implemented, please also provide an option to follow focus with the moved container.
The default i3 moving command doesn't do that, and there's no way to enforce focus-following as-is.

@korreman
Copy link
Owner Author

korreman commented Mar 4, 2022

[...] and there's no way to enforce focus-following as-is.

It might take a while before I try implementing the feature, but for focus-following in native, maybe the following sequence could work?

mark _myfocus; <your movement command>; [con_mark=_myfocus] focus; mark --toggle _myfocus

Although you'd have to do that for every movement command that doesn't follow focus.

@Myrdden
Copy link

Myrdden commented Mar 15, 2022

@korreman I've noticed there's quite a bit more than that going on but I've not had time to update my issues or PR or anything as life and work gets in the way. If I'm understanding what you're after here, I think it might be worth pointing out that in i3, moving containers to any containers always works like this, moving any window into any container, but sway doesn't implement any of the same algorithm that i3 uses. I've been trying to implement it myself in swaywm/sway/pull/6835, but I've not had much time to devote to it.

But in any case, if I'm understanding you, I think this is actually more an issue with sway itself.

@Myrdden
Copy link

Myrdden commented Mar 15, 2022

Here is the relevant function in i3 that I think does what you're after, if you're interested.

@korreman
Copy link
Owner Author

korreman commented Aug 14, 2023

I've looked at this issue on-and-off for a while now, so I thought that I'd summarize the current situation as I remember it.

  • We need (an equivalent to) a move to <before|after> container <con_id> command.
  • The closest command is move to mark <mark>. We can use it by marking the destination before invocation.
  • Moving a container to the position before another container can be accomplished with an additional swap container with con_id <con_id>.

Problem 1

Sway explicitly refuses moves to a parent container this way. This can be circumvented by moving the source to a new temporary workspace before moving it to its destination. This shouldn't be observable on screen, as all commands seem to be parsed and performed within a single frame.

Problem 2

Another problem is that workspaces (and maybe top level containers?)
aren't treated as proper containers in sway. You cannot focus them by ID, you cannot mark them, etc. This means that we cannot use marks to move to the parent of a top-level container.

It should be possible to circumvent this by conditionally using the command move container to workspace <number>. It should have roughly the same behavior as move to mark.

Problem 3

Moving our source to a container will place it inside that container rather than next to it. When moving to a window, it will be placed next to it.

In i3, we can solve this by moving our source to the parent of our destination.
This will place the container into the parent, right after its focused child.

In sway, this will place the container into the parent, but as the last child. This is the main issue preventing me from implementing the feature. Because of this, even if we jump through all those other hoops, we cannot arbitrarily move containers.

Possible solutions

Currently, the only way to accomplish an arbitrary move on my end would be to run a pathfinding function and then submit the resulting series of movement commands. I'm not going to venture down that rabbit hole.

In order for movement to be feasible, it would be necessary to at least fix problem 3 by matching sway behavior to i3. Of course, it'd be preferable if sway got a move container to con_id command that places the source next to the target.

@justyn
Copy link

justyn commented Aug 15, 2023

Problem 3

Moving our source to a container will place it inside that container rather than next to it. When moving to a window, it will be placed next to it.

In i3, we can solve this by moving our source to the parent of our destination. This will place the container into the parent, right after its focused child.

Is this feature request related? It was so long ago my memory is completely failing me.

@korreman
Copy link
Owner Author

Yes, it should be possible for you to get that behavior in i3 in a roundabout way:

mark --add source;
[con_id = <target>] focus;
focus parent;
mark --add dest;
[con_mark = source] focus;
move container to mark dest;

Let me know if it works.

@justyn
Copy link

justyn commented Aug 15, 2023

Right, but this still doesn't allow movement to an arbitrary point, because if you're inserting via a parent then you can only move the window/container to be the last or right-most container.

@korreman
Copy link
Owner Author

Are you using i3 or sway? Sway will just place the element as the last child of a container, but per the i3 documentation:

The window will be moved right after the marked container in the tree, i.e., it ends up in the same position as if you had opened a new window when the marked container was focused. If the mark is on a split container, the window will appear as a new child after the currently focused child within that container.

I don't have an i3 instance to test on right now, but I'm fairly certain that you can insert your element right after whichever child is focused.

While I'd still like an exact arbitrary movement command in both WMs, the easiest way to get this functionality uniformly would be a push for sway to match the behavior of i3 in this regard.

@justyn
Copy link

justyn commented Aug 15, 2023

Oh, I see! Sorry, for some reason I had not properly appreciated that you could use the mark on the parent and the child focus together to move to any point, that's excellent.

Yes getting the matching behaviour in sway must be the best bet.

@korreman
Copy link
Owner Author

korreman commented Nov 6, 2024

There's some relevant activity around problem 3 in swaywm/sway#8418
If this is merged, I think it's possible to work around all other blockers.

@ccdunder
Copy link

ccdunder commented Nov 24, 2024

There's some relevant activity around problem 3 in swaywm/sway#8418 If this is merged, I think it's possible to work around all other blockers.

Yep! Problem 1 was fixed as well (swaywm/sway#8356).

That leaves problem 2, which I left a TODO for (swaywm/sway#8474). Do you know if move container to workspace <number> will result in the correct ordering (respecting whether the container was moved right or left)? If not, I think another workaround would be to create a root container if the destination is the workspace, but it's a little more complex so would be nice to avoid if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants