debauchee / barrier

Open-source KVM software
Other
27.73k stars 1.52k forks source link

Multi-display Configuration: facilitate entry point arrangement to be other monitors #1112

Open ylluminate opened 3 years ago

ylluminate commented 3 years ago

I run multiple workstations with multiple displays. When I go into a client from the server workstation I have an issue where I need to flip the display arrangement. A monitor that would normally be considered is actually mapped to be on top and the monitor on top is mapped to be on bottom. We need a way to map monitors for client systems so that they can have an entry point on other than what is perceived by the system to be the bottom or aligned monitor.

ShareMouse does a very good job of providing a UI/UX for this, but of course with their not supporting Linux they're a non-starter option.

Aterfax commented 2 years ago

Also have this issue. I can only mouse off my lowest monitor to the screen/laptop on my desk.

I'd prefer to be able to move the mouse off the bottom of any of the 3 lower monitors!

image

i.e. I can only mouse off monitor 3, where I want to be able to mouse down off 1, 2 or 3.

TomSomerville commented 2 years ago

I believe this is the same issue I am having. My set up currently looks like the following:

                      _______________    ______________
                     |               |  |              | 
                     |   Monitor 1   |  |  Monitor 2   | 
                     |   (Laptop A)  |  |  (Laptop A)  | 
                     ----------------   ----------------
       _________         _________
      |         |       |         |
      | Laptop B|       | Laptop A|
     -----------       -----------

Laptop A == Server Laptop B == Client

When I move my mouse off the left edge of Laptop A screen, nothing occurs, and the mouse does not move to Laptop B as expect. When I move my mouse off the left edge of Monitor 1, the mouse moves to Laptop B.

It would be nice to have some type of multi monitor support that lets us select which edge of which monitor goes to which client, or lets us more fine tune how the monitors between all clients are laid out.

vjpr commented 2 years ago

Here is the detection code:

https://github.com/debauchee/barrier/blob/653e4badeb88f61de901581667d4465d7b1e2d52/src/lib/server/Server.cpp#L1779-L1804

My setup looks like so:


                     ┌────────────────┐
                     │                │
                     │  CLIENT        │
                     │                │
                     └────────────────┘

       ┌──────┬───────┐               ┌────────────────────────┐
       │      │       │               │                        │
       │      │       ├───────────────┤                        │
       │      │       │               │                        │
       │      │       │               │                        │
       │      │       │               │                        │
       │      │       ├─┬──────────┬──┤                        │
       │      │       │ │          │  │                        │
       └──────┴───────┘ │          │  └────────────────────────┘
                        └──────────┘

After hitting a breakpoint when my mouse is at the top edge of my middle screen, these are the values of the variables related to the code that determines whether to move the cursor to another screen:

ax = -3239
ay = -1763
aw = 8800
ah = 3092

y = -1440
zoneSize = 1
    if (y < ay + zoneSize) {
        yv  -= zoneSize;
        dirv = kTop;
    }

As you can see, y < ay + zoneSize is false. -1440 < -1763 = false.

The function getShape, gets the maximum bounds of all your screens combined relative to the primary screen.

Here is where the bounds are read from:

https://github.com/debauchee/barrier/blob/653e4badeb88f61de901581667d4465d7b1e2d52/src/lib/platform/OSXScreen.mm#L1549-L1554

So -1763 refers to the top edge of the highest screen.

So only exceeding this value will trigger a change in screen.

    // get screen shape
    SInt32 ax, ay, aw, ah;
    m_active->getShape(ax, ay, aw, ah);

To fix this, we need to get the monitor the cursor is on, check for neighboring monitors, and if there is no neighbouring monitor, trigger a direction change.


Todo

There is a barrier::Screen which accepts a PlatformScreen impl such as OSXScreen.

Each PlatformScreen impl should expose a method to check whether the cursor position is at an edge with no neighboring displays.

One consideration though is sometimes you may not want an edge with no neighboring displays to trigger a switch. Ideally you should compare if the destination screen is adjacent to the source screen.

vjpr commented 2 years ago

I have done a rough implementation for moving up and down here (https://github.com/debauchee/barrier/pull/1626).

davidkennedydev commented 2 years ago

https://github.com/debauchee/barrier/discussions/1451