labwc icon indicating copy to clipboard operation
labwc copied to clipboard

Provide SnapToEdge with half width/height

Open heroin-moose opened this issue 2 years ago • 9 comments

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.

heroin-moose avatar Jun 09 '22 18:06 heroin-moose

Do you mean quarter tiling? SnapToCorner maybe? If yes, +1, I'd really like to see that too.

Flrian avatar Jun 09 '22 18:06 Flrian

Yep, exactly that. SnapToCorner sounds good!

heroin-moose avatar Jun 09 '22 18:06 heroin-moose

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 allow top-left, top-right, bottom-left and bottom-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.

Consolatis avatar Jun 09 '22 19:06 Consolatis

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.

johanmalm avatar Jun 09 '22 20:06 johanmalm

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.

Consolatis avatar Jun 10 '22 12:06 Consolatis

Looks awesome!

heroin-moose avatar Jun 10 '22 12:06 heroin-moose

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.

Consolatis avatar Jul 04 '22 23:07 Consolatis

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.

johanmalm avatar Jul 05 '22 15:07 johanmalm

Regarding overlapping regions, maybe we could snap to the nearest region-centre from the view-centre.

That sounds like a good solution, indeed.

Consolatis avatar Jul 05 '22 16:07 Consolatis

Should be fixed by

  • #433

Consolatis avatar Jan 11 '23 20:01 Consolatis