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
21.12k stars 883 forks source link

toggle dpms state #2845

Open 0x5a4 opened 1 year ago

0x5a4 commented 1 year ago

Description

I have keybindings to toggle the dpms state for specific monitors, because sometimes i feel like purging all light from my room.

Currently I achieve this using this very compact and beautiful one-liner: if [ $(hyprctl monitors -j | jq ".[]|select(.name==\"<output-name>\").dpmsStatus") = "true" ]; then hyprctl dispatch dpms off <output-name>; else hyprctl dispatch dpms on <output-name>; fi

I looked at the code for the dpms dispatcher and this seems quite simple to implement. (I'd do it myself but I cant c++)

spikespaz commented 1 year ago

I don't understand what this accomplishes. For me, the dpms off dispatcher turns off all monitors.

0x5a4 commented 1 year ago

I can see that I should've made my point a little more clear.

Yes, dmps off turns everything off, but if you then want to turn it back on again you either need a second keybinding or the one-liner from above. It just seems like an oversight to me that there is no builtin toggle-option.

spikespaz commented 1 year ago
hyprctl dispatch dpms toggle

I will update the wiki

zakk4223 commented 1 year ago

I'm confused. Why are you updating the wiki with 'toggle' when that is not a real argument to the dpms dispatcher?

spikespaz commented 1 year ago

I'm confused. Why are you updating the wiki with 'toggle' when that is not a real argument to the dpms dispatcher?

Because it is. I thought it definitely was. I use it in my configs. Must just think it works because I have DPMS reactivate when input event. Sorry. Will leave PR open for when Vaxry adds the feature.

vaxerski commented 1 year ago

https://github.com/hyprwm/Hyprland/commit/08651736ada39f62b246c44c1d8a81e2787f23d5

spikespaz commented 1 year ago

Ah. My attempt didn't use any, that's why it didn't work. Well, I tried at least, but I'm a C++ noob.

spikespaz commented 1 year ago

@vaxerski This commit 08651736ada39f62b246c44c1d8a81e2787f23d5 does not work for me. I have verified that I am using that same commit.

Testing with:

sleep 1 & hyprctl dispatch dpms toggle && sleep 5 && hyprctl dispatch dpms toggle

Edit: I re-read the code. This toggle option works oddly.

  1. Monitor 1 OFF, Monitor 2 ON - toggle turns both OFF
  2. Monitor 1 ON, Monitor 2 ON - toggle does nothing
  3. Monitor 1 OFF, Monitor 2 OFF - toggle does nothing

Perhaps the option toggle is only meant to turn ON monitors which are currently OFF, but then the word toggle makes little sense. Regardless of semantics, the option does not work as intended.

0x5a4 commented 1 year ago

I've also noticed the implementation to be... odd. Currently whether to enable or disable monitors is calculated only once, instead of per monitor. This works for 'on' and 'off', but for 'toggle' this leads to very inconsistent behaviour, as described by @spikespaz.

This can easily be fixed by moving the 'enabled' calculation into the loop that applies it to the target monitor(s).

spikespaz commented 1 year ago

I think we need two toggle options.

Here's a truth table, where first three columns is each state before dispatch, and "All Monitors" is after dispatch. The red square (:red_square:) is OFF, the green square (:green_square:) is ON.

Monitor A Monitor B Monitor C Toggle Mode All Monitors
:red_square: :red_square: :red_square: on :green_square:
:green_square: :red_square: :red_square: on :green_square:
:green_square: :green_square: :red_square: on :green_square:
:green_square: :green_square: :green_square: on :green_square:
:red_square: :red_square: :red_square: off :red_square:
:green_square: :red_square: :red_square: off :red_square:
:green_square: :green_square: :red_square: off :red_square:
:green_square: :green_square: :green_square: off :red_square:
:red_square: :red_square: :red_square: toggleon :green_square:
:green_square: :red_square: :red_square: toggleon :green_square:
:green_square: :green_square: :red_square: toggleon :green_square:
:green_square: :green_square: :green_square: toggleon :red_square:
:red_square: :red_square: :red_square: toggleoff :green_square:
:green_square: :red_square: :red_square: toggleoff :red_square:
:green_square: :green_square: :red_square: toggleoff :red_square:
:green_square: :green_square: :green_square: toggleoff :red_square:

That got complicated really quickly.

Why does GitHub use slightly different emojis in each table cell even when they have the same name?

0x5a4 commented 1 year ago

What should happen if a monitor is specified? toggleoff and toggleon make little sense in that case. I personally find toggleon to be more logical, so maybe just implement that as toggle?

spikespaz commented 1 year ago

What should happen if a monitor is specified? toggleoff and toggleon make little sense in that case. I personally find toggleon to be more logical, so maybe just implement that as toggle?

Then I think they ought to just do the same thing. This is really only an issue for multi monitor setups of course.

For a single monitor all that is needed is toggle. Maybe that's why Vaxry made the mistake.

vaxerski commented 1 year ago

I will think about it when its not 3am

heather7283 commented 1 year ago

hyprctl dispatch dpms toggle doesn't work for me - command prints "ok" but nothing happens. hyprctl dispatch dpms off and hyprctl dispatch dpms on work fine.

OS: Arch Linux Machine: Asus TUF Gaming A15 laptop Hyprland version: Latest from the official repository (not the -git one from AUR)

tmccombs commented 9 months ago

I can't get hyprctl dispatch dpms toggle to work regardless of if I specify a monitor.

I would like to have key binding that toggle dpms for specific monitors. So that if I am playing a game, watching a video, etc. on one monitor I can temporarily turn off the other one.

dsancheznet commented 8 months ago

I have the same behavior as Heather7283, ok is printed out, but the screen stays on.

Best regards

diogeek commented 5 months ago

Hello! Any progress ? I understand the trouble about the meaning of the word toggle, but even if it is only usable on one monitor at a time, I really need that option, as there is a specific button on my keyboard that is designed to do exactly that (I own an Asus Zenbook Duo, the second screen of which is toggleable with a designated key).

animanna commented 4 months ago

I recently got a new monitor so my laptop screen is not needed always. I can successfully apply dpms toggle dispatches...

Here's my keybind config

# Resizing Extravaganza and View Control Center

bind = CTRLALT, End, submap, vcc
submap = vcc

bind = ,1, resizeactive, exact 800 600 
# >> ...
# >> Here are some resizes I abuse
# >> ...
bind = ,9, resizeactive, exact 90% 90%

bind = ,H, exec, hyprctl keyword monitor DP-1,highres,auto-left,1,bitdepth,10; hyprctl keyword monitor eDP-1,highrr,0x422,1
bind = ,V, exec, hyprctl keyword monitor DP-1,highres,auto-left,1,bitdepth,10,transform,3; hyprctl keyword monitor eDP-1,highrr,0x840,1

## The bind below does 2 things.
## It carries all the layout and the clients to the DP-1 monitor and powers down the laptop monitor.
bind = Alt, 2, execr, hyprctl dispatch dpms toggle eDP-1 && hyprctl keyword monitor eDP-1,disable

# I use the binds laid below when I need to turn the Laptop Screen On
# Turning on the eDP-1, when the DP-1 is Horizontal
bind = Ctrl, H, execr, hyprctl dispatch dpms toggle eDP-1 && hyprctl keyword monitor eDP-1,highrr,0x422,1
# Turning on the eDP-1 when the DP-1 is Vertical 
bind = Ctrl, V, execr, hyprctl dispatch dpms toggle eDP-1 && hyprctl keyword monitor eDP-1,highrr,0x840,1 

bind = ,escape, submap, reset
bind = CTRLALT, End, submap, reset
submap = reset

I have no complaints with this, dpms toggle works when combined with monitor disable. I suppose it doesn't work if you don't disable the monitor with the same command.

When I use the CTRL - H or CTRL - V the laptop screen won't turn off. There is a keyword that sets the monitor. But when I use the dpms toggle eDP-1 dispatch eDP-1 with the monitor eDP-1, disable keyword it disables like it should do.

Cheers

Edit: When I check 'hyprctl monitors`... dpms toggle' dispatch don't worky as it is when the screen is on. But it works after turning off with 'dpms off'. Butdpms off` won't be something I would use anyways, as to take all the clients to the active monitor we need to disable the monitor.

I think we can just bind bind = MOD,KEY, execr, hyprctl keyword monitor eDP-1,disable instead of using 'dpms toggle' to power down a screen.

And be well off...

sephid86 commented 4 months ago

https://github.com/hyprwm/Hyprland/commit/08651736ada39f62b246c44c1d8a81e2787f23d5

this is not work.

$ hyprctl dispatch dpms toggle DP-1

print -> ok

but does'nt changed monitor status.

if have multi monitors

When watching a movie, need a toggle shortcut key to turn on/off the monitor that is not in use.