hyprwm / Hyprland

Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
https://hyprland.org
BSD 3-Clause "New" or "Revised" License
20.94k stars 879 forks source link

Better workspace management with multiple displays/monitors #747

Closed erlonbie closed 2 years ago

erlonbie commented 2 years ago

Hi, first of all thanks for this project, I'm in love with it.

As the title suggests, I think there is room for improvement when managing multiple displays.

Supose that we have two monitors, monitor_1 (left) and monitor_2 (right)

If I'm looking at the monitor_1 and I switch to a workspace that is in the monitor_2, it woud be nice (in my opinion) if the worskpace that was in monitor_2 got swapped with the previous workspace that was in monitor_1.This way I don't have to constantly turn my head to a different monitor. I know this sound silly, but it makes a huge difference in usability (again, a personal opinion). In summary, the priority where the workspace should go is the current monitor of the focused window, and not the current monitor of the workspace that were are trying to access.

I'm aware of the Dispatchers moveworkspacetomonitor and swapactiveworkspaces, but couldn't figure it out how to solve this problem.

Should be something like this:

(I'm using monitor_1)

if workspace_desired is in monitor_2 && showing_in_monitor_2: swapactiveworkspaces 1 2 else if workspace_desired is in monitor_2: moveworkspacetomonitor workspace_desired 1, moveworkspacetomonitor previous_workspace 2. else: workspace desired_workspace

That said, is this achievable through hyprctl (maybe with some bash scripting) or just tweaking the config file? If so, any help would be appreciated

Thanks again!

vaxerski commented 2 years ago
bind=SUPER,1,moveworkspacetomonitor,1 current
bind=SUPER,1,workspace,1

try this

erlonbie commented 2 years ago
bind=SUPER,1,moveworkspacetomonitor,1 current
bind=SUPER,1,workspace,1

try this

wow, that just worked! I feel ashamed that was a simple binding.

so, I can put bindings and rules mapping the same thing and the first one is the one gets priority?

vaxerski commented 2 years ago

you are allowed to assign multiple binds to one key. They will be executed in the order they appear in the config.

erlonbie commented 2 years ago

sorry to reopen it, but it's still not accomplishing 100% that I mentioned in this issue.

I noticed that it does not swapps if both workspaces are showing in each monitor. Is this possible to do?

If I'm focused in monitor_1 and app A is in monitor_1 and app B is in monitor_2. It brings app B to monitor_1 and leaves monitor_2 empety (no workspace).

vaxerski commented 2 years ago

it's not empty. It creates a new workspace. If you want to switch only when there is one workspace left, it's not possible. You can experiment with swapactiveworkspaces though.

erikdubois commented 1 year ago

Can either of you provide me the code to have hyprland work on a dual monitor? Maybe there is a github I can visit? Figuring out here how to set my workspaces per monitor and then later how to move an app on my left monitor to my right monitor with a keybinding.

Maybe add an example for the dual screen guys to the wiki? thanks in advance

vaxerski commented 1 year ago

https://wiki.hyprland.org/Configuring/Monitors/

monitor configs (and default + bound workspaces)

https://wiki.hyprland.org/Configuring/Dispatchers/

bind dispatchers

you can find example configs here: https://wiki.hyprland.org/Configuring/Example-configurations/

erikdubois commented 1 year ago

been there done that it is the how to set up my monitors that is the issue and then later how to ensure that workspace 1-5 is on monitor 1 and 6-10 is on monitor 2 and then later how to move a app from monitor 1 to monitor2 with a keybinding

a wiki does not help

I spend hours reading

a working config would help

vaxerski commented 1 year ago

wdym "set up"?

binding workspaces to a monitor - it's at the bottom of the first page I linked.

moving from monitor to monitor - it's on the dispatchers page. Find an appropriate dispatcher that suits you, as there are multiple ways.

erikdubois commented 1 year ago

do you have a dual monitor?

vaxerski commented 1 year ago

yes, so does for example fufexan, and his example configuration here: config.nix

erikdubois commented 1 year ago

Can I know where your config is?

vaxerski commented 1 year ago

mine is not public, and besides, I don't bind workspaces.

erikdubois commented 1 year ago

https://github.com/flick0/dotfiles/tree/master/archive/dotfiles-12-6-2022 this example does not have hyprland files if I am not mistaken...

erikdubois commented 1 year ago

Thanks for your time. I give it up (again).

I even wonder if what I have in my head can actually be done on Hyprand/Waybar.

More examples on the wiki will help everyone ... if you could consider that or pass it along.

erlonbie commented 1 year ago

Thanks for your time. I give it up (again).

I even wonder if what I have in my head can actually be done on Hyprand/Waybar.

More examples on the wiki will help everyone ... if you could consider that or pass it along.

@erikdubois I've seen that you have posted a lot of hyprland videos on your youtube channel, so I assume that you've figured it out, right?

erikdubois commented 1 year ago

I did not figure it out unfortunately. It remains a mystery.

I am currently on Chadwm.

It lets me use 10 workspaces on my left monitor and 10 workspaces on my rightmonitor.

I would already be content with 5 workspaces left and 5 workspaces right.

A working config - some examples would be nice so I can extrapolate what I need to set.

taylor85345 commented 1 year ago

@erlonbie If you're still in need of a solution for workspace swapping, here is the script I wrote to enable the behavior your requesting. It has some kinks I'm still working out, but it's mostly there. https://github.com/taylor85345/hyprland-dotfiles/blob/master/hypr/scripts/workspace

@erikdubois you might check out Hyprsome to help achieve discrete workspaces per-monitor https://github.com/sopa0/hyprsome

erikdubois commented 1 year ago

as a matter of fact I tested hyprsome yesterday and left a post on their github telling I was unsuccesfull. I keep hoping.

I will look into your script.

taylor85345 commented 1 year ago

Yeah, both Hyprsome projects (the rust and go versions) were written months ago and don't seem to have adapted to some changes in socket output since. I've considered scripting my own solution in bash since it comes up a lot on Discord, but the discrete workspace paradigm doesn't really suit my workflow.

My script is aimed at xmonad/qtile style shared workspaces with dynamic switching, which doesn't really sound like what you're looking for

erikdubois commented 1 year ago

1-5 workspace on left waybar 6-10 workspace on right waybar

erlonbie commented 1 year ago

@erlonbie If you're still in need of a solution for workspace swapping, here is the script I wrote to enable the behavior your requesting. It has some kinks I'm still working out, but it's mostly there. https://github.com/taylor85345/hyprland-dotfiles/blob/master/hypr/scripts/workspace

@erikdubois you might check out Hyprsome to help achieve discrete workspaces per-monitor https://github.com/sopa0/hyprsome

Thanks for the reply, but how do I actualy use it? I've tryed to simply run it, but it does not seem to change the way the workspaces are already working.

I'm really interested on this since I came from Qtile :)

erlonbie commented 1 year ago

I did not figure it out unfortunately. It remains a mystery.

I am currently on Chadwm.

It lets me use 10 workspaces on my left monitor and 10 workspaces on my rightmonitor.

I would already be content with 5 workspaces left and 5 workspaces right.

A working config - some examples would be nice so I can extrapolate what I need to set.

I'm sorry to hear that you couldn't find a solution.

I don't know if it will help you, but this is my config The bottom rules are the ones that handle workspace management

taylor85345 commented 1 year ago

@erlonbie Run the script with the number of the workspace you want to switch to as the first (only) argument. For example bind:

bind=SUPER,1,exec,~/.config/hypr/scripts/workspace 1

Basically it moves whichever workspace number you call to the active monitor and focuses it. If the workspace is already visible on another monitor, it will swap places with the current workspace on the active monitor.

To be fair, this is based on workspace behavior in Leftwm. I understand that workspace management is similar in qtile, but I've never actually used Qtile so there could be details that I haven't implemented.

erlonbie commented 1 year ago

@erlonbie Run the script with the number of the workspace you want to switch to as the first (only) argument. For example bind:

bind=SUPER,1,exec,~/.config/hypr/scripts/workspace 1

Basically it moves whichever workspace number you call to the active monitor and focuses it. If the workspace is already visible on another monitor, it will swap places with the current workspace on the active monitor.

To be fair, this is based on workspace behavior in Leftwm. I understand that workspace management is similar in qtile, but I've never actually used Qtile so there could be details that I haven't implemented.

Thank you so much! It worked as expected 🚀

I've never used Leftwm, but I can assume it handles multi monitors/workspaces in similar way, the best way in my opition.

baxlash commented 1 year ago

@erlonbie Run the script with the number of the workspace you want to switch to as the first (only) argument. For example bind:

bind=SUPER,1,exec,~/.config/hypr/scripts/workspace 1

Basically it moves whichever workspace number you call to the active monitor and focuses it. If the workspace is already visible on another monitor, it will swap places with the current workspace on the active monitor.

To be fair, this is based on workspace behavior in Leftwm. I understand that workspace management is similar in qtile, but I've never actually used Qtile so there could be details that I haven't implemented.

This is a great script. Very good job. I have found 2 errors though. On line 7 it should be ... grep -B 5 ... and on the line 13 it should be ... grep -B 11 .... I think there is some change in the output of hyprctl monitors. Additional lines have been introduced to the output if this command.

maxhbr commented 10 months ago

@erlonbie If you're still in need of a solution for workspace swapping, here is the script I wrote to enable the behavior your requesting. It has some kinks I'm still working out, but it's mostly there. https://github.com/taylor85345/hyprland-dotfiles/blob/master/hypr/scripts/workspace

Thanks @taylor85345 for the script. I have rewritten it, using json output and jq:

#!/usr/bin/env bash
# SPDX-License-Identifier: CC0-1.0
set -euo pipefail

get_number_of_monitors() {
    jq -r '.|length'
}

get_active_monitor() {
    jq -r '[.[]|select(.focused == true)][0].id'
}

get_passive_monitor_with_workspace() {
    local workspace="$1"
    jq -r '[.[]|select(.focused == false and .activeWorkspace.id == '"$workspace"')][0].id'
}

switch_to_workspace() {
    local workspace="$1"
    if [[ $# -eq 2 ]]; then
        local activemonitor="$2"
        hyprctl dispatch moveworkspacetomonitor "$workspace $activemonitor"
    fi
    hyprctl dispatch workspace "$workspace"
}

swap_active_workspaces() {
    local activemonitor="$1"
    local passivemonitor="$2"
    hyprctl dispatch swapactiveworkspaces "$activemonitor" "$passivemonitor"
}

main() {
    if [[ $# -ne 1 ]]; then
        echo "Usage: $0 <workspace>" >&2
        exit 1
    fi
    local workspace=$1
    local monitors="$(hyprctl -j monitors)"

    if [[ $(echo "$monitors" | get_number_of_monitors) -eq 1 ]]; then
        switch_to_workspace "$workspace"
    fi

    local activemonitor="$(echo "$monitors" | get_active_monitor)"
    local passivemonitor="$(echo "$monitors" | get_passive_monitor_with_workspace "$workspace")"

    if [[ "$passivemonitor" == "null" ]]; then
        switch_to_workspace "$workspace" "$activemonitor"
    else
        swap_active_workspaces "$activemonitor" "$passivemonitor"
    fi
}

main "$@"
EarlofBurl commented 8 months ago

@erlonbie If you're still in need of a solution for workspace swapping, here is the script I wrote to enable the behavior your requesting. It has some kinks I'm still working out, but it's mostly there. https://github.com/taylor85345/hyprland-dotfiles/blob/master/hypr/scripts/workspace

Thanks @taylor85345 for the script. I have rewritten it, using json output and jq:

Great script, thank you!

But I'm using 3 monitors and it works only work, when I'm on monitor 1 and switching with monitor 2. On monitor 2 and 3 it sends the workspace to my active monitor, opens a empty workspace on the passive monitor and leaves the "old" workspace in the background of the active monitor.

edit: I got it wrong, I didn't use your script but the original and copied yours in the .bak.

Yours is working great! Thx, again!

virchau13 commented 8 months ago

This feature has been merged in #4439 and is now present in v0.35.0. Use the dispatcher focusworkspaceoncurrentmonitor instead of workspace to get the requested behavior.