fixed lid handling with lidstate file

This commit is contained in:
2026-03-14 15:01:31 +01:00
parent e8ef6712af
commit 13bc86f713
6 changed files with 104 additions and 42 deletions

1
hypr/lid_monitor.conf Normal file
View File

@@ -0,0 +1 @@
monitor=eDP-1, disable

1
hypr/lid_state.conf Normal file
View File

@@ -0,0 +1 @@
monitor=eDP-1, disable

View File

@@ -14,4 +14,4 @@ exec-once = uwsm app -- hyprpaper
# exec-once = uwsm app -- /usr/lib/xdg-desktop-portal-hyprland # exec-once = uwsm app -- /usr/lib/xdg-desktop-portal-hyprland
exec-once = wl-paste --type text --watch cliphist store # Stores only text data exec-once = wl-paste --type text --watch cliphist store # Stores only text data
exec-once = wl-paste --type image --watch cliphist store # Stores only image data exec-once = wl-paste --type image --watch cliphist store # Stores only image data
exec-once = uwsm app -- ~/.config/waybar/fluxo-rs/target/release/fluxo-rs daemon exec-once = uwsm app -- ~/.cargo/bin/fluxo-rs daemon

View File

@@ -1,7 +1,9 @@
# monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 2560x1440@240, 0x-1440, 1 # laptop screen
# monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 2560x1440@90, 0x-1440, 1, bitdepth, 10
monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 1920x1080@240, 0x-1080, 1
# monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 1920x1080@60, 0x-1080, 1
# monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 1280x720@240, 0x-720, 1
monitor = eDP-1, 1920x1080@60, 0x0, 1 monitor = eDP-1, 1920x1080@60, 0x0, 1
# samsung home monitor
monitor = desc:Samsung Electric Company LC27G7xT H4ZRA00734, 2560x1440@90, 0x-1440, 1
# lid_state fallback
source = ~/.config/hypr/lid_state.conf

View File

@@ -1,6 +1,21 @@
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules # See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
# ==========================================
# VARIABLES
# ==========================================
# Dialogs and utility apps that should float in the center
$dialog_titles = ^(Open Form|Open File|Select a File|Choose a file|Open Workspace|Choose Directory|Save As|Save File|branchdialog|pinentry-gtk-2|Confirm to replace files|File Operation Progress)$
$dialog_classes = ^(pavucontrol|blueman-manager|nm-connection-editor|org.pulseaudio.pavucontrol)$
# App classes
$steam = ^(steam)$
$gamescope = ^(gamescope)$
# ==========================================
# GENERAL & FIXES
# ==========================================
# Ignore maximize requests from apps. You'll probably like this. # Ignore maximize requests from apps. You'll probably like this.
# windowrule = suppress_event maximize, match:class .* # windowrule = suppress_event maximize, match:class .*
@@ -9,45 +24,54 @@
windowrule = no_blur 1, match:class ^$, match:title ^$ windowrule = no_blur 1, match:class ^$, match:title ^$
# games for tearing add the immediate rule # ==========================================
# FLOATING & CENTERED DIALOGS
# ==========================================
# Make them float
windowrule = float 1, match:title $dialog_titles
windowrule = float 1, match:class $dialog_classes
# Float Windows # Set to 800x600
windowrule = float 1, match:title ^(Open File|Select a File|Select Folder|Choose a file|Open Form|Open Workspace|Choose Directory|Save As|Save File|branchdialog|pinentry-gtk-2|Confirm to replace files|File Operation Progress)$ windowrule = size 800 600, match:title $dialog_titles
windowrule = float 1, match:class ^(pavucontrol|blueman-manager|nm-connection-editor)$ windowrule = size 800 600, match:class $dialog_classes
# Center and Resize Windows # Center them on the screen
windowrule = size 800 600, match:title ^(Open Form|Open File|Select a File|Choose a file|Open Workspace|Choose Directory|Save As|Save File|branchdialog|pinentry-gtk-2|Confirm to replace files|File Operation Progress)$ windowrule = center 1, match:title $dialog_titles
windowrule = size 800 600, match:class ^(pavucontrol|blueman-manager|nm-connection-editor)$ windowrule = center 1, match:class $dialog_classes
windowrule = center 1, match:title ^(Open Form|Open File|Select a File|Choose a file|Open Workspace|Choose Directory|Save As|Save File|branchdialog|pinentry-gtk-2|Confirm to replace files|File Operation Progress)$ # Disable blur
windowrule = center 1, match:class ^(pavucontrol|blueman-manager|nm-connection-editor)$ windowrule = no_blur 1, match:title $dialog_titles
windowrule = no_blur 1, match:class $dialog_classes
windowrule = no_blur 1, match:title ^(Open Form|Open File|Select a File|Choose a file|Open Workspace|Choose Directory|Save As|Save File|branchdialog|pinentry-gtk-2|Confirm to replace files|File Operation Progress)$
windowrule = no_blur 1, match:class ^(pavucontrol|blueman-manager|nm-connection-editor)$
# Workspace Rules # ==========================================
# WORKSPACE ASSIGNMENTS
# ==========================================
# Normal Workspaces
# windowrule = workspace 1, match:class ^(firefox)$ # windowrule = workspace 1, match:class ^(firefox)$
# windowrule = workspace 2, match:class ^(kitty)$ # windowrule = workspace 2, match:class ^(kitty)$
# windowrule = workspace 3, match:class ^(Code)$ # windowrule = workspace 3, match:class ^(Code)$
windowrule = workspace 1, match:class $gamescope
# Special Workspaces
windowrule = workspace special:virtual, match:class ^(Spotify|spotify)$ windowrule = workspace special:virtual, match:class ^(Spotify|spotify)$
windowrule = workspace special:discord, match:class ^(discord|vesktop)$ windowrule = workspace special:discord, match:class ^(discord|vesktop)$
# steam rules
windowrule = workspace 3 silent, match:class ^(steam)$, match:title ^(Steam)$ # ==========================================
windowrule = workspace 4, match:class ^(gamescope)$ # APP-SPECIFIC RULES: STEAM & GAMING
# ==========================================
# windowrule = workspace 3 silent, match:class $steam, match:title ^(Steam)$
# fixed sizes for different windows # Fixed sizes for specific Steam windows
windowrule = size 400 800, match:title ^(Friends List)$, match:class ^(steam)$ windowrule = size 400 800, match:title ^(Friends List)$, match:class $steam
windowrule = size 1000 800, match:title ^(Steam Settings)$, match:class ^(steam)$ windowrule = size 1000 800, match:title ^(Steam Settings)$, match:class $steam
windowrule = size 1000 800, match:title ^(Add Non-Steam Game)$, match:class ^(steam)$ windowrule = size 1000 800, match:title ^(Add Non-Steam Game)$, match:class $steam
# float windows that arent the main steam window # Float and disable blur for Steam windows that aren't the main window
windowrule = float 1, match:class ^(steam)$, match:title negative:^(Steam)$ windowrule = float 1, match:class $steam, match:title negative:^(Steam)$
windowrule = no_blur 1, match:class ^(steam)$, match:title negative:^(Steam)$ windowrule = no_blur 1, match:class $steam, match:title negative:^(Steam)$
# windowrule = center 1, match:class ^(steam)$, match:title negative:^(Steam)$ # windowrule = center 1, match:class $steam, match:title negative:^(Steam)$
# allow tearing for games started with gamescope # Allow tearing for games started with Gamescope
windowrule = immediate 1, match:class ^(gamescope)$ windowrule = immediate 1, match:class $gamescope

View File

@@ -1,19 +1,53 @@
#!/bin/bash #!/bin/bash
# ~/.config/hypr/scripts/lid_handler.sh # ~/.config/hypr/scripts/lid_handler.sh
# The file that tells Hyprland to keep the lid off during reloads
LID_STATE_FILE="$HOME/.config/hypr/lid_state.conf"
restart_ui() {
# Spawn in background and detach
systemctl restart --user waybar hyprpaper
}
if [[ "$1" == "close" ]]; then if [[ "$1" == "close" ]]; then
# Lid closed: disable laptop screen if any DP-* monitor is present # Check if ANY external monitor is connected and active
# Using 'all' to detect monitors even if they are currently disabled if hyprctl monitors all | grep -qE "Monitor (DP|HDMI|Type-C)-"; then
if hyprctl monitors all | grep -q "Monitor DP-"; then
hyprctl keyword monitor "eDP-1, disable" # Disable laptop display
# Enable all detected DP-* monitors # Prevent laptop screen from turning on during manual config reloads
for monitor in $(hyprctl monitors all | grep "Monitor DP-" | awk '{print $2}'); do echo "monitor=eDP-1, disable" > "$LID_STATE_FILE"
hyprctl keyword monitor "$monitor, enable"
# Extract the CURRENT live settings of all external monitors using jq
# This grabs the active resolution, refresh rate, position, and scale.
LIVE_MONITORS=$(hyprctl -j monitors | jq -c '.[] | select(.name != "eDP-1")')
# 3. Disable the laptop screen
hyprctl keyword monitor "eDP-1, disable"
# 4. Re-apply the live settings to external monitors so they don't reset
echo "$LIVE_MONITORS" | while read -r mon_json; do
NAME=$(echo "$mon_json" | jq -r '.name')
WIDTH=$(echo "$mon_json" | jq -r '.width')
HEIGHT=$(echo "$mon_json" | jq -r '.height')
REFRESH=$(echo "$mon_json" | jq -r '.refreshRate')
X=$(echo "$mon_json" | jq -r '.x')
Y=$(echo "$mon_json" | jq -r '.y')
SCALE=$(echo "$mon_json" | jq -r '.scale')
# Formats it exactly as Hyprland expects: DP-1, 1920x1080@240, 0x0, 1
hyprctl keyword monitor "$NAME, ${WIDTH}x${HEIGHT}@${REFRESH}, ${X}x${Y}, $SCALE"
done done
systemd-run --user --on-active=5s systemctl --user restart waybar.service hyprpaper.service
# restart ui
restart_ui
fi fi
elif [[ "$1" == "open" ]]; then elif [[ "$1" == "open" ]]; then
# Lid opened: re-enable laptop screen # Clear the override file so the laptop screen is allowed to turn on again
hyprctl keyword monitor "eDP-1, enable" echo "" > "$LID_STATE_FILE"
# Let Hyprland reload itself.
# This automatically re-enables eDP-1 based on your hardcoded hyprland.conf!
hyprctl reload
restart_ui
fi fi