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

Only show waybar when modifier key is pressed #255

Closed
vially opened this issue Mar 31, 2019 · 40 comments
Closed

Only show waybar when modifier key is pressed #255

vially opened this issue Mar 31, 2019 · 40 comments
Labels
enhancement New feature or request

Comments

@vially
Copy link

vially commented Mar 31, 2019

Is there any way to configure sway/waybar so that it behaves similar to i3's mode hide?

Sway already supports mode hide for their swaybar. I was wondering if it would be possible to implement the same for waybar?

Basically what I'm looking for is having this sway configuration work as expected:

bar {
  mode hide
  swaybar_command waybar
}
@Alexays Alexays added the enhancement New feature or request label Mar 31, 2019
@rif
Copy link

rif commented Apr 5, 2019

This is the feature that I'm also waiting for to be able to make the switch to waybar, great tool!

@toger5
Copy link

toger5 commented Jun 5, 2019

Would be great to have that feature!

@toger5
Copy link

toger5 commented Jul 16, 2019

Seems like there is already some kind of hide functionality built in the code (the toggle function).
It probably just needs to listen to some kind of sway events.
See the main function:

std::signal(SIGUSR1, [](int /*signal*/) {

It seems that there is a USRSIG which is used for the toggle.
I tired with a little c program

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

int main(void)
{
    kill(/*the Pid*/, SIGUSR1);
}

and the bar actually gives the space to the compositor.

@toger5
Copy link

toger5 commented Jul 16, 2019

Also this is realted to #157.
Basically the c program i posted is eqivalent to killall -SIGUSR1 waybar which can be bound to some shortcut. But it is still not possible to toggle when holding $mod.

@xPMo
Copy link
Contributor

xPMo commented Sep 3, 2019

I've been poking around in sway's IPC docs and here's what I've learned. I will use this as an example config:

bar {
    id bar1
    modifier $mod
}

By default, bar1 is started in mode dock. Pressing and releasing $mod sends no events while the bar is in this mode. Now suppose that by a binding or a swaymsg call, that the command bar mode invisible was run. An event of type barconfig_update is sent, the json object sent has fields including "mode": "invisible", and "id": "bar1". Pressing and releasing $mod while the bar is in this mode also sends no events. Similarly for mode "overlay".

Now, if either bar mode hide or (while the bar is in "dock" mode) bar mode toggle is sent, an event of type "barconfig_update" is sent with field "mode": "hide", just like before.

While the bar is in mode "hide", pressing and releasing $mod will send events of type bar_status_update. The objects will be: {"id": "bar1", "visible_by_modifier": [bool]}, where [bool] is true or false.


Either:

  • the barconfig_update events are ignored, and all users must usebar { mode hide } so that bar { modifier $mod } works consistently, and waybar uses another mechanism to toggle dock/hide mode
  • or these bar-mode events are used to control the layer-shell state in a sway-bar compatible way.

There are a number of benefits to the second option:

  • in a session with multiple bars, waybar can use its bar ID to identify its state, as opposed to PID
  • users don't have to set bar mode hide in their sway config
  • being totally ipc-compatible with sway's first-party bar makes it easy to migrate from swaybar.

The downsides to the second option:

  • allowing a compositor-specific module to control the visibility/layer-shell properties of waybar is a really deep integration. This would tie waybar down to sway far more than the current sway/mode, sway/workspaces, or sway/window modules do, possibly at the expense of future compositor support.

EDIT: @Alexays, comments on feasibility? Am I off the mark here?

EDIT2: Optimally, swaywm/wlr-protocols#41 would be adopted so waybar can change layers without destroying its surface.

@l3s2d
Copy link

l3s2d commented Oct 2, 2019

Not sure if I'm off the mark here, but another, albeit more complex, option would be to implement a control program for waybar, i.e. waybarctl. This would be useful for a few reasons:

  • Allow external programs to interact with waybar while it's running, instead of having waybar rely on polling for everything
  • This might address the current issue by doing something like
    • bindsym $key waybarctl show
    • bindsym --release $key waybarctl hide

@xPMo
Copy link
Contributor

xPMo commented Oct 8, 2019

This might address the current issue by doing something like

  • bindsym $key exec waybarctl show
  • bindsym --release $key exec waybarctl hide

This works for normal keys, but not modifiers. If you want to bind this to Mod4 (for example), you can use bindsym Super_L exec waybarctl show (and similar with --release). However, while the first gets run consistently when the key is pressed, the --release binding is ONLY run if another shortcut is not run first. So if you have the show/hide bindings as above, running any command (like $mod+l to focus left) will show the bar and not hide it when Mod4 is released.

This can be worked around by having another IPC client which reads the bar_status_update events and then calls waybarctl, but it seems wasteful to attach a whole other process when waybar already has a connected socket.

nyyManni added a commit to nyyManni/Waybar that referenced this issue Oct 30, 2019
…essed

Closes Alexays#255

Setup instructions:
- Set the *mode* of the bar to "hide" in sway configuration file
- Set the *layer* of the bar to "overlay" in Waybar configuration file
- Add "sway/hide" into *modules-left* -list in Waybar configuration file
@nyyManni
Copy link

I was playing around with this feature in my fork, and have got it into a shape where it is mostly good enough for my use.

In order to not tie Waybar too much into sway, I created a "meta-module" sway/hide which does not actually have any visible GUI, but just hooks into bar_status_update events from sway and toggles the visibility of the bar accordingly. This way the core of waybar is kept "non-sway-aware". The only thing added to the core was the support for showing the bar in an overlay mode (, which also would solve #491).

There are still problems, though. The biggest one I am facing right now is that when the bar is in overlay mode (on top of tiled windows) and hidden by the gtk style option, the invisible bar still sucks the mouse events from the area. In other words for example the tab bar in my browser is difficult to use with a mouse as the invisible bar covers about 75% of it. (I am still ok with it, as I mostly use keyboard shortcuts anyway, but...)

Ideas on how to solve the invisible overlay stealing mouse clicks would be welcome, as that would make the feature more suitable for daily use.

@xPMo
Copy link
Contributor

xPMo commented Oct 31, 2019

@nyyManni Have you tried setting waybar to use the bottom layer?

@nyyManni
Copy link

@xPMo I am setting the layer into ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY which is needed as I want to show the bar on top of other clients whenever it is visible. A solution might be to dynamically set the layer to ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM while the bar is hidden, allthough I am not sure if I can modify that attribute without destroying and recreating the surface.

@xPMo
Copy link
Contributor

xPMo commented Oct 31, 2019

dynamically set the layer

You can't right now, but there's already an issue for it (swaywm/wlr-protocols#41, I linked it earlier in this thread).

Currently, swaybar destroys its surface instead of changing layers when it hides.

nyyManni added a commit to nyyManni/Waybar that referenced this issue Dec 26, 2019
…essed

Closes Alexays#255

Setup instructions:
- Set the *mode* of the bar to "hide" in sway configuration file
- Set the *layer* of the bar to "overlay" in Waybar configuration file
- Add "sway/hide" into *modules-left* -list in Waybar configuration file
@xPMo
Copy link
Contributor

xPMo commented Dec 31, 2019

@nyyManni @ALL Good news:

wlroots 0.9.0 has been released; the layer shell protocol and wlroots now support changing layer at runtime.

It is now possible for waybar to simply raise its layer on modifier. I like this option, since waybar will always be visible on empty workspaces, or when it is uncovered/partially covered by floating windows. Additionally, it solves the focus-stealing problem @nyyManni mentioned.

However, some may prefer their bar to be completely hidden, even on empty workspaces (like swaybar). A "hide-on-modifier": <bool> option in the module may be useful; setting it to false makes waybar change layer without hiding. If this is supported, a name like "sway/hide" may be misleading; maybe call the module "sway/bar_events".

@nyyManni
Copy link

@xPMo indeed!

I already tried it last week (see the referenced commit 5 days ago), and have been using it since.

My solution is a hack, though, and I am having an issue that when I "raise" the bar with the modifier, sometimes the remaining of the screen "jumps back in time" showing an old version of my framebuffer, at least with XWayland clients.

xPMo pushed a commit to xPMo/Waybar that referenced this issue Jan 8, 2020
…essed

Closes Alexays#255

Setup instructions:
- Set the *mode* of the bar to "hide" in sway configuration file
- Set the *layer* of the bar to "overlay" in Waybar configuration file
- Add "sway/hide" into *modules-left* -list in Waybar configuration file
@ghost
Copy link

ghost commented Feb 13, 2020

I am wanting to raise the ante' and configure the bar to be say '2px and transparent(or peaking through)' and then when the move hovers over the area, the bar changes height to the full area with whatever styling

I tried using hideIt.sh but couldn't get it to work properly. :/

VV theres also this bit of code in bar.cpp VV

auto waybar::Bar::toggle() -> void { ...
...
window.get_style_context()->add_class("hidden")
...
}

but I am not quite sure what to do with it. I don't know .. ?

@ghost
Copy link

ghost commented Feb 13, 2020

theres also this bit of code ..
auto waybar::Bar::toggle() -> void { ... ... window.get_style_context()->add_class("hidden") ... }
but I am not quite sure what to do with it. I don't know .. ?

@ghost ghost mentioned this issue May 1, 2020
@mox-mox
Copy link

mox-mox commented Aug 27, 2020

Hey, is there any progress so far?

@ghost
Copy link

ghost commented Aug 27, 2020 via email

@xPMo
Copy link
Contributor

xPMo commented Aug 28, 2020

Hey, is there any progress so far?

I have some work on the feature, but unfortunately it is both old and didn't quite work. My severe inexperience with C++ is the biggest culprit, I have a decent grasp on the wayland/sway side of things.

somini pushed a commit to somini/Waybar that referenced this issue Sep 21, 2020
This allows auto-showing the bar when the modifier is pressed

Closes Alexays#255

Setup instructions:
- Set the `mode` of the bar to "hide" in sway configuration file
- Set the `layer` of the bar to "overlay" in Waybar configuration file
- Add "sway/hide" into `modules-left` in Waybar configuration file
@somini
Copy link

somini commented Sep 21, 2020

swaywm/wlr-protocols#41 was fixed by swaywm/wlr-protocols#59 apparently, I don't have problem with hiding and showing the bar now, if I send a USR1 to the waybar process.

My use case is having a simple main bar that it's always on, and another more complex one that is only shown when a modifier is pressed, for extra information.

https://github.com/xPMo/Waybar/tree/sway-hide sounds like a good solution that doesn't tie Waybar to sway so much, but provides integration, particularly with more than one bar.

I tweaked the code by trying to reuse the toggle function, and I get some segfaults if I toggle it too rapidly (I also don't know enough C++, might be something on my side). It seems that if a toggle operation is triggered while the previous operation is happening yet, there's a crash. The code in in #860

somini pushed a commit to somini/Waybar that referenced this issue Sep 21, 2020
This allows auto-showing the bar when the modifier is pressed

Closes Alexays#255

Setup instructions:
- Set the `mode` of the bar to "hide" in sway configuration file
- Set the `layer` of the bar to "overlay" in Waybar configuration file
- Add "sway/hide" into `modules-left` in Waybar configuration file
@creeperdeking
Copy link

Is it possible to merge this commit? This is a functionality I am personally very much waiting for!

@xPMo
Copy link
Contributor

xPMo commented Jun 3, 2021

Is it possible to merge this commit? This is a functionality I am personally very much waiting for!

#860 is still only marked as a Draft PR, @somini needs to mark it as ready to merge first. I don't know whether or not it is, so we'll have to wait. :)

@somini
Copy link

somini commented Jun 7, 2021

Please see #860 (comment), it's really just a draft. It needs more C++ expertise than I have, sadly.

@creeperdeking
Copy link

Okay, I really like this hide functionality, so I have switched back to sway-bar for the time being.

@emirror-de
Copy link

Hi, is there any progress on this?

@somini
Copy link

somini commented Aug 14, 2021

Hi, is there any progress on this?

#860 has some initial work, but my C++ knowledge prevents me from going further. It's out of sync with the main branch now.

@emirror-de
Copy link

Hey there,
thanks for all your work already done @somini and @xPMo!
I had a look into it and merged it to the latest master branch. Also tried a bit around and it seems that I have found the SIGSEGV reason. See my pull request for the changes I did.

I am happy to adjust anything further that is required to merge it!

Sorry @somini, I was not able to push to your draft. However if thats somehow possible, I am happy to push the changes to your PR and cancel mine.

Greetings!

@somini
Copy link

somini commented Sep 19, 2021

@emirror-de No problem, my PR was a just a hack anyway. I'll close it in favour of your PR, it's more advanced than mine.

@creeperdeking
Copy link

great news!

@somini
Copy link

somini commented Oct 30, 2021

In case anyone is only tracking this on this issue, #1241 by @emirror-de does the trick, it's implemented now.

@emirror-de
Copy link

The PR is still marked as Draft because I found that it is not stable enough yet. I have a multimonitor setup and sometimes one bar freezes and the other one works as expected. In addition to that, the application sometimes crashes with an "Address boundary error". I was not able to find the reason yet, I think I need help to fix this.

Analysis with valgrind --leak-check=yes waybar returns multiple memory leaks:

...

==9792== 464 bytes in 1 blocks are possibly lost in loss record 14,701 of 15,829
==9792==    at 0x483E5EF: calloc (vg_replace_malloc.c:1328)
==9792==    by 0x40130E7: calloc (rtld-malloc.h:44)
==9792==    by 0x40130E7: allocate_dtv (dl-tls.c:366)
==9792==    by 0x40130E7: _dl_allocate_tls (dl-tls.c:612)
==9792==    by 0x62E0BE4: allocate_stack (allocatestack.c:624)
==9792==    by 0x62E0BE4: pthread_create@@GLIBC_2.2.5 (pthread_create.c:634)
==9792==    by 0x603DB19: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29)
==9792==    by 0x196887: waybar::modules::sway::Ipc::setWorker(std::function<void ()>&&) (in /home/dev/bin/waybar)
==9792==    by 0x1BCA03: waybar::modules::sway::Hide::Hide(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, waybar::Bar const&, Json::Value const&) (in /home/dev/bin/waybar)
==9792==    by 0x147E22: waybar::Factory::makeModule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (in /home/dev/bin/waybar)
==9792==    by 0x16A4C5: waybar::Bar::getModules(waybar::Factory const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /home/dev/bin/waybar)
==9792==    by 0x16A6D3: waybar::Bar::setupWidgets() (in /home/dev/bin/waybar)
==9792==    by 0x16B4C2: waybar::Bar::Bar(waybar::waybar_output*, Json::Value const&) (in /home/dev/bin/waybar)
==9792==    by 0x173E4B: waybar::Client::handleOutputDone(void*, zxdg_output_v1*) (in /home/dev/bin/waybar)
==9792==    by 0x64C49D9: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0)

...

This report repeats for every module that is configured on the bar. Maybe this is a separate issue? When I am correctly interpreting the report, this is an error in libstdc++.so.6.0.29? But I am not too deep into this debugging methods to be sure.

Any help would be appreciated! 🚀

@somini
Copy link

somini commented Dec 27, 2021

This finally moved to #1244, that's already merged. This issue can be closed once that's released.

@TRPB
Copy link

TRPB commented Jan 15, 2022

How can I send the IPC message on another WM?

@Alexays Alexays closed this as completed Oct 27, 2022
@hamdav
Copy link

hamdav commented Nov 17, 2022

I would also love to have this feature on Hyprfine, has anyone tried that?

@vlbn
Copy link

vlbn commented Dec 29, 2023

i'm using hyprland. i just binded a key combination (super+Print) to toggle the waybar process. it does the job.
bind = $mainMod, Print, exec, pkill waybar || waybar
@Alexays am i being too lazy?

@dron1885
Copy link

am i being too lazy?

Well you can do it a bit more "properly".

Add these lines to the hyprland config

bind = , SUPER_L, exec, killall -SIGUSR1 waybar
bindir = , SUPER_L, exec, sleep 0.5 && killall -SIGUSR1 waybar

And following to waybar config:

"mode": "hide",
"start_hidden": true

@Hubro
Copy link

Hubro commented Mar 12, 2024

@dron1885 Does that work for you? For me, the "release" modifier only works if I click and release Super_L alone. If I hold the Super_L key as part of another key bind, like Superh, waybar appears and never disappears, and the toggle behavior is now inverted :S

@dron1885
Copy link

@Hubro It should be bindit and binditr respectively.

@Hubro
Copy link

Hubro commented Mar 12, 2024

@Hubro It should be bindit and binditr respectively.

Ah, I was missing the t, now it works 😁 But after playing with it for a couple of minutes I realized it completely breaks the system tray. I can't interact with it while holding Super_L, and if I add a short sleep so I can open context menus, the menus disappear together with waybar after the delay.

Also the background blur behind waybar seems to stick around while waybar is hidden.

This would definitely need some polish in order to be usable.

@gustavosbarreto
Copy link

gustavosbarreto commented May 22, 2024

@Hubro It should be bindit and binditr respectively.

Ah, I was missing the t, now it works 😁 But after playing with it for a couple of minutes I realized it completely breaks the system tray. I can't interact with it while holding Super_L, and if I add a short sleep so I can open context menus, the menus disappear together with waybar after the delay.

Also the background blur behind waybar seems to stick around while waybar is hidden.

This would definitely need some polish in order to be usable.

@Hubro The issue with the system tray is caused by the bindings to resize windows where it is listening for mouse events and not propagating to waybar. To fix it, simply disable it by removing the following lines from hyprland.conf:

# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow

I'm keyboard-oriented, so mouse bindings in a tiling window manager are completely useless for me.

@Hubro
Copy link

Hubro commented May 29, 2024

@gustavosbarreto Aha, you're right! Unfortunately I'm a heavy user of the mouse for moving and resizing floating windows 😞 I guess I can't have both without some changes to Hyprland.

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