diff --git a/frame12/desktop-configuration.nix b/frame12/desktop-configuration.nix index ca216da..bd826c8 100644 --- a/frame12/desktop-configuration.nix +++ b/frame12/desktop-configuration.nix @@ -29,6 +29,7 @@ in imports = [ modules/user/main_user.nix modules/niri/niri_conf.nix + modules/niri/auto-rotation.nix ../shared/modules/system/power_manager.nix ]; @@ -111,6 +112,12 @@ in ]; }; + niri-auto-rotation = { + enable = true; + user = deskCfg.userName; + monitor = "eDP-1"; + }; + environment.systemPackages = with pkgs; [ cryptsetup cage diff --git a/frame12/linked-dotfiles/niri/config.kdl b/frame12/linked-dotfiles/niri/config.kdl index cb3bfbe..83ee111 100644 --- a/frame12/linked-dotfiles/niri/config.kdl +++ b/frame12/linked-dotfiles/niri/config.kdl @@ -5,7 +5,7 @@ output "eDP-1"{ scale 1.0 variable-refresh-rate - // transform "90" + transform "normal" } input { diff --git a/frame12/modules/home-manager/home.nix b/frame12/modules/home-manager/home.nix index 979739d..957a98d 100644 --- a/frame12/modules/home-manager/home.nix +++ b/frame12/modules/home-manager/home.nix @@ -53,8 +53,8 @@ jq python310 unstable.claude-code - ### LSP's - nil # Nix LSP + ### LSP's + nil nodePackages_latest.bash-language-server openscad-lsp vscode-langservers-extracted # provides eslint, markdown, json, css, and html lsp @@ -69,7 +69,7 @@ webcord # - # Better Unix + # Unix tools # bat duf @@ -82,10 +82,11 @@ gtop htop neofetch - # Normies unzip llpp nmap + gnupg + pinentry-tty # # Photo / Video diff --git a/frame12/modules/niri/auto-rotation.nix b/frame12/modules/niri/auto-rotation.nix new file mode 100644 index 0000000..0e03697 --- /dev/null +++ b/frame12/modules/niri/auto-rotation.nix @@ -0,0 +1,142 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.niri-auto-rotation; + + rotationScript = pkgs.writeScriptBin "niri-auto-rotate" '' + #!${pkgs.bash}/bin/bash + NIRI_CONFIG="$HOME/nixos/frame12/linked-dotfiles/niri/config.kdl" + MONITOR="eDP-1" + + # Find the accelerometer device (cros-ec-accel) + ACCEL_DEVICE="" + for device in /sys/bus/iio/devices/iio:device*; do + if [ -f "$device/name" ] && ${pkgs.gnugrep}/bin/grep -q "cros-ec-accel" "$device/name"; then + ACCEL_DEVICE="$device" + break + fi + done + + if [ -z "$ACCEL_DEVICE" ]; then + echo "No accelerometer found!" + exit 1 + fi + + echo "Using accelerometer: $ACCEL_DEVICE" + + LAST_ORIENTATION="" + + while true; do + # Read accelerometer values + if [ -f "$ACCEL_DEVICE/in_accel_x_raw" ]; then + X=$(${pkgs.coreutils}/bin/cat "$ACCEL_DEVICE/in_accel_x_raw") + Y=$(${pkgs.coreutils}/bin/cat "$ACCEL_DEVICE/in_accel_y_raw") + Z=$(${pkgs.coreutils}/bin/cat "$ACCEL_DEVICE/in_accel_z_raw") + + # Determine orientation based on accelerometer values + # Assuming standard orientation when lid/base orientation + ABS_X=''${X#-} + ABS_Y=''${Y#-} + ABS_Z=''${Z#-} + + ORIENTATION="normal" + + # Simple orientation detection based on which axis has highest absolute value + if [ "$ABS_Z" -gt 9000 ]; then + # Device is flat + if [ "$Z" -lt 0 ]; then + ORIENTATION="normal" + else + ORIENTATION="bottom-up" + fi + elif [ "$ABS_Y" -gt "$ABS_X" ] && [ "$ABS_Y" -gt 9000 ]; then + # Y axis dominant + if [ "$Y" -gt 0 ]; then + ORIENTATION="normal" + else + ORIENTATION="bottom-up" + fi + elif [ "$ABS_X" -gt 9000 ]; then + # X axis dominant + if [ "$X" -gt 0 ]; then + ORIENTATION="right-up" + else + ORIENTATION="left-up" + fi + fi + + # Only update if orientation changed + if [ "$ORIENTATION" != "$LAST_ORIENTATION" ]; then + echo "Orientation changed: $LAST_ORIENTATION -> $ORIENTATION (X=$X, Y=$Y, Z=$Z)" + LAST_ORIENTATION="$ORIENTATION" + + case "$ORIENTATION" in + "normal") + ${pkgs.gnused}/bin/sed -i 's/transform ".*"/transform "normal"/' "$NIRI_CONFIG" + ;; + "left-up") + ${pkgs.gnused}/bin/sed -i 's/transform ".*"/transform "90"/' "$NIRI_CONFIG" + ;; + "right-up") + ${pkgs.gnused}/bin/sed -i 's/transform ".*"/transform "270"/' "$NIRI_CONFIG" + ;; + "bottom-up") + ${pkgs.gnused}/bin/sed -i 's/transform ".*"/transform "180"/' "$NIRI_CONFIG" + ;; + esac + fi + fi + + ${pkgs.coreutils}/bin/sleep 0.5 + done + ''; + +in +{ + options.niri-auto-rotation = { + enable = lib.mkEnableOption "Enable automatic screen rotation for Niri using accelerometer"; + + user = lib.mkOption { + type = lib.types.str; + description = "User to run the auto-rotation service for"; + }; + + monitor = lib.mkOption { + type = lib.types.str; + default = "eDP-1"; + description = "Monitor name to rotate"; + }; + }; + + config = lib.mkIf cfg.enable { + # Enable IIO sensor support + hardware.sensor.iio.enable = true; + + # Add custom udev rule for Framework 12 accelerometer + services.udev.extraRules = '' + # Framework 12 accelerometer fix - ensure cros-ec-accel is recognized + SUBSYSTEM=="iio", KERNEL=="iio:device*", ATTR{name}=="cros-ec-accel", ENV{IIO_SENSOR_PROXY_TYPE}="accel" + ''; + + # Install required packages + environment.systemPackages = with pkgs; [ + iio-sensor-proxy + rotationScript + ]; + + # Create systemd user service for the rotation daemon + systemd.user.services.niri-auto-rotate = { + description = "Niri automatic screen rotation"; + after = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + + serviceConfig = { + ExecStart = "${rotationScript}/bin/niri-auto-rotate"; + Restart = "on-failure"; + RestartSec = 5; + }; + + wantedBy = [ "graphical-session.target" ]; + }; + }; +}