You are not logged in.
I made a udev rule to change my laptop screen refresh rate when plugging or unplugging the charger, and for the most part it works (using hyprctl so it needs the instance signature to work). However when trying to get hyprland to automatically write the instance signature to a file it just doesn't seem to work. The command runs fine from the terminal, but it doesn't work when putting it in my hyprland config.
Initially the line was:
exec-once = printf %s\n "$HYPRLAND_INSTANCE_SIGNATURE" > /tmp/hyprinstancesig I tried changing it to:
exec-once = sh -c 'sleep 1 && printf %s\n "$HYPRLAND_INSTANCE_SIGNATURE" > /tmp/hyprinstancesig' Neither of which worked.
EDIT: Forgot to add but I also tried using echo to the same result. Runs as intended in the terminal, doesn't work in autostart.
Last edited by CChromaKee (2025-09-19 16:29:12)
Offline
What do you mean exactly by "doesn't work": does it create an empty file, or no file at all? If it's the former, HYPRLAND_INSTANCE_SIGNATURE likely isn't set yet when "exec-one" is called. You can test that by using `printf %s\n "M$HYPRLAND_INSTANCE_SIGNATURE"` (with the added M as a prefix) and see if there's just a single `M` in /tmp/hyprinstancesig. If the file isn't created at all, try writing it to a different location inside your $HOME, perhaps it's a permissions issue.
I don't run hyprland, what user "runs" that "exec-once" command? Is that your log-in user, or a system user?
Offline
What do you mean exactly by "doesn't work": does it create an empty file, or no file at all? If it's the former, HYPRLAND_INSTANCE_SIGNATURE likely isn't set yet when "exec-one" is called. You can test that by using `printf %s\n "M$HYPRLAND_INSTANCE_SIGNATURE"` (with the added M as a prefix) and see if there's just a single `M` in /tmp/hyprinstancesig. If the file isn't created at all, try writing it to a different location inside your $HOME, perhaps it's a permissions issue.
I don't run hyprland, what user "runs" that "exec-once" command? Is that your log-in user, or a system user?
I assume its the login user, as every other user-space application is run with that same command (Eg, the dock, waybar, and I could have firefox for example open on startup using that same exec-once command).
After adding the M it does show the instance signature with the M as a prefix, but it appears to be the previous instance signature as (after removing the M) the udev rule fails with hyprctl unable to find the instance until I manually run the command. However I agree I should've done this before posting to be sure as to what the issue was exactly, so that's a mistake on my part, I apologise.
Offline
However when trying to get hyprland to automatically write the instance signature to a file
When is that run and what sets/updates HYPRLAND_INSTANCE_SIGNATURE how and where?
Offline
but it appears to be the previous instance signature
Do another test: *remove* /tmp/hyprinstancesig and then restart. After logging in, use that hyprctrl command with what's inside the /tmp/hyprinstancesig file (which should be created again).
Also please post the actual Udev rule/command you use to set the screen refresh and/or the hyprctrl command you use to check the instance signature. That way we can see the whole thing in motion, or at least how it's supposed to work vs what is actually happening.
Offline
CChromaKee wrote:However when trying to get hyprland to automatically write the instance signature to a file
When is that run and what sets/updates HYPRLAND_INSTANCE_SIGNATURE how and where?
The instance signature is the first thing (if not one of) the first things hyprland sets when it's run (when run in debug its the first thing that is logged). And the config (which contains the exec commands) is read after hyprland is done initializing, so way after the signature is set.
CChromaKee wrote:but it appears to be the previous instance signature
Do another test: *remove* /tmp/hyprinstancesig and then restart. After logging in, use that hyprctrl command with what's inside the /tmp/hyprinstancesig file (which should be created again).
Also please post the actual Udev rule/command you use to set the screen refresh and/or the hyprctrl command you use to check the instance signature. That way we can see the whole thing in motion, or at least how it's supposed to work vs what is actually happening.
Doing this (deleting the file and restarting, the script works and runs as intended:
Sep 19 12:12:42 ArchCChroma (udev-worker)[1995]: ADP1: Running command "/usr/local/bin/refresh-rate-switcher ac"
Sep 19 12:12:42 ArchCChroma (udev-worker)[1995]: ADP1: Found callout binary: "/usr/local/bin/refresh-rate-switcher".
Sep 19 12:12:42 ArchCChroma (udev-worker)[1995]: ADP1: Starting '/usr/local/bin/refresh-rate-switcher ac'
Sep 19 12:12:42 ArchCChroma (udev-worker)[1995]: Successfully forked off '(spawn)' as PID 2294.
Sep 19 12:12:42 ArchCChroma su[2300]: (to Kee) root on none
Sep 19 12:12:42 ArchCChroma su[2300]: pam_unix(su-l:session): session opened for user Kee(uid=1000) by (uid=0)
Sep 19 12:12:43 ArchCChroma (udev-worker)[1995]: ADP1: '/usr/local/bin/refresh-rate-switcher ac'(out) 'ok'But after a restart without deleting the file:
Sep 19 12:27:30 ArchCChroma (udev-worker)[5854]: ADP1: Running command "/usr/local/bin/refresh-rate-switcher ac"
Sep 19 12:27:30 ArchCChroma (udev-worker)[5854]: ADP1: Found callout binary: "/usr/local/bin/refresh-rate-switcher".
Sep 19 12:27:30 ArchCChroma (udev-worker)[5854]: ADP1: Starting '/usr/local/bin/refresh-rate-switcher ac'
Sep 19 12:27:30 ArchCChroma (udev-worker)[5854]: Successfully forked off '(spawn)' as PID 5885.
Sep 19 12:27:30 ArchCChroma su[5891]: (to Kee) root on none
Sep 19 12:27:30 ArchCChroma su[5891]: pam_unix(su-l:session): session opened for user Kee(uid=1000) by (uid=0)
Sep 19 12:27:31 ArchCChroma (udev-worker)[5854]: ADP1: '/usr/local/bin/refresh-rate-switcher ac'(out) 'Couldn't connect to /run/user/1000/hypr/46174f78b364b6cea669c48880877a8bdcf7802f_1758283920_1829279956/.socket.sock. (4)'Then, after running the command normally:
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: ADP1: Running command "/usr/local/bin/refresh-rate-switcher ac"
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: ADP1: Found callout binary: "/usr/local/bin/refresh-rate-switcher".
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: ADP1: Starting '/usr/local/bin/refresh-rate-switcher ac'
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: Successfully forked off '(spawn)' as PID 6378.
Sep 19 12:28:57 ArchCChroma su[6384]: (to Kee) root on none
Sep 19 12:28:57 ArchCChroma su[6384]: pam_unix(su-l:session): session opened for user Kee(uid=1000) by (uid=0)
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: ADP1: '/usr/local/bin/refresh-rate-switcher ac'(out) 'ok'
Sep 19 12:28:57 ArchCChroma su[6384]: pam_unix(su-l:session): session closed for user Kee
Sep 19 12:28:57 ArchCChroma (udev-worker)[6252]: ADP1: Process '/usr/local/bin/refresh-rate-switcher ac' succeeded.The udev rules:
SUBSYSTEM=="power_supply",ENV{POWER_SUPPLY_ONLINE}=="0",RUN+="/usr/local/bin/refresh-rate-switcher bat"
SUBSYSTEM=="power_supply",ENV{POWER_SUPPLY_ONLINE}=="1",RUN+="/usr/local/bin/refresh-rate-switcher ac"And the script:
#!/bin/bash
# Find the username of the user
USER=$(who | awk '/tty[0-9]+/ {print $1; exit}')
if [[ -z "$USER" ]]; then
exit 1 # No active user found
fi
# Get the user's ID
USER_ID=$(id -u "$USER")
if [[ "$1" == "ac" ]]; then
HYPRCTL_COMMAND="hyprctl keyword monitor '$MONITOR,1920x1080@120.00,auto,1'"
elif [[ "$1" == "bat" ]]; then
HYPRCTL_COMMAND="hyprctl keyword monitor '$MONITOR,1920x1080@60.02,auto,1'"
else
exit 2 # Invalid argument
fi
su - "$USER" -c "export XDG_RUNTIME_DIR=/run/user/$USER_ID HYPRLAND_INSTANCE_SIGNATURE=$(cat /tmp/hyprinstancesig); $HYPRCTL_COMMAND"
exit 0Offline
The instance signature is the first thing (if not one of) the first things hyprland sets when it's run (when run in debug its the first thing that is logged). And the config (which contains the exec commands) is read after hyprland is done initializing, so way after the signature is set.
So if that was true the correct value would be written, no?
And the script:
…su - "$USER" -c "export XDG_RUNTIME_DIR=/run/user/$USER_ID HYPRLAND_INSTANCE_SIGNATURE=$(cat /tmp/hyprinstancesig); $HYPRCTL_COMMAND"
Just import the value from the hyprland process instead?
https://gist.githubusercontent.com/Alad … tfile1.txt
Offline
The instance signature is the first thing (if not one of) the first things hyprland sets when it's run (when run in debug its the first thing that is logged). And the config (which contains the exec commands) is read after hyprland is done initializing, so way after the signature is set.
So if that was true the correct value would be written, no?
And the script:
…su - "$USER" -c "export XDG_RUNTIME_DIR=/run/user/$USER_ID HYPRLAND_INSTANCE_SIGNATURE=$(cat /tmp/hyprinstancesig); $HYPRCTL_COMMAND"Just import the value from the hyprland process instead?
https://gist.githubusercontent.com/Alad … tfile1.txt
Oh my god thank you I had no idea that was even possible.
The new script:
#!/bin/bash
pid=$(pgrep Hyprland)
pid=$(pgrep -P $pid -n)
import_environment() {
(( pid )) && for var; do
IFS='=' read key val < <(grep -Ez "$var" /proc/$pid/environ)
printf -v "$key" %s "$val"
[[ ${!key} ]] && export "$key"
done
}
import_environment USER XDG_RUNTIME_DIR HYPRLAND_INSTANCE_SIGNATURE
if [[ "$1" == "ac" ]]; then
HYPRCTL_COMMAND="hyprctl keyword monitor 'eDP-1,1920x1080@120.00,auto,1'"
elif [[ "$1" == "bat" ]]; then
HYPRCTL_COMMAND="hyprctl keyword monitor 'eDP-1,1920x1080@60.02,auto,1'"
else
exit 2 # Invalid Argument
fi
sudo --preserve-env -u "$USER" bash -c "$HYPRCTL_COMMAND"
exit 0From what I understand it pulls the pid of the newest child process under hyprland and gets the variables from there, which (for some reason) ended up being necessary as the Hyprland process itself doesn't store the signature. It now works without issue.
Thank you so much!
Offline
as the Hyprland process itself doesn't store the signature
What would kinda explain the failure of the other approach - if you're under the impression this being documented differently you might want to file a bug against Hyprland.
Offline