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

Smart warp/swap for window drag actions #142

Closed
dominiklohmann opened this issue Jul 17, 2019 · 16 comments
Closed

Smart warp/swap for window drag actions #142

dominiklohmann opened this issue Jul 17, 2019 · 16 comments
Labels
enhancement New feature or request

Comments

@dominiklohmann
Copy link
Collaborator

dominiklohmann commented Jul 17, 2019

Discussion / Feature request

Currently, dragging window A onto window B (1) swaps their position when they are on the same display, and (2) warps window A onto window B when are on different displays. (3) Dragging window A onto an empty desktop on another display moves window A to the other display.

This feature request aims to unify (1) and (2).

To do this, separate window B into 5 zones: A center rectangle, and four trapezoids by drawing a line from the rectangles corners to the window corners. See the mockup below.

Dragging onto the center rectangle should swap the windows, and dragging onto any of the trapezoids should warp onto the window in that direction.

Obviously some warps are swaps already, and warps that are no-ops (e.g. warp east from the eastward window that is the windows direct child) should be swaps instead.

The edges of the center rectangle should be at 25% and 75% of the total width and height of the window respectively.

An alternative design would be to have the trapezoids have a fixed width/height of maybe 50px, but at most 25% of the total window width/height.

Smart Warp Mockup

Math to check for the positions is quite simple. Pseudocode:

# check if p1 and p2 are on the same side of the line drawn from a to b
function same_side(p1, p2, a, b):
    return dot_product(
        cross_product(b - a, p1 - a),
        cross_product(b - a, p2 - a)) >= 0

# check if p is in the triangle with the corners a, b and c
function point_in_triangle(p, a, b, c):
    return (same_side(p, a, b, c)
        AND same_side(p, b, a, c)
        AND same_side(p, c, a, b))

# check if p is in the center 50% of the frame
function point_in_inner_rectangle(p, frame):
    return (p.x > frame.x + 0.25 * frame.w
        AND p.x < frame.x + 0.75 * frame.w
        AND p.y < frame.y + 0.25 * frame.h
        AND p.y < frame.y + 0.75 * frame.h)

# check if p is in the top triangle, but not in the inner rectangle
function is_in_top_trapezoid(p, frame):
    a.x, a.y = frame.x, frame.y
    b.x, b.y = frame.x + frame.w, frame.y
    c.x, c.y = frame.x + 0.5 * frame.w, frame.y + 0.5 * frame.y
    return (NOT point_in_inner_rectangle(p, frame)
        AND point_in_triangle(p, a, b, c))
@goranmoomin
Copy link

Yeah, as a person who exclusively uses mouse to control the tiling windows, warping will be very, very helpful for my workflow.

I was playing with react-mosaic the other day and it looks like this might be some inspiration?̊̈

react-mosaic-demo

@dominiklohmann
Copy link
Collaborator Author

I was playing with react-mosaic the other day and it looks like this might be some inspiration?̊̈

This certainly looks nice. Only does warp, no swap like I suggested, and additionally does warp at outer edges of the space. Really nice example to play with.

I also like the overlay. A visual indicator like this might be nice to have.

@koekeishiya koekeishiya added the enhancement New feature or request label Jul 24, 2019
@koekeishiya koekeishiya added the addressed on master; not released Fixed upstream, but not yet released label Oct 11, 2019
@koekeishiya
Copy link
Owner

koekeishiya commented Oct 11, 2019

Implemented on master, although there is no visual feedback as to which action is performed.
The center 25% -> 75% region (both width and height) will trigger a swap operation.
Any other section will be a warp in the appropriate direction.

I'll likely do some modifications to check whether the warp should actually be a swap etc before this goes public in a release. done.

koekeishiya added a commit that referenced this issue Oct 11, 2019
@dominiklohmann
Copy link
Collaborator Author

This is working amazingly well so far.

One small thing I've noticed:

If I have two windows left/right of each other, dragging one onto the top/bottom trapezoid of the other window should warp instead of swapping the windows position.

@koekeishiya
Copy link
Owner

Fixed last quirks on master.

@dominiklohmann
Copy link
Collaborator Author

I've wondered whether the same rules should apply for drags across displays. Currently that's always a warp.

@koekeishiya
Copy link
Owner

It should follow the same rules across displays. I'll do a test and fix it if not, when I have time.

@koekeishiya
Copy link
Owner

koekeishiya commented Oct 16, 2019

So the reason that it can only warp when movement happens across displays, is that I am stupid. Will fix later today, hopefully.

Edit: Fixed on latest master.

@maxmckenzie
Copy link

I had a great deal of trouble working this out. I was trying to drag it to the edge of the window, below. It might be worth sharing that zones image above in the docs?

How could i enable visual feedback? is there another project I can use or does this need to be coded into the project?

loving yabai 👍

@tophee
Copy link

tophee commented Aug 25, 2022

I had a great deal of trouble working this out. I was trying to drag it to the edge of the window, below. It might be worth sharing that zones image above in the docs?

Totally agree. The "erratic" behaviour of dragged windows was driving me nuts... So the drop-zone for warp it is 25% space on all edges?

@koekeishiya
Copy link
Owner

So the drop-sone for warp it is 25% space on all edges?

Yeah, that is correct. It works as shown in the picture in the first comment. I'll make a note to expand on this in the wiki, as I think it is not mentioned there at all.

@dominiklohmann
Copy link
Collaborator Author

@koekeishiya Might be a good idea to make that 0.25 configurable if that's feasible without much effort? Then users can set it to 0 if they want to always have the center action, or adjust it to some value that works better for them.

@koekeishiya
Copy link
Owner

I wonder if it would be fine if there were some kind of visual feedback. I sometimes have issues eye-ing the separation of the drop-zones and drop the window slightly to the wrong side of the zone. Making the 25% configurable shouldn't be particularly hard.

@hittingray
Copy link

I often find I'll miss the zone I want by just a tiny bit. A visual indicator would be a huge help; I recently used the tiling on PopOS which has visual indicators and it would be awesome to have here.

@michaelaye
Copy link

I don't think there is a GH issue for the visual indicator yet? should we create one?

@koekeishiya
Copy link
Owner

visual feedback has been implemented #2109

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

7 participants