#!/bin/sh # Triggered by n # as defined in [org/gnome/settings-daemon/plugins/media-keys] # in ~/.config/gnome-settings/key-bindings.ini # # Night Light control: # # - n => "when" toggle # + "Force" the screen to be warm right now! # (Turns Night Light on if it was off, and keeps it on all day) # + "Un-force" the Night Light into the local evening schedule # - n => "if" toggle # Plain on/off switch for the Night Light feature # - Left => Make the screen cooler # - Right => Make the screen warmer, and "force" warmness # # # State machine: # # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | | "IF" toggle | "WHEN" toggle | "make COOLER" | "make WARMER" | # | Current STATE | n | n | Left | Right | # | | | | | | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | DISABLED | ENABLE | enabled | still disabled | enabled | # | + scheduled | + still scheduled | + FORCED on | + still scheduled | + FORCED on | # | => no tint | => no or set tint | => set tint | => still no tint | => set tint | # | | based on time N? | | N! | *1 | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | DISABLED | ENABLE | enabled | still disabled | enabled | # | + forced on | + still forced | + still FORCED on | + still forced | + still FORCED on | # | => no tint | => set tint | => set tint | => still no tint | => set tint | # | | | | N! | *1 | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | enabled | DISABLE | still enabled | still enabled | still enabled | # | + SCHEDULED (day) | + still scheduled | + FORCED on | + still scheduled | + FORCED on | # | => no tint yet | => still no tint | => set tint | => still no tint | => set tint | # | | N! | | N! | *1 | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | enabled | DISABLE | still enabled | still enabled | still enabled | # | + SCHEDULED (ramping) | + still scheduled | + FORCED on | + still scheduled | + FORCED on | # | => some tint already | => no tint | => set tint | => no change in tint | => set tint | # | | | | N! | | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | enabled | DISABLE | still enabled | still enabled | still enabled | # | + SCHEDULED (night) | + still scheduled | + FORCED on | + still scheduled | + FORCED on | # | => set tint | => no tint | => set tint | => LESS tint | => MORE tint | # | | | N! | *2 N? | N? | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # | enabled | DISABLE | still enabled | still enabled | still enabled | # | + FORCED on | + still forced on | + back to SCHEDULED | + still forced on | + still forced on | # | => set tint | => no tint | => no or set tint | => LESS tint | => MORE tint | # | | | based on time N? | *2 N? | N? | # +-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+ # Legend: # - N! => A notification is shown for sure because there is no visible change on the screen # - N? => A notification is shown if there was no visible change on the screen # - *1 => The temperature is snapped to 2200K to ensure a visible effect # - *2 => The tint is turned off entirely when stepping over the maximum temperature # # Notes: # - The main state property or state change is shown in CAPS # - Steps range from 1200K (warmest) to 4700K (coolest), # which is a bit more than the 1700K to 4700K in `gnome-control-center` # - If the range is already exhausted, so that the tint does not change, a notification is shown # - A 03:00 timer re-enables the Night Light feature and puts it back on the automatic schedule # with the `$_DEFAULT_TEMPERATURE` set # set -eu notify() { ID_FILE="${XDG_RUNTIME_DIR}/night-light-notification-id" _id=$(cat "$ID_FILE" 2>/dev/null || true) if [ -n "$_id" ]; then notify-send -p -t 5000 --replace-id="$_id" "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE" else notify-send -p -t 5000 "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE" fi } Schema=org.gnome.settings-daemon.plugins.color active_before=$(gdbus call --session \ --dest org.gnome.SettingsDaemon.Color \ --object-path /org/gnome/SettingsDaemon/Color \ --method org.freedesktop.DBus.Properties.Get \ org.gnome.SettingsDaemon.Color NightLightActive) applied=$(gdbus call --session \ --dest org.gnome.SettingsDaemon.Color \ --object-path /org/gnome/SettingsDaemon/Color \ --method org.freedesktop.DBus.Properties.Get \ org.gnome.SettingsDaemon.Color Temperature \ | sed -E 's/.*uint32 ([0-9]+).*/\1/') automatic=$(gsettings get $Schema night-light-schedule-automatic) enabled=$(gsettings get $Schema night-light-enabled) target=$(gsettings get $Schema night-light-temperature | awk '{print $2}') if [ "$automatic" = "true" ] || [ "$enabled" = "false" ]; then # Force "Night Light" enabled, enabling it if needed gsettings set $Schema night-light-enabled true gsettings set $Schema night-light-schedule-automatic false gsettings set $Schema night-light-schedule-from 0.0 gsettings set $Schema night-light-schedule-to 24.0 if [ "$active_before" = "(,)" ] && [ "$automatic" = "true" ] \ && [ $((applied - target)) -le 300 ]; then notify "is now forced to stay on and no longer on an automatic schedule" fi else # Back to the live location's schedule gsettings set $Schema night-light-schedule-automatic true gsettings set $Schema night-light-schedule-from 18.0 gsettings set $Schema night-light-schedule-to 6.0 if [ "$active_before" = "(,)" ]; then # Give the settings daemon a moment to recompute "NightLightActive" sleep 0.1 active_after=$(gdbus call --session \ --dest org.gnome.SettingsDaemon.Color \ --object-path /org/gnome/SettingsDaemon/Color \ --method org.freedesktop.DBus.Properties.Get \ org.gnome.SettingsDaemon.Color NightLightActive) if [ "$active_after" = "(,)" ]; then notify "is still on because of an automatic schedule" fi fi fi