Alexays / Waybar

Highly customizable Wayland bar for Sway and Wlroots based compositors. :v: :tada:
MIT License
6.7k stars 710 forks source link

Hyprland/workspaces improvements and further development #2271

Open zjeffer opened 1 year ago

zjeffer commented 1 year ago

I'm creating this issue so we can keep track of further development for the newly implemented hyprland/workspaces module (by @Anakael in https://github.com/Alexays/Waybar/pull/2264)

Here are some features I would personally like to see:

Bugs to fix:

Anakael commented 1 year ago

Active (focused) class is already implemented.

Anakael commented 1 year ago

Wiki is updated: https://github.com/Alexays/Waybar/wiki/Module:-Hyprland (Also fixed wrong class name in https://github.com/Alexays/Waybar/wiki/Module:-Workspaces)

VincentBerthier commented 1 year ago

Hi, It seems the icons for the workspaces specified in the configuration only work if they’re specified for a workspace ID, not its name. The icons also aren’t updated when a workspace is created, but the icons appear fine if the bar is killed and recreated. Oh and the active workspace doesn’t seem to be tracked properly.

maxwelljens commented 1 year ago

I can open up a separate issue for this, if it sounds interesting.

zjeffer commented 1 year ago

@maxwelljens @VincentBerthier Can you guys share your configs?

For me, the multi-monitor displaying & active workspace tracking does work properly. I use this config:

"hyprland/workspaces": {
    "format": "{name}",
    "format-icons": {
      "active": "",
      "default": "",
      "persistent": ""
    },
    "on-scroll-up": "hyprctl dispatch workspace r-1",
    "on-scroll-down": "hyprctl dispatch workspace r+1",
    "all-outputs": false,
    "persistent_workspaces": {
      "*": 5
    }
  }

and my style.css:

button {
    box-shadow: inset 0 -3px transparent;
    border: none;
    border-radius: 0;
}

button:hover {
    transition-duration: .1s;
    background: inherit;
    box-shadow: inset 0 -3px #ffffff;
}

#workspaces button {
    padding: 0 5px;
    background-color: #ffffff;
    color: #2e3440;
}

#workspaces button.persistent {
    background-color: #d8dee9;
    color: #4c566a;
}

#workspaces button.active {
    box-shadow: inset 0 -4px #4c566a;
    background-color: #ffffff;
}

@maxwelljens Some questions for you:

Active workspace only updates when an unseen workspace is switched to.

What do you mean by "unseen workspace"?

Names also do not work, with Waybar claiming that the argument {name} does not exist.

Can you share the exact error?

VincentBerthier commented 1 year ago

That’s not me for the unseen ^^ I changed my configuration to use IDs instead of names, it works fine now. I think.

maxwelljens commented 1 year ago

@zjeffer I tried many different configurations and the one you presented is one of those I tried. None of the options seem to do anything, except format.

    "hyprland/workspaces": {
        "format": "{id}",
        "all-outputs": false,
        "persistent_workspaces": {
                "*": 5
            }
    },

The error in question is this, if you set "format": "{name}":

[2023-08-11 08:54:32.006] [error] hyprland/workspaces: argument not found
[2023-08-11 08:54:32.121] [error] hyprland/workspaces: argument not found

It is definitely that element, because if I set "format": "{id}" or "format": "{}" then it does not show that error. No other errors are present either.

What do you mean by "unseen workspace"?

I should have said "not visible" instead. If we have three workspaces 1, 2, and 3:

Hope that was clear enough.

zjeffer commented 1 year ago

That's so strange, I don't have any of those issues.

Here's a video of me moving my mouse between two of my monitors:

https://github.com/Alexays/Waybar/assets/4633209/36a3b3a4-8dbd-4988-bd9b-7c3bae78e13c

It was kind of difficult to record so I only managed to record the workspace regions of my left and middle monitors. I move the mouse and the active workspace changes. Active means a white line appears at the bottom. Non-empty workspaces are a slightly whiter color. At the end of the video, I moved to my third monitor, which makes the other monitors not have an active workspace.

This seems to work perfectly fine on my system. Can you double-check you are running the latest version?

maxwelljens commented 1 year ago

According to waybar --version, I am indeed running the latest version 0.9.20.

zjeffer commented 1 year ago

Is that the release version or the latest git commit? Because the 0.9.20 release was published a month ago, while my PR with the changes necessary for persistent workspaces was merged two weeks ago (https://github.com/Alexays/Waybar/commit/600653538b778cf9528bb7a230428418b5b9220b)

I use v0.9.20-64-gb084bf72 from the AUR, which is the latest git version.

maxwelljens commented 1 year ago

I believe it is the release version. I use Waybar as distributed in the Fedora 38 repositories.

zjeffer commented 1 year ago

Alright, so you'll have to compile Waybar yourself or wait until the next version releases.

@VincentBerthier Can you check your version as well?

VincentBerthier commented 1 year ago

0.9.20 too, so… Hmm… Well, I guess this explains that.

proudhon commented 1 year ago

I don't know if this is how the module is intended to work but it is not working as expected for me.

It arbitrarily numbers persistent workspaces from left to right not respecting which workspace I've bound to each monitor via hyprland configs.

I don't know if it is feasible but we should be able to pick which individual workspace to show as persistent or automatically show all workspaces bound to the monitor instead of specifying the amount of persistent workspaces 2023-08-14-215217_hyprshot

Edit: grammar

zjeffer commented 1 year ago

I don't know if this is how the module is intended to work

I use it together with my fork of Duckonaut's split-monitor-workspaces plugin. This plugin automatically binds workspaces to monitors, and sets up keybinds so that you can for example do this:

The good thing about this approach is that I can use the exact same formula in Waybar, so that the binds the plugin makes correspond to the same workspaces that are shown on each monitor's bar. The plugin assigns workspace 6 to the second monitor, and Waybar also assigns workspace 6 to that monitor. Keybinds work perfectly and without configuration.

If I connect a monitor it has never seen before, it will automatically create 5 persistent workspaces in Waybar and the plugin. All without ever touching Hyprland's config file: no need to set binds. I just tell Waybar and the plugin settings to both add 5 workspaces per monitor, and that's it.


The problem with this approach is exactly as you describe: if you manually set your own binds in your hyprland config, the IDs you set in your Hyprland config won't necessarily match Waybar's formula.

The solution to this is manually setting the persistent_workspaces just like you would in wlr/workspaces (https://github.com/Alexays/Waybar/wiki/Module:-Workspaces#persistent-workspaces). The good news: I also implemented this in hyprland/workspaces :)

Instead of using "*": 5, you can manually set which monitors should show which workspaces:

"persistent_workspaces": {
        "1": ["DP-1"], // workspace ID : [array of monitors to show this workspace on, ...]
        "2": ["DP-1"],
        "3": ["DP-1"]
        // and so on, up to 5...
        "6": ["DP-2"],
        // up to 10...
        "11": ["DP-3"],
        // up to 15
}

I dislike this approach which is why I implemented the "*": 5 automatic approach, but I understand if you want to do it manually like above, to have more control over the workspace names.

Let me know if this works for you @proudhon

proudhon commented 1 year ago

Thank you so much for the explanation, I couldn't find the manual setup in the wiki and therefore I ended up being confused.

I will try both the approaches and I will give you a feedback asap.

proudhon commented 1 year ago

Manual setup works flawlessly, thank you so much. I will try your own approach asap as it looks more flexible (especially because my docking station tends to mess with my monitor names very often).

mischw commented 1 year ago

I just switched from sway to hyprland using the hyprland/workspaces module. Working great so far but one thing is odd to me. Clicking on a active worksapce does not bring me back to the last active workspace even tough I have

binds {
    allow_workspace_cycles = true
    workspace_back_and_forth = true
}

in my hyprland config. Is that something that is yet to be implemented or did I screw up my config somewhere in the process of switching?

zjeffer commented 1 year ago

@mischw That is not yet implemented, I'll see if I can implement that today.

zjeffer commented 1 year ago

@mischw I just looked at the Hyprland wiki and the description of those settings implied it should work with the current implementation, so I tested it on my system and it already seems to work fine.

Are you using the latest release?

mischw commented 1 year ago

@zjeffer Oh sorry, I didn't see that there was just a new release. I will try that. Can't get it to compile right now but will try again tomorrow.

jr64 commented 1 year ago

Fantastic work, thank you very much for implementing!

Is there a way to style workspaces that are currently visible on a monitor differently than those that are not shown on any monitor?

zjeffer commented 1 year ago

Is there a way to style workspaces that are currently visible on a monitor differently than those that are not shown on any monitor?

@jr64 Not yet, I'm thinking of implementing that soon, though

khaneliman commented 1 year ago

Just curious if we need to go down this road or request something more similar to the approach we're taking in nixpkgs in discussion https://github.com/NixOS/nixpkgs/pull/251115 about just enabling the experimental flag and using wlr/workspaces as-is. It looks like it functions fine so I'm not sure whether its worth investing effort into this module anymore. @zjeffer opinions/context?

Looks like urgent got merged if you want to update the checklist.

zjeffer commented 1 year ago

@khaneliman Some things that come to mind why I dislike that approach:

khaneliman commented 1 year ago

@khaneliman Some things that come to mind why I dislike that approach:

* The persistent workspaces implementation is quite limited in wlr/workspaces.

* With wlr/workspaces, you have to specify `"<workspace>": [<array of monitors to show workspace on>]`. This is quite cumbersome and doesn't automatically work with keybinds. With my changes in hyprland/workspaces, you can simply specify `"*": 5` to show 5 workspaces on each monitor.

* Persistent workspaces are named automatically based on hyprland monitor IDs, to make sure the names match between waybar and plugins like [split-monitor-workspaces](https://github.com/zjeffer/split-monitor-workspaces).

* This would need to be ported to wlr/workspaces but it uses hyprland specific stuff (monitor IDs) to accomplish the automatic workspace naming. I actually tried to implement this before hyprland/workspaces existed, see here: [[wlr/workspaces] Improve persistent_workspaces by allowing fixed nr of workspaces per monitor #2251](https://github.com/Alexays/Waybar/pull/2251).

* See [this issue](https://github.com/Alexays/Waybar/issues/2243) for more info about why I implemented it this way.

The interesting thing is that the wlr implementation supports my use case better of wanting to show specific workspaces on a monitor, albeit in poor experience of declaring it in configuration. I use specific icons/names per monitor and can't seem to get that functioning with hyprland persistent workspaces.

wlr/workspaces image

hyprland/workspaces image

The video workspace is assigned to a different monitor but the perisistent workspace implementation in hyprland shows it on my other monitor. Ignore the ugly green css, i was testing that PR for persistent vs empty. lol

zjeffer commented 1 year ago

The interesting thing is that the wlr implementation supports my use case better of wanting to show specific workspaces on a monitor, albeit in poor experience of declaring it in configuration. I use specific icons/names per monitor and can't seem to get that functioning with hyprland persistent workspaces.

Your wlr persistent workspace configuration should be able to work the same on both modules, unless I made a mistake while programming it ;)

The video workspace is assigned to a different monitor but the perisistent workspace implementation in hyprland shows it on my other monitor.

That sounds more like a bug than an intended feature. Can you create a separate issue for this, with a minimal reproducible example?

khaneliman commented 1 year ago

Your wlr persistent workspace configuration should be able to work the same on both modules, unless I made a mistake while programming it ;)

My understanding from the wiki was that I had to just specify a number of workspaces for a monitor and then it just loops through and assigns that many.

hyprland/workspaces ``` { "hyprland/workspaces": { "all-outputs": false, "active-only": "false", "format": "{icon}", "format-icons": { "1": "", "2": "", "3": "", "4": "", "5": "", "6": "", "7": "", "8": "󰢹", "urgent": "", "default": "", "persistent": "persistent", "empty": "empty" }, "persistent_workspaces": { "*": 8, "DP-3": 1 } }, ```
wlr/workspaces ``` "wlr/workspaces": { "all-outputs": false, "active-only": "false", "on-click": "activate", "format": "{icon}", "format-icons": { "1": "", "2": "", "3": "", "4": "", "5": "", "6": "", "7": "", "8": "󰢹", "urgent": "", "default": "" }, "persistent_workspaces": { "1": [ "DP-3" ], "2": [ "DP-1" ], "3": [ "DP-1" ], "4": [ "DP-1" ], "5": [ "DP-1" ], "6": [ "DP-1" ], "7": [ "DP-1" ], "8": [ "DP-1" ] } } ```

If i can just put an array of workspaces into that instead of a single number, that'd be nicer. I tried to but it doesn't seem to work.

hyprland/workspaces ideal but probably hard to support ``` "hyprland/workspaces": { "all-outputs": false, "active-only": "false", "format": "{icon}", "format-icons": { "1": "", "2": "", "3": "", "4": "", "5": "", "6": "", "7": "", "8": "󰢹", "urgent": "", "default": "", "persistent": "persistent", "empty": "empty" }, "persistent_workspaces": { "*": [ 2, 3, 4, 5, 6, 7, 8 ], "DP-3": 1 } }, ```
khaneliman commented 1 year ago

The interesting thing is that the wlr implementation supports my use case better of wanting to show specific workspaces on a monitor, albeit in poor experience of declaring it in configuration. I use specific icons/names per monitor and can't seem to get that functioning with hyprland persistent workspaces.

Your wlr persistent workspace configuration should be able to work the same on both modules, unless I made a mistake while programming it ;)

See, I didn't see that referenced in the wiki so I did try just copying that config style over and it did work, as intended. :P That works for me, actually... and solves the issue I had with empty persistent workspaces crashing waybar when i clicked on them in wlr/workspaces.

zjeffer commented 1 year ago

Yeah the wiki should be updated with that info and more examples but I've been kind of busy with other stuff lately and didn't feel like it :)

zjeffer commented 1 year ago

@khaneliman

hyprland/workspaces ideal but probably hard to support

That actually looks pretty easy to implement, I'll do it if I find some time.

khaneliman commented 1 year ago

@khaneliman

hyprland/workspaces ideal but probably hard to support

That actually looks pretty easy to implement, I'll do it if I find some time.

I guess just check if it's an array within it instead of a single number to process differently. I'd just need to change my second monitor to be an array of the single workspace.

zjeffer commented 1 year ago

I guess just check if it's an array within it instead of a single number to process differently

Indeed.

MightyPlaza commented 1 year ago

special workspaces can now opened empty in hyprland so persistent special workspaces can exist and behavior should be tested

zjeffer commented 1 year ago

so persistent special workspaces can exist and behavior should be tested

Current behaviour with this config:

"hyprland/workspaces": {
    "format": "{icon}",
    "format-icons": {
      "urgent": "",
      "active": "",
      "default": "",
      "persistent": "",
      "special": "s"
    },
    "on-scroll-up": "hyprctl dispatch workspace r-1",
    "on-scroll-down": "hyprctl dispatch workspace r+1",
    "all-outputs": false,
    "show-special": true,
    "persistent_workspaces": {
      "*": 5,
      "special": [
        "eDP-1",
        "DP-2",
        "HDMI-A-1"
      ]
    }
  },

seems to show the workspace persistently on all my monitors, and has the correct css class both when empty and not empty.

There seems to be no active class when the special workspace is toggled. I would assume the user wants visual feedback when the special workspace is active, right? Should the currently active workspace keep its active class or should it become non-active? I think it should keep the active class.

There's also some weird behaviour with named special workspaces, I'll have to investigate further.

MightyPlaza commented 1 year ago

there isn't a IPC event for when a special workspace is opened you can find out by calling hyprcctl monitors feel free to create a feature request, but for now the best you can do is start preparing the code for when it gets implemented

maybe add a format for special-active

There's also some weird behaviour with named special workspaces, I'll have to investigate further.

?

cyrinux commented 1 year ago

Hi,

Thanks for this new module, but, do I miss something 🤔 I can't get working my https://github.com/hyprland-community/hyprland-autoname-workspaces with this new module. What is the way to keep the same format and behavior as wlr/workspaces ?

Thanks

khaneliman commented 1 year ago
  • And also, wlr/workspaces didn't work anymore for me, but I can't find relevant error, nothing but no workspaces anymore at all with this legacy(?) module.

The protocol that supported wlr/workspaces module in Hyprland was removed from Hyprland recently.

khaneliman commented 1 year ago
* I would like to be able to still use hyprland-autoname-workspaces to control the content of my workspaces in waybar.

I've never used that program before, but I can try and take a look at what the workspaces module needs to make it work.

cyrinux commented 1 year ago
* I would like to be able to still use hyprland-autoname-workspaces to control the content of my workspaces in waybar.

I've never used that program before, but I can try and take a look at what the workspaces module needs to make it work.

I would be happy if you can do this please 👍🏻

MightyPlaza commented 1 year ago

new PR for "activespecial" IPC event is up so special workspace integration should be fully doable now

zjeffer commented 1 year ago

new PR for "activespecial" IPC event is up so special workspace integration should be fully doable now

Alright, I'll probably do this next weekend because I'll be too tired after work during the week... Unless someone else wants to implement it? ;)

niksingh710 commented 1 year ago

for me the persistent workspace icon is shown every where i wanted to modify the workspaces somehow so that occupied have different icons then non occupied workspace. it was possible int wlr/workspace as then occupied used to have only the default: icons and all unoccupied used to have persistent: icon but in hyprland/workspace persistent icons override the default one's

zjeffer commented 1 year ago

@niksingh710 If I understand your request correctly, you should be able to get the behaviour you want by using the "empty" icon class.

Occupied persistent workspaces will have the persistent icon, while non-occopied persistent workspaces will have the empty icon. If you don't define the empty icon in your config, it will fall back to the persistent icon. Hope this helps.

niksingh710 commented 1 year ago

Occupied persistent workspaces will have the persistent icon, while non-occopied persistent workspaces will have the empty icon. If you don't define the empty icon in your config, it will fall back to the persistent icon. Hope this helps.

Exactly what I wanted. I guess it wasn't on the wiki earlier.

cyrinux commented 1 year ago
* I would like to be able to still use hyprland-autoname-workspaces to control the content of my workspaces in waybar.

I've never used that program before, but I can try and take a look at what the workspaces module needs to make it work.

I understand we maybe need a "mode" in this module, that will "just" fetch for example every second, or on events the name of workspaces. Maybe react on the same events as hyprland-autoname-workspaces to be sure in this mode. https://github.com/hyprland-community/hyprland-autoname-workspaces/blob/main/src/renamer/mod.rs#L163

edit: After chatting again with @maximbaz, we should add a new "rename" event in hyprland codebase then this module would be able to just listen on this one to prevent race condition

cyrinux commented 1 year ago

The renameworkspace event was added https://github.com/hyprwm/Hyprland/commit/2d100bf57e0c0184d307bd4173b1a8d9fc7130e1#diff-3c089c6c6b23a85ab5b4cffb002e8880ad069c8a8b3462f7aafa9e5345c0333d

tumon-art commented 1 year ago

#workspaces button.urgent

isn't working anymore!

khaneliman commented 1 year ago

workspaces button.urgent

isn't working anymore!

In what way? I daily drive the last commit and it works for me. My example of styling in other issue: https://github.com/Alexays/Waybar/issues/2469#issuecomment-1707603189

tumon-art commented 1 year ago

workspaces button.urgent

isn't working anymore!

In what way? I daily drive the last commit and it works for me. My example of styling in other issue: #2469 (comment)

It works with "wlr/workspaces" module in hyprland 28 I tired with "hyprland/workspaces" module in hyparland 28 but it doesn't work.

I'm using hyprland 29.1 now and "hyprland/workspaces" module. It doesn't work for me.

Waybar Config ``` { "layer": "top", // Waybar at top layer "position": "left", // Waybar position (top|bottom|left|right) //"height": 5, // Waybar height (to be removed for auto height) // "width": 1280, // Waybar width "width": 5, // Waybar width "spacing": 4, // Gaps between modules (4px) "margin-top": 0, "margin-bottom": 0, // Choose the order of the modules "modules-left": ["hyprland/workspaces"], // "modules-center": ["hyprland/window"], "modules-right": ["idle_inhibitor", "pulseaudio", "memory", "cpu", "temperature", "clock", "tray", "custom/power-menu"], // Modules configuration "keyboard-state": { "numlock": true, "capslock": true, "format": "{name} {icon}", "format-icons": { "locked": "", "unlocked": "" } }, "hyprland/window": { "max-length": 200, "rotate": 90 }, "hyprland/workspaces": { "on-scroll-up": "hyprctl dispatch workspace e+1", "on-scroll-down": "hyprctl dispatch workspace e-1", "on-click": "activate", "all-outputs": false, "active-only": false }, "mpd": { "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ", "format-disconnected": "Disconnected ", "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ", "unknown-tag": "N/A", "interval": 2, "consume-icons": { "on": " " }, "random-icons": { "off": " ", "on": " " }, "repeat-icons": { "on": " " }, "single-icons": { "on": "1 " }, "state-icons": { "paused": "", "playing": "" }, "tooltip-format": "MPD (connected)", "tooltip-format-disconnected": "MPD (disconnected)" }, "idle_inhibitor": { "format": "{icon}", "format-icons": { "activated": "", "deactivated": "" } }, "tray": { // "icon-size": 21, "spacing": 10, "rotate": 90 }, "clock": { // "timezone": "Asia/Seoul", "tooltip-format": "{:%d-}\n{calendar}", // "format-alt": "{:%m\n%d}", // "format": "{:%I:%M %p}", "format": "{:%I \n%M}", "align":1 }, "cpu": { "format": "{usage}% ", "tooltip": false, "rotate": 90 }, "memory": { "format": "{}% ", "rotate": 90 }, "temperature": { "thermal-zone": 2, // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", "critical-threshold": 80, // "format-critical": "{temperatureC}°C {icon}", "format": "{temperatureC}°C {icon}", "format-icons": ["", "", ""], "rotate": 90 }, "network": { "interface": "wlp0s20u1", // (Optional) To force the use of this interface "format-wifi": "{essid} ({signalStrength}%) ", "tooltip": false, "format-ethernet": "{ipaddr}/{cidr} ", "tooltip-format": "{ifname} via {gwaddr} ", "format-linked": "{ifname} (No IP) ", "format-disconnected": "Disconnected ⚠", "format-alt": "{ifname}: {ipaddr}/{cidr}" }, "pulseaudio": { // "scroll-step": 1, // %, can be a float "tooltip": false, "format": "{volume}% {icon} {format_source}", "format-bluetooth": "{volume}% {icon} {format_source}", "format-bluetooth-muted": " {icon} {format_source}", "format-muted": " {format_source}", "format-source":"", "format-source-muted": "", "format-icons": { "headphone": "", "hands-free": "", "headset": "", "phone": "", "portable": "", "car": "", "default": ["", "", ""] }, "on-click": "pavucontrol", "rotate": 90 }, "custom/media": { "format": "{icon} {}", "return-type": "json", "max-length": 40, "format-icons": { "spotify": "", "default": "🎜" }, "escape": true, "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name }, "custom/power-menu": { "format": "󰚥", "on-click": "~/.config/waybar/scripts/power_menu.sh", "return-type": "json" }, "custom/network-usage": { "format": "net {speed}", "exec": "~/.config/waybar/scripts/network_usage.sh", "interval": 1 } } ```
Waybar CSS ``` #pulseaudio,#cpu, #tray, #memory, #temperature, #clock{ color: white; padding:0.5rem 0; font-weight: bold; font-size: 12px; } #waybar { background: rgba(30,35,35, 1); } window#waybar { color: white; } #clock { font-size: 12px; background: rgba(50,60,60, 1); } #custom-power-menu { border-radius: 5px; padding: 5px; } #workspaces button { padding: 1px; font-weight: bold; border-radius: 0; } #workspaces button.active { background: rgba(50,60,60, 1); } #workspaces button.urgent { background: maroon; } #custom-power-menu { color: tomato; } ```