From b6fe27e83790a7116a2d08e865286b18a1a3714c Mon Sep 17 00:00:00 2001 From: h8d13 Date: Fri, 2 Oct 2026 13:38:08 +0200 Subject: [PATCH 1/7] delete assets files, delete `dms-greeter` delete excludes from `pyproject.toml` aims to fix: #4820 and potentially add `hyprland` from same deployer restore seat choice. Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 77 +++++ .../default_profiles/desktops/niri_dms.py | 64 ---- .../desktops/niri_dms_assets/dms/alttab.kdl | 10 - .../desktops/niri_dms_assets/dms/binds.kdl | 221 -------------- .../desktops/niri_dms_assets/dms/colors.kdl | 39 --- .../desktops/niri_dms_assets/dms/cursor.kdl | 6 - .../desktops/niri_dms_assets/dms/layout.kdl | 22 -- .../desktops/niri_dms_assets/dms/outputs.kdl | 7 - .../desktops/niri_dms_assets/niri.kdl | 279 ------------------ archinstall/default_profiles/profile.py | 1 - archinstall/lib/profile/profiles_handler.py | 23 -- pyproject.toml | 1 - 12 files changed, 77 insertions(+), 673 deletions(-) create mode 100644 archinstall/default_profiles/desktops/dms.py delete mode 100644 archinstall/default_profiles/desktops/niri_dms.py delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/alttab.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/binds.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/colors.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/cursor.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/layout.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/dms/outputs.kdl delete mode 100644 archinstall/default_profiles/desktops/niri_dms_assets/niri.kdl diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py new file mode 100644 index 0000000000..554e333db5 --- /dev/null +++ b/archinstall/default_profiles/desktops/dms.py @@ -0,0 +1,77 @@ +from typing import TYPE_CHECKING, override + +from archinstall.default_profiles.desktops.utils import select_seat_access +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.lib.log import debug, info + +if TYPE_CHECKING: + from archinstall.lib.installer import Installer + from archinstall.lib.models.users import User + + +class NiriDmsProfile(Profile): + def __init__(self) -> None: + super().__init__( + 'niri - DankMaterialShell', + ProfileType.WindowMgr, + support_gfx_driver=True, + display_server=DisplayServerType.Wayland, + ) + + self.custom_settings = {CustomSetting.SeatAccess: None} + + @property + @override + def packages(self) -> list[str]: + additional = [] + if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): + additional = [seat] + + return [ + 'niri', + 'dms-shell-niri', + 'xdg-desktop-portal-gnome', + 'xorg-xwayland', + 'matugen', + 'cava', + 'kimageformats', + 'alacritty', + 'inter-font', + 'ttf-fira-code', + ] + additional + + @property + @override + def default_greeter_type(self) -> GreeterType: + return GreeterType.Ly + + @property + @override + def services(self) -> list[str]: + if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): + return [pref] + return [] + + @override + async def do_on_select(self) -> None: + default = self.custom_settings.get(CustomSetting.SeatAccess, None) + seat_access = await select_seat_access(self.name, default) + self.custom_settings[CustomSetting.SeatAccess] = seat_access.value + + @override + def provision(self, install_session: Installer, users: list[User]) -> None: + super().provision(install_session, users) + + # dms.service (WantedBy=graphical-session.target) autostarts the shell + # in any session that activates the target, which niri does natively. + # `dms setup headless` only adds spawn-at-startup with --no-systemd and + # never enables the unit itself (no user manager in the chroot anyway) + debug('Enabling dms.service globally for all users') + install_session.arch_chroot('systemctl --global enable dms.service') + + # `dms setup headless` writes the niri config and the dms/ overrides + # under $HOME, so it has to run as the user. --terminal sets the binds' + # terminal (defaults to ghostty) and also deploys a themed alacritty config + for user in users: + info(f'Running dms setup for {user.username}') + install_session.arch_chroot('dms setup headless --compositor niri --terminal alacritty --skip-existing', run_as=user.username) diff --git a/archinstall/default_profiles/desktops/niri_dms.py b/archinstall/default_profiles/desktops/niri_dms.py deleted file mode 100644 index bcb8387afe..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms.py +++ /dev/null @@ -1,64 +0,0 @@ -import shutil -from pathlib import Path -from typing import TYPE_CHECKING, override - -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType - -if TYPE_CHECKING: - from archinstall.lib.installer import Installer - from archinstall.lib.models.users import User - - -_TERMINAL = 'alacritty' -_ASSETS_DIR = Path(__file__).parent / 'niri_dms_assets' - - -class NiriDmsProfile(Profile): - def __init__(self) -> None: - super().__init__( - 'niri - DankMaterialShell', - ProfileType.WindowMgr, - support_gfx_driver=True, - display_server=DisplayServerType.Wayland, - ) - - @property - @override - def packages(self) -> list[str]: - return [ - 'niri', - 'dms-shell-niri', - 'polkit', - 'xdg-desktop-portal-gnome', - 'xorg-xwayland', - 'matugen', - 'cava', - 'kimageformats', - _TERMINAL, - ] - - @property - @override - def default_greeter_type(self) -> GreeterType: - return GreeterType.GreetdDms - - @override - def provision(self, install_session: Installer, users: list[User]) -> None: - binds = (_ASSETS_DIR / 'dms/binds.kdl').read_text().replace('{{TERMINAL_COMMAND}}', _TERMINAL) - - for user in users: - home = install_session.target / 'home' / user.username - niri_dir = home / '.config/niri' - dms_dir = niri_dir / 'dms' - dms_dir.mkdir(parents=True, exist_ok=True) - - shutil.copy(_ASSETS_DIR / 'niri.kdl', niri_dir / 'config.kdl') - for name in ('colors.kdl', 'layout.kdl', 'alttab.kdl', 'outputs.kdl', 'cursor.kdl'): - shutil.copy(_ASSETS_DIR / 'dms' / name, dms_dir / name) - (dms_dir / 'binds.kdl').write_text(binds) - - niri_unit_dropin = home / '.config/systemd/user/niri.service.d' - niri_unit_dropin.mkdir(parents=True, exist_ok=True) - (niri_unit_dropin / 'dms.conf').write_text('[Unit]\nWants=dms.service\n') - - install_session.arch_chroot(f'chown -R {user.username}:{user.username} /home/{user.username}/.config') diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/alttab.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/alttab.kdl deleted file mode 100644 index 5f9bdcd009..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/alttab.kdl +++ /dev/null @@ -1,10 +0,0 @@ -// ! DO NOT EDIT ! -// ! AUTO-GENERATED BY DMS ! -// ! CHANGES WILL BE OVERWRITTEN ! -// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE ! - -recent-windows { - highlight { - corner-radius 12 - } -} diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/binds.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/binds.kdl deleted file mode 100644 index 27cb860e92..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/binds.kdl +++ /dev/null @@ -1,221 +0,0 @@ -binds { - // === System & Overview === - Mod+D repeat=false { toggle-overview; } - Mod+Tab repeat=false { toggle-overview; } - Mod+Shift+Slash { show-hotkey-overlay; } - - // === Application Launchers === - Mod+T hotkey-overlay-title="Open Terminal" { spawn "{{TERMINAL_COMMAND}}"; } - Mod+Space hotkey-overlay-title="Application Launcher" { - spawn "dms" "ipc" "call" "spotlight" "toggle"; - } - Mod+V hotkey-overlay-title="Clipboard Manager" { - spawn "dms" "ipc" "call" "clipboard" "toggle"; - } - Mod+M hotkey-overlay-title="Task Manager" { - spawn "dms" "ipc" "call" "processlist" "focusOrToggle"; - } - - Super+X hotkey-overlay-title="Power Menu: Toggle" { spawn "dms" "ipc" "call" "powermenu" "toggle"; } - Mod+Comma hotkey-overlay-title="Settings" { - spawn "dms" "ipc" "call" "settings" "focusOrToggle"; - } - Mod+Y hotkey-overlay-title="Browse Wallpapers" { - spawn "dms" "ipc" "call" "dankdash" "wallpaper"; - } - Mod+N hotkey-overlay-title="Notification Center" { spawn "dms" "ipc" "call" "notifications" "toggle"; } - Mod+Shift+N hotkey-overlay-title="Notepad" { spawn "dms" "ipc" "call" "notepad" "toggle"; } - - // === Security === - Mod+Alt+L hotkey-overlay-title="Lock Screen" { - spawn "dms" "ipc" "call" "lock" "lock"; - } - Mod+Shift+E { quit; } - Ctrl+Alt+Delete hotkey-overlay-title="Task Manager" { - spawn "dms" "ipc" "call" "processlist" "focusOrToggle"; - } - - // === Audio Controls === - XF86AudioRaiseVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "increment" "3"; - } - XF86AudioLowerVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "decrement" "3"; - } - XF86AudioMute allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "mute"; - } - XF86AudioMicMute allow-when-locked=true { - spawn "dms" "ipc" "call" "audio" "micmute"; - } - XF86AudioPause allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "playPause"; - } - XF86AudioPlay allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "playPause"; - } - XF86AudioPrev allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "previous"; - } - XF86AudioNext allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "next"; - } - Ctrl+XF86AudioRaiseVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "increment" "3"; - } - Ctrl+XF86AudioLowerVolume allow-when-locked=true { - spawn "dms" "ipc" "call" "mpris" "decrement" "3"; - } - - // === Brightness Controls === - XF86MonBrightnessUp allow-when-locked=true { - spawn "dms" "ipc" "call" "brightness" "increment" "5" ""; - } - XF86MonBrightnessDown allow-when-locked=true { - spawn "dms" "ipc" "call" "brightness" "decrement" "5" ""; - } - - // === Window Management === - Mod+Q repeat=false { close-window; } - Mod+F { maximize-column; } - Mod+Shift+F { fullscreen-window; } - Mod+Shift+T { toggle-window-floating; } - Mod+Shift+V { switch-focus-between-floating-and-tiling; } - Mod+W { toggle-column-tabbed-display; } - Mod+Shift+W hotkey-overlay-title="Create window rule" { spawn "dms" "ipc" "call" "window-rules" "toggle"; } - - // === Focus Navigation === - 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; } - - // === Window Movement === - 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; } - - // === Column Navigation === - Mod+Home { focus-column-first; } - Mod+End { focus-column-last; } - Mod+Ctrl+Home { move-column-to-first; } - Mod+Ctrl+End { move-column-to-last; } - - // === Monitor Navigation === - Mod+Ctrl+Left { focus-monitor-left; } - //Mod+Ctrl+Down { focus-monitor-down; } - //Mod+Ctrl+Up { focus-monitor-up; } - Mod+Ctrl+Right { focus-monitor-right; } - Mod+Ctrl+H { focus-monitor-left; } - Mod+Ctrl+J { focus-monitor-down; } - Mod+Ctrl+K { focus-monitor-up; } - Mod+Ctrl+L { focus-monitor-right; } - - // === Move to Monitor === - 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; } - - // === Workspace Navigation === - Mod+Page_Down { focus-workspace-down; } - Mod+Page_Up { focus-workspace-up; } - Mod+U { focus-workspace-down; } - Mod+I { focus-workspace-up; } - Mod+Ctrl+Down { move-column-to-workspace-down; } - Mod+Ctrl+Up { move-column-to-workspace-up; } - Mod+Ctrl+U { move-column-to-workspace-down; } - Mod+Ctrl+I { move-column-to-workspace-up; } - - // === Workspace Management === - Ctrl+Shift+R hotkey-overlay-title="Rename Workspace" { - spawn "dms" "ipc" "call" "workspace-rename" "open"; - } - - // === Move Workspaces === - Mod+Shift+Page_Down { move-workspace-down; } - Mod+Shift+Page_Up { move-workspace-up; } - Mod+Shift+U { move-workspace-down; } - Mod+Shift+I { move-workspace-up; } - - // === Mouse Wheel Navigation === - Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } - Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } - Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } - Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } - - Mod+WheelScrollRight { focus-column-right; } - Mod+WheelScrollLeft { focus-column-left; } - Mod+Ctrl+WheelScrollRight { move-column-right; } - Mod+Ctrl+WheelScrollLeft { move-column-left; } - - Mod+Shift+WheelScrollDown { focus-column-right; } - Mod+Shift+WheelScrollUp { focus-column-left; } - Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } - Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } - - // === Numbered Workspaces === - Mod+1 { focus-workspace 1; } - Mod+2 { focus-workspace 2; } - Mod+3 { focus-workspace 3; } - Mod+4 { focus-workspace 4; } - Mod+5 { focus-workspace 5; } - Mod+6 { focus-workspace 6; } - Mod+7 { focus-workspace 7; } - Mod+8 { focus-workspace 8; } - Mod+9 { focus-workspace 9; } - - // === Move to Numbered Workspaces === - 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; } - - // === Column Management === - Mod+BracketLeft { consume-or-expel-window-left; } - Mod+BracketRight { consume-or-expel-window-right; } - Mod+Period { expel-window-from-column; } - - // === Sizing & Layout === - Mod+R { switch-preset-column-width; } - Mod+Shift+R { switch-preset-window-height; } - Mod+Ctrl+R { reset-window-height; } - Mod+Ctrl+F { expand-column-to-available-width; } - Mod+C { center-column; } - Mod+Ctrl+C { center-visible-columns; } - - // === Manual Sizing === - Mod+Minus { set-column-width "-10%"; } - Mod+Equal { set-column-width "+10%"; } - Mod+Shift+Minus { set-window-height "-10%"; } - Mod+Shift+Equal { set-window-height "+10%"; } - - // === Screenshots === - XF86Launch1 { screenshot; } - Ctrl+XF86Launch1 { screenshot-screen; } - Alt+XF86Launch1 { screenshot-window; } - Print { screenshot; } - Ctrl+Print { screenshot-screen; } - Alt+Print { screenshot-window; } - // === System Controls === - Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } - Mod+Shift+P { power-off-monitors; } -} diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/colors.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/colors.kdl deleted file mode 100644 index 145a179861..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/colors.kdl +++ /dev/null @@ -1,39 +0,0 @@ -// ! Auto-generated file. Do not edit directly. -// Remove `include "dms/colors.kdl"` from your config to override. - -layout { - background-color "transparent" - - focus-ring { - active-color "#d0bcff" - inactive-color "#948f99" - urgent-color "#f2b8b5" - } - - border { - active-color "#d0bcff" - inactive-color "#948f99" - urgent-color "#f2b8b5" - } - - shadow { - color "#00000070" - } - - tab-indicator { - active-color "#d0bcff" - inactive-color "#948f99" - urgent-color "#f2b8b5" - } - - insert-hint { - color "#d0bcff80" - } -} - -recent-windows { - highlight { - active-color "#4f378b" - urgent-color "#f2b8b5" - } -} diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/cursor.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/cursor.kdl deleted file mode 100644 index db3d385a01..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/cursor.kdl +++ /dev/null @@ -1,6 +0,0 @@ -// Place cursor configuration here. -// Example: -// cursor { -// xcursor-theme "Adwaita" -// xcursor-size 24 -// } diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/layout.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/layout.kdl deleted file mode 100644 index 1951500b6c..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/layout.kdl +++ /dev/null @@ -1,22 +0,0 @@ -// ! DO NOT EDIT ! -// ! AUTO-GENERATED BY DMS ! -// ! CHANGES WILL BE OVERWRITTEN ! -// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE ! - -layout { - gaps 4 - - border { - width 2 - } - - focus-ring { - width 2 - } -} -window-rule { - geometry-corner-radius 12 - clip-to-geometry true - tiled-state true - draw-border-with-background false -} diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/dms/outputs.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/dms/outputs.kdl deleted file mode 100644 index 3fe3735813..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/dms/outputs.kdl +++ /dev/null @@ -1,7 +0,0 @@ -// Place per-output configuration here. -// Example: -// output "DP-1" { -// mode "2560x1440@165" -// position x=0 y=0 -// scale 1 -// } diff --git a/archinstall/default_profiles/desktops/niri_dms_assets/niri.kdl b/archinstall/default_profiles/desktops/niri_dms_assets/niri.kdl deleted file mode 100644 index 0a759e461c..0000000000 --- a/archinstall/default_profiles/desktops/niri_dms_assets/niri.kdl +++ /dev/null @@ -1,279 +0,0 @@ -// This config is in the KDL format: https://kdl.dev -// "/-" comments out the following node. -// Check the wiki for a full description of the configuration: -// https://github.com/YaLTeR/niri/wiki/Configuration:-Introduction -config-notification { - disable-failed -} - -gestures { - hot-corners { - off - } -} - -// Input device configuration. -// Find the full list of options on the wiki: -// https://github.com/YaLTeR/niri/wiki/Configuration:-Input -input { - keyboard { - xkb { - // You can set rules, model, layout, variant and options. - // For more information, see xkeyboard-config(7). - - // For example: - // layout "us,ru" - // options "grp:win_space_toggle,compose:ralt,ctrl:nocaps" - - // If this section is empty, niri will fetch xkb settings - // from org.freedesktop.locale1. You can control these using - // localectl set-x11-keymap. - } - - // Enable numlock on startup, omitting this setting disables it. - numlock - } - - // Next sections include libinput settings. - // Omitting settings disables them, or leaves them at their default values. - // All commented-out settings here are examples, not defaults. - touchpad { - // off - tap - // dwt - // dwtp - // drag false - // drag-lock - natural-scroll - // accel-speed 0.2 - // accel-profile "flat" - // scroll-method "two-finger" - // disabled-on-external-mouse - } - - mouse { - // off - // natural-scroll - // accel-speed 0.2 - // accel-profile "flat" - // scroll-method "no-scroll" - } - - trackpoint { - // off - // natural-scroll - // accel-speed 0.2 - // accel-profile "flat" - // scroll-method "on-button-down" - // scroll-button 273 - // scroll-button-lock - // middle-emulation - } - - // Uncomment this to make the mouse warp to the center of newly focused windows. - // warp-mouse-to-focus - - // Focus windows and outputs automatically when moving the mouse into them. - // Setting max-scroll-amount="0%" makes it work only on windows already fully on screen. - // focus-follows-mouse max-scroll-amount="0%" -} -// You can configure outputs by their name, which you can find -// by running `niri msg outputs` while inside a niri instance. -// The built-in laptop monitor is usually called "eDP-1". -// Find more information on the wiki: -// https://github.com/YaLTeR/niri/wiki/Configuration:-Outputs -// Remember to uncomment the node by removing "/-"! -/-output "eDP-2" { - mode "2560x1600@239.998993" - position x=2560 y=0 - variable-refresh-rate -} -// Settings that influence how windows are positioned and sized. -// Find more information on the wiki: -// https://github.com/YaLTeR/niri/wiki/Configuration:-Layout -layout { - // Set gaps around windows in logical pixels. - background-color "transparent" - // When to center a column when changing focus, options are: - // - "never", default behavior, focusing an off-screen column will keep at the left - // or right edge of the screen. - // - "always", the focused column will always be centered. - // - "on-overflow", focusing a column will center it if it doesn't fit - // together with the previously focused column. - center-focused-column "never" - // You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between. - preset-column-widths { - // Proportion sets the width as a fraction of the output width, taking gaps into account. - // For example, you can perfectly fit four windows sized "proportion 0.25" on an output. - // The default preset widths are 1/3, 1/2 and 2/3 of the output. - proportion 0.33333 - proportion 0.5 - proportion 0.66667 - // Fixed sets the width in logical pixels exactly. - // fixed 1920 - } - // You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between. - // preset-window-heights { } - // You can change the default width of the new windows. - default-column-width { proportion 0.5; } - // If you leave the brackets empty, the windows themselves will decide their initial width. - // default-column-width {} - // By default focus ring and border are rendered as a solid background rectangle - // behind windows. That is, they will show up through semitransparent windows. - // This is because windows using client-side decorations can have an arbitrary shape. - // - // If you don't like that, you should uncomment `prefer-no-csd` below. - // Niri will draw focus ring and border *around* windows that agree to omit their - // client-side decorations. - // - // Alternatively, you can override it with a window rule called - // `draw-border-with-background`. - border { - off - width 4 - active-color "#707070" // Neutral gray - inactive-color "#d0d0d0" // Light gray - urgent-color "#cc4444" // Softer red - } - shadow { - softness 30 - spread 5 - offset x=0 y=5 - color "#0007" - } - struts { - } -} -layer-rule { - match namespace="^quickshell$" - place-within-backdrop true -} -overview { - workspace-shadow { - off - } -} -// Add lines like this to spawn processes at startup. -// Note that running niri as a session supports xdg-desktop-autostart, -// which may be more convenient to use. -// See the binds section below for more spawn examples. -// This line starts waybar, a commonly used bar for Wayland compositors. -environment { - XDG_CURRENT_DESKTOP "niri" -} -hotkey-overlay { - skip-at-startup -} -prefer-no-csd -screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" -animations { - workspace-switch { - spring damping-ratio=0.80 stiffness=523 epsilon=0.0001 - } - window-open { - duration-ms 150 - curve "ease-out-expo" - } - window-close { - duration-ms 150 - curve "ease-out-quad" - } - horizontal-view-movement { - spring damping-ratio=0.85 stiffness=423 epsilon=0.0001 - } - window-movement { - spring damping-ratio=0.75 stiffness=323 epsilon=0.0001 - } - window-resize { - spring damping-ratio=0.85 stiffness=423 epsilon=0.0001 - } - config-notification-open-close { - spring damping-ratio=0.65 stiffness=923 epsilon=0.001 - } - screenshot-ui-open { - duration-ms 200 - curve "ease-out-quad" - } - overview-open-close { - spring damping-ratio=0.85 stiffness=800 epsilon=0.0001 - } -} -// Window rules let you adjust behavior for individual windows. -// Find more information on the wiki: -// https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules -// Work around WezTerm's initial configure bug -// by setting an empty default-column-width. -window-rule { - // This regular expression is intentionally made as specific as possible, - // since this is the default config, and we want no false positives. - // You can get away with just app-id="wezterm" if you want. - match app-id=r#"^org\.wezfurlong\.wezterm$"# - default-column-width {} -} -window-rule { - match app-id=r#"^org\.gnome\."# - draw-border-with-background false - geometry-corner-radius 12 - clip-to-geometry true -} -window-rule { - match app-id=r#"^gnome-control-center$"# - match app-id=r#"^pavucontrol$"# - match app-id=r#"^nm-connection-editor$"# - default-column-width { proportion 0.5; } - open-floating false -} -window-rule { - match app-id=r#"^org\.gnome\.Calculator$"# - match app-id=r#"^gnome-calculator$"# - match app-id=r#"^galculator$"# - match app-id=r#"^blueman-manager$"# - match app-id=r#"^org\.gnome\.Nautilus$"# - match app-id=r#"^xdg-desktop-portal$"# - open-floating true -} -window-rule { - match app-id=r#"^steam$"# title=r#"^notificationtoasts_\d+_desktop$"# - default-floating-position x=10 y=10 relative-to="bottom-right" - open-focused false -} -window-rule { - match app-id=r#"^org\.wezfurlong\.wezterm$"# - match app-id="Alacritty" - match app-id="zen" - match app-id="com.mitchellh.ghostty" - match app-id="kitty" - draw-border-with-background false -} -window-rule { - match app-id=r#"firefox$"# title="^Picture-in-Picture$" - match app-id="zoom" - open-floating true -} -// Open dms windows as floating by default -window-rule { - match app-id=r#"org.quickshell$"# - match app-id=r#"com.danklinux.dms$"# - open-floating true -} -debug { - honor-xdg-activation-with-invalid-serial -} - -// Override to disable super+tab -recent-windows { - binds { - Alt+Tab { next-window scope="output"; } - Alt+Shift+Tab { previous-window scope="output"; } - Alt+grave { next-window filter="app-id"; } - Alt+Shift+grave { previous-window filter="app-id"; } - } -} - -// Include dms files -include "dms/colors.kdl" -include "dms/layout.kdl" -include "dms/alttab.kdl" -include "dms/binds.kdl" -include "dms/outputs.kdl" -include "dms/cursor.kdl" diff --git a/archinstall/default_profiles/profile.py b/archinstall/default_profiles/profile.py index d473840ca2..65d594df8e 100644 --- a/archinstall/default_profiles/profile.py +++ b/archinstall/default_profiles/profile.py @@ -37,7 +37,6 @@ class GreeterType(Enum): Ly = 'ly' CosmicSession = 'cosmic-greeter' PlasmaLoginManager = 'plasma-login-manager' - GreetdDms = 'dms-greeter' class SelectResult(Enum): diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py index eb54671642..8582303405 100644 --- a/archinstall/lib/profile/profiles_handler.py +++ b/archinstall/lib/profile/profiles_handler.py @@ -175,9 +175,6 @@ def install_greeter(self, install_session: Installer, greeter: GreeterType) -> N case GreeterType.PlasmaLoginManager: packages = ['plasma-login-manager'] service = ['plasmalogin'] - case GreeterType.GreetdDms: - packages = ['greetd'] - service = ['greetd'] if packages: install_session.add_additional_packages(packages) @@ -197,26 +194,6 @@ def install_greeter(self, install_session: Installer, greeter: GreeterType) -> N with open(path, 'w') as file: file.write(filedata) - if greeter == GreeterType.GreetdDms: - greetd_config = install_session.target / 'etc/greetd/config.toml' - greetd_config.parent.mkdir(parents=True, exist_ok=True) - greetd_config.write_text( - '[terminal]\n' - 'vt = 1\n' - '\n' - '[default_session]\n' - 'user = "greeter"\n' - 'command = "/usr/share/quickshell/dms/Modules/Greetd/assets/dms-greeter --command niri -p /usr/share/quickshell/dms"\n', - ) - - tmpfiles = install_session.target / 'etc/tmpfiles.d/dms-greeter.conf' - tmpfiles.parent.mkdir(parents=True, exist_ok=True) - tmpfiles.write_text( - '# Path Mode User Group Age Argument\n' - 'd /var/cache/dms-greeter 0750 greeter greeter -\n' - 'd /var/lib/greeter 0755 greeter greeter -\n', - ) - def install_gfx_driver(self, install_session: Installer, driver: GfxDriver) -> None: debug(f'Installing GFX driver: {driver.value}') diff --git a/pyproject.toml b/pyproject.toml index 64abe9aedf..6decd63bad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,6 @@ include-package-data = true "**/*.po", "**/*.pot", "**/*.json", - "**/*.kdl", ] [tool.setuptools.package-dir] From fea08f290faf034a79a572290e80670c7e95b67b Mon Sep 17 00:00:00 2001 From: h8d13 Date: Fri, 2 Oct 2026 13:57:02 +0200 Subject: [PATCH 2/7] allow to pick `hyprland` Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 93 +++++++++++++++----- archinstall/default_profiles/profile.py | 1 + 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index 554e333db5..ac234c92d8 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -1,24 +1,51 @@ +from enum import StrEnum from typing import TYPE_CHECKING, override from archinstall.default_profiles.desktops.utils import select_seat_access from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.log import debug, info +from archinstall.lib.menu.helpers import Selection +from archinstall.lib.translationhandler import tr +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType if TYPE_CHECKING: from archinstall.lib.installer import Installer from archinstall.lib.models.users import User -class NiriDmsProfile(Profile): +class DmsCompositor(StrEnum): + # values double as the `dms setup headless --compositor` argument + Niri = 'niri' + Hyprland = 'hyprland' + + def packages(self) -> list[str]: + match self: + case DmsCompositor.Niri: + return ['niri', 'dms-shell-niri', 'xdg-desktop-portal-gnome'] + case DmsCompositor.Hyprland: + return ['hyprland', 'dms-shell-hyprland', 'xdg-desktop-portal-hyprland'] + + +class DmsProfile(Profile): def __init__(self) -> None: super().__init__( - 'niri - DankMaterialShell', + 'DankMaterialShell', ProfileType.WindowMgr, support_gfx_driver=True, display_server=DisplayServerType.Wayland, ) - self.custom_settings = {CustomSetting.SeatAccess: None} + self.custom_settings = { + CustomSetting.DmsCompositor: None, + CustomSetting.SeatAccess: None, + } + + @property + def compositor(self) -> DmsCompositor: + if value := self.custom_settings.get(CustomSetting.DmsCompositor, None): + return DmsCompositor(value) + return DmsCompositor.Niri @property @override @@ -27,18 +54,19 @@ def packages(self) -> list[str]: if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): additional = [seat] - return [ - 'niri', - 'dms-shell-niri', - 'xdg-desktop-portal-gnome', - 'xorg-xwayland', - 'matugen', - 'cava', - 'kimageformats', - 'alacritty', - 'inter-font', - 'ttf-fira-code', - ] + additional + return ( + self.compositor.packages() + + [ + 'xorg-xwayland', + 'matugen', + 'cava', + 'kimageformats', + 'alacritty', + 'inter-font', + 'ttf-fira-code', + ] + + additional + ) @property @override @@ -52,8 +80,26 @@ def services(self) -> list[str]: return [pref] return [] + async def _select_compositor(self) -> None: + header = tr('Select the compositor to run DankMaterialShell on') + '\n' + + items = [MenuItem(c.value, value=c) for c in DmsCompositor] + group = MenuItemGroup(items, sort_items=False) + group.set_default_by_value(self.compositor) + + result = await Selection[DmsCompositor]( + group, + header=header, + allow_skip=False, + ).show() + + if result.type_ == ResultType.Selection: + self.custom_settings[CustomSetting.DmsCompositor] = result.get_value().value + @override async def do_on_select(self) -> None: + await self._select_compositor() + default = self.custom_settings.get(CustomSetting.SeatAccess, None) seat_access = await select_seat_access(self.name, default) self.custom_settings[CustomSetting.SeatAccess] = seat_access.value @@ -62,16 +108,21 @@ async def do_on_select(self) -> None: def provision(self, install_session: Installer, users: list[User]) -> None: super().provision(install_session, users) - # dms.service (WantedBy=graphical-session.target) autostarts the shell - # in any session that activates the target, which niri does natively. - # `dms setup headless` only adds spawn-at-startup with --no-systemd and + # dms.service (WantedBy=graphical-session.target) autostarts the shell in + # any session that activates the target: niri natively, hyprland via the + # hyprland-session.target its DMS config starts. `dms setup headless` # never enables the unit itself (no user manager in the chroot anyway) debug('Enabling dms.service globally for all users') install_session.arch_chroot('systemctl --global enable dms.service') - # `dms setup headless` writes the niri config and the dms/ overrides + # `dms setup headless` writes the compositor config, the dms/ overrides + # and (for hyprland) ~/.config/systemd/user/hyprland-session.target # under $HOME, so it has to run as the user. --terminal sets the binds' # terminal (defaults to ghostty) and also deploys a themed alacritty config + compositor = self.compositor.value for user in users: - info(f'Running dms setup for {user.username}') - install_session.arch_chroot('dms setup headless --compositor niri --terminal alacritty --skip-existing', run_as=user.username) + info(f'Running dms setup for {user.username} ({compositor})') + install_session.arch_chroot( + f'dms setup headless --compositor {compositor} --terminal alacritty --skip-existing', + run_as=user.username, + ) diff --git a/archinstall/default_profiles/profile.py b/archinstall/default_profiles/profile.py index 65d594df8e..eedeef4c48 100644 --- a/archinstall/default_profiles/profile.py +++ b/archinstall/default_profiles/profile.py @@ -48,6 +48,7 @@ class SelectResult(Enum): class CustomSetting(StrEnum): SeatAccess = 'seat_access' PlasmaFlavor = 'plasma_flavor' + DmsCompositor = 'dms_compositor' class Profile: From c157475be7617c64fd293847980961c893a7dead Mon Sep 17 00:00:00 2001 From: h8d13 Date: Fri, 2 Oct 2026 14:14:28 +0200 Subject: [PATCH 3/7] formatting, comments Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index ac234c92d8..9ea29edf0c 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -15,16 +15,23 @@ class DmsCompositor(StrEnum): - # values double as the `dms setup headless --compositor` argument Niri = 'niri' Hyprland = 'hyprland' def packages(self) -> list[str]: match self: case DmsCompositor.Niri: - return ['niri', 'dms-shell-niri', 'xdg-desktop-portal-gnome'] + return [ + 'niri', + 'dms-shell-niri', + 'xdg-desktop-portal-gnome', + ] case DmsCompositor.Hyprland: - return ['hyprland', 'dms-shell-hyprland', 'xdg-desktop-portal-hyprland'] + return [ + 'hyprland', + 'dms-shell-hyprland', + 'xdg-desktop-portal-hyprland', + ] class DmsProfile(Profile): @@ -110,15 +117,12 @@ def provision(self, install_session: Installer, users: list[User]) -> None: # dms.service (WantedBy=graphical-session.target) autostarts the shell in # any session that activates the target: niri natively, hyprland via the - # hyprland-session.target its DMS config starts. `dms setup headless` - # never enables the unit itself (no user manager in the chroot anyway) + # hyprland-session.target its DMS config starts. debug('Enabling dms.service globally for all users') install_session.arch_chroot('systemctl --global enable dms.service') # `dms setup headless` writes the compositor config, the dms/ overrides # and (for hyprland) ~/.config/systemd/user/hyprland-session.target - # under $HOME, so it has to run as the user. --terminal sets the binds' - # terminal (defaults to ghostty) and also deploys a themed alacritty config compositor = self.compositor.value for user in users: info(f'Running dms setup for {user.username} ({compositor})') From 4716fc88cf9042b11f4411d81108ab1a23cb5d24 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Fri, 2 Oct 2026 14:18:28 +0200 Subject: [PATCH 4/7] seat: use new helper pattern Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index 9ea29edf0c..d8e5314017 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -1,7 +1,7 @@ from enum import StrEnum from typing import TYPE_CHECKING, override -from archinstall.default_profiles.desktops.utils import select_seat_access +from archinstall.default_profiles.desktops.utils import seat_access_packages, seat_access_services, select_seat_access from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.log import debug, info from archinstall.lib.menu.helpers import Selection @@ -57,10 +57,6 @@ def compositor(self) -> DmsCompositor: @property @override def packages(self) -> list[str]: - additional = [] - if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): - additional = [seat] - return ( self.compositor.packages() + [ @@ -72,7 +68,7 @@ def packages(self) -> list[str]: 'inter-font', 'ttf-fira-code', ] - + additional + + seat_access_packages(self.custom_settings.get(CustomSetting.SeatAccess)) ) @property @@ -83,9 +79,7 @@ def default_greeter_type(self) -> GreeterType: @property @override def services(self) -> list[str]: - if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): - return [pref] - return [] + return seat_access_services(self.custom_settings.get(CustomSetting.SeatAccess)) async def _select_compositor(self) -> None: header = tr('Select the compositor to run DankMaterialShell on') + '\n' From 6eba143cc588d8aaedb5deb30e62e46a5290aa0f Mon Sep 17 00:00:00 2001 From: h8d13 Date: Fri, 2 Oct 2026 14:38:04 +0200 Subject: [PATCH 5/7] add `uwsm` like `hyprland` profile. Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index d8e5314017..b381dcdc40 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -29,6 +29,7 @@ def packages(self) -> list[str]: case DmsCompositor.Hyprland: return [ 'hyprland', + 'uwsm', 'dms-shell-hyprland', 'xdg-desktop-portal-hyprland', ] From a494be6d25eb3f12f1cccf4633982a58d38690e6 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Sat, 3 Oct 2026 11:43:07 +0200 Subject: [PATCH 6/7] fix pkg names with new upstream 1.6.2-2 Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index b381dcdc40..198b95665c 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -23,14 +23,12 @@ def packages(self) -> list[str]: case DmsCompositor.Niri: return [ 'niri', - 'dms-shell-niri', 'xdg-desktop-portal-gnome', ] case DmsCompositor.Hyprland: return [ 'hyprland', 'uwsm', - 'dms-shell-hyprland', 'xdg-desktop-portal-hyprland', ] @@ -61,6 +59,7 @@ def packages(self) -> list[str]: return ( self.compositor.packages() + [ + 'dms-shell', 'xorg-xwayland', 'matugen', 'cava', @@ -68,8 +67,8 @@ def packages(self) -> list[str]: 'alacritty', 'inter-font', 'ttf-fira-code', + *seat_access_packages(self.custom_settings.get(CustomSetting.SeatAccess)), ] - + seat_access_packages(self.custom_settings.get(CustomSetting.SeatAccess)) ) @property From 22c9b86ee71d4b545bc797f69d81f9cb4b96b4a1 Mon Sep 17 00:00:00 2001 From: h8d13 Date: Sat, 3 Oct 2026 12:15:09 +0200 Subject: [PATCH 7/7] chore(ci): ruff new rules Signed-off-by: h8d13 --- archinstall/default_profiles/desktops/dms.py | 26 +++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/archinstall/default_profiles/desktops/dms.py b/archinstall/default_profiles/desktops/dms.py index 198b95665c..41649b1f1c 100644 --- a/archinstall/default_profiles/desktops/dms.py +++ b/archinstall/default_profiles/desktops/dms.py @@ -56,20 +56,18 @@ def compositor(self) -> DmsCompositor: @property @override def packages(self) -> list[str]: - return ( - self.compositor.packages() - + [ - 'dms-shell', - 'xorg-xwayland', - 'matugen', - 'cava', - 'kimageformats', - 'alacritty', - 'inter-font', - 'ttf-fira-code', - *seat_access_packages(self.custom_settings.get(CustomSetting.SeatAccess)), - ] - ) + return [ + *self.compositor.packages(), + 'dms-shell', + 'xorg-xwayland', + 'matugen', + 'cava', + 'kimageformats', + 'alacritty', + 'inter-font', + 'ttf-fira-code', + *seat_access_packages(self.custom_settings.get(CustomSetting.SeatAccess)), + ] @property @override