diff --git a/environments/niri/home.nix b/environments/niri/home.nix index 70f309c..0c1addd 100644 --- a/environments/niri/home.nix +++ b/environments/niri/home.nix @@ -5,6 +5,25 @@ ]; services.gnome-keyring.enable = true; + systemd.user.services.polkit-gnome-authentication-agent-1 = { + Unit = { + Description = "polkit-gnome-authentication-agent-1"; + Wants = ["graphical-session.target"]; + After = ["graphical-session.target"]; + }; + Install = { + WantedBy = ["graphical-session.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; + Restart = "on-failure"; + RestartSec = 1; + TimeoutStopSec = 10; + }; + }; + + home.packages = with pkgs; [ pamixer brightnessctl diff --git a/environments/niri/niri.kdl b/environments/niri/niri.kdl index 3368a49..f92a955 100644 --- a/environments/niri/niri.kdl +++ b/environments/niri/niri.kdl @@ -9,17 +9,12 @@ input { touchpad { tap dwt - drag + drag true drag-lock natural-scroll scroll-method "two-finger" } - mouse { - natural-scroll false - } - - disable-power-key-handling warp-mouse-to-focus focus-follows-mouse max-scroll-amount="0%" @@ -27,8 +22,11 @@ input { } prefer-no-csd -hide-when-typing -hide-after-inactive-ms 1000 + +cursor { + hide-when-typing + hide-after-inactive-ms 1000 +} clipboard { disable-primary @@ -36,11 +34,11 @@ clipboard { hotkey-overlay { skip-at-startup } -animations { - off -} +// animations { +// off +// } -bind { +binds { XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; } XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; } XF86AudioMedia allow-when-locked=true { spawn "playerctl" "play-pause"; } @@ -52,80 +50,43 @@ bind { XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "s" "+5%"; } XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "s" "5%-"; } - Mod+r { spawn "uwsm" "app" "--" "zen"; } - Mod+e { spawn "uwsm" "app" "--" "kitty"; } - Mod+p { spawn "rofi" "-show" "drun" "-show-icons" "-run-command" "uwsm app -- {cmd}"; } - Mod+x { spawn "screenshot"; } - Mod+Control+x { spawn "screenshot-freeze"; } - Mod+Shift+x { spawn "record"; } - Mod+b { spawn "sh" "-c" "hyprpicker | wl-copy"; } - Mod+v { spawn "sh" "-c" "cliphist list | rofi -dmenu -display-columns 2 | cliphist decode | wl-copy"; } + Mod+R { spawn "uwsm" "app" "--" "zen"; } + Mod+E { spawn "uwsm" "app" "--" "kitty"; } + Mod+P { spawn "rofi" "-show" "drun" "-show-icons" "-run-command" "uwsm app -- {cmd}"; } + Mod+X { spawn "screenshot"; } + Mod+Control+X { spawn "screenshot-freeze"; } + Mod+Shift+X { spawn "record"; } + Mod+B { spawn "sh" "-c" "hyprpicker | wl-copy"; } + Mod+V { spawn "sh" "-c" "cliphist list | rofi -dmenu -display-columns 2 | cliphist decode | wl-copy"; } Super+Shift+L { spawn "loginctl" "lock-session"; } - Mod+o repeat=false { toggle-overview; } - Mod+c repeat=false { close-window; } + Mod+O repeat=false { toggle-overview; } + Mod+C repeat=false { close-window; } - Mod+Left { focus-column-left; } - Mod+Down { focus-window-down; } - Mod+Up { focus-window-up; } - Mod+Right { focus-column-right; } - Mod+H { focus-column-left; } - Mod+J { focus-window-down; } - Mod+K { focus-window-up; } - Mod+L { focus-column-right; } - - Mod+Shift+Left { move-column-left; } - Mod+Shift+Down { move-window-down; } - Mod+Shift+Up { move-window-up; } - Mod+Shift+Right { move-column-right; } - Mod+Shift+H { move-column-left; } - Mod+Shift+J { move-window-down; } - Mod+Shift+K { move-window-up; } - Mod+Shift+L { move-column-right; } + Mod+J { focus-window-up-or-column-left; } + Mod+K { focus-window-down-or-column-right; } + // TODO: add move window down or column right (need to implement those) + Mod+Shift+J { move-window-up; } + Mod+Shift+K { move-window-down; } Mod+Home { focus-column-first; } Mod+End { focus-column-last; } Mod+Shift+Home { move-column-to-first; } Mod+Shift+End { move-column-to-last; } - Mod+Shift+Left { focus-monitor-left; } - Mod+Shift+Down { focus-monitor-down; } - Mod+Shift+Up { focus-monitor-up; } - Mod+Shift+Right { focus-monitor-right; } - Mod+Shift+H { focus-monitor-left; } - Mod+Shift+J { focus-monitor-down; } - Mod+Shift+K { focus-monitor-up; } - Mod+Shift+L { focus-monitor-right; } + Mod+Comma { focus-monitor-previous; } + Mod+Period { focus-monitor-next; } + Mod+Shift+Comma { move-window-to-monitor-previous; } + Mod+Shift+Period { move-window-to-monitor-next; } + Mod+Ctrl+Shift+Comma { move-column-to-monitor-previous; } + Mod+Ctrl+Shift+Period { move-column-to-monitor-next; } - Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } - Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } - Mod+Shift+Ctrl+Up { move-column-to-monitor-up; } - Mod+Shift+Ctrl+Right { move-column-to-monitor-right; } - Mod+Shift+Ctrl+H { move-column-to-monitor-left; } - Mod+Shift+Ctrl+J { move-column-to-monitor-down; } - Mod+Shift+Ctrl+K { move-column-to-monitor-up; } - Mod+Shift+Ctrl+L { move-column-to-monitor-right; } - - // Alternatively, there are commands to move just a single window: - Mod+Shift+Ctrl+Left { move-window-to-monitor-left; } - // ... - - // And you can also move a whole workspace to another monitor: - // Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; } - // ... - - Mod+Page_Down { focus-workspace-down; } - Mod+Page_Up { focus-workspace-up; } - Mod+U { focus-workspace-down; } - Mod+I { focus-workspace-up; } - Mod+Shift+Page_Down { move-column-to-workspace-down; } - Mod+Shift+Page_Up { move-column-to-workspace-up; } - Mod+Shift+U { move-column-to-workspace-down; } - Mod+Shift+I { move-column-to-workspace-up; } - - // Alternatively, there are commands to move just a single window: - // Mod+Ctrl+Page_Down { move-window-to-workspace-down; } - // ... + Mod+Alt+J { focus-workspace-down; } + Mod+Alt+K { focus-workspace-up; } + Mod+Alt+Shift+J { move-window-to-workspace-down; } + Mod+Alt+Shift+K { move-window-to-workspace-up; } + Mod+Alt+Ctrl+Shift+J { move-column-to-workspace-down; } + Mod+Alt+Ctrl+Shift+K { move-column-to-workspace-up; } Mod+Shift+Page_Down { move-workspace-down; } Mod+Shift+Page_Up { move-workspace-up; } @@ -151,18 +112,24 @@ bind { Mod+7 { focus-workspace 7; } Mod+8 { focus-workspace 8; } Mod+9 { focus-workspace 9; } - Mod+Shift+1 { move-column-to-workspace 1; } - Mod+Shift+2 { move-column-to-workspace 2; } - Mod+Shift+3 { move-column-to-workspace 3; } - Mod+Shift+4 { move-column-to-workspace 4; } - Mod+Shift+5 { move-column-to-workspace 5; } - Mod+Shift+6 { move-column-to-workspace 6; } - Mod+Shift+7 { move-column-to-workspace 7; } - Mod+Shift+8 { move-column-to-workspace 8; } - Mod+Shift+9 { move-column-to-workspace 9; } - - // Alternatively, there are commands to move just a single window: - // Mod+Ctrl+1 { move-window-to-workspace 1; } + Mod+Shift+1 { move-window-to-workspace 1; } + Mod+Shift+2 { move-window-to-workspace 2; } + Mod+Shift+3 { move-window-to-workspace 3; } + Mod+Shift+4 { move-window-to-workspace 4; } + Mod+Shift+5 { move-window-to-workspace 5; } + Mod+Shift+6 { move-window-to-workspace 6; } + Mod+Shift+7 { move-window-to-workspace 7; } + Mod+Shift+8 { move-window-to-workspace 8; } + Mod+Shift+9 { move-window-to-workspace 9; } + Mod+Ctrl+Shift+1 { move-column-to-workspace 1; } + Mod+Ctrl+Shift+2 { move-column-to-workspace 2; } + Mod+Ctrl+Shift+3 { move-column-to-workspace 3; } + Mod+Ctrl+Shift+4 { move-column-to-workspace 4; } + Mod+Ctrl+Shift+5 { move-column-to-workspace 5; } + Mod+Ctrl+Shift+6 { move-column-to-workspace 6; } + Mod+Ctrl+Shift+7 { move-column-to-workspace 7; } + Mod+Ctrl+Shift+8 { move-column-to-workspace 8; } + Mod+Ctrl+Shift+9 { move-column-to-workspace 9; } // The following binds move the focused window in and out of a column. // If the window is alone, they will consume it into the nearby column to the side. @@ -170,49 +137,25 @@ bind { Mod+BracketLeft { consume-or-expel-window-left; } Mod+BracketRight { consume-or-expel-window-right; } - // Consume one window from the right to the bottom of the focused column. - Mod+Comma { consume-window-into-column; } - // Expel the bottom window from the focused column to the right. - Mod+Period { expel-window-from-column; } + Mod+U { consume-window-into-column; } + Mod+I { expel-window-from-column; } - Mod+R { switch-preset-column-width; } - Mod+Shift+R { switch-preset-window-height; } - Mod+Ctrl+R { reset-window-height; } - Mod+F { maximize-column; } - Mod+Shift+F { fullscreen-window; } - - // Expand the focused column to space not taken up by other fully visible columns. - // Makes the column "fill the rest of the space". + // Mod+R { switch-preset-column-width; } + // Mod+Shift+R { switch-preset-window-height; } + // Mod+Ctrl+R { reset-window-height; } + Mod+D { toggle-column-tabbed-display; } + Mod+M { maximize-column; } + Mod+F { fullscreen-window; } Mod+Ctrl+F { expand-column-to-available-width; } - Mod+C { center-column; } + Mod+Z { center-column; } + Mod+Ctrl+Z { center-visible-columns; } - // Center all fully visible columns on screen. - Mod+Ctrl+C { center-visible-columns; } + Mod+H { set-column-width "-5%"; } + Mod+L { set-column-width "+5%"; } - // Finer width adjustments. - // This command can also: - // * set width in pixels: "1000" - // * adjust width in pixels: "-5" or "+5" - // * set width as a percentage of screen width: "25%" - // * adjust width as a percentage of screen width: "-10%" or "+10%" - // Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0, - // set-column-width "100" will make the column occupy 200 physical screen pixels. - Mod+Minus { set-column-width "-10%"; } - Mod+Equal { set-column-width "+10%"; } - - // Finer height adjustments when in column with other windows. - Mod+Shift+Minus { set-window-height "-10%"; } - Mod+Shift+Equal { set-window-height "+10%"; } - - // Move the focused window between the floating and the tiling layout. - Mod+V { toggle-window-floating; } - Mod+Shift+V { switch-focus-between-floating-and-tiling; } - - // Toggle tabbed column display mode. - // Windows in this column will appear as vertical tabs, - // rather than stacked on top of each other. - Mod+m { toggle-column-tabbed-display; } + Mod+Shift+V { toggle-window-floating; } + Mod+Alt+V { switch-focus-between-floating-and-tiling; } // Applications such as remote-desktop clients and software KVM switches may // request that niri stops processing the keyboard shortcuts defined here @@ -224,3 +167,8 @@ bind { // which ensures niri always processes them, even when an inhibitor is active. Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } } + +spawn-at-startup "wallpaper" +spawn-at-startup "ags" +spawn-at-startup "uwsm" "finalize" "DISPLAY" "WAYLAND_DISPLAY" "XDG_CURRENT_DESKTOP" "NIXOS_OZONE_WL" "XCURSOR_THEME" "XCURSOR_SIZE" +spawn-at-startup "hyprlock" "--immediate" diff --git a/flake.nix b/flake.nix index 17db0b5..7b680fa 100644 --- a/flake.nix +++ b/flake.nix @@ -67,7 +67,7 @@ }); in { nixosConfigurations.fuhen = mkSystem "fuhen" { - env = "hyprland"; + env = "niri"; custom = [ nixos-hardware.nixosModules.tuxedo-infinitybook-pro14-gen7 ]; diff --git a/modules/wm/ags/layouts/bar.js b/modules/wm/ags/layouts/bar.js index 4b44d0b..0e92e65 100644 --- a/modules/wm/ags/layouts/bar.js +++ b/modules/wm/ags/layouts/bar.js @@ -19,16 +19,16 @@ export const Bar = (monitor) => anchor: ["top", "left", "right"], layer: "bottom", child: Widget.CenterBox({ - startWidget: Widget.Box({ - children: [ - wm.Tags({ - monitor, - labels: ["一", "二", "三", "四", "五", "六", "七", "八", "九"], - }), - wm.Layout({ monitor }), - wm.ClientLabel({ monitor }), - ], - }), + // startWidget: Widget.Box({ + // children: [ + // wm.Tags({ + // monitor, + // labels: ["一", "二", "三", "四", "五", "六", "七", "八", "九"], + // }), + // wm.Layout({ monitor }), + // wm.ClientLabel({ monitor }), + // ], + // }), centerWidget: Widget.Box({ hpack: "center", children: [ diff --git a/modules/wm/ags/modules/wm.js b/modules/wm/ags/modules/wm.js index 222a413..02eee7b 100644 --- a/modules/wm/ags/modules/wm.js +++ b/modules/wm/ags/modules/wm.js @@ -1,96 +1,96 @@ import Gdk from "gi://Gdk?version=3.0"; -const hyprland = await Service.import("hyprland"); - -const display = Gdk.Display.get_default(); -/** @param {number} monitor */ -const getMonitorName = (monitor) => { - return display.get_default_screen().get_monitor_plug_name(monitor); -}; - -/** @type {Record} */ -const urgents = {} - -/** @param {{monitor: number, labels: string[]} & import("types/widgets/box").BoxProps} props */ -export const Tags = ({ monitor, labels, ...props }) => { - const monName = getMonitorName(monitor); - // @ts-ignore - return Widget.Box({ - ...props, - children: Array.from({ length: 9 }, (_, i) => i).map((i) => - Widget.EventBox({ - child: Widget.Label({ label: labels[i], className: "tags" }), - attribute: i + 1, - onPrimaryClickRelease: () => { - hyprland.message(`dispatch workspace ${i + 1}`); - }, - }), - ), - setup: (self) => { - self.hook(hyprland, (_, address) => { - const client = hyprland.getClient(address); - if (!client) return; - const ws = client.workspace.id; - urgents[ws] = true; - }, "urgent-window"); - - self.hook(hyprland, () => - self.children.forEach((btn) => { - const mon = hyprland.monitors.find((x) => x.name === monName); - const ws = hyprland.workspaces.find((x) => x.id === btn.attribute); - - const occupied = (ws?.windows ?? 0) > 0; - const selected = mon?.activeWorkspace?.id === btn.attribute; - if (selected) urgents[btn.attribute] = false; - const urgent = urgents[btn.attribute]; - - btn.visible = occupied || selected; - btn.class_names = [ - selected ? "accent" : "", - urgent ? "secondary" : "", - ]; - }), - ); - }, - }); -}; - -/** @param {{monitor: number } & import("types/widgets/label").LabelProps} props */ -export const Layout = ({ monitor, ...props }) => { - const monName = getMonitorName(monitor); - return Widget.Label({ - className: "module", - ...props, - }).hook( - hyprland, - (self) => { - const mon = hyprland.monitors.find((x) => x.name === monName); - const ws = hyprland.workspaces.find( - (x) => x.id === mon?.activeWorkspace?.id, - ); - self.label = ws?.windows ? `[${ws?.windows}]` : ""; - }, - "changed", - ); -} - -/** @param {{monitor: number, fallback?: string} & import("types/widgets/label").LabelProps} props */ -export const ClientLabel = ({ monitor, fallback = "", ...props }) => { - const monName = getMonitorName(monitor); - return Widget.Label({ - truncate: "end", - maxWidthChars: 25, - className: "module", - ...props, - }).hook( - hyprland, - (self) => { - const mon = hyprland.monitors.find((x) => x.name === monName); - const ws = hyprland.workspaces.find( - (x) => x.id === mon?.activeWorkspace?.id, - ); - self.label = ws?.lastwindowtitle || fallback; - }, - "changed", - ); -}; +// const hyprland = await Service.import("hyprland"); +// +// const display = Gdk.Display.get_default(); +// /** @param {number} monitor */ +// const getMonitorName = (monitor) => { +// return display.get_default_screen().get_monitor_plug_name(monitor); +// }; +// +// /** @type {Record} */ +// const urgents = {} +// +// /** @param {{monitor: number, labels: string[]} & import("types/widgets/box").BoxProps} props */ +// export const Tags = ({ monitor, labels, ...props }) => { +// const monName = getMonitorName(monitor); +// // @ts-ignore +// return Widget.Box({ +// ...props, +// children: Array.from({ length: 9 }, (_, i) => i).map((i) => +// Widget.EventBox({ +// child: Widget.Label({ label: labels[i], className: "tags" }), +// attribute: i + 1, +// onPrimaryClickRelease: () => { +// hyprland.message(`dispatch workspace ${i + 1}`); +// }, +// }), +// ), +// setup: (self) => { +// self.hook(hyprland, (_, address) => { +// const client = hyprland.getClient(address); +// if (!client) return; +// const ws = client.workspace.id; +// urgents[ws] = true; +// }, "urgent-window"); +// +// self.hook(hyprland, () => +// self.children.forEach((btn) => { +// const mon = hyprland.monitors.find((x) => x.name === monName); +// const ws = hyprland.workspaces.find((x) => x.id === btn.attribute); +// +// const occupied = (ws?.windows ?? 0) > 0; +// const selected = mon?.activeWorkspace?.id === btn.attribute; +// if (selected) urgents[btn.attribute] = false; +// const urgent = urgents[btn.attribute]; +// +// btn.visible = occupied || selected; +// btn.class_names = [ +// selected ? "accent" : "", +// urgent ? "secondary" : "", +// ]; +// }), +// ); +// }, +// }); +// }; +// +// /** @param {{monitor: number } & import("types/widgets/label").LabelProps} props */ +// export const Layout = ({ monitor, ...props }) => { +// const monName = getMonitorName(monitor); +// return Widget.Label({ +// className: "module", +// ...props, +// }).hook( +// hyprland, +// (self) => { +// const mon = hyprland.monitors.find((x) => x.name === monName); +// const ws = hyprland.workspaces.find( +// (x) => x.id === mon?.activeWorkspace?.id, +// ); +// self.label = ws?.windows ? `[${ws?.windows}]` : ""; +// }, +// "changed", +// ); +// } +// +// /** @param {{monitor: number, fallback?: string} & import("types/widgets/label").LabelProps} props */ +// export const ClientLabel = ({ monitor, fallback = "", ...props }) => { +// const monName = getMonitorName(monitor); +// return Widget.Label({ +// truncate: "end", +// maxWidthChars: 25, +// className: "module", +// ...props, +// }).hook( +// hyprland, +// (self) => { +// const mon = hyprland.monitors.find((x) => x.name === monName); +// const ws = hyprland.workspaces.find( +// (x) => x.id === mon?.activeWorkspace?.id, +// ); +// self.label = ws?.lastwindowtitle || fallback; +// }, +// "changed", +// ); +// };