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

How to show/hide dock programatically instead of toggling? #55

Closed
karamanliev opened this issue Aug 28, 2024 · 28 comments · Fixed by #56
Closed

How to show/hide dock programatically instead of toggling? #55

karamanliev opened this issue Aug 28, 2024 · 28 comments · Fixed by #56

Comments

@karamanliev
Copy link

karamanliev commented Aug 28, 2024

I made a script to show the dock when there are no windows after workspace change and to make it in -d (autohide) mode when there are windows on the workspace.

Unfortunately I can't find a way to do it currently because I can't find a way to do it, because there is an option only to toggle it.

Also, is it possible to show the dock on every monitor? I tried launching multiple instances but it didn't work.

Am I missing something?

@nwg-piotr
Copy link
Owner

You are right. We have no way to turn on/off specifically, just USR1 to toggle.

@karamanliev
Copy link
Author

karamanliev commented Aug 28, 2024

I treid to implement an "intelligent" dock, using hyprland's IPC socket in bash. It kind of works, but it's getting complex, because of no real on/off state. Now I have to do it for multiple monitors & workspaces with floating windows only 🤣

recording_2024-08-29_02-19-28.mp4

A future update to have this feature will be very appreciated. I haven't used Go, but I might try to do a PR if I have some more free time. Thanks for the great software!

@nwg-piotr
Copy link
Owner

nwg-piotr commented Aug 28, 2024

The hardest part is to decide which signals to use for show and hide, as we need to leave USR1 as is, to avoid breaking users' configs. The code itself would be easy.

@karamanliev
Copy link
Author

karamanliev commented Aug 28, 2024

I currently implemented it for workspace, openwindow, closewindow, activespecial and focusedmon, but there might be more like changefloatingmode and movewindow.

@nwg-piotr
Copy link
Owner

Maybe, instead of external scripting, it would make sense to add such behaviour as a dock option?

@karamanliev
Copy link
Author

Oh, it would be awesome!

@nwg-piotr
Copy link
Owner

Make a list which event should trigger which action, e.g.:

openwindow - hide
closewindow - show
(...)

and so on, and I'll try to do so.

@karamanliev
Copy link
Author

I'm not sure if it would be that simple. In my opinion, active workspace window count and maybe window positions should be tracked on different signals. And then, depending on the result the dock should be hidden or shown.

@nwg-piotr
Copy link
Owner

nwg-piotr commented Aug 29, 2024

Well, maybe it makes more sense to leave it for an external script. I can imagine dozen of issues submitted by people who want stuff to work differently.

@karamanliev
Copy link
Author

Yeah, you're right. Just a simple nwg-dock-hyprland --show / nwg-dock-hyprland --hide switch would suffice. This would not disrupt the current toggle behaviour.

A bonus would be, if it's possible to add something like --show -o monitorID to force showing on a specified display. This currently works with -d. The dock shows on the display where you hover the hotspot.

@nwg-piotr
Copy link
Owner

nwg-piotr commented Aug 29, 2024

I'll stick to signals. In addition to the current USR1 for Toggle, I'll make:

  • SIGRTMIN+1 for Toggle (USR1 will be deprecated from now on),
  • SIGRTMIN+2 for Show,
  • SIGRTMIN+3 for Hide.

Basic code is ready.

A bonus would be (...)

This would be difficult, if even possible.

@nwg-piotr
Copy link
Owner

@karamanliev Would you mind sharing your script, when adjusted to the latest changes? We could add it to the repo.

@maarutan
Copy link

I can't wait to see your script ;))))

@karamanliev
Copy link
Author

karamanliev commented Aug 30, 2024

Basically works perfect on a single monitor with -d and -r and on multiple monitors with -r. If anyone has any ideas how to make it work, please do. I think the process should be killed and started again and something like a debounce ot throttle should be added so it doesn't run multiple times if switching very fast between monitors. I'm not good at bash 🤣

Maybe I will just create a custom hotspot for myself that just toggles the dock on mouse enter / mouse leave.

There's also no event to track when a window has ended moving or something to be able to hide it if you move a floating window with mouse.

I've only tested with dock on bottom, but I guess it'll be almost the same on the sides/top. Instead window X size and pos should be tracked and maybe the free_space calculation should change a bit.

recording_2024-08-30_18-05-48.mp4
video_2024-08-30_18-10-37.mp4
#!/usr/bin/env bash

DOCK_HEIGHT=120
INITIAL_LAUNCH_FLAGS="-r -i 64 -w 10 -mb 6 -hd 0 -c 'rofi -show drun' -ico '/usr/share/icons/Papirus-Dark/symbolic/actions/view-app-grid-symbolic.svg'"
HIDE_SIGNAL="pkill -37 -f nwg-dock-hyprland"
SHOW_SIGNAL="pkill -36 -f nwg-dock-hyprland"

toggle_dock() {
  if [ "$1" = "show" ]; then
    $SHOW_SIGNAL
  else
    $HIDE_SIGNAL
  fi
}

get_active_ws_id() {
  local ws_id=$(echo "$1" | awk 'NR==2')
  local special_ws_id=$(echo "$1" | awk 'NR==3')

  if [ "$special_ws_id" -eq 0 ]; then
    echo "$ws_id"
  else
    echo "$special_ws_id"
  fi
}

show_hide_dock() {
  local monitor_info=$(hyprctl monitors -j | jq -r '.[] | select (.focused == true) | .height, .activeWorkspace.id, .specialWorkspace.id')
  local monitor_height=$(echo "$monitor_info" | awk 'NR==1')
  local ws_id=$(get_active_ws_id "$monitor_info")
  local window_count=$(hyprctl workspaces -j | jq ".[] | select(.id == $ws_id) | .windows")

  if [ "$window_count" -eq 0 ]; then
    toggle_dock "show"
    return
  fi

  # get all windows Y pos and Y size on the active workspace
  local windows_data=$(hyprctl clients -j | jq -c ".[] | select(.workspace.id == $ws_id) | {at: .at[1], size: .size[1]}")
  local should_show=1

  while IFS= read -r window; do
    local pos_y=$(echo "$window" | jq -r '.at')
    local size_y=$(echo "$window" | jq -r '.size')
    local free_space=$((monitor_height - pos_y - size_y))

    if [ "$free_space" -lt "$DOCK_HEIGHT" ]; then
      should_show=0
      break
    fi
  done <<<"$windows_data"

  if [ "$should_show" -eq 1 ]; then
    toggle_dock "show"
  else
    toggle_dock "hide"
  fi
}

initial_dock_launch() {
  hyprctl dispatch exec "nwg-dock-hyprland $INITIAL_LAUNCH_FLAGS"

  # need to wait this much only if using '-d', I don't know why. Needs only 0.1 with '-r'
  sleep 0.6 && show_hide_dock
}

function handle {
  case $1 in
  changefloatingmode* | workspacev2* | closewindow* | openwindow* | activespecial*)
    show_hide_dock
    ;;

  focusedmon*)
    # buggy with "-d" if you hover on the hotspot on one monitor it stops moving between monitors, works perfect with "-r"
    toggle_dock "hide" && show_hide_dock
    ;;
  esac
}

initial_dock_launch

socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do handle "$line"; done

@karamanliev
Copy link
Author

karamanliev commented Aug 30, 2024

Hacky, but it does the job. Multi monitor "intelligent" dock on active screen works perfect this way. I'd really like it if there was a native way to do it from nwg-dock-hyprland.

recording_2024-08-30_20-27-43.mp4

@nwg-piotr
Copy link
Owner

I think the process should be killed and started again and something like a debounce ot throttle should be added so it doesn't run multiple times if switching very fast between monitors.

Pay attention to the fact, that you are unable to run multiple instances of the program. Depending on the arguments in use, it'll behave differently, but 2 instances should be impossible in any case.

@karamanliev
Copy link
Author

Pay attention to the fact, that you are unable to run multiple instances of the program. Depending on the arguments in use, it'll behave differently, but 2 instances should be impossible in any case.

Yep, it almost worked when relaunching with pkill -f nwg-dock-hyprland when switching between monitors, but it was not perfect. I'll revisit it tomorrow, when I have some free time.

@maarutan
Copy link

The script doesn't work for me, can you tell me in detail how to run it?

@karamanliev
Copy link
Author

karamanliev commented Aug 31, 2024

The script doesn't work for me, can you tell me in detail how to run it?

just chmod +x path/to/script.sh, then exec-once = path/to/script.sh in your hyprland config.

Also check the INITIAL_LAUNCH_FLAGS and change them accordingly to suit your needs.

Try to run it in your terminal first. And tell me if you're getting any errors.

@maarutan
Copy link

At the same time, autoHide does not work for me when aiming at a hot spot

@karamanliev
Copy link
Author

At the same time, autoHide does not work for me when aiming at a hot spot

Change -r with -d for autohide

@maarutan
Copy link

maarutan commented Aug 31, 2024

I already have it at -d

DOCK_HEIGHT=120 INITIAL_LAUNCH_FLAGS=(-notooltips -d -i 64 -w 10 -mb 6 -hd 0 -c "rofi -show drun") HIDE_SIGNAL="pkill -37 -f nwg-dock-hyprland" SHOW_SIGNAL="pkill -36 -f nwg-dock-hyprland"

@karamanliev
Copy link
Author

karamanliev commented Aug 31, 2024

lol, remove -notooltips. I forked the repo and built a binary for myself with it.

Sorry, my bad, forgot to remove it from the script.

@maarutan
Copy link

lol thanks for the script ^^

@maarutan
Copy link

maarutan commented Sep 1, 2024

I'm sorry, but how did you style the application launcher???

@karamanliev
Copy link
Author

karamanliev commented Sep 1, 2024

/*-----   ~/.config/nwg-dock-hyprland/style.css   -----*/

window {
  background: rgba(34, 36, 54, 0.5);
  border-radius: 16px;
  border-style: none;
  border-width: 0px;
  border-color: rgba(156, 142, 122, 0.7);
}

#box {
  /* Define attributes of the box surrounding icons here */
  padding: 10px;
}

#active {
  /* This is to underline the button representing the currently active window */
  border-bottom: solid 0px;
  border-color: rgba(255, 255, 255, 0.3);
}

button,
image {
  background: none;
  border-style: none;
  box-shadow: none;
  color: #999;
}

button {
  padding: 4px;
  border-radius: 16px;
  margin-left: 4px;
  margin-right: 4px;
  margin-bottom: 4px;
  color: #eee;
  font-size: 12px;
}

button:hover {
  background-color: rgba(192, 202, 245, 0.3);
}

button:focus {
  box-shadow: none;
}
# ~/.config/hypr/hyprland.conf

layerrule = blur, ^(nwg-dock)$
layerrule = ignorealpha 0, ^(nwg-dock)$

@maarutan
Copy link

maarutan commented Sep 1, 2024

my app launcher is orange i want to change it to white or purple

@karamanliev
Copy link
Author

karamanliev commented Sep 1, 2024

It's in the README. Use -ico and provide path for your own icon.
-ico '/usr/share/icons/Papirus-Dark/symbolic/actions/view-app-grid-symbolic.svg'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants