labwc
labwc copied to clipboard
Provide SnapToEdge with half width/height
Currently snap to edge uses all vertical/horizontal space depending on the snap direction.
For example, SnapToEdge (left) takes both Upper left
and Bottom left
:
+----------------------------+
| Upper left | Upper right |
+-------------+--------------+
| Bottom left | Bottom right |
+----------------------------+
On a relatively large screen (like 5k 27"), a whole lot of space seems wasted, so it would be nice to have SnapToEdgeHalved (poor naming, just an example) that fits the window in only one quadrant instead of two.
Do you mean quarter tiling? SnapToCorner maybe? If yes, +1, I'd really like to see that too.
Yep, exactly that. SnapToCorner sounds good!
Somewhat related to
- #122
- #362
The question here is if we want to
- add a new specialized command like you proposed (
SnapToCorner
) and thus limit it to the 4 corners - somehow let the user define a layout (which really gets tricky to get right) and then have something like
SnapToRegion
with a user defined region as argument - modify
SnapToEdge
to additionally allowtop-left
,top-right
,bottom-left
andbottom-right
as argument + possibly create a new additional alias for that command so it actually matches the feature set
Or maybe there is already something covering one or both of those use cases with a nice API we could re-implement.
The other question is if one of these variants would be in-scope for labwc. Let's see what @johanmalm has to say about that.
To start with, I would like this feature too.
As a general principle, we should try to implement small (atomic?) actions and we ought to focus on Cat A and Cat B items in the Requirements Document as a starting point (e.g. 5.22 - 5.28)
Looking at MoveResizeTo it does take fractions and percentages as <width>
and <height>
arguments.
<SnapToEdge>
is a compond-action (if that's a word). For example super+right-arrow
sets width=50%, moves to the edge and if already snapped-to that edge, it moves over to the next output :smile:
Now don't get me wrong, I really, really like this feature (probably because I was used to it from Gnome + Windows), but from a design and development perspective it was the wrong time to add it (in my opinion). We should have implemented simpler actions which could be combined to perform the same thing, because that way we get much more flexibility to turn it into other things without complicating the code. So, the reason for sharing all that is that I much prefer to not extend SnapToEdge, but rather go back to basics and really design the right small actions.
Not there is a balance... if for example we implement <MoveResizeTo>
and find that the combination for <MoveResizeTo>
and <MoveToEdge>
is not enough, then I'm up for designing some higher level (compound) actions to implementing more sophisticated tiling.
The type of actions I have thought of for a while is one where you could keep pressing for example super+left-arrow
and resize to 1/2 width, the press again and resize to 1/3 width, then 1/4, and so on. I think I'd be happy to add a view->tile_fraction
variable for this.
Interestingly <MoveToEdge>
should take into account other windows - not just output edges - so the combination of these actions could then answer a lot of use-cases. Just a thought.
Hmm, so MoveResizeTo
could be used something like this (SnapToEdge
/ SnapToCorner
as examples):
<SnapToEdge to="left">
<action name="MoveResizeTo" x="0" y="0" height="100%" width="50%" />
</SnapToEdge>
<SnapToEdge to="right">
<action name="MoveResizeTo" x="50%" y="0" height="100%" width="50%" />
</SnapToEdge>
<SnapToEdge to="top">
<action name="MoveResizeTo" x="0" y="0" height="50%" width="100%" />
</SnapToEdge>
<SnapToEdge to="bottom">
<action name="MoveResizeTo" x="0" y="50%" height="50%" width="100%" />
</SnapToEdge>
<SnapToCorner to="top-left">
<action name="MoveResizeTo" x="0" y="0" height="50%" width="50%" />
</SnapToCorner>
<SnapToCorner to="top-right">
<action name="MoveResizeTo" x="50%" y="0" height="50%" width="50%" />
</SnapToCorner>
<SnapToCorner to="bottom-left">
<action name="MoveResizeTo" x="0" y="50%" height="50%" width="50%" />
</SnapToCorner>
<SnapToCorner to="bottom-right">
<action name="MoveResizeTo" x="50%" y="50%" height="50%" width="50%" />
</SnapToCorner>
So it looks like we could indeed use that to allow users to implement 1/2
(SnapToEdge), 1/4
(SnapToCorner) or whatever tiling they want. At least via keybindings. I don't see a way currently to use this in combination with cursor edge / corner snapping.
I don't understand this example though: (I'd assume the window to be at the top left corner using the original size)
<action name="MoveResizeTo">
<!-- put the window in the bottom right corner -->
<x>-0</x>
<y>-0</y>
</action>
Edit: oh wow. Just recognized the -
in front of the 0
.
So a "negative" 0
would be based on right / bottom edge and a "positive" 0
would be based on top / left edge.
But even if this is true, x
and y
should be the top-left position of the view so the result would be 1px of the view being on the bottom-right corner and the rest being either invisible or - depending on the screen layout - shown on the screens right and below that current screen. Not much a fan of this positive / negative 0
notation, especially as 100%
should mean the same thing as -0
.
Looks awesome!
An alternative to the MoveResizeTo
variant would be to provide something like this in rc.xml
:
<!-- Percent based regions based on output->usable_area -->
<regions>
<!-- bottom-left -->
<region id="1" x="0%" y="50%" height="50%" width="50%" />
<!-- bottom -->
<region id="2" x="0%" y="50%" height="50%" width="100%" />
<!-- bottom-right -->
<region id="3" x="50%" y="50%" height="50%" width="50%" />
<!-- left -->
<region id="4" x="0%" y="0%" height="100%" width="50%" />
<!-- fake-maximized -->
<region id="5" x="0%" y="0%" height="100%" width="100%" />
<!-- right -->
<region id="6" x="50%" y="0%" height="100%" width="50%" />
<!-- top-left -->
<region id="7" x="0%" y="0%" height="50%" width="50%" />
<!-- top -->
<region id="8" x="0%" y="0%" height="50%" width="100%" />
<!-- top-right -->
<region id="9" x="50%" y="0%" height="50%" width="50%" />
</regions>
And then a key-config like this
<keybinds>
<!-- Resize via W-Numpad -->
<keybind key="W-KP_1"><action name="SnapToRegion" id="1" /></keybind>
<keybind key="W-KP_2"><action name="SnapToRegion" id="2" /></keybind>
<keybind key="W-KP_3"><action name="SnapToRegion" id="3" /></keybind>
<keybind key="W-KP_4"><action name="SnapToRegion" id="4" /></keybind>
<keybind key="W-KP_5"><action name="SnapToRegion" id="5" /></keybind>
<keybind key="W-KP_6"><action name="SnapToRegion" id="6" /></keybind>
<keybind key="W-KP_7"><action name="SnapToRegion" id="7" /></keybind>
<keybind key="W-KP_8"><action name="SnapToRegion" id="8" /></keybind>
<keybind key="W-KP_9"><action name="SnapToRegion" id="9" /></keybind>
<keybinds>
This would allow to additionally implement using the mouse for region snapping + showing a preview / outline of the area to snap to. Could be something like press-modifier-while-moving-window-to-highlight-area-to-snap-to
and when releasing the cursor button snap to that region.
Not sure how to deal with overlapping regions though (like left
and top-left
).. maybe always use the smaller one. But then you couldn't ever use the mouse to snap to the left
area at all because either top-left
or bottom-left
would be used instead.
Interesting.
Regarding overlapping regions, maybe we could snap to the nearest region-centre from the view-centre.
In terms of user interface I’m keen on being able to snap my windows using only Super+Arrow. I think proposal could be a good candidate for this bases on the nearest-centre-approach.
We had to make sure it doesn’t interfere with window manipulation that takes place when a window goes outside of an output.
Regarding overlapping regions, maybe we could snap to the nearest region-centre from the view-centre.
That sounds like a good solution, indeed.
Should be fixed by
- #433