diff --git a/sway/config b/sway/config index 56e40b0..23b97d5 100644 --- a/sway/config +++ b/sway/config @@ -33,9 +33,7 @@ set $printscreen grim -g "$(slurp -b '#00000044' -c '#FFAD66' -w 2)" -t png - | output * bg /home/larssonmartin/.config/wallpapers/catppuccin/cloudsnight.jpg fill output DP-1 { mode 3840x2160@240.016Hz - scale 1.75 - # mode 1920x1080@480.001Hz - # scale 1.0 + scale 1.5 } input "type:pointer" { @@ -46,6 +44,9 @@ input "type:pointer" { # Enables inhibit_idle when playing audio exec sway-audio-idle-inhibit +# Automatically switch to the highst resolution w/ the highest refresh rate +exec --no-startup-id ~/.config/sway/resolution_updater.sh + exec_always --no-startup-id ~/.config/sway/sway_unfocused_effects.py # https://github.com/ErikReider/SwayAudioIdleInhibit diff --git a/sway/resolution_updater.sh b/sway/resolution_updater.sh new file mode 100755 index 0000000..18f861a --- /dev/null +++ b/sway/resolution_updater.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +LOCK_FILE="/tmp/resolution_updater.lock" + +# Remove any stale lock file at startup +[ -f "$LOCK_FILE" ] && rm -f "$LOCK_FILE" + +remove_lock() { + if [ -f "$LOCK_FILE" ]; then + rm -f "$LOCK_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') - Lock file removed" + fi +} + +trap remove_lock EXIT INT TERM + +update_display() { + if [ -f "$LOCK_FILE" ]; then + # Check lock file age + lock_age=$(($(date +%s) - $(stat -c %Y "$LOCK_FILE"))) + if [ $lock_age -gt 10 ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') - Stale lock file detected (${lock_age}s old), removing" + remove_lock + else + echo "$(date '+%Y-%m-%d %H:%M:%S') - Lock file exists (${lock_age}s old), skipping update" + return + fi + fi + + # Process each output and determine if changes are needed + local changes_needed=false + + local output_data=$(swaymsg -t get_outputs -r) + + # Process each output + echo "$output_data" | jq -r '.[] | + { + name: .name, + current_mode: { + width: .current_mode.width, + height: .current_mode.height, + refresh: .current_mode.refresh + }, + current_scale: .scale, + modes: .modes + } | + .best_mode = (.modes | map({width, height, refresh, pixels: (.width * .height)}) | sort_by(-.pixels, -.refresh) | first) | + "\(.name)|\(.current_mode.width)|\(.current_mode.height)|\(.current_mode.refresh)|\(.current_scale)|\(.best_mode.width)|\(.best_mode.height)|\(.best_mode.refresh)" + ' | while IFS="|" read -r name curr_width curr_height curr_refresh curr_scale best_width best_height best_refresh; do + # Determine target scale based on best resolution + target_scale=1 + if [ "$best_height" -ge 2160 ]; then + target_scale=1.5 + fi + + # Convert refresh rates to integers for comparison + curr_refresh_int=$(echo "$curr_refresh/1000" | bc) + best_refresh_int=$(echo "$best_refresh/1000" | bc) + + # Check if changes needed for this display + if [ "$curr_width" -ne "$best_width" ] || + [ "$curr_height" -ne "$best_height" ] || + [ "$curr_refresh_int" -ne "$best_refresh_int" ]; then + + touch "$LOCK_FILE" + changes_needed=true + + echo "$(date '+%Y-%m-%d %H:%M:%S') - Changing $name from ${curr_width}x${curr_height}@${curr_refresh_int}Hz (scale ${curr_scale}) to ${best_width}x${best_height}@${best_refresh_int}Hz (scale ${target_scale})" + + # Apply the resolution change + swaymsg output "$name" mode "${best_width}x${best_height}@${best_refresh_int}Hz" + + # Apply scaling + swaymsg output "$name" scale $target_scale + else + echo "$(date '+%Y-%m-%d %H:%M:%S') - No changes needed for $name - already at optimal settings" + fi + done + + # Remove lock file after a delay if changes were made + if $changes_needed; then + # Use a function for lock removal with delay + (sleep 3 && remove_lock) & + fi +} + +swaymsg -m -t subscribe '["output"]' | jq --unbuffered -r '.change' | while read -r change; do + if [[ "$change" == "unspecified" || "$change" == "reconnect" || "$change" == "mode" ]]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') - Display change detected: $change" + sleep 1 + update_display + fi +done