From 3b2ccc84170fb438faf6af4d4b61c001b7408eee Mon Sep 17 00:00:00 2001 From: Thomas Syms Date: Tue, 19 Aug 2025 09:23:21 -0300 Subject: [PATCH] Updated Configuration --- flake.lock | 49 +- flake.nix | 5 +- .../panotaka/common/optional/browsers/zen.nix | 2 +- .../optional/desktops/gnome/default.nix | 19 + .../desktops/gnome/zenbook-screen.nix | 605 +++++++++++++----- hosts/common/optional/system76-scheduler.nix | 3 + hosts/common/optional/thermal-management.nix | 102 +-- hosts/nixos/Bellerophon/default.nix | 1 + .../Bellerophon/hardware-configuration.nix | 11 +- pkgs/common/gnome-mosaic/package.nix | 0 10 files changed, 575 insertions(+), 222 deletions(-) create mode 100644 hosts/common/optional/system76-scheduler.nix create mode 100644 pkgs/common/gnome-mosaic/package.nix diff --git a/flake.lock b/flake.lock index 92cd179..e7c8115 100644 --- a/flake.lock +++ b/flake.lock @@ -108,11 +108,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1754932432, - "narHash": "sha256-QKGglSkjG/pX4qaVviJI4KB2azeQ1MDsfGowjcqCXWY=", + "lastModified": 1754965112, + "narHash": "sha256-22HMBoUpOHdjpSrmNqpVZNRA+p4dYpTKN7JDwd/8N3k=", "owner": "cachix", "repo": "devenv", - "rev": "54818026faf56d279f88d56714d97edd2f5b522e", + "rev": "262213d0fbc94e1c5a556ba0d4382f0318a71f78", "type": "github" }, "original": { @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1753140376, - "narHash": "sha256-7lrVrE0jSvZHrxEzvnfHFE/Wkk9DDqb+mYCodI5uuB8=", + "lastModified": 1754971456, + "narHash": "sha256-p04ZnIBGzerSyiY2dNGmookCldhldWAu03y0s3P8CB0=", "owner": "nix-community", "repo": "disko", - "rev": "545aba02960caa78a31bd9a8709a0ad4b6320a5c", + "rev": "8246829f2e675a46919718f9a64b71afe3bfb22d", "type": "github" }, "original": { @@ -370,6 +370,27 @@ "type": "github" } }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "zen-browser", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1754974548, + "narHash": "sha256-XMjUjKD/QRPcqUnmSDczSYdw46SilnG0+wkho654DFM=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "27a26be51ff0162a8f67660239f9407dba68d7c5", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, "nix": { "inputs": { "flake-compat": [ @@ -435,11 +456,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1754878481, - "narHash": "sha256-Yqsya1+kx/R5BAVbSBdsf5F0TryNRf1we2rFVbT7cp8=", + "lastModified": 1754964312, + "narHash": "sha256-6H7a1ZB6NKYUTYfw4IjmiPI0n1AaLJmX7FBSksdLbOA=", "owner": "nix-community", "repo": "nix4vscode", - "rev": "1341a783616a03f4999f14b2ed539787ba9c0bee", + "rev": "82694090541069224a4645899c06905fbb367c3c", "type": "github" }, "original": { @@ -781,19 +802,17 @@ }, "zen-browser": { "inputs": { - "home-manager": [ - "home-manager" - ], + "home-manager": "home-manager_2", "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1754887481, - "narHash": "sha256-tVUL4zteseaPi1E9pymhJGYgnJZjGzHLzBUnP1CQbcU=", + "lastModified": 1754972926, + "narHash": "sha256-2CEQSI3o7XWMc/DOdeNf6gTKjgGf8hHS0TB0HYPmSmA=", "owner": "0xc000022070", "repo": "zen-browser-flake", - "rev": "72e1881d340fec7e418207ac292118179c89eea6", + "rev": "508a7c0c5c993d237773be89f5ca91ff8c997b44", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 9b29164..914703c 100644 --- a/flake.nix +++ b/flake.nix @@ -169,10 +169,7 @@ # zen-browser = { url = "github:0xc000022070/zen-browser-flake"; - inputs = { - home-manager.follows = "home-manager"; - nixpkgs.follows = "nixpkgs"; - }; + inputs.nixpkgs.follows = "nixpkgs"; }; # diff --git a/home/panotaka/common/optional/browsers/zen.nix b/home/panotaka/common/optional/browsers/zen.nix index e79c57f..6c8d54b 100644 --- a/home/panotaka/common/optional/browsers/zen.nix +++ b/home/panotaka/common/optional/browsers/zen.nix @@ -5,7 +5,7 @@ }: { # home.nix imports = [ - inputs.zen-browser.homeModules.beta + inputs.zen-browser.homeModules.default # inputs.zen-browser.homeModules.twilight # inputs.zen-browser.homeModules.twilight-official ]; diff --git a/home/panotaka/common/optional/desktops/gnome/default.nix b/home/panotaka/common/optional/desktops/gnome/default.nix index 21d39c2..0f15e88 100644 --- a/home/panotaka/common/optional/desktops/gnome/default.nix +++ b/home/panotaka/common/optional/desktops/gnome/default.nix @@ -23,6 +23,7 @@ gnomeExtensions.caffeine gnomeExtensions.clipboard-indicator gnomeExtensions.launch-new-instance + gnomeExtensions.pop-shell ]; # GNOME desktop settings via dconf @@ -48,6 +49,7 @@ "caffeine@patapon.info" "clipboard-indicator@tudmotu.com" "launch-new-instance@gnome-shell-extensions.gcampax.github.com" + "pop-shell@system76.com" ]; }; @@ -67,5 +69,22 @@ "org/gnome/mutter" = { experimental-features = ["scale-monitor-framebuffer" "variable-refresh-rate"]; }; + + # Unset conflicting Pop Shell keybindings to avoid conflicts with screen lock + "org/gnome/shell/extensions/pop-shell" = { + # Unset the HJKL directional bindings + tile-up = []; # Default was ['k'] + tile-down = []; # Default was ['j'] + tile-left = []; # Default was ['h'] + tile-right = []; # Default was ['l'] + + # Unset the launcher binding that also uses Meta+L + activate-launcher = []; # Default was ['slash', 'l'] + }; + + # Ensure the standard GNOME screen lock shortcut is active + "org/gnome/settings-daemon/plugins/media-keys" = { + screensaver = ["l"]; + }; }; } diff --git a/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix b/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix index 2934509..99f70dd 100644 --- a/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix +++ b/home/panotaka/common/optional/desktops/gnome/zenbook-screen.nix @@ -1,141 +1,414 @@ {pkgs, ...}: let - # Main duo script for display management + # Configuration constants + duoConfig = { + # For 3K model (adjust as needed) + prefered_resolution = "2880x1800@120.000"; + ui_scale = 1.5; + y_offset = 1200; # height of resolution / ui_scale (1800/1.5 = 1200) + backlight = "card1-eDP-2-backlight"; + + # USB ID for ZenBook Duo keyboard dock detection + dock_usb_id = "0b05:1b2c"; + + # Display device identifiers + primary_display = "eDP-1"; + secondary_display = "eDP-2"; + + # Touchscreen/tablet device IDs + primary_touch_id = "04f3:425b"; + secondary_touch_id = "04f3:425a"; + + # For 1080p model (uncomment if needed) + # prefered_resolution = "1920x1200@60.003"; + # ui_scale = 1; + # y_offset = 1200; + }; + + # Core display management script with separated concerns duoScript = pkgs.writeShellScript "duo" '' - #!/usr/bin/env bash + #!/usr/bin/env bash + set -euo pipefail - # Configuration for 3K model (adjust as needed) - prefered_resolution="2880x1800@120.000" - ui_scale=1.5 - # y offset = height of resolution / ui_scale (1800/1.5 = 1200) - y_offset=1200 - backlight=card1-eDP-2-backlight + # Import configuration + PREFERRED_RESOLUTION="${duoConfig.prefered_resolution}" + UI_SCALE="${toString duoConfig.ui_scale}" + Y_OFFSET="${toString duoConfig.y_offset}" + BACKLIGHT="${duoConfig.backlight}" + DOCK_USB_ID="${duoConfig.dock_usb_id}" + PRIMARY_DISPLAY="${duoConfig.primary_display}" + SECONDARY_DISPLAY="${duoConfig.secondary_display}" + PRIMARY_TOUCH_ID="${duoConfig.primary_touch_id}" + SECONDARY_TOUCH_ID="${duoConfig.secondary_touch_id}" - # Uncomment for 1080p model - #prefered_resolution="1920x1200@60.003" - #ui_scale=1 - #y_offset=1200 + # Logging function + log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2 + } - function suenv { - sudo /usr/bin/env "$@" - } + # Error handling + handle_error() { + log "ERROR: $1" + exit 1 + } - function external-display-connected { - [ "$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep display-name|grep -v 'Built-in display'|wc -l)" != "0" ] - } + # Utility functions + suenv() { + sudo /usr/bin/env "$@" + } - function active-external-displays { - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep -vE 'eDP-[12]'|sed -nE 's/Monitor \[ (.+) \] ON/\1/p' - } + retry_command() { + local retries=$1 + shift + local count=0 + until "$@"; do + count=$((count + 1)) + if [ $count -ge $retries ]; then + return 1 + fi + log "Command failed, retrying ($count/$retries)..." + sleep 1 + done + } - case "$1" in - watch-displays) - while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/ ; do - if ! external-display-connected; then - "$0" normal + # ===== DETECTION LOGIC ===== + + # Check if external displays are connected + has_external_displays() { + local external_count + external_count=$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list 2>/dev/null | \ + grep "display-name" | grep -v "Built-in display" | wc -l) + [ "$external_count" -gt 0 ] + } + + # Get list of active external displays + get_active_external_displays() { + ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list 2>/dev/null | \ + grep -vE 'eDP-[12]' | \ + sed -nE 's/Monitor \[ (.+) \] ON/\1/p' + } + + # Check if dock is connected (determines single vs dual screen mode) + is_dock_connected() { + ${pkgs.usbutils}/bin/lsusb 2>/dev/null | grep -q "$DOCK_USB_ID" + } + + # Get current internal display status + get_internal_display_status() { + local monitors_on + monitors_on=$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list 2>/dev/null | \ + grep -E "Monitor \\[ eDP-. \\] ON" || true) + + local count + count=$(echo "$monitors_on" | grep -v -E "^$" | wc -l) + + case "$count" in + 0) echo "none" ;; + 1) + if echo "$monitors_on" | grep -q "Monitor \[ $PRIMARY_DISPLAY \] ON"; then + echo "top" + elif echo "$monitors_on" | grep -q "Monitor \[ $SECONDARY_DISPLAY \] ON"; then + echo "bottom" + else + echo "unknown" + fi + ;; + 2) echo "both" ;; + *) echo "unknown" ;; + esac + } + + # Get device orientation from accelerometer + get_orientation() { + # This would typically come from iio-sensor-proxy + # For now, return normal as default + echo "normal" + } + + # Determine optimal display configuration based on current state + determine_optimal_config() { + local has_external dock_connected orientation current_status + + has_external=$(has_external_displays && echo "true" || echo "false") + dock_connected=$(is_dock_connected && echo "true" || echo "false") + orientation=$(get_orientation) + current_status=$(get_internal_display_status) + + log "State: external=$has_external, dock=$dock_connected, orientation=$orientation, current=$current_status" + + # Determine internal display configuration based on orientation and dock status + # External displays don't affect internal display arrangement + case "$orientation" in + "normal") + if [ "$dock_connected" = "true" ]; then + echo "top-only" + else + echo "both-stacked" + fi + ;; + "left-up") + echo "both-left" + ;; + "right-up") + echo "both-right" + ;; + "bottom-up") + echo "bottom-only" + ;; + *) + echo "both-stacked" # Safe default + ;; + esac + } + + # ===== MONITOR CONFIGURATION LOGIC ===== + + # Apply display configuration with error handling + apply_display_config() { + local config_name="$1" + log "Applying display configuration: $config_name" + + case "$config_name" in + "top-only") + retry_command 3 ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM "$PRIMARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -x 0 -y 0 + ;; + "bottom-only") + retry_command 3 ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM "$SECONDARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -x 0 -y 0 + ;; + "both-stacked") + retry_command 3 ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM "$PRIMARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -x 0 -y 0 \ + -LM "$SECONDARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -x 0 -y "$Y_OFFSET" + ;; + "both-left") + retry_command 3 ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LpM "$SECONDARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -t left -x 0 -y 0 \ + -LM "$PRIMARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -t left -x "$Y_OFFSET" -y 0 + ;; + "both-right") + retry_command 3 ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ + -LM "$PRIMARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -t right -x 0 -y 0 \ + -LpM "$SECONDARY_DISPLAY" -m "$PREFERRED_RESOLUTION" -s "$UI_SCALE" -t right -x "$Y_OFFSET" -y 0 + ;; + *) + handle_error "Unknown display configuration: $config_name" + ;; + esac + + # Update tablet/touchscreen mappings after successful display config + update_tablet_mappings "$config_name" + } + + # Update tablet and touchscreen mappings based on display config + update_tablet_mappings() { + local config="$1" + log "Updating tablet mappings for configuration: $config" + + # Always map primary touch to primary display and secondary to secondary + for device_type in tablets touchscreens; do + ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/$device_type/$PRIMARY_TOUCH_ID/output" \ + "['SDC', '0x419d', '0x00000000', '$PRIMARY_DISPLAY']" 2>/dev/null || true + ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/$device_type/$SECONDARY_TOUCH_ID/output" \ + "['SDC', '0x419d', '0x00000000', '$SECONDARY_DISPLAY']" 2>/dev/null || true + done + } + + # ===== EVENT HANDLING & WATCHERS ===== + + # Handle display change events + handle_display_change() { + log "Display change detected" + sleep 1 # Allow hardware to stabilize + + local optimal_config + optimal_config=$(determine_optimal_config) + apply_display_config "$optimal_config" + } + + # Handle orientation change events + handle_orientation_change() { + local new_orientation="$1" + log "Orientation changed to: $new_orientation" + + # Always reconfigure internal displays when orientation changes + # External displays don't affect the need to maintain proper internal layout + local optimal_config + optimal_config=$(determine_optimal_config) + apply_display_config "$optimal_config" + } + + # Watch for USB device changes (dock connect/disconnect) + watch_usb_changes() { + log "Starting USB device watcher" + while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/ 2>/dev/null; do + handle_display_change + done + } + + # Watch for orientation changes + watch_orientation_changes() { + log "Starting orientation watcher" + ${pkgs.iio-sensor-proxy}/bin/monitor-sensor --accel 2>/dev/null | \ + ${pkgs.coreutils}/bin/stdbuf -oL grep "orientation" | \ + ${pkgs.coreutils}/bin/stdbuf -oL cut -d: -f2 | \ + ${pkgs.coreutils}/bin/stdbuf -oL sed 's/[ )]//g' | \ + while read -r orientation; do + handle_orientation_change "$orientation" + done + } + + # ===== BACKLIGHT MANAGEMENT ===== + + # Sync backlight between displays + sync_backlight() { + if [ -r "/sys/class/backlight/intel_backlight/brightness" ] && [ -w "/sys/class/backlight/$BACKLIGHT/brightness" ]; then + cat "/sys/class/backlight/intel_backlight/brightness" | \ + suenv tee "/sys/class/backlight/$BACKLIGHT/brightness" >/dev/null fi - done - ;; - set-displays) - sleep 1 - if ! external-display-connected; then - "$0" normal - fi - ;; - normal|bottom-up) - if ${pkgs.usbutils}/bin/lsusb|grep 0b05:1b2c ; then - "$0" top - else - "$0" both - fi - ;; - top) - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ - -LpM eDP-1 -m $prefered_resolution -s $ui_scale -x 0 -y 0 - ;; - both) - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ - -LpM eDP-1 -m $prefered_resolution -s $ui_scale -x 0 -y 0 \ - -LM eDP-2 -m $prefered_resolution -s $ui_scale -x 0 -y $y_offset - ;; - bottom) - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ - -LpM eDP-2 -m $prefered_resolution -s $ui_scale -x 0 -y 0 - ;; - left-up) - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ - -LpM eDP-2 -m $prefered_resolution -s $ui_scale -t left -x 0 -y 0 \ - -LM eDP-1 -m $prefered_resolution -s $ui_scale -t left -x $y_offset -y 0 - ;; - right-up) - ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config set \ - -LM eDP-1 -m $prefered_resolution -s $ui_scale -t right -x 0 -y 0 \ - -LpM eDP-2 -m $prefered_resolution -s $ui_scale -t right -x $y_offset -y 0 - ;; - status-internal) - internal_monitors="$(${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list|grep -E "Monitor \\[ eDP-. \\] ON")" - case "$(echo "$internal_monitors"|grep -v -E "^$"|wc -l)" in - 0) echo "none" ;; - 1) case "$(echo "$internal_monitors"|grep ON)" in - "Monitor [ eDP-1 ] ON") echo top ;; - "Monitor [ eDP-2 ] ON") echo bottom ;; - esac ;; - 2) echo "both" ;; + } + + # Watch backlight changes + watch_backlight() { + log "Starting backlight watcher" + sync_backlight # Initial sync + while ${pkgs.inotify-tools}/bin/inotifywait -e modify "/sys/class/backlight/intel_backlight/brightness" 2>/dev/null; do + sync_backlight + done + } + + # ===== MAIN COMMAND INTERFACE ===== + + case "''${1:-}" in + # Automatic configuration + "auto"|"configure") + optimal_config=$(determine_optimal_config) + apply_display_config "$optimal_config" + ;; + + # Manual display configurations + "top") + apply_display_config "top-only" + ;; + "bottom") + apply_display_config "bottom-only" + ;; + "both"|"normal") + apply_display_config "both-stacked" + ;; + "left-up") + apply_display_config "both-left" + ;; + "right-up") + apply_display_config "both-right" + ;; + + # Toggle between configurations + "toggle") + current_status=$(get_internal_display_status) + case "$current_status" in + "both") apply_display_config "top-only" ;; + "top"|"bottom") apply_display_config "both-stacked" ;; + *) apply_display_config "both-stacked" ;; + esac + ;; + + # Status reporting + "status") + echo "Internal: $(get_internal_display_status)" + if has_external_displays; then + echo "External: $(get_active_external_displays | tr '\n' '+')" + fi + echo "Dock: $(is_dock_connected && echo "connected" || echo "disconnected")" + ;; + + # Event watchers + "watch-displays") + watch_usb_changes + ;; + "watch-orientation") + watch_orientation_changes + ;; + "watch-backlight") + watch_backlight + ;; + + # Utility functions + "sync-backlight") + sync_backlight + ;; + "set-tablet-mapping") + update_tablet_mappings "both-stacked" + ;; + "toggle-bottom-touch") + path="/org/gnome/desktop/peripherals/touchscreens/$SECONDARY_TOUCH_ID/output" + if [ -z "$(${pkgs.dconf}/bin/dconf read "$path" 2>/dev/null || true)" ]; then + ${pkgs.dconf}/bin/dconf write "$path" "['SDC', '0x419d', '0x00000000', '$SECONDARY_DISPLAY']" + else + ${pkgs.dconf}/bin/dconf reset "$path" + fi + ;; + "bat-limit") + echo "''${2:-80}" | suenv tee /sys/class/power_supply/BAT0/charge_control_end_threshold + ;; + "set-kb-backlight") + suenv ${zenbook-kb-backlight}/bin/zenbook-kb-backlight "''${2:-1}" + ;; + + # Deprecated aliases for backward compatibility + "set-displays") + log "DEPRECATED: Use 'auto' instead of 'set-displays'" + "$0" auto + ;; + "bottom-up") + log "DEPRECATED: Use specific orientation commands" + apply_display_config "bottom-only" + ;; + "status-internal") + get_internal_display_status + ;; + + # Help + "help"|"-h"|"--help"|"") + cat << EOF + ZenBook Duo Display Management Tool + + USAGE: duo [options] + + AUTOMATIC CONFIGURATION: + auto, configure Automatically configure displays based on current state + + MANUAL CONFIGURATION: + top Enable only top display + bottom Enable only bottom display + both, normal Enable both displays in stacked configuration + left-up Both displays rotated left + right-up Both displays rotated right + toggle Toggle between single and dual display modes + + STATUS & MONITORING: + status Show current display and device status + watch-displays Monitor for display/dock changes + watch-orientation Monitor for orientation changes + watch-backlight Monitor and sync backlight changes + + UTILITIES: + sync-backlight Manually sync backlight between displays + set-tablet-mapping Update tablet/touchscreen mappings + toggle-bottom-touch Toggle bottom touchscreen mapping + bat-limit [0-100] Set battery charge limit (default: 80) + set-kb-backlight [0-3] Set keyboard backlight level + + help Show this help message + EOF + ;; + + *) + echo "Unknown command: $1" + echo "Use 'duo help' for usage information" + exit 1 + ;; esac - ;; - status) - ( - active-external-displays - )|grep -vE "^$"|sed -z "s/\n/+/g" - "$0" status-internal - ;; - toggle) - if ${pkgs.gnome-monitor-config}/bin/gnome-monitor-config list | grep OFF | grep eDP > /dev/null; then - "$0" both - else - "$0" top - fi - ;; - set-tablet-mapping) - for type in tablets touchscreens; do - ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/''${type}/04f3:425b/output" \ - "['SDC', '0x419d', '0x00000000', 'eDP-1']" - ${pkgs.dconf}/bin/dconf write "/org/gnome/desktop/peripherals/''${type}/04f3:425a/output" \ - "['SDC', '0x419d', '0x00000000', 'eDP-2']" - done - ;; - toggle-bottom-touch) - path="/org/gnome/desktop/peripherals/touchscreens/04f3:425a/output" - if [ -z "$(${pkgs.dconf}/bin/dconf read "$path")" ]; then - ${pkgs.dconf}/bin/dconf write "$path" "['SDC', '0x419d', '0x00000000', 'eDP-2']" - else - ${pkgs.dconf}/bin/dconf reset "$path" - fi - ;; - bat-limit) - echo "''${2:-80}" | suenv tee /sys/class/power_supply/BAT0/charge_control_end_threshold - ;; - sync-backlight) - cat "/sys/class/backlight/intel_backlight/brightness" | - suenv tee /sys/class/backlight/$backlight/brightness - ;; - set-kb-backlight) - suenv ${zenbook-kb-backlight}/bin/zenbook-kb-backlight "$2" - ;; - watch-backlight) - "$0" sync-backlight - while ${pkgs.inotify-tools}/bin/inotifywait -e modify /sys/class/backlight/intel_backlight/brightness ; do - "$0" sync-backlight - done - ;; - watch-rotation) - ${pkgs.iio-sensor-proxy}/bin/monitor-sensor --accel | - ${pkgs.coreutils}/bin/stdbuf -oL grep orientation | - ${pkgs.coreutils}/bin/stdbuf -oL cut -d: -f2 | - ${pkgs.coreutils}/bin/stdbuf -oL sed 's/[ )]//g' | - ${pkgs.findutils}/bin/xargs -I '{}' ${pkgs.coreutils}/bin/stdbuf -oL "$0" '{}' - ;; - *) echo "Usage: duo " - esac ''; # Keyboard backlight control script @@ -279,8 +552,10 @@ in { }; Service = { Type = "oneshot"; - ExecStart = "${zenbook-duo-tools}/bin/duo normal"; + ExecStart = "${zenbook-duo-tools}/bin/duo auto"; RemainAfterExit = true; + # Add some delay to ensure graphics are ready + ExecStartPre = "${pkgs.coreutils}/bin/sleep 2"; }; Install.WantedBy = ["graphical-session.target"]; }; @@ -290,12 +565,34 @@ in { Description = "ZenBook Duo Display Watcher"; After = ["graphical-session.target" "zenbook-display-startup.service"]; PartOf = ["graphical-session.target"]; + Requires = ["zenbook-display-startup.service"]; }; Service = { Type = "simple"; ExecStart = "${zenbook-duo-tools}/bin/duo watch-displays"; Restart = "always"; - RestartSec = "5"; + RestartSec = "10"; + # Prevent rapid restarts + StartLimitInterval = "60"; + StartLimitBurst = "3"; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + + zenbook-orientation-watcher = { + Unit = { + Description = "ZenBook Duo Orientation Watcher"; + After = ["graphical-session.target" "zenbook-display-startup.service"]; + PartOf = ["graphical-session.target"]; + Requires = ["zenbook-display-startup.service"]; + }; + Service = { + Type = "simple"; + ExecStart = "${zenbook-duo-tools}/bin/duo watch-orientation"; + Restart = "always"; + RestartSec = "10"; + StartLimitInterval = "60"; + StartLimitBurst = "3"; }; Install.WantedBy = ["graphical-session.target"]; }; @@ -311,21 +608,9 @@ in { ExecStart = "${zenbook-duo-tools}/bin/duo watch-backlight"; Restart = "always"; RestartSec = "5"; - }; - Install.WantedBy = ["graphical-session.target"]; - }; - - zenbook-rotation-watcher = { - Unit = { - Description = "ZenBook Duo Rotation Watcher"; - After = ["graphical-session.target"]; - PartOf = ["graphical-session.target"]; - }; - Service = { - Type = "simple"; - ExecStart = "${zenbook-duo-tools}/bin/duo watch-rotation"; - Restart = "always"; - RestartSec = "5"; + # This is less critical, allow more restarts + StartLimitInterval = "300"; + StartLimitBurst = "10"; }; Install.WantedBy = ["graphical-session.target"]; }; @@ -333,31 +618,43 @@ in { # Shell aliases for convenience (generic across all shells) home.shellAliases = { + # Main commands duo = "${zenbook-duo-tools}/bin/duo"; + duo-auto = "${zenbook-duo-tools}/bin/duo auto"; + duo-status = "${zenbook-duo-tools}/bin/duo status"; + duo-help = "${zenbook-duo-tools}/bin/duo help"; + + # Display configurations duo-toggle = "${zenbook-duo-tools}/bin/duo toggle"; duo-both = "${zenbook-duo-tools}/bin/duo both"; duo-top = "${zenbook-duo-tools}/bin/duo top"; - duo-status = "${zenbook-duo-tools}/bin/duo status"; + duo-bottom = "${zenbook-duo-tools}/bin/duo bottom"; + + # Utilities + duo-sync-backlight = "${zenbook-duo-tools}/bin/duo sync-backlight"; zenbook-kb = "${zenbook-duo-tools}/bin/zenbook-kb-backlight"; + + # Backward compatibility + duo-normal = "${zenbook-duo-tools}/bin/duo both"; # Alias for legacy 'normal' command }; # GNOME specific configuration dconf.settings = { # Enable tablet/touchscreen support for specific device IDs - "org/gnome/desktop/peripherals/tablets/04f3:425b" = { - output = ["SDC" "0x419d" "0x00000000" "eDP-1"]; + "org/gnome/desktop/peripherals/tablets/${duoConfig.primary_touch_id}" = { + output = ["SDC" "0x419d" "0x00000000" duoConfig.primary_display]; }; - "org/gnome/desktop/peripherals/tablets/04f3:425a" = { - output = ["SDC" "0x419d" "0x00000000" "eDP-2"]; + "org/gnome/desktop/peripherals/tablets/${duoConfig.secondary_touch_id}" = { + output = ["SDC" "0x419d" "0x00000000" duoConfig.secondary_display]; }; - "org/gnome/desktop/peripherals/touchscreens/04f3:425b" = { - output = ["SDC" "0x419d" "0x00000000" "eDP-1"]; + "org/gnome/desktop/peripherals/touchscreens/${duoConfig.primary_touch_id}" = { + output = ["SDC" "0x419d" "0x00000000" duoConfig.primary_display]; }; - "org/gnome/desktop/peripherals/touchscreens/04f3:425a" = { - output = ["SDC" "0x419d" "0x00000000" "eDP-2"]; + "org/gnome/desktop/peripherals/touchscreens/${duoConfig.secondary_touch_id}" = { + output = ["SDC" "0x419d" "0x00000000" duoConfig.secondary_display]; }; }; } diff --git a/hosts/common/optional/system76-scheduler.nix b/hosts/common/optional/system76-scheduler.nix new file mode 100644 index 0000000..579ee04 --- /dev/null +++ b/hosts/common/optional/system76-scheduler.nix @@ -0,0 +1,3 @@ +{ + services.system76-scheduler.enable = true; +} diff --git a/hosts/common/optional/thermal-management.nix b/hosts/common/optional/thermal-management.nix index 0b34c41..50844dd 100644 --- a/hosts/common/optional/thermal-management.nix +++ b/hosts/common/optional/thermal-management.nix @@ -3,61 +3,77 @@ services.tlp = { enable = true; - settings = { - # Set CPU driver operation mode to 'active' to allow the CPU to manage its own frequency scaling - CPU_DRIVER_OPMODE_ON_AC = "active"; - CPU_DRIVER_OPMODE_ON_BAT = "active"; + settings = + # In services.tlp.settings + { + # --- CPU Settings for Core Ultra 9 185H --- - # Use 'performance' governor for max performance on AC - CPU_SCALING_GOVERNOR_ON_AC = "performance"; - CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; + # Use the modern 'intel_pstate' driver in active mode. This is correct. + CPU_DRIVER_OPMODE_ON_AC = "active"; + CPU_DRIVER_OPMODE_ON_BAT = "active"; - # Set Energy Performance Preference (EPP) to balance performance on AC and favor power savings on battery - CPU_ENERGY_PERF_POLICY_ON_AC = "balance_performance"; - CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power"; + # CRITICAL: Use 'powersave' for both. On modern Intel chips, this enables + # dynamic scaling from idle up to max boost. It is the best-performing + # and most efficient setting. + CPU_SCALING_GOVERNOR_ON_AC = "powersave"; + CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; - # Define CPU performance limits: full performance on AC, limited to 50% on battery to save power - CPU_MIN_PERF_ON_AC = 0; - CPU_MAX_PERF_ON_AC = 100; - CPU_MIN_PERF_ON_BAT = 0; - CPU_MAX_PERF_ON_BAT = 50; + # This is your main performance tuning knob. 'performance' tells the CPU + # to aggressively ramp up to high clock speeds when it detects a load. + # 'balance_power' is a good choice for extending battery life. + CPU_ENERGY_PERF_POLICY_ON_AC = "performance"; + CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power"; - # Enable Turbo Boost on AC for maximum performance; disable on battery to conserve energy - CPU_BOOST_ON_AC = 1; - CPU_BOOST_ON_BAT = 0; + # Allow the CPU to use its full performance range when plugged in. + CPU_MIN_PERF_ON_AC = 0; + CPU_MAX_PERF_ON_AC = 100; + CPU_MIN_PERF_ON_BAT = 0; + CPU_MAX_PERF_ON_BAT = 60; # Slightly higher than before for better battery responsiveness. - # Enable Intel's Hardware P-States (HWP) dynamic boost on AC; disable on battery - CPU_HWP_DYN_BOOST_ON_AC = 1; - CPU_HWP_DYN_BOOST_ON_BAT = 1; + # ESSENTIAL: Enable Turbo Boost on AC. This is how you get peak performance. + # The 'powersave' governor will use boost intelligently when needed. + # Disabling on battery is key for thermal control and battery life. + CPU_BOOST_ON_AC = 1; + CPU_BOOST_ON_BAT = 0; - # Set platform profile to 'performance' on AC and 'low-power' on battery, if supported by the system - PLATFORM_PROFILE_ON_AC = "performance"; - PLATFORM_PROFILE_ON_BAT = "low-power"; + # HWP Dynamic Boost is a good feature to keep enabled. + CPU_HWP_DYN_BOOST_ON_AC = 1; + CPU_HWP_DYN_BOOST_ON_BAT = 1; - # Enable Wi-Fi power saving on both AC and battery - WIFI_PWR_ON_AC = "on"; - WIFI_PWR_ON_BAT = "on"; + # --- Intel Arc GPU & System Settings --- - # Configure PCIe Active State Power Management: 'performance' on AC, aggressive power saving on battery - PCIE_ASPM_ON_AC = "performance"; - PCIE_ASPM_ON_BAT = "powersupersave"; + # Set the platform profile. 'balanced' is a much safer bet than 'performance' + # to avoid overwhelming the chassis's cooling solution. + PLATFORM_PROFILE_ON_AC = "balanced"; + PLATFORM_PROFILE_ON_BAT = "low-power"; - # Enable runtime power management for PCIe devices: 'on' for AC, 'auto' for battery - RUNTIME_PM_ON_AC = "on"; - RUNTIME_PM_ON_BAT = "auto"; + # Use 'powersupersave' for PCIe ASPM. This allows the components, + # including the GPU, to enter deeper sleep states, reducing idle heat. + PCIE_ASPM_ON_AC = "powersupersave"; + PCIE_ASPM_ON_BAT = "powersupersave"; - # Enable sound power saving on both AC and battery; '1' sets a 1-second timeout - SOUND_POWER_SAVE_ON_AC = 1; - SOUND_POWER_SAVE_ON_BAT = 1; - SOUND_POWER_SAVE_CONTROLLER = "Y"; + # Runtime Power Management is crucial for the integrated GPU to power down + # when not in heavy use. 'auto' is the recommended setting for modern hardware. + RUNTIME_PM_ON_AC = "auto"; + RUNTIME_PM_ON_BAT = "auto"; + # Whitelist everything except devices known to cause issues (like some audio codecs). + # The default blacklist is usually sufficient. + RUNTIME_PM_DRIVER_BLACKLIST = "amdgpu nouveau nvidia pcieport"; - # Enable USB autosuspend to save power when devices are idle - USB_AUTOSUSPEND = 1; + # --- Other Power Saving --- - #Optional helps save long term battery health - #START_CHARGE_THRESH_BAT0 = 40; # 40 and below it starts to charge - #STOP_CHARGE_THRESH_BAT0 = 80; # 80 and above it stops charging - }; + # Keep Wi-Fi power saving on; it's generally fine. + WIFI_PWR_ON_AC = "on"; + WIFI_PWR_ON_BAT = "on"; + + # Sound power saving is fine. + SOUND_POWER_SAVE_ON_AC = 1; + SOUND_POWER_SAVE_ON_BAT = 1; + SOUND_POWER_SAVE_CONTROLLER = "Y"; + + # USB autosuspend is fine. + USB_AUTOSUSPEND = 1; + }; }; #powerManagement.powertop.enable = true; diff --git a/hosts/nixos/Bellerophon/default.nix b/hosts/nixos/Bellerophon/default.nix index dd3d6d7..7be007e 100644 --- a/hosts/nixos/Bellerophon/default.nix +++ b/hosts/nixos/Bellerophon/default.nix @@ -78,6 +78,7 @@ "hosts/common/optional/gdm.nix" "hosts/common/optional/flatpak.nix" "hosts/common/optional/thermal-management.nix" + "hosts/common/optional/system76-scheduler.nix" # Theming "hosts/common/optional/theming/targets/all-except-vscode.nix" diff --git a/hosts/nixos/Bellerophon/hardware-configuration.nix b/hosts/nixos/Bellerophon/hardware-configuration.nix index 0577b12..e620d7f 100644 --- a/hosts/nixos/Bellerophon/hardware-configuration.nix +++ b/hosts/nixos/Bellerophon/hardware-configuration.nix @@ -15,7 +15,10 @@ boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usbhid"]; boot.initrd.kernelModules = []; boot.kernelModules = ["kvm-intel" "evdi"]; - boot.kernelParams = ["i915.enable_psr=0"]; + boot.kernelParams = [ + "i915.enable_guc=3" + #"i915.enable_psr=0" + ]; boot.kernelPatches = [ /* { @@ -40,9 +43,7 @@ sof-firmware #rotation stuff - gnome-monitor-config - usbutils - inotify-tools - kdePackages.libkscreen + intel-gpu-tools # For debugging and monitoring the iGPU + intel-media-driver # VA-API driver for modern Intel GPUs ]; } diff --git a/pkgs/common/gnome-mosaic/package.nix b/pkgs/common/gnome-mosaic/package.nix new file mode 100644 index 0000000..e69de29