diff options
71 files changed, 11269 insertions, 29 deletions
diff --git a/accounts/gkleen@skadhi/default.nix b/accounts/gkleen@skadhi/default.nix index 4c0c4028..fc969348 100644 --- a/accounts/gkleen@skadhi/default.nix +++ b/accounts/gkleen@skadhi/default.nix | |||
| @@ -1,10 +1,13 @@ | |||
| 1 | { flake, flakeInputs, userName, config, lib, ... }: | 1 | { flake, flakeInputs, userName, config, pkgs, lib, sources, ... }: |
| 2 | let | 2 | let |
| 3 | user = config.users.users.${userName}; | 3 | user = config.users.users.${userName}; |
| 4 | in { | 4 | in { |
| 5 | imports = with flake.nixosModules.userProfiles.${userName}; [ | 5 | imports = (with flake.nixosModules.userProfiles.${userName}; [ |
| 6 | zsh | 6 | zsh mpv yt-dlp ./greetd.nix |
| 7 | ]; | 7 | ]) ++ (with flake.nixosModules.systemProfiles; [ |
| 8 | niri-unstable | ||
| 9 | flakeInputs.nixVirt.nixosModules.default | ||
| 10 | ]); | ||
| 8 | 11 | ||
| 9 | config = { | 12 | config = { |
| 10 | users.users.gkleen.group = "gkleen"; | 13 | users.users.gkleen.group = "gkleen"; |
| @@ -17,9 +20,32 @@ in { | |||
| 17 | }; | 20 | }; |
| 18 | }; | 21 | }; |
| 19 | 22 | ||
| 20 | home-manager.users.${userName} = let sysConfig = config; in { config, ... }: { | 23 | programs = { |
| 24 | dconf.enable = true; | ||
| 25 | niri.enable = true; | ||
| 26 | }; | ||
| 27 | environment.sessionVariables."GTK_USE_PORTAL" = "1"; | ||
| 28 | services.niri-autoselect-portal.enable = true; | ||
| 29 | xdg.portal = { | ||
| 30 | enable = true; | ||
| 31 | extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; | ||
| 32 | config.niri = { | ||
| 33 | default = lib.mkForce ["gnome" "gtk"]; | ||
| 34 | "org.freedesktop.impl.portal.FileChooser" = ["gtk"]; | ||
| 35 | "org.freedesktop.impl.portal.OpenFile" = ["gtk"]; | ||
| 36 | "org.freedesktop.impl.portal.Access" = ["gtk"]; | ||
| 37 | "org.freedesktop.impl.portal.Notification" = ["gtk"]; | ||
| 38 | "org.freedesktop.impl.portal.Secret" = ["none"]; | ||
| 39 | "org.freedesktop.impl.portal.Inhibit" = ["none"]; | ||
| 40 | }; | ||
| 41 | }; | ||
| 42 | |||
| 43 | security.pam.services.quickshell = {}; | ||
| 44 | |||
| 45 | home-manager.users.${userName} = { sysConfig, config, ... }: { | ||
| 21 | imports = [ | 46 | imports = [ |
| 22 | flakeInputs.nix-index-database.homeModules.nix-index | 47 | flakeInputs.nix-index-database.homeModules.nix-index |
| 48 | ./niri.nix ./shell ./emacs ./zsh | ||
| 23 | ]; | 49 | ]; |
| 24 | 50 | ||
| 25 | home.stateVersion = "26.05"; | 51 | home.stateVersion = "26.05"; |
| @@ -30,26 +56,164 @@ in { | |||
| 30 | ]; | 56 | ]; |
| 31 | }; | 57 | }; |
| 32 | 58 | ||
| 33 | programs.zsh.dirHashes = let | 59 | programs.nix-index.enable = true; |
| 34 | flakeHashes = lib.mapAttrs' (n: v: lib.nameValuePair (inputNames.${n} or n) (toString v)) flakeInputs; | 60 | |
| 35 | inputNames = { | 61 | programs.alacritty = { |
| 36 | self = "nixos"; | 62 | enable = true; |
| 63 | theme = "kitty"; | ||
| 64 | settings = { | ||
| 65 | font = { | ||
| 66 | normal = { | ||
| 67 | family = "Fira Mono"; | ||
| 68 | style = "Medium"; | ||
| 69 | }; | ||
| 70 | size = 10; | ||
| 71 | }; | ||
| 72 | hints = { | ||
| 73 | alphabet = "aoeuhtns"; | ||
| 74 | enabled = [ | ||
| 75 | { | ||
| 76 | command = lib.getExe' pkgs.xdg-utils "xdg-open"; | ||
| 77 | hyperlinks = true; | ||
| 78 | post_processing = true; | ||
| 79 | persist = false; | ||
| 80 | mouse.enabled = true; | ||
| 81 | binding = { key = "O"; mods = "Control|Shift"; }; | ||
| 82 | regex = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\\\s{-}\\\\^⟨⟩`\\\\\\\\]+"; | ||
| 83 | } | ||
| 84 | { | ||
| 85 | command = lib.getExe' pkgs.wl-clipboard-rs "wl-copy"; | ||
| 86 | hyperlinks = true; | ||
| 87 | post_processing = true; | ||
| 88 | persist = false; | ||
| 89 | mouse.enabled = true; | ||
| 90 | binding = { key = "Y"; mods = "Control|Shift"; }; | ||
| 91 | regex = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\\\s{-}\\\\^⟨⟩`\\\\\\\\]+"; | ||
| 92 | } | ||
| 93 | ]; | ||
| 94 | }; | ||
| 95 | terminal.shell.program = lib.getExe config.programs.zsh.package; | ||
| 37 | }; | 96 | }; |
| 38 | in flakeHashes // { | 97 | }; |
| 39 | docs = "$HOME/documents"; | 98 | programs.fuzzel = { |
| 40 | dl = "$HOME/Downloads"; | 99 | enable = true; |
| 41 | scrot = "$HOME/screenshots"; | 100 | settings = { |
| 42 | media = "$HOME/media"; | 101 | main = { |
| 102 | terminal = "${lib.getExe config.programs.alacritty.package} msg --socket /run/user/1000/alacritty.sock create-window --command ${lib.getExe' sysConfig.systemd.package "systemd-run"} --user --pty --same-dir --wait --collect --quiet --service-type=exec --expand-environment=no {cmd}"; | ||
| 103 | layer = "overlay"; | ||
| 104 | icon-theme = "Paper"; | ||
| 105 | font = "Fira Sans"; | ||
| 106 | }; | ||
| 107 | colors = { | ||
| 108 | background = "000000cc"; | ||
| 109 | text = "cdd6f4ff"; | ||
| 110 | match = "94e2d5ff"; | ||
| 111 | selection = "585b70ff"; | ||
| 112 | selection-match = "94e2d5ff"; | ||
| 113 | selection-text = "cdd6f4ff"; | ||
| 114 | border = "b4befeff"; | ||
| 115 | }; | ||
| 116 | dmenu = { | ||
| 117 | exit-immediately-if-empty = true; | ||
| 118 | }; | ||
| 43 | }; | 119 | }; |
| 44 | programs.starship.settings = { | ||
| 45 | directory.substitutions = lib.mapAttrs' (name: value: let | ||
| 46 | value' = builtins.unsafeDiscardStringContext value; | ||
| 47 | value'' = if lib.hasPrefix "$HOME/" value' then "~" + lib.removePrefix "$HOME" value' else value'; | ||
| 48 | in lib.nameValuePair value'' "~${name}" | ||
| 49 | ) config.programs.zsh.dirHashes; | ||
| 50 | }; | 120 | }; |
| 51 | 121 | ||
| 52 | programs.nix-index.enable = true; | 122 | services.xembed-sni-proxy = { |
| 123 | enable = true; | ||
| 124 | package = pkgs.kdePackages.plasma-workspace; | ||
| 125 | }; | ||
| 126 | services.network-manager-applet.enable = true; | ||
| 127 | services.blueman-applet.enable = true; | ||
| 128 | |||
| 129 | home.pointerCursor = { | ||
| 130 | package = pkgs.vanilla-dmz; | ||
| 131 | name = "Vanilla-DMZ-AA"; | ||
| 132 | size = 16; | ||
| 133 | |||
| 134 | x11 = { | ||
| 135 | enable = true; | ||
| 136 | defaultCursor = "left_ptr"; | ||
| 137 | }; | ||
| 138 | gtk.enable = true; | ||
| 139 | }; | ||
| 140 | |||
| 141 | gtk = { | ||
| 142 | enable = true; | ||
| 143 | font = { | ||
| 144 | package = pkgs.fira; | ||
| 145 | name = "Fira Sans"; | ||
| 146 | size = 10; | ||
| 147 | }; | ||
| 148 | theme = { | ||
| 149 | package = pkgs.kdePackages.breeze-gtk; | ||
| 150 | name = "Breeze-Dark"; | ||
| 151 | }; | ||
| 152 | iconTheme = { | ||
| 153 | package = pkgs.adwaita-icon-theme; | ||
| 154 | name = "Adwaita"; | ||
| 155 | }; | ||
| 156 | }; | ||
| 157 | qt.enable = true; | ||
| 158 | qt.platformTheme.name = "gtk"; | ||
| 159 | |||
| 160 | home.sessionVariables = { | ||
| 161 | QT_QPA_PLATFORMTHEME = lib.mkForce "gtk3"; | ||
| 162 | }; | ||
| 163 | home.extraProfileCommands = '' | ||
| 164 | export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}''${XDG_DATA_DIRS:+:''${XDG_DATA_DIRS}}" | ||
| 165 | ''; | ||
| 166 | |||
| 167 | xdg.configFile."systemd/user/home-manager.service.d/before-graphical-session.conf".text = '' | ||
| 168 | [Unit] | ||
| 169 | Before=graphical-session-pre.target | ||
| 170 | ''; | ||
| 171 | |||
| 172 | fonts = { | ||
| 173 | fontconfig.enable = true; | ||
| 174 | }; | ||
| 175 | |||
| 176 | i18n.inputMethod = { | ||
| 177 | enable = true; | ||
| 178 | type = "fcitx5"; | ||
| 179 | fcitx5 = { | ||
| 180 | waylandFrontend = true; | ||
| 181 | settings = { | ||
| 182 | globalOptions."Behavior/DisabledAddons" = { | ||
| 183 | "0" = "clipboard"; | ||
| 184 | }; | ||
| 185 | inputMethod = { | ||
| 186 | "Groups/0" = { | ||
| 187 | Name = "Default"; | ||
| 188 | "Default Layout" = "us"; | ||
| 189 | DefaultIM = "keyboard-us"; | ||
| 190 | }; | ||
| 191 | "Groups/0/Items/0" = { | ||
| 192 | Name = "keyboard-us"; | ||
| 193 | Layout = ""; | ||
| 194 | }; | ||
| 195 | "GroupOrder"."0" = "Default"; | ||
| 196 | }; | ||
| 197 | addons = { | ||
| 198 | classicui.globalSection = { | ||
| 199 | "Vertical Candidate List" = "True"; | ||
| 200 | Font = "Fira Sans 10"; | ||
| 201 | MenuFont = "Fira Sans 10"; | ||
| 202 | TrayFont = "Fira Sans Demi-Bold 10"; | ||
| 203 | UseDarkTheme = "True"; | ||
| 204 | }; | ||
| 205 | quickphrase = { | ||
| 206 | globalSection = { | ||
| 207 | "Choose Modifier" = "None"; | ||
| 208 | Spell = "True"; | ||
| 209 | FallbackSpellLanguage = "en"; | ||
| 210 | }; | ||
| 211 | sections.TriggerKey."0" = "Super+E"; | ||
| 212 | }; | ||
| 213 | }; | ||
| 214 | }; | ||
| 215 | }; | ||
| 216 | }; | ||
| 53 | }; | 217 | }; |
| 54 | }; | 218 | }; |
| 55 | } | 219 | } |
diff --git a/accounts/gkleen@skadhi/emacs/default.nix b/accounts/gkleen@skadhi/emacs/default.nix new file mode 100644 index 00000000..4cf6b0b9 --- /dev/null +++ b/accounts/gkleen@skadhi/emacs/default.nix | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | { pkgs, lib, config, sources, ... }: | ||
| 2 | let | ||
| 3 | editor = pkgs.symlinkJoin { | ||
| 4 | name = "${config.services.emacs.package.name}-editor"; | ||
| 5 | buildInputs = with pkgs; [ makeWrapper ]; | ||
| 6 | paths = [ config.services.emacs.package ]; | ||
| 7 | postBuild = '' | ||
| 8 | wrapProgram $out/bin/emacsclient \ | ||
| 9 | --inherit-argv0 \ | ||
| 10 | --add-flags ${lib.escapeShellArg (lib.escapeShellArgs config.services.emacs.client.arguments)} | ||
| 11 | ''; | ||
| 12 | }; | ||
| 13 | in { | ||
| 14 | config = { | ||
| 15 | home.persistence."/persistent".directories = [ | ||
| 16 | ".local/state/emacs/saves" ".local/state/emacs/undo" | ||
| 17 | ]; | ||
| 18 | |||
| 19 | programs.emacs = { | ||
| 20 | enable = true; | ||
| 21 | package = pkgs.emacs-pgtk; | ||
| 22 | extraPackages = epkgs: with epkgs; [ | ||
| 23 | evil evil-dvorak undo-tree magit haskell-tng-mode nix-mode | ||
| 24 | yaml-mode json-mode shakespeare-mode smart-mode-line | ||
| 25 | highlight-parentheses highlight-symbol ag sass-mode | ||
| 26 | lua-mode fira-code-mode use-package wanderlust # notmuch | ||
| 27 | git-gutter scratch edit-server mediawiki editorconfig | ||
| 28 | typescript-mode markdown-mode nftables-mode rustic | ||
| 29 | lsp-mode lsp-ui direnv company projectile | ||
| 30 | tomorrow-night-paradise-theme | ||
| 31 | treesit-grammars.with-all-grammars magit-delta scad-mode | ||
| 32 | typst-ts-mode | ||
| 33 | ]; | ||
| 34 | overrides = self: super: { | ||
| 35 | tomorrow-night-paradise-theme = super.trivialBuild { | ||
| 36 | inherit (sources.tomorrow-night-paradise-theme) pname version src; | ||
| 37 | }; | ||
| 38 | scratch = pkgs.stdenv.mkDerivation { | ||
| 39 | inherit (sources.emacs-scratch_el) pname version src; | ||
| 40 | |||
| 41 | phases = [ "unpackPhase" "installPhase" ]; | ||
| 42 | |||
| 43 | installPhase = '' | ||
| 44 | install -Dt $out/share/emacs/site-lisp scratch.el | ||
| 45 | ''; | ||
| 46 | }; | ||
| 47 | }; | ||
| 48 | }; | ||
| 49 | xdg.configFile."emacs/init.el".source = pkgs.substitute { | ||
| 50 | src = ./emacs.el; | ||
| 51 | substitutions = [ | ||
| 52 | "--subst-var-by" "ksshaskpass" (lib.getExe pkgs.kdePackages.ksshaskpass) | ||
| 53 | ]; | ||
| 54 | }; | ||
| 55 | |||
| 56 | home.sessionVariables.EDITOR = lib.getExe' editor "emacsclient"; | ||
| 57 | |||
| 58 | services.emacs = { | ||
| 59 | enable = true; | ||
| 60 | socketActivation.enable = true; | ||
| 61 | client = { | ||
| 62 | enable = true; | ||
| 63 | arguments = lib.mkForce ["--create-frame" "--alternate-editor" (lib.getExe config.services.emacs.package)]; | ||
| 64 | }; | ||
| 65 | }; | ||
| 66 | }; | ||
| 67 | } | ||
diff --git a/accounts/gkleen@skadhi/emacs/emacs.el b/accounts/gkleen@skadhi/emacs/emacs.el new file mode 100644 index 00000000..a9d22621 --- /dev/null +++ b/accounts/gkleen@skadhi/emacs/emacs.el | |||
| @@ -0,0 +1,262 @@ | |||
| 1 | (menu-bar-mode -1) | ||
| 2 | (scroll-bar-mode -1) | ||
| 3 | (tool-bar-mode -1) | ||
| 4 | |||
| 5 | (setq inhibit-startup-message t) | ||
| 6 | (defalias 'yes-or-no-p 'y-or-n-p) | ||
| 7 | |||
| 8 | ;; (set-face-attribute 'default nil :font "Fira Code" :height 49) | ||
| 9 | (set-frame-font "Fira Code 8" nil nil) | ||
| 10 | (load-theme 'modus-vivendi t) | ||
| 11 | ;; (add-to-list 'default-frame-alist '(alpha-background . 90)) | ||
| 12 | |||
| 13 | (require 'package) | ||
| 14 | (setq package-archives nil) | ||
| 15 | (package-initialize) | ||
| 16 | (require 'use-package) | ||
| 17 | ;; (use-package use-package-ensure-system-package :ensure t) | ||
| 18 | |||
| 19 | (require 'evil) | ||
| 20 | (evil-mode 1) | ||
| 21 | |||
| 22 | (editorconfig-mode 1) | ||
| 23 | |||
| 24 | (require 'edit-server) | ||
| 25 | (edit-server-start) | ||
| 26 | |||
| 27 | (require 'mediawiki) | ||
| 28 | (setq mediawiki-mode-hook | ||
| 29 | (lambda () | ||
| 30 | (define-key mediawiki-mode-map (kbd "<C-left>") nil) | ||
| 31 | (define-key mediawiki-mode-map (kbd "<C-right>") nil))) | ||
| 32 | |||
| 33 | (require 'typescript-mode) | ||
| 34 | |||
| 35 | (global-subword-mode) | ||
| 36 | (global-undo-tree-mode) | ||
| 37 | (global-fira-code-mode) | ||
| 38 | |||
| 39 | (evil-set-undo-system 'undo-tree) | ||
| 40 | |||
| 41 | (add-hook 'magit-mode-hook (lambda () (magit-delta-mode +1))) | ||
| 42 | |||
| 43 | (global-set-key (kbd "RET") 'newline-and-indent) | ||
| 44 | (global-set-key (kbd "M-g") 'magit-status) | ||
| 45 | (global-set-key (kbd "M-?") 'vc-git-grep) | ||
| 46 | |||
| 47 | (require 'git-gutter) | ||
| 48 | (global-git-gutter-mode t) | ||
| 49 | (custom-set-variables '(git-gutter:update-interval 2)) | ||
| 50 | (custom-set-variables '(git-gutter:hide-gutter t)) | ||
| 51 | |||
| 52 | (require 'scratch) | ||
| 53 | ;; (global-set-key (kbd "C-x b") 'scratch-switch-to-buffer) | ||
| 54 | (global-set-key (kbd "C-x B") 'scratch-create) | ||
| 55 | ;; (setq initial-major-mode 'scratch-mode) | ||
| 56 | (setq initial-scratch-message "") | ||
| 57 | |||
| 58 | (global-set-key (kbd "C-x K") 'kill-current-buffer) | ||
| 59 | |||
| 60 | (setq backup-directory-alist `(("." . "~/.local/state/emacs/saves"))) | ||
| 61 | (setq undo-tree-history-directory-alist `(("." . "~/.local/state/emacs/undo"))) | ||
| 62 | (setq delete-old-versions t | ||
| 63 | kept-new-versions 6 | ||
| 64 | kept-old-versions 2 | ||
| 65 | version-control t) | ||
| 66 | |||
| 67 | (setq undo-tree-visualizer-timestamps t | ||
| 68 | undo-tree-visualizer-diff t | ||
| 69 | ;; 10X bump of the undo limits to avoid issues with premature | ||
| 70 | ;; Emacs GC which truncages the undo history very aggresively | ||
| 71 | undo-limit 800000 | ||
| 72 | undo-strong-limit 12000000 | ||
| 73 | undo-outer-limit 120000000) | ||
| 74 | |||
| 75 | (add-hook 'haskell-mode-hook 'haskell-indentation-mode) | ||
| 76 | (add-hook 'haskell-mode-hook 'subword-mode) | ||
| 77 | (add-hook 'haskell-mode-hook 'highlight-symbol-mode) | ||
| 78 | (add-hook 'haskell-mode-hook 'highlight-paretheses-mode) | ||
| 79 | |||
| 80 | (add-hook 'js-mode-hook 'highlight-symbol-mode) | ||
| 81 | (add-hook 'js-mode-hook 'highlight-parentheses-mode) | ||
| 82 | (defun my-js-mode-hook () | ||
| 83 | "Custom `js-mode' behaviours." | ||
| 84 | (setq js-indent-level 2) | ||
| 85 | ) | ||
| 86 | (add-hook 'js-mode-hook 'my-js-mode-hook) | ||
| 87 | |||
| 88 | (define-derived-mode anansi-mode | ||
| 89 | markdown-mode "Anansi" | ||
| 90 | "Major mode for anansi" | ||
| 91 | (lambda () (setq indent-tabs-mode nil))) | ||
| 92 | (add-to-list 'auto-mode-alist '("\\.anansi\\'" . anansi-mode)) | ||
| 93 | |||
| 94 | (projectile-mode +1) | ||
| 95 | (define-key projectile-mode-map (kbd "s-p") 'projectile-command-map) | ||
| 96 | |||
| 97 | (add-hook 'rustic-mode-hook (lambda () (setq indent-tabs-mode nil))) | ||
| 98 | (add-hook 'rustic-mode-hook #'lsp-deferred) | ||
| 99 | (add-hook 'rustic-mode-hook (lambda () (setq lsp-ui-sideline-enable nil))) | ||
| 100 | (setq lsp-auto-guess-root t) | ||
| 101 | (setq lsp-inlay-hint-enable t) | ||
| 102 | ;; (add-hook 'rust-mode-hook 'lsp-inlay-hints-mode) | ||
| 103 | (setq lsp-rust-analyzer-server-display-inlay-hints t) | ||
| 104 | (setq lsp-rust-analyzer-inlay-hints-mode t) | ||
| 105 | (setq lsp-rust-analyzer-display-parameter-hints t) | ||
| 106 | (setq lsp-rust-analyzer-display-chaining-hints t) | ||
| 107 | (setq lsp-rust-analyzer-hide-named-constructor nil) | ||
| 108 | |||
| 109 | (setq undo-tree-auto-save-history t) | ||
| 110 | |||
| 111 | (defvar expand-file-name-custom-tilde-alist '(("u2w-srv01" . "/ssh:srv01.uniworx.de:/home/gkleen/projects/uni2work") ("fra-srv01" . "/ssh:srv01.uniworx.de:/home/gkleen/projects/fradrive"))) | ||
| 112 | (defun my/add-to-tilde-alist (hash) | ||
| 113 | (let* ((tilde:dir (split-string hash "=")) | ||
| 114 | (tilde (car tilde:dir)) | ||
| 115 | (dir (cadr tilde:dir))) | ||
| 116 | (push (cons tilde dir) expand-file-name-custom-tilde-alist))) | ||
| 117 | (mapc #'my/add-to-tilde-alist | ||
| 118 | (split-string (let ((process-environment (cl-copy-list process-environment))) (setenv "TERM" nil) (with-output-to-string (call-process "script" nil standard-output nil "-qec" "zsh -ic \"hash -d\"" "/dev/null"))) | ||
| 119 | "\r\n" t)) | ||
| 120 | |||
| 121 | (defadvice expand-file-name (before expand-file-name-custom-tilde | ||
| 122 | (name &optional default-directory) | ||
| 123 | activate compile) | ||
| 124 | "User-defined expansions for ~NAME in file names." | ||
| 125 | (save-match-data | ||
| 126 | (when (string-match "\\`\\(\\(.*/\\)?~\\([^:/]+\\)\\)/" name) | ||
| 127 | (let ((replacement (assoc (match-string 3 name) expand-file-name-custom-tilde-alist))) | ||
| 128 | (when replacement | ||
| 129 | (setq name (replace-match (cdr replacement) t t name 1))))))) | ||
| 130 | |||
| 131 | (setq edit-server-new-frame nil) | ||
| 132 | (setq edit-server-url-major-mode-alist '(("rzint\\.mathinst\\.loc" . mediawiki-mode))) | ||
| 133 | |||
| 134 | ;; (setq notmuch-address-internal-completion '(received nil)) | ||
| 135 | ;; (setq notmuch-always-prompt-for-sender t) | ||
| 136 | ;; (setq notmuch-command "notmuch-ssh") | ||
| 137 | ;; (setq notmuch-crypto-process-mime t) | ||
| 138 | ;; (setq notmuch-draft-tags '("+draft" "-inbox")) | ||
| 139 | ;; (setq notmuch-fcc-dirs nil) | ||
| 140 | ;; (setq notmuch-hello-sections '(notmuch-hello-insert-header notmuch-hello-insert-saved-searches)) | ||
| 141 | ;; (setq notmuch-hello-thousands-separator " ") | ||
| 142 | ;; (setq notmuch-identities '("gkleen@yggdrasil.li" "g@141.li" "kleen@cip.ifi.lmu.de" "Gregor.Kleen@stud.ifi.lmu.de" "G.Kleen@campus.lmu.de" "G.Kleen@lmu.de" "gregor.kleen@ifi.lmu.de" "uni2work@ifi.lmu.de" "gregor@kleen.li")) | ||
| 143 | ;; (setq notmuch-message-headers '("Subject" "To" "Cc" "Date")) | ||
| 144 | ;; (setq notmuch-message-replied-tags '("+replied" "-unread" "-inbox")) | ||
| 145 | ;; (setq notmuch-saved-searches | ||
| 146 | ;; (quote | ||
| 147 | ;; ((:name "inbox" :query "tag:inbox" :key "i") | ||
| 148 | ;; (:name "unread" :query "tag:unread AND tag:inbox" :key "u") | ||
| 149 | ;; (:name "drafts" :query "tag:draft" :key "d") | ||
| 150 | ;; (:name "all mail" :query "date:month.." :key "a" :count-query "*") | ||
| 151 | ;; (:name "sent" :query "is:sent" :key "s" :count-query "is:sent") | ||
| 152 | ;; ))) | ||
| 153 | ;; (setq notmuch-search-oldest-first nil) | ||
| 154 | ;; (setq notmuch-show-all-tags-list t) | ||
| 155 | ;; (setq notmuch-show-logo nil) | ||
| 156 | |||
| 157 | (setq send-mail-function 'sendmail-send-it) | ||
| 158 | (setq mail-envelope-from 'header) | ||
| 159 | (setq mail-specify-envelope-from 't) | ||
| 160 | (setq mail-default-headers nil) | ||
| 161 | (setq message-default-headers "") | ||
| 162 | (setq message-default-mail-headers "") | ||
| 163 | (setq message-sendmail-envelope-from 'header) | ||
| 164 | |||
| 165 | (setq highlight-symbol-idle-delay 0) | ||
| 166 | |||
| 167 | (setq indent-tabs-mode nil) | ||
| 168 | |||
| 169 | (setq ido-enable-flex-matching t) | ||
| 170 | (setq ido-everywhere t) | ||
| 171 | (ido-mode 1) | ||
| 172 | |||
| 173 | (setq tramp-default-method "ssh") | ||
| 174 | (customize-set-variable 'tramp-use-ssh-controlmaster-options nil) | ||
| 175 | (setq tramp-allow-unsafe-temporary-files t) | ||
| 176 | |||
| 177 | (direnv-mode) | ||
| 178 | (setq direnv-enabled-hosts '("uni2work-dev1")) | ||
| 179 | |||
| 180 | (setq auth-sources '()) | ||
| 181 | |||
| 182 | (setq ring-bell-function 'ignore) | ||
| 183 | |||
| 184 | (setq enable-remote-dir-locals 't) | ||
| 185 | |||
| 186 | (setq-default indicate-empty-lines t) | ||
| 187 | (setq-default show-trailing-whitespace t) | ||
| 188 | |||
| 189 | (defun tramp-sh-handle-start-file-process@my-direnv (args) | ||
| 190 | "Enable Direnv for hosts in `direnv-enabled-hosts'." | ||
| 191 | (with-parsed-tramp-file-name (expand-file-name default-directory) nil | ||
| 192 | (if (member host direnv-enabled-hosts) | ||
| 193 | (pcase-let ((`(,name ,buffer ,program . ,args) args)) | ||
| 194 | `(,name | ||
| 195 | ,buffer | ||
| 196 | "direnv" | ||
| 197 | "exec" | ||
| 198 | ,localname | ||
| 199 | ,program | ||
| 200 | ,@args)) | ||
| 201 | args))) | ||
| 202 | |||
| 203 | (with-eval-after-load "tramp-sh" | ||
| 204 | (advice-add 'tramp-sh-handle-start-file-process | ||
| 205 | :filter-args #'tramp-sh-handle-start-file-process@my-direnv)) | ||
| 206 | |||
| 207 | (setq mail-host-address "sif.midgard.yggdrasil") | ||
| 208 | (setq user-full-name "Gregor Kleen") | ||
| 209 | |||
| 210 | (defun tell-emacsclients-for-buffer-to-die () | ||
| 211 | "Sends error exit command to every client for the current buffer." | ||
| 212 | (interactive) | ||
| 213 | (dolist (proc server-buffer-clients) | ||
| 214 | (server-send-string proc "-error die"))) | ||
| 215 | |||
| 216 | (defun kill-buffer-with-special-emacsclient-handling () | ||
| 217 | "Wrapper around kill-buffer that ensures tell-emacsclients-for-buffer-to-die is on the hooks" | ||
| 218 | (interactive) | ||
| 219 | (add-hook 'kill-buffer-hook 'tell-emacsclients-for-buffer-to-die nil t) | ||
| 220 | (kill-buffer)) | ||
| 221 | |||
| 222 | ;; (global-set-key (kbd "C-x k") 'kill-buffer) | ||
| 223 | |||
| 224 | (defun install-emacsclient-wrapped-kill-buffer () | ||
| 225 | "Installs wrapped kill-buffer with special emacsclient handling. | ||
| 226 | Best not to install it unconditionally because the server is not | ||
| 227 | necessarily running." | ||
| 228 | (interactive) | ||
| 229 | (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling)) | ||
| 230 | |||
| 231 | (add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer) | ||
| 232 | (add-hook 'server-switch-hook #'raise-frame) | ||
| 233 | |||
| 234 | (defun move-file (new-location) | ||
| 235 | "Write this file to NEW-LOCATION, and delete the old one." | ||
| 236 | (interactive (list (expand-file-name | ||
| 237 | (if buffer-file-name | ||
| 238 | (read-file-name "Move file to: ") | ||
| 239 | (read-file-name "Move file to: " | ||
| 240 | default-directory | ||
| 241 | (expand-file-name (file-name-nondirectory (buffer-name)) | ||
| 242 | default-directory)))))) | ||
| 243 | (when (file-exists-p new-location) | ||
| 244 | (delete-file new-location)) | ||
| 245 | (let ((old-location (expand-file-name (buffer-file-name)))) | ||
| 246 | (message "old file is %s and new file is %s" | ||
| 247 | old-location | ||
| 248 | new-location) | ||
| 249 | (write-file new-location t) | ||
| 250 | (when (and old-location | ||
| 251 | (file-exists-p new-location) | ||
| 252 | (not (string-equal old-location new-location))) | ||
| 253 | (delete-file old-location)))) | ||
| 254 | |||
| 255 | (bind-key "C-x C-m" #'move-file) | ||
| 256 | |||
| 257 | (let ((ssh_auth_sock (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket")))) (setenv "SSH_AUTH_SOCK" ssh_auth_sock)) | ||
| 258 | (setenv "SSH_ASKPASS_REQUIRE" "prefer") | ||
| 259 | (setenv "SSH_ASKPASS" "@ksshaskpass@") | ||
| 260 | |||
| 261 | (define-key typst-ts-mode-map (kbd "C-<left>") nil) | ||
| 262 | (define-key typst-ts-mode-map (kbd "C-<right>") nil) | ||
diff --git a/accounts/gkleen@skadhi/greetd.nix b/accounts/gkleen@skadhi/greetd.nix new file mode 100644 index 00000000..1972404c --- /dev/null +++ b/accounts/gkleen@skadhi/greetd.nix | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | { config, pkgs, lib, flakeInputs, ... }: | ||
| 2 | |||
| 3 | let | ||
| 4 | gkleenConfig = config.home-manager.users."gkleen"; | ||
| 5 | toIni = lib.generators.toINI { | ||
| 6 | mkKeyValue = | ||
| 7 | key: value: | ||
| 8 | let | ||
| 9 | value' = if lib.isBool value then lib.boolToString value else toString value; | ||
| 10 | in | ||
| 11 | "${lib.escape [ "=" ] key}=${value'}"; | ||
| 12 | }; | ||
| 13 | toDconfIni = let | ||
| 14 | gvariant = import (flakeInputs.home-manager + "/modules/lib/gvariant.nix") { inherit lib; }; | ||
| 15 | mkIniKeyValue = key: value: "${key}=${toString (gvariant.mkValue value)}"; | ||
| 16 | in lib.generators.toINI { mkKeyValue = mkIniKeyValue; }; | ||
| 17 | in { | ||
| 18 | config = { | ||
| 19 | services.greetd = { | ||
| 20 | enable = true; | ||
| 21 | settings.default_session.command = lib.getExe (pkgs.writeShellApplication { | ||
| 22 | name = "sway"; | ||
| 23 | runtimeInputs = [ pkgs.sway pkgs.fontconfig ]; | ||
| 24 | runtimeEnv = { | ||
| 25 | XDG_DATA_DIRS = lib.makeSearchPath "share" [ | ||
| 26 | pkgs.kdePackages.breeze-gtk pkgs.adwaita-icon-theme pkgs.fira | ||
| 27 | ]; | ||
| 28 | QT_PLUGIN_PATH = lib.makeSearchPath (pkgs.qt6.qtbase.qtPluginPrefix) [ | ||
| 29 | pkgs.qt6Packages.qtbase | ||
| 30 | ]; | ||
| 31 | QML2_IMPORT_PATH = lib.makeSearchPath (pkgs.qt6.qtbase.qtQmlPrefix) [ | ||
| 32 | pkgs.qt6Packages.qtbase | ||
| 33 | ]; | ||
| 34 | QT_QPA_PLATFORMTHEME = "gtk3"; | ||
| 35 | XDG_CONFIG_DIR = pkgs.symlinkJoin { | ||
| 36 | name = "config"; | ||
| 37 | paths = [ | ||
| 38 | (pkgs.writeTextDir "gtk-3.0/settings.ini" (toIni { | ||
| 39 | Settings = { | ||
| 40 | gtk-font-name = "Fira Sans 10"; | ||
| 41 | gtk-theme-name = "Breeze-Dark"; | ||
| 42 | gtk-icon-theme-name = "Adwaita"; | ||
| 43 | }; | ||
| 44 | })) | ||
| 45 | ]; | ||
| 46 | }; | ||
| 47 | # XDG_CACHE_HOME = "/var/cache/greetd/greeter"; | ||
| 48 | # XDG_CONFIG_HOME = "/var/cache/greetd/greeter/config"; | ||
| 49 | }; | ||
| 50 | text = '' | ||
| 51 | exec &>/tmp/sway-$$.log | ||
| 52 | |||
| 53 | unset MANAGERPID SYSTEMD_EXEC_PID | ||
| 54 | |||
| 55 | # ${lib.getExe' pkgs.coreutils "mkdir"} -p ''${XDG_CONFIG_HOME}/dconf | ||
| 56 | ${lib.getExe pkgs.dconf} load / < ${pkgs.writeText "dconf.ini" (toDconfIni { | ||
| 57 | "org/gnome/desktop/interface" = { | ||
| 58 | "color-scheme" = "prefer-dark"; | ||
| 59 | "font-name" = "Fira Sans 10"; | ||
| 60 | "gtk-theme" = "Breeze-Dark"; | ||
| 61 | "icon-theme" = "Adwaita"; | ||
| 62 | }; | ||
| 63 | })} | ||
| 64 | |||
| 65 | exec sway --unsupported-gpu --config ${pkgs.writeText "sway-config" '' | ||
| 66 | exec "${lib.getExe' config.systemd.package "systemctl"} --user import-environment {,WAYLAND_}DISPLAY SWAYSOCK; ${lib.getExe gkleenConfig.programs.quickshell.package} --path ${gkleenConfig.xdg.configFile."quickshell".source}/displaymanager.qml; swaymsg exit" | ||
| 67 | |||
| 68 | input type:keyboard { | ||
| 69 | xkb_layout "us,us" | ||
| 70 | xkb_variant "dvp," | ||
| 71 | xkb_options "compose:caps,grp:win_space_toggle" | ||
| 72 | } | ||
| 73 | |||
| 74 | output eDP-1 scale 1.5 | ||
| 75 | ''} | ||
| 76 | ''; | ||
| 77 | }); | ||
| 78 | }; | ||
| 79 | |||
| 80 | # security.pam.services.greetd.fprintAuth = false; | ||
| 81 | |||
| 82 | systemd.services.greetd.serviceConfig = { | ||
| 83 | ExecStartPre = ''${lib.getExe' pkgs.coreutils "install"} -d -o greeter -g greeter -m 0700 ''${CACHE_DIRECTORY}/greeter''; | ||
| 84 | # CacheDirectory = "greetd"; | ||
| 85 | }; | ||
| 86 | |||
| 87 | users.users.greeter = { | ||
| 88 | home = "/var/lib/greeter"; | ||
| 89 | createHome = true; | ||
| 90 | }; | ||
| 91 | }; | ||
| 92 | } | ||
diff --git a/accounts/gkleen@skadhi/niri.nix b/accounts/gkleen@skadhi/niri.nix new file mode 100644 index 00000000..b30c5701 --- /dev/null +++ b/accounts/gkleen@skadhi/niri.nix | |||
| @@ -0,0 +1,1005 @@ | |||
| 1 | { config, hostConfig, pkgs, lib, utils, flakeInputs, ... }: | ||
| 2 | let | ||
| 3 | cfg = config.programs.niri; | ||
| 4 | |||
| 5 | kdl = flakeInputs.niri-flake.lib.kdl; | ||
| 6 | sleaf = name: arg: kdl.node name [arg] []; | ||
| 7 | |||
| 8 | niri = cfg.package; | ||
| 9 | spawnTerminal = { command ? lib.getExe config.programs.zsh.package, extraArgs ? [] }: | ||
| 10 | [(lib.getExe config.programs.alacritty.package) "msg" "--socket" "/run/user/1000/alacritty.sock" "create-window"] ++ lib.toList extraArgs ++ ["--command" (lib.getExe' hostConfig.systemd.package "systemd-run") "--user" "--pty" "--same-dir" "--wait" "--collect" "--quiet" "--service-type=exec" "--expand-environment=no"] ++ lib.mapAttrsToList (k: v: "--property=Environment=${utils.escapeSystemdExecArg "${k}=${if v == null then "" else v}"}") execEnvironment ++ lib.toList command; | ||
| 11 | |||
| 12 | execEnvironment = { | ||
| 13 | NIXOS_OZONE_WL = "1"; | ||
| 14 | QT_QPA_PLATFORM = "wayland"; | ||
| 15 | QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; | ||
| 16 | GDK_BACKEND = "wayland"; | ||
| 17 | SDL_VIDEODRIVER = "wayland"; | ||
| 18 | DISPLAY = ":0"; | ||
| 19 | ELECTRON_OZONE_PLATFORM_HINT = "auto"; | ||
| 20 | SSH_ASKPASS_REQUIRE = "prefer"; | ||
| 21 | SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; | ||
| 22 | SUDO_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; | ||
| 23 | GTK_IM_MODULE = null; | ||
| 24 | QT_IM_MODULE = null; | ||
| 25 | QT_IM_MODULES = null; | ||
| 26 | }; | ||
| 27 | |||
| 28 | focus_or_spawn = pkgs.writeShellApplication { | ||
| 29 | name = "focus-or-spawn"; | ||
| 30 | runtimeInputs = [ niri pkgs.gojq pkgs.gnugrep pkgs.socat ]; | ||
| 31 | text = '' | ||
| 32 | window_select="$1" | ||
| 33 | shift | ||
| 34 | workspace_name="$1" | ||
| 35 | shift | ||
| 36 | |||
| 37 | workspaces_json="$(niri msg -j workspaces)" | ||
| 38 | workspace_output="$(jq -r --arg workspace_name "$workspace_name" '.[] | select(.name == $workspace_name) | .output' <<<"$workspaces_json")" | ||
| 39 | # active_workspace="$(jq -r --arg workspace_output "$workspace_output" '.[] | select(.output == $workspace_output and .is_active) | .id' <<<"$workspaces_json")" | ||
| 40 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | ||
| 41 | if [[ $workspace_output != "$active_output" ]]; then | ||
| 42 | niri msg action move-workspace-to-monitor --reference "$workspace_name" "$active_output" | ||
| 43 | # socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' | ||
| 44 | # niri msg action move-workspace-to-index --reference "$workspace_name" 1 | ||
| 45 | fi | ||
| 46 | |||
| 47 | while IFS=$'\n' read -r window_json; do | ||
| 48 | if [[ -n $(jq -c "$window_select" <<<"$window_json") ]]; then | ||
| 49 | if jq -e '.is_focused' <<<"$window_json" >/dev/null; then | ||
| 50 | niri msg action focus-workspace-previous | ||
| 51 | else | ||
| 52 | if [[ $(jq -r --arg workspace_name "$workspace_name" 'map(select(.name == $workspace_name)) | .[0].is_focused' <<<"$workspaces_json") != "true" ]] && [[ $(jq -r --arg workspace_name "$workspace_name" 'map(select(.name == $workspace_name)) | .[0].id' <<<"$workspaces_json") = $(jq -r '.workspace_id' <<<"$window_json") ]]; then | ||
| 53 | niri msg action focus-workspace "$workspace_name" | ||
| 54 | else | ||
| 55 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | ||
| 56 | fi | ||
| 57 | fi | ||
| 58 | exit 0 | ||
| 59 | fi | ||
| 60 | done < <(niri msg -j windows | jq -c '.[]') | ||
| 61 | |||
| 62 | exec "$@" | ||
| 63 | ''; | ||
| 64 | }; | ||
| 65 | focus-or-spawn-action = config.lib.niri.actions.spawn (lib.getExe focus_or_spawn); | ||
| 66 | |||
| 67 | with_adjacent_workspace = pkgs.writeShellApplication { | ||
| 68 | name = "with-adjacent-workspace"; | ||
| 69 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
| 70 | text = '' | ||
| 71 | blacklist="$1" | ||
| 72 | shift | ||
| 73 | direction="$1" | ||
| 74 | shift | ||
| 75 | action="$1" | ||
| 76 | shift | ||
| 77 | |||
| 78 | workspaces_json="$(niri msg -j workspaces)" | ||
| 79 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" | ||
| 80 | workspace_output="$(jq -r --arg active_workspace "$active_workspace" '.[] | select(.id == ($active_workspace | tonumber)) | .output' <<<"$workspaces_json")" | ||
| 81 | workspace_idx="$(jq -r '.[] | select(.is_focused) | .idx' <<<"$workspaces_json")" | ||
| 82 | |||
| 83 | jq_script='map(select(' | ||
| 84 | case "$direction" in | ||
| 85 | down) | ||
| 86 | # shellcheck disable=SC2016 | ||
| 87 | jq_script=''${jq_script}'.idx > ($workspace_idx | tonumber)';; | ||
| 88 | up) | ||
| 89 | # shellcheck disable=SC2016 | ||
| 90 | jq_script=''${jq_script}'.idx < ($workspace_idx | tonumber)';; | ||
| 91 | esac | ||
| 92 | # shellcheck disable=SC2016 | ||
| 93 | jq_script=''${jq_script}' and .output == $workspace_output and ((.name == null) or (.name | test($blacklist) | not)))) | sort_by(.idx)' | ||
| 94 | [[ $direction == "up" ]] && jq_script=''${jq_script}' | reverse' | ||
| 95 | jq_script=''${jq_script}' | .[0]' | ||
| 96 | |||
| 97 | workspace_json=$(jq -c --arg blacklist "$blacklist" --arg workspace_output "$workspace_output" --arg workspace_idx "$workspace_idx" "$jq_script" <<<"$workspaces_json") | ||
| 98 | [[ -n $workspace_json && $workspace_json != null ]] || exit 0 | ||
| 99 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | ||
| 100 | ''; | ||
| 101 | }; | ||
| 102 | with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^${lib.concatMapStringsSep "|" ({ name, ...}: name) cfg.scratchspaces}$"; | ||
| 103 | focus-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; | ||
| 104 | move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}''; | ||
| 105 | |||
| 106 | with_unnamed_workspace = pkgs.writeShellApplication { | ||
| 107 | name = "with-unnamed-workspace"; | ||
| 108 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
| 109 | text = '' | ||
| 110 | action="$1" | ||
| 111 | shift | ||
| 112 | |||
| 113 | workspaces_json="$(niri msg -j workspaces)" | ||
| 114 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | ||
| 115 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" | ||
| 116 | |||
| 117 | history_json="$(socat STDIO UNIX-CONNECT:"$XDG_RUNTIME_DIR"/niri-workspace-history.sock)" | ||
| 118 | workspace_json="$(jq -c --arg active_output "$active_output" --argjson history "$history_json" 'map(select(.output == $active_output and .name == null)) | map({"value": ., "history_idx": ((. as $workspace | ($history[$active_output] | index($workspace | .id))) as $active_idx | if $active_idx then $active_idx else ($history[$active_output] | length) + 1 end)}) | sort_by(.history_idx, .value.idx) | map(.value) | .[0]' <<<"$workspaces_json")" | ||
| 119 | [[ -n $workspace_json && $workspace_json != null ]] || exit 0 | ||
| 120 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | ||
| 121 | ''; | ||
| 122 | }; | ||
| 123 | with-unnamed-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_unnamed_workspace); | ||
| 124 | |||
| 125 | with_empty_unnamed_workspace = pkgs.writeShellApplication { | ||
| 126 | name = "with-empty-unnamed-workspace"; | ||
| 127 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
| 128 | text = '' | ||
| 129 | action="$1" | ||
| 130 | shift | ||
| 131 | |||
| 132 | workspaces_json="$(niri msg -j workspaces)" | ||
| 133 | active_output="$(jq '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | ||
| 134 | target_workspace_id="$(jq --argjson active_output "$active_output" 'map(select(.active_window_id == null and .name == null and .output == $active_output)) | sort_by(.idx) | .[0].id' <<<"$workspaces_json")" | ||
| 135 | jq --argjson workspace_id "$target_workspace_id" -nc "$action" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | ||
| 136 | ''; | ||
| 137 | }; | ||
| 138 | with-empty-unnamed-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_empty_unnamed_workspace); | ||
| 139 | |||
| 140 | with_select_window = pkgs.writeShellApplication { | ||
| 141 | name = "with-select-window"; | ||
| 142 | runtimeInputs = [ niri pkgs.gojq pkgs.socat config.programs.fuzzel.package pkgs.gawk ]; | ||
| 143 | text = '' | ||
| 144 | window_select="$1" | ||
| 145 | shift | ||
| 146 | action="$1" | ||
| 147 | shift | ||
| 148 | |||
| 149 | windows_json="$(niri msg -j windows)" | ||
| 150 | active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")" | ||
| 151 | window_ix="$(gojq -r --arg active_workspace "$active_workspace" '.[] | select('"$window_select"') | "\(.title)\u0000icon\u001f\(.app_id)"' <<<"$windows_json" | fuzzel --width=60 --log-level=warning --dmenu --index)" | ||
| 152 | # shellcheck disable=SC2016 | ||
| 153 | window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")" | ||
| 154 | |||
| 155 | [[ -z "$window_json" ]] && exit 1 | ||
| 156 | |||
| 157 | jq -c "$action" <<<"$window_json" | socat STDIO "$NIRI_SOCKET" | ||
| 158 | ''; | ||
| 159 | }; | ||
| 160 | with-select-window-action = config.lib.niri.actions.spawn (lib.getExe with_select_window); | ||
| 161 | |||
| 162 | with_predicate_window = pred: pkgs.writeShellApplication { | ||
| 163 | name = "with-predicate-window"; | ||
| 164 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
| 165 | text = '' | ||
| 166 | action="$1" | ||
| 167 | shift | ||
| 168 | |||
| 169 | windows_json="$(niri msg -j windows)" | ||
| 170 | window_json="$(gojq -rc 'map(select(${pred})) | .[0]' <<<"$windows_json")" | ||
| 171 | |||
| 172 | [[ -z "$window_json" || $window_json = "null" ]] && exit 1 | ||
| 173 | |||
| 174 | jq -c "$action" <<<"$window_json" | socat STDIO "$NIRI_SOCKET" | ||
| 175 | ''; | ||
| 176 | }; | ||
| 177 | |||
| 178 | with-urgent-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_urgent")); | ||
| 179 | with-focused-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_focused")); | ||
| 180 | in { | ||
| 181 | options = { | ||
| 182 | programs.niri.scratchspaces = lib.mkOption { | ||
| 183 | type = lib.types.listOf (lib.types.submodule ({ config, ... }: { | ||
| 184 | options = { | ||
| 185 | name = lib.mkOption { | ||
| 186 | type = lib.types.str; | ||
| 187 | }; | ||
| 188 | match = lib.mkOption { | ||
| 189 | type = lib.types.listOf (lib.types.attrsOf kdl.types.kdl-args); | ||
| 190 | default = []; | ||
| 191 | }; | ||
| 192 | exclude = lib.mkOption { | ||
| 193 | type = lib.types.listOf (lib.types.attrsOf kdl.types.kdl-args); | ||
| 194 | default = []; | ||
| 195 | }; | ||
| 196 | windowRuleExtra = lib.mkOption { | ||
| 197 | type = kdl.types.kdl-nodes; | ||
| 198 | default = []; | ||
| 199 | }; | ||
| 200 | key = lib.mkOption { | ||
| 201 | type = lib.types.nullOr lib.types.str; | ||
| 202 | default = null; | ||
| 203 | }; | ||
| 204 | moveKey = lib.mkOption { | ||
| 205 | type = lib.types.nullOr lib.types.str; | ||
| 206 | default = let | ||
| 207 | keys = lib.splitString "+" config.key; | ||
| 208 | defMoveKey = lib.concatStringsSep "+" (lib.flatten [ | ||
| 209 | (lib.take (lib.length keys - 1) keys) | ||
| 210 | ["Shift"] | ||
| 211 | (lib.takeEnd 1 keys) | ||
| 212 | ]); | ||
| 213 | in if config.key == null then null else defMoveKey; | ||
| 214 | }; | ||
| 215 | spawn = lib.mkOption { | ||
| 216 | type = lib.types.nullOr (lib.types.listOf lib.types.str); | ||
| 217 | default = null; | ||
| 218 | }; | ||
| 219 | app-id = lib.mkOption { | ||
| 220 | type = lib.types.nullOr lib.types.str; | ||
| 221 | default = null; | ||
| 222 | }; | ||
| 223 | selector = lib.mkOption { | ||
| 224 | type = lib.types.nullOr lib.types.str; | ||
| 225 | default = null; | ||
| 226 | }; | ||
| 227 | }; | ||
| 228 | |||
| 229 | config = lib.mkMerge [ | ||
| 230 | (lib.mkIf (config.app-id != null) { | ||
| 231 | match = lib.mkDefault [ { app-id = "^${lib.escapeRegex config.app-id}$"; } ]; | ||
| 232 | selector = lib.mkDefault "select(.app_id == \"${config.app-id}\")"; | ||
| 233 | }) | ||
| 234 | ]; | ||
| 235 | })); | ||
| 236 | default = []; | ||
| 237 | }; | ||
| 238 | }; | ||
| 239 | |||
| 240 | config = { | ||
| 241 | home.packages = [ pkgs.xwayland-satellite-unstable ]; | ||
| 242 | |||
| 243 | systemd.user.sockets.niri-workspace-history = { | ||
| 244 | Socket = { | ||
| 245 | ListenStream = "%t/niri-workspace-history.sock"; | ||
| 246 | SocketMode = "0600"; | ||
| 247 | }; | ||
| 248 | }; | ||
| 249 | systemd.user.services.niri-workspace-history = { | ||
| 250 | Unit = { | ||
| 251 | BindsTo = [ "niri.service" ]; | ||
| 252 | After = [ "niri.service" ]; | ||
| 253 | }; | ||
| 254 | Install = { | ||
| 255 | WantedBy = [ "niri.service" ]; | ||
| 256 | }; | ||
| 257 | Service = { | ||
| 258 | Type = "simple"; | ||
| 259 | Sockets = [ "niri-workspace-history.socket" ]; | ||
| 260 | ExecStart = pkgs.writers.writePython3 "niri-workspace-history" { flakeIgnore = ["E501"]; } '' | ||
| 261 | import os | ||
| 262 | import socket | ||
| 263 | import json | ||
| 264 | # import sys | ||
| 265 | from collections import defaultdict | ||
| 266 | from threading import Thread, Lock | ||
| 267 | from socketserver import StreamRequestHandler, ThreadingTCPServer | ||
| 268 | from contextlib import contextmanager | ||
| 269 | from io import TextIOWrapper | ||
| 270 | |||
| 271 | |||
| 272 | @contextmanager | ||
| 273 | def detaching(thing): | ||
| 274 | try: | ||
| 275 | yield thing | ||
| 276 | finally: | ||
| 277 | thing.detach() | ||
| 278 | |||
| 279 | |||
| 280 | workspace_history = defaultdict(list) | ||
| 281 | history_lock = Lock() | ||
| 282 | |||
| 283 | |||
| 284 | def monitor_niri(): | ||
| 285 | workspaces = list() | ||
| 286 | |||
| 287 | def focus_workspace(output, workspace): | ||
| 288 | with history_lock: | ||
| 289 | workspace_history[output] = [workspace] + [ws for ws in workspace_history[output] if ws != workspace] | ||
| 290 | # print(json.dumps(workspace_history), file=sys.stderr) | ||
| 291 | |||
| 292 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | ||
| 293 | sock.connect(os.environ["NIRI_SOCKET"]) | ||
| 294 | sock.send(b"\"EventStream\"\n") | ||
| 295 | for line in sock.makefile(buffering=1, encoding='utf-8'): | ||
| 296 | if line_json := json.loads(line): | ||
| 297 | if "WorkspacesChanged" in line_json: | ||
| 298 | workspaces = line_json["WorkspacesChanged"]["workspaces"] | ||
| 299 | for ws in workspaces: | ||
| 300 | if ws["is_focused"]: | ||
| 301 | focus_workspace(ws["output"], ws["id"]) | ||
| 302 | if "WorkspaceActivated" in line_json: | ||
| 303 | for ws in workspaces: | ||
| 304 | if ws["id"] != line_json["WorkspaceActivated"]["id"]: | ||
| 305 | continue | ||
| 306 | focus_workspace(ws["output"], ws["id"]) | ||
| 307 | break | ||
| 308 | |||
| 309 | |||
| 310 | class RequestHandler(StreamRequestHandler): | ||
| 311 | def handle(self): | ||
| 312 | with detaching(TextIOWrapper(self.wfile, encoding='utf-8', write_through=True)) as out: | ||
| 313 | with history_lock: | ||
| 314 | json.dump(workspace_history, out) | ||
| 315 | |||
| 316 | |||
| 317 | class Server(ThreadingTCPServer): | ||
| 318 | def __init__(self): | ||
| 319 | ThreadingTCPServer.__init__(self, ("", 8000), RequestHandler, bind_and_activate=False) | ||
| 320 | self.socket = socket.fromfd(3, self.address_family, self.socket_type) | ||
| 321 | |||
| 322 | |||
| 323 | def run_server(): | ||
| 324 | with Server() as server: | ||
| 325 | server.serve_forever() | ||
| 326 | |||
| 327 | |||
| 328 | niri = Thread(target=monitor_niri) | ||
| 329 | niri.daemon = True | ||
| 330 | niri.start() | ||
| 331 | |||
| 332 | server_thread = Thread(target=run_server) | ||
| 333 | server_thread.daemon = True | ||
| 334 | server_thread.start() | ||
| 335 | |||
| 336 | while True: | ||
| 337 | server_thread.join(timeout=0.5) | ||
| 338 | niri.join(timeout=0.5) | ||
| 339 | |||
| 340 | if not (niri.is_alive() and server_thread.is_alive()): | ||
| 341 | break | ||
| 342 | ''; | ||
| 343 | }; | ||
| 344 | }; | ||
| 345 | systemd.user.services.niri-workspace-sort = { | ||
| 346 | Unit = { | ||
| 347 | BindsTo = [ "niri.service" ]; | ||
| 348 | After = [ "niri.service" ]; | ||
| 349 | }; | ||
| 350 | Install = { | ||
| 351 | WantedBy = [ "niri.service" ]; | ||
| 352 | }; | ||
| 353 | Service = { | ||
| 354 | Type = "simple"; | ||
| 355 | ExecStart = pkgs.writers.writePython3 "niri-workspace-sort" { flakeIgnore = ["E501"]; } '' | ||
| 356 | import os | ||
| 357 | import sys | ||
| 358 | import socket | ||
| 359 | import json | ||
| 360 | |||
| 361 | outputs = None | ||
| 362 | only = {'HDMI-A-1': {'bmr'}, 'eDP-1': {'vid'}} | ||
| 363 | |||
| 364 | |||
| 365 | class Niri(socket.socket): | ||
| 366 | def __init__(self): | ||
| 367 | super().__init__(socket.AF_UNIX, socket.SOCK_STREAM) | ||
| 368 | super().connect(os.environ["NIRI_SOCKET"]) | ||
| 369 | self.fh = super().makefile(mode='rw', buffering=1, encoding='utf-8') | ||
| 370 | |||
| 371 | def cmd(self, obj): | ||
| 372 | print(json.dumps(obj, separators=(',', ':')), flush=True, file=self.fh) | ||
| 373 | |||
| 374 | def event_stream(self): | ||
| 375 | self.cmd("EventStream") | ||
| 376 | return self.fh | ||
| 377 | |||
| 378 | |||
| 379 | with Niri() as niri, Niri().event_stream() as niri_stream: | ||
| 380 | for line in niri_stream: | ||
| 381 | workspaces = None | ||
| 382 | if line_json := json.loads(line): | ||
| 383 | if "WorkspacesChanged" in line_json: | ||
| 384 | workspaces = line_json["WorkspacesChanged"]["workspaces"] | ||
| 385 | |||
| 386 | if workspaces is None: | ||
| 387 | continue | ||
| 388 | |||
| 389 | old_outputs = outputs | ||
| 390 | outputs = {ws["output"] for ws in workspaces} | ||
| 391 | if old_outputs is None: | ||
| 392 | print("Initial outputs: {}".format(outputs), file=sys.stderr) | ||
| 393 | continue | ||
| 394 | |||
| 395 | new_outputs = outputs - old_outputs | ||
| 396 | if not new_outputs: | ||
| 397 | continue | ||
| 398 | print("New outputs: {}".format(new_outputs), file=sys.stderr) | ||
| 399 | |||
| 400 | relevant_workspaces = list(filter(lambda ws: (ws["name"] is not None) or (ws["active_window_id"] is not None), workspaces)) | ||
| 401 | target_output = next(iter(outputs - set(only.keys()))) | ||
| 402 | if not target_output: | ||
| 403 | continue | ||
| 404 | for ws in relevant_workspaces: | ||
| 405 | ws_ident = ws["name"] if ws["name"] is not None else (ws["output"], ws["idx"]) | ||
| 406 | if ws["output"] not in set(only.keys()): | ||
| 407 | continue | ||
| 408 | if ws_ident in only[ws["output"]]: | ||
| 409 | continue | ||
| 410 | |||
| 411 | print("{} -> {}".format(ws_ident, target_output), file=sys.stderr) | ||
| 412 | niri.cmd({"Action": {"MoveWorkspaceToMonitor": {"reference": {"Id": ws["id"]}, "output": target_output}}}) | ||
| 413 | ''; | ||
| 414 | Restart = "on-failure"; | ||
| 415 | RestartSec = 10; | ||
| 416 | }; | ||
| 417 | }; | ||
| 418 | |||
| 419 | programs.niri.scratchspaces = [ | ||
| 420 | { name = "pwctl"; | ||
| 421 | key = "Mod+Control+A"; | ||
| 422 | spawn = ["pwvucontrol"]; | ||
| 423 | app-id = "com.saivert.pwvucontrol"; | ||
| 424 | } | ||
| 425 | { name = "kpxc"; | ||
| 426 | exclude = [ | ||
| 427 | { title = "^Unlock Database.*"; } | ||
| 428 | { title = "^Access Request.*"; } | ||
| 429 | { title = ".*Passkey credentials$"; } | ||
| 430 | ]; | ||
| 431 | windowRuleExtra = with kdl; [ | ||
| 432 | (sleaf "open-focused" false) | ||
| 433 | ]; | ||
| 434 | key = "Mod+Control+P"; | ||
| 435 | app-id = "org.keepassxc.KeePassXC"; | ||
| 436 | spawn = [ "keepassxc" ]; | ||
| 437 | } | ||
| 438 | { name = "bmgr"; | ||
| 439 | key = "Mod+Control+B"; | ||
| 440 | app-id = ".blueman-manager-wrapped"; | ||
| 441 | spawn = [ "blueman-manager" ]; | ||
| 442 | } | ||
| 443 | { name = "term"; | ||
| 444 | key = "Mod+Control+Return"; | ||
| 445 | app-id = "Alacritty-scratch"; | ||
| 446 | spawn = spawnTerminal { extraArgs = ["--class" "Alacritty-scratch"]; }; | ||
| 447 | } | ||
| 448 | { name = "edit"; | ||
| 449 | match = [ { title = "^scratch$"; app-id = "^emacs$"; } ]; | ||
| 450 | key = "Mod+Control+E"; | ||
| 451 | selector = "select(.app_id == \"emacs\" and .title == \"scratch\")"; | ||
| 452 | spawn = [ "emacsclient" "-c" "--frame-parameters=(quote (name . \"scratch\"))" ]; | ||
| 453 | } | ||
| 454 | { name = "eff"; | ||
| 455 | key = "Mod+Control+O"; | ||
| 456 | app-id = "com.github.wwmm.easyeffects"; | ||
| 457 | spawn = [ "easyeffects" ]; | ||
| 458 | } | ||
| 459 | { name = "time"; | ||
| 460 | key = "Mod+Control+K"; | ||
| 461 | app-id = "chrome-kimai.yggdrasil.li__-Default"; | ||
| 462 | spawn = [ (toString (pkgs.resholve.writeScript "kimai" { | ||
| 463 | interpreter = pkgs.runtimeShell; | ||
| 464 | inputs = [ pkgs.dex ]; | ||
| 465 | execer = [ "cannot:${lib.getExe pkgs.dex}" ]; | ||
| 466 | } '' | ||
| 467 | exec dex $HOME/.local/state/nix/profile/share/applications/kimai.desktop | ||
| 468 | '')) ]; | ||
| 469 | windowRuleExtra = with kdl; [ | ||
| 470 | (sleaf "block-out-from" "screencast") | ||
| 471 | ]; | ||
| 472 | } | ||
| 473 | ]; | ||
| 474 | programs.niri.config = | ||
| 475 | let | ||
| 476 | inherit (kdl) node plain leaf flag; | ||
| 477 | optional-node = cond: v: | ||
| 478 | if cond | ||
| 479 | then v | ||
| 480 | else null; | ||
| 481 | opt-props = lib.filterAttrs (lib.const (value: value != null)); | ||
| 482 | normalize-nodes = nodes: lib.remove null (lib.flatten nodes); | ||
| 483 | in | ||
| 484 | normalize-nodes [ | ||
| 485 | (flag "prefer-no-csd") | ||
| 486 | |||
| 487 | (sleaf "screenshot-path" "~/screenshots/%Y-%m-%dT%H:%M:%S.png") | ||
| 488 | |||
| 489 | (plain "hotkey-overlay" [ | ||
| 490 | (flag "skip-at-startup") | ||
| 491 | ]) | ||
| 492 | |||
| 493 | (plain "input" [ | ||
| 494 | (plain "keyboard" [ | ||
| 495 | (sleaf "repeat-delay" 300) | ||
| 496 | (sleaf "repeat-rate" 50) | ||
| 497 | |||
| 498 | (plain "xkb" [ | ||
| 499 | (sleaf "layout" "us,us") | ||
| 500 | (sleaf "variant" "dvp,") | ||
| 501 | (sleaf "options" "compose:caps,grp:win_space_toggle") | ||
| 502 | ]) | ||
| 503 | ]) | ||
| 504 | |||
| 505 | (flag "workspace-auto-back-and-forth") | ||
| 506 | # (sleaf "focus-follows-mouse" {}) | ||
| 507 | # (flag "warp-mouse-to-focus") | ||
| 508 | |||
| 509 | # (plain "touchpad" [ (flag "off") ]) | ||
| 510 | (plain "trackball" [ | ||
| 511 | (sleaf "scroll-method" "on-button-down") | ||
| 512 | (sleaf "scroll-button" 278) | ||
| 513 | ]) | ||
| 514 | (plain "touch" [ | ||
| 515 | (sleaf "map-to-output" "eDP-1") | ||
| 516 | ]) | ||
| 517 | (plain "tablet" [ | ||
| 518 | (sleaf "map-to-output" "eDP-1") | ||
| 519 | ]) | ||
| 520 | ]) | ||
| 521 | |||
| 522 | (plain "gestures" [ | ||
| 523 | (plain "hot-corners" [(flag "off")]) | ||
| 524 | ]) | ||
| 525 | |||
| 526 | (plain "environment" (lib.mapAttrsToList sleaf execEnvironment)) | ||
| 527 | |||
| 528 | (node "output" ["eDP-1"] [ | ||
| 529 | (sleaf "scale" 1.5) | ||
| 530 | (sleaf "position" { x = 0; y = 0; }) | ||
| 531 | ]) | ||
| 532 | (node "output" ["Ancor Communications Inc ASUS PB287Q 0x0000DD9B"] [ | ||
| 533 | (sleaf "scale" 1.5) | ||
| 534 | (sleaf "position" { x = 2560; y = 0; }) | ||
| 535 | ]) | ||
| 536 | (node "output" ["HP Inc. HP 727pu CN4417143K"] [ | ||
| 537 | (sleaf "mode" "2560x1440@119.998") | ||
| 538 | (sleaf "scale" 1) | ||
| 539 | (sleaf "position" { x = 2560; y = 0; }) | ||
| 540 | (flag "variable-refresh-rate") | ||
| 541 | ]) | ||
| 542 | |||
| 543 | (plain "debug" [ | ||
| 544 | (sleaf "render-drm-device" "/dev/dri/by-path/pci-0000:00:02.0-render") | ||
| 545 | ]) | ||
| 546 | |||
| 547 | (plain "animations" [ | ||
| 548 | (sleaf "slowdown" 0.5) | ||
| 549 | (plain "workspace-switch" [(flag "off")]) | ||
| 550 | ]) | ||
| 551 | |||
| 552 | (plain "layout" [ | ||
| 553 | (sleaf "gaps" 8) | ||
| 554 | (plain "struts" [ | ||
| 555 | (sleaf "left" 26) | ||
| 556 | (sleaf "right" 26) | ||
| 557 | (sleaf "top" 0) | ||
| 558 | (sleaf "bottom" 0) | ||
| 559 | ]) | ||
| 560 | (plain "border" [ | ||
| 561 | (sleaf "width" 2) | ||
| 562 | (sleaf "active-gradient" { | ||
| 563 | from = "hsla(195 100% 45% 1)"; | ||
| 564 | to = "hsla(155 100% 37.5% 1)"; | ||
| 565 | angle = 29; | ||
| 566 | relative-to = "workspace-view"; | ||
| 567 | }) | ||
| 568 | (sleaf "inactive-gradient" { | ||
| 569 | from = "hsla(0 0% 27.7% 1)"; | ||
| 570 | to = "hsla(0 0% 23% 1)"; | ||
| 571 | angle = 29; | ||
| 572 | relative-to = "workspace-view"; | ||
| 573 | }) | ||
| 574 | ]) | ||
| 575 | (plain "focus-ring" [ | ||
| 576 | (flag "off") | ||
| 577 | ]) | ||
| 578 | |||
| 579 | (plain "preset-column-widths" (map (prop: sleaf "proportion" prop) [ | ||
| 580 | (1. / 4.) (1. / 3.) (1. / 2.) (2. / 3.) (3. / 4.) (1.) | ||
| 581 | ])) | ||
| 582 | (plain "default-column-width" [ (sleaf "proportion" (1. / 2.)) ]) | ||
| 583 | (plain "preset-window-heights" (map (prop: sleaf "proportion" prop) [ | ||
| 584 | (1. / 3.) (1. / 2.) (2. / 3.) (1.) | ||
| 585 | ])) | ||
| 586 | |||
| 587 | (flag "always-center-single-column") | ||
| 588 | |||
| 589 | (plain "tab-indicator" [ | ||
| 590 | (sleaf "gap" 4) | ||
| 591 | (sleaf "width" 8) | ||
| 592 | (sleaf "gaps-between-tabs" 4) | ||
| 593 | (flag "place-within-column") | ||
| 594 | (sleaf "length" { total-proportion = 1.; }) | ||
| 595 | (sleaf "active-gradient" { | ||
| 596 | from = "hsla(195 100% 60% 0.75)"; | ||
| 597 | to = "hsla(155 100% 50% 0.75)"; | ||
| 598 | angle = 29; | ||
| 599 | relative-to = "workspace-view"; | ||
| 600 | }) | ||
| 601 | (sleaf "inactive-gradient" { | ||
| 602 | from = "hsla(0 0% 42% 0.66)"; | ||
| 603 | to = "hsla(0 0% 35% 0.66)"; | ||
| 604 | angle = 29; | ||
| 605 | relative-to = "workspace-view"; | ||
| 606 | }) | ||
| 607 | ]) | ||
| 608 | ]) | ||
| 609 | |||
| 610 | (plain "cursor" [ | ||
| 611 | (flag "hide-when-typing") | ||
| 612 | ]) | ||
| 613 | |||
| 614 | (map (name: | ||
| 615 | (node "workspace" [name] [ | ||
| 616 | (sleaf "open-on-output" "eDP-1") | ||
| 617 | ]) | ||
| 618 | ) (map ({name, ...}: name) cfg.scratchspaces)) | ||
| 619 | (map (name: | ||
| 620 | (sleaf "workspace" name) | ||
| 621 | ) ["comm" "web" "vid" "bmr"]) | ||
| 622 | |||
| 623 | (plain "window-rule" [ | ||
| 624 | (sleaf "clip-to-geometry" true) | ||
| 625 | ]) | ||
| 626 | |||
| 627 | (plain "window-rule" [ | ||
| 628 | (sleaf "match" { is-floating = true; }) | ||
| 629 | (sleaf "geometry-corner-radius" 8) | ||
| 630 | (plain "shadow" [ (flag "on") ]) | ||
| 631 | ]) | ||
| 632 | |||
| 633 | (plain "window-rule" [ | ||
| 634 | (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; }) | ||
| 635 | (sleaf "block-out-from" "screencast") | ||
| 636 | ]) | ||
| 637 | (plain "window-rule" (normalize-nodes [ | ||
| 638 | (map (title: | ||
| 639 | (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) | ||
| 640 | ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$" "Browser Access Request$"]) | ||
| 641 | (sleaf "open-focused" true) | ||
| 642 | (sleaf "open-floating" true) | ||
| 643 | ])) | ||
| 644 | |||
| 645 | (map ({ name, match, exclude, windowRuleExtra, ... }: | ||
| 646 | (optional-node (match != []) (plain "window-rule" (normalize-nodes [ | ||
| 647 | (map (sleaf "match") match) | ||
| 648 | (map (sleaf "exclude") exclude) | ||
| 649 | (sleaf "open-on-workspace" name) | ||
| 650 | (sleaf "open-maximized" true) | ||
| 651 | windowRuleExtra | ||
| 652 | ]))) | ||
| 653 | ) cfg.scratchspaces) | ||
| 654 | |||
| 655 | (plain "window-rule" [ | ||
| 656 | (sleaf "match" { app-id = "^emacs$"; }) | ||
| 657 | (sleaf "match" { app-id = "^firefox$"; }) | ||
| 658 | (sleaf "match" { app-id = "^gnucash$"; }) | ||
| 659 | (sleaf "exclude" { app-id = "^gnucash$"; title = "^(Securities|Price Database)$"; }) | ||
| 660 | (plain "default-column-width" [(sleaf "proportion" (2. / 3.))]) | ||
| 661 | ]) | ||
| 662 | (plain "window-rule" [ | ||
| 663 | (sleaf "match" { app-id = "^Alacritty$"; }) | ||
| 664 | (sleaf "match" { app-id = "^Alacritty-play$"; }) | ||
| 665 | (plain "default-column-width" [(sleaf "proportion" (1. / 3.))]) | ||
| 666 | ]) | ||
| 667 | |||
| 668 | (plain "window-rule" [ | ||
| 669 | (sleaf "match" { app-id = "^thunderbird$"; }) | ||
| 670 | (sleaf "match" { app-id = "^Element$"; }) | ||
| 671 | (sleaf "match" { app-id = "^chrome-web\.openrainbow\.com__-Default$"; }) | ||
| 672 | (sleaf "open-on-workspace" "comm") | ||
| 673 | ]) | ||
| 674 | (plain "window-rule" [ | ||
| 675 | (sleaf "match" { app-id = "^firefox$"; }) | ||
| 676 | (sleaf "open-on-workspace" "web") | ||
| 677 | (sleaf "open-maximized" true) | ||
| 678 | ]) | ||
| 679 | (plain "window-rule" [ | ||
| 680 | (sleaf "match" { app-id = "^mpv$"; }) | ||
| 681 | (sleaf "open-on-workspace" "vid") | ||
| 682 | (plain "default-column-width" [(sleaf "proportion" 1.)]) | ||
| 683 | ]) | ||
| 684 | (plain "window-rule" [ | ||
| 685 | (sleaf "match" { app-id = "^Alacritty-play$"; }) | ||
| 686 | (sleaf "open-on-workspace" "vid") | ||
| 687 | (sleaf "open-focused" false) | ||
| 688 | ]) | ||
| 689 | (plain "window-rule" [ | ||
| 690 | (sleaf "match" { app-id = "^chrome-audiobookshelf\.yggdrasil\.li__-Default$"; }) | ||
| 691 | (sleaf "match" { app-id = "^YouTube Music Desktop App$"; }) | ||
| 692 | (sleaf "open-on-workspace" "vid") | ||
| 693 | ]) | ||
| 694 | (plain "window-rule" [ | ||
| 695 | (sleaf "match" { app-id = "^pdfpc$"; }) | ||
| 696 | (plain "default-column-width" [(sleaf "proportion" 1.)]) | ||
| 697 | ]) | ||
| 698 | (plain "window-rule" [ | ||
| 699 | (sleaf "match" { app-id = "^pdfpc$"; title = "^.*presentation.*$"; }) | ||
| 700 | (plain "default-column-width" [(sleaf "proportion" 1.)]) | ||
| 701 | (sleaf "open-fullscreen" true) | ||
| 702 | (sleaf "open-on-workspace" "bmr") | ||
| 703 | (sleaf "open-focused" false) | ||
| 704 | ]) | ||
| 705 | (plain "window-rule" (normalize-nodes [ | ||
| 706 | (map (sleaf "match") [ | ||
| 707 | { app-id = "^Gimp-"; title = "^Quit GIMP$"; } | ||
| 708 | { app-id = "^org\\.kde\\.polkit-kde-authentication-agent-1$"; } | ||
| 709 | { app-id = "^xdg-desktop-portal-gtk$"; } | ||
| 710 | ]) | ||
| 711 | (sleaf "open-floating" true) | ||
| 712 | ])) | ||
| 713 | (plain "window-rule" [ | ||
| 714 | (sleaf "match" { app-id = "^org\\.pwmt\\.zathura$"; }) | ||
| 715 | (sleaf "match" { app-id = "^evince$"; }) | ||
| 716 | (sleaf "match" { app-id = "^org\\.gnome\\.Papers$"; }) | ||
| 717 | (sleaf "default-column-display" "tabbed") | ||
| 718 | ]) | ||
| 719 | (plain "window-rule" [ | ||
| 720 | (sleaf "match" { is-window-cast-target = true; }) | ||
| 721 | (plain "border" [ | ||
| 722 | (sleaf "width" 2) | ||
| 723 | (sleaf "active-gradient" { | ||
| 724 | from = "hsla(20 100% 45% 1)"; | ||
| 725 | to = "hsla(340 100% 37.5% 1)"; | ||
| 726 | angle = 29; | ||
| 727 | relative-to = "workspace-view"; | ||
| 728 | }) | ||
| 729 | (sleaf "inactive-gradient" { | ||
| 730 | from = "hsla(20 50% 27.7% 1)"; | ||
| 731 | to = "hsla(340 50% 23% 1)"; | ||
| 732 | angle = 29; | ||
| 733 | relative-to = "workspace-view"; | ||
| 734 | }) | ||
| 735 | ]) | ||
| 736 | ]) | ||
| 737 | |||
| 738 | (plain "layer-rule" [ | ||
| 739 | (sleaf "match" { namespace = "^notifications$"; }) | ||
| 740 | (sleaf "match" { namespace = "^bar$"; }) | ||
| 741 | (sleaf "match" { namespace = "^launcher$"; }) | ||
| 742 | (sleaf "block-out-from" "screencast") | ||
| 743 | ]) | ||
| 744 | |||
| 745 | (plain "recent-windows" [ | ||
| 746 | (flag "off") | ||
| 747 | ]) | ||
| 748 | |||
| 749 | (plain "binds" | ||
| 750 | (let | ||
| 751 | bind = name: cfg: node name [(lib.removeAttrs cfg ["action"])] (lib.mapAttrsToList leaf (lib.removeAttrs cfg.action ["__functor"])); | ||
| 752 | |||
| 753 | move-column-to-workspace = kdl.magic-leaf "move-column-to-workspace"; | ||
| 754 | screenshot = kdl.magic-leaf "screenshot"; | ||
| 755 | screenshot-window = kdl.magic-leaf "screenshot-window"; | ||
| 756 | screenshot-screen = kdl.magic-leaf "screenshot-screen"; | ||
| 757 | in | ||
| 758 | normalize-nodes [ | ||
| 759 | (lib.mapAttrsToList bind (with config.lib.niri.actions; { | ||
| 760 | "Mod+Slash".action = show-hotkey-overlay; | ||
| 761 | |||
| 762 | "Mod+Return".action = spawn (spawnTerminal {}); | ||
| 763 | "Mod+Shift+Return".action = spawn (spawnTerminal { | ||
| 764 | command = lib.getExe config.programs.nushell.package; | ||
| 765 | }); | ||
| 766 | "Mod+Q".action = close-window; | ||
| 767 | "Mod+O".action = spawn (lib.getExe config.programs.fuzzel.package); | ||
| 768 | "Mod+Shift+O".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; | ||
| 769 | |||
| 770 | "Mod+Alt+E".action = spawn (lib.getExe' config.services.emacs.package "emacsclient") "-c"; | ||
| 771 | "Mod+Alt+Y".action = spawn (lib.getExe (pkgs.writeShellApplication { | ||
| 772 | name = "queue-yt-dlp"; | ||
| 773 | runtimeInputs = with pkgs; [ wl-clipboard-rs socat ]; | ||
| 774 | text = '' | ||
| 775 | socat STDIO UNIX-CONNECT:"$XDG_RUNTIME_DIR"/yt-dlp.sock <<<$'{ "urls": ["'"$(wl-paste)"$'"] }' | ||
| 776 | ''; | ||
| 777 | })); | ||
| 778 | "Mod+Alt+L".action = spawn (lib.getExe (pkgs.writeShellApplication { | ||
| 779 | name = "queue-yt-dlp"; | ||
| 780 | runtimeInputs = with pkgs; [ wl-clipboard-rs ]; | ||
| 781 | text = '' | ||
| 782 | exec -- ${lib.concatStringsSep " " (spawnTerminal { | ||
| 783 | extraArgs = [ "--class" "Alacritty-play" "--working-directory" "\"$HOME\"/media" ]; | ||
| 784 | command = ["mpv" "\"$(wl-paste)\""]; | ||
| 785 | })} | ||
| 786 | ''; | ||
| 787 | })); | ||
| 788 | "Mod+Alt+M".action = spawn (lib.getExe' pkgs.screen-message "sm") "-n" "Fira Mono" "-a" "1" "-f" "#fff" "-b" "#000"; | ||
| 789 | |||
| 790 | "Mod+U".action = spawn (lib.getExe (pkgs.writeShellApplication { | ||
| 791 | name = "qalc-fuzzel"; | ||
| 792 | runtimeInputs = with pkgs; [ wl-clipboard-rs libqalculate config.programs.fuzzel.package coreutils findutils libnotify gnugrep ]; | ||
| 793 | text = '' | ||
| 794 | RESULTS_DIR="$HOME/.cache/qalc-fuzzel" | ||
| 795 | prev() { | ||
| 796 | FOUND=false | ||
| 797 | while IFS= read -r line; do | ||
| 798 | [[ -n "$line" ]] || continue | ||
| 799 | FOUND=true | ||
| 800 | echo "$line" | ||
| 801 | done < <(export LC_ALL=C.UTF-8; echo; find "$RESULTS_DIR" -type f -printf $'%T@ %p\n' | sort -n | cut -d' ' -f2- | xargs -r cat) | ||
| 802 | $FOUND || echo | ||
| 803 | } | ||
| 804 | FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> " --width=60) || exit $? | ||
| 805 | if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then | ||
| 806 | QALC_RES="$FUZZEL_RES" | ||
| 807 | QALC_RET=0 | ||
| 808 | else | ||
| 809 | QALC_RES=$(qalc -set "autocalc off" "$FUZZEL_RES" 2>&1) | ||
| 810 | QALC_RET=$? | ||
| 811 | fi | ||
| 812 | [[ -n "$QALC_RES" ]] || exit 1 | ||
| 813 | EXISTING=false | ||
| 814 | set +o pipefail | ||
| 815 | grep -Fxrl "$QALC_RES" "$RESULTS_DIR" | xargs -r touch | ||
| 816 | [[ ''${PIPESTATUS[0]} -eq 0 ]] && EXISTING=true | ||
| 817 | set -o pipefail | ||
| 818 | if [[ $QALC_RET -eq 0 ]] && ! $EXISTING; then | ||
| 819 | set +o pipefail | ||
| 820 | RES_FILE="$RESULTS_DIR"/$(date -uIs).$(tr -Cd 'a-zA-Z0-9' </dev/random | head -c 10) | ||
| 821 | set -o pipefail | ||
| 822 | cat >"$RES_FILE" <<<"$QALC_RES" | ||
| 823 | fi | ||
| 824 | [[ "$QALC_RES" =~ .*\ =\ (.*) ]] && QALC_RES="''${BASH_REMATCH[1]}" | ||
| 825 | [[ $QALC_RET -eq 0 ]] && wl-copy "$QALC_RES" | ||
| 826 | notify-send "$QALC_RES" | ||
| 827 | ''; | ||
| 828 | })); | ||
| 829 | "Mod+Shift+U".action = spawn (spawnTerminal { | ||
| 830 | command = lib.getExe pkgs.libqalculate; | ||
| 831 | }); | ||
| 832 | # "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { | ||
| 833 | # name = "emoji-fuzzel"; | ||
| 834 | # runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; | ||
| 835 | # text = '' | ||
| 836 | # FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " --cache "$HOME"/.cache/fuzzel-emoji --width=60 <"$HOME"/.local/share/emoji-data/list.txt) || exit $? | ||
| 837 | # [[ -n "$FUZZEL_RES" ]] || exit 1 | ||
| 838 | # wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste | ||
| 839 | # ''; | ||
| 840 | # })); | ||
| 841 | "Print".action = screenshot; | ||
| 842 | "Control+Print".action = screenshot-window; | ||
| 843 | "Shift+Print".action = screenshot-screen; | ||
| 844 | "Mod+B".action = with-select-window-action ".workspace_id == ($active_workspace | tonumber)" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | ||
| 845 | "Mod+Shift+B".action = with-select-window-action "true" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | ||
| 846 | |||
| 847 | "Mod+Escape" = { | ||
| 848 | allow-inhibiting = false; | ||
| 849 | action = toggle-keyboard-shortcuts-inhibit; | ||
| 850 | }; | ||
| 851 | |||
| 852 | "Mod+H".action = focus-column-left; | ||
| 853 | "Mod+T".action = focus-window-down; | ||
| 854 | "Mod+N".action = focus-window-up; | ||
| 855 | "Mod+S".action = focus-column-right; | ||
| 856 | |||
| 857 | "Mod+Shift+H".action = move-column-left; | ||
| 858 | "Mod+Shift+T".action = move-window-down; | ||
| 859 | "Mod+Shift+N".action = move-window-up; | ||
| 860 | "Mod+Shift+S".action = move-column-right; | ||
| 861 | |||
| 862 | "Mod+Control+H".action = focus-monitor-left; | ||
| 863 | "Mod+Control+T".action = focus-monitor-down; | ||
| 864 | "Mod+Control+N".action = focus-monitor-up; | ||
| 865 | "Mod+Control+S".action = focus-monitor-right; | ||
| 866 | |||
| 867 | "Mod+Shift+Control+H".action = move-workspace-to-monitor-left; | ||
| 868 | "Mod+Shift+Control+T".action = move-workspace-to-monitor-down; | ||
| 869 | "Mod+Shift+Control+N".action = move-workspace-to-monitor-up; | ||
| 870 | "Mod+Shift+Control+S".action = move-workspace-to-monitor-right; | ||
| 871 | |||
| 872 | "Mod+G".action = focus-adjacent-workspace "down"; | ||
| 873 | "Mod+C".action = focus-adjacent-workspace "up"; | ||
| 874 | |||
| 875 | "Mod+Shift+G".action = move-column-to-adjacent-workspace "down"; | ||
| 876 | "Mod+Shift+C".action = move-column-to-adjacent-workspace "up"; | ||
| 877 | |||
| 878 | "Mod+Shift+Control+G".action = move-workspace-down; | ||
| 879 | "Mod+Shift+Control+C".action = move-workspace-up; | ||
| 880 | |||
| 881 | "Mod+ParenLeft".action = focus-workspace "comm"; | ||
| 882 | "Mod+Shift+ParenLeft".action = move-column-to-workspace "comm"; | ||
| 883 | |||
| 884 | "Mod+ParenRight".action = focus-workspace "web"; | ||
| 885 | "Mod+Shift+ParenRight".action = move-column-to-workspace "web"; | ||
| 886 | |||
| 887 | "Mod+BraceRight".action = focus-workspace "read"; | ||
| 888 | "Mod+Shift+BraceRight".action = move-column-to-workspace "read"; | ||
| 889 | |||
| 890 | "Mod+BraceLeft".action = focus-workspace "mon"; | ||
| 891 | "Mod+Shift+BraceLeft".action = move-column-to-workspace "mon"; | ||
| 892 | |||
| 893 | "Mod+Asterisk".action = focus-workspace "vid"; | ||
| 894 | "Mod+Shift+Asterisk".action = move-column-to-workspace "vid"; | ||
| 895 | |||
| 896 | "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; | ||
| 897 | "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}''; | ||
| 898 | |||
| 899 | "Mod+M".action = consume-or-expel-window-left; | ||
| 900 | "Mod+W".action = consume-or-expel-window-right; | ||
| 901 | |||
| 902 | "Mod+Shift+M".action = toggle-column-tabbed-display; | ||
| 903 | |||
| 904 | "Mod+L".action = maximize-window-to-edges; | ||
| 905 | "Mod+R".action = switch-preset-column-width; | ||
| 906 | "Mod+Shift+R".action = maximize-column; | ||
| 907 | "Mod+Shift+Ctrl+R".action = switch-preset-window-height; | ||
| 908 | "Mod+F".action = center-column; | ||
| 909 | "Mod+Shift+F".action = toggle-windowed-fullscreen; | ||
| 910 | "Mod+Ctrl+Shift+F".action = fullscreen-window; | ||
| 911 | |||
| 912 | "Mod+V".action = switch-focus-between-floating-and-tiling; | ||
| 913 | "Mod+Shift+V".action = toggle-window-floating; | ||
| 914 | |||
| 915 | "Mod+Left".action = set-column-width "-10%"; | ||
| 916 | "Mod+Down".action = set-window-height "-10%"; | ||
| 917 | "Mod+Up".action = set-window-height "+10%"; | ||
| 918 | "Mod+Right".action = set-column-width "+10%"; | ||
| 919 | |||
| 920 | "Mod+Shift+Z" = { | ||
| 921 | action = power-off-monitors; | ||
| 922 | allow-when-locked = true; | ||
| 923 | }; | ||
| 924 | "Mod+Shift+E".action = quit; | ||
| 925 | |||
| 926 | # "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; | ||
| 927 | # "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; | ||
| 928 | # "Mod+Period".action = spawn makoctl "menu" "--" (lib.getExe config.programs.fuzzel.package) "--dmenu"; | ||
| 929 | # "Mod+Comma".action = spawn makoctl "restore"; | ||
| 930 | |||
| 931 | "Mod+Control+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"FocusWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; | ||
| 932 | "Mod+Control+Shift+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"MoveColumnToWorkspace\":{\"reference\":{\"Id\": $workspace_id}, \"focus\": true}}}"; | ||
| 933 | |||
| 934 | "Mod+X".action = set-dynamic-cast-window; | ||
| 935 | "Mod+Shift+X".action = set-dynamic-cast-monitor; | ||
| 936 | "Mod+Control+Shift+X".action = clear-dynamic-cast-target; | ||
| 937 | |||
| 938 | "Mod+D".action = with-urgent-window-action "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | ||
| 939 | "Mod+Shift+D".action = with-focused-window-action "{\"Action\":{\"UnsetUrgent\":{\"id\": .id}}}"; | ||
| 940 | |||
| 941 | "Mod+K".action = spawn (toString (pkgs.resholve.writeScript "worktime-ui" { | ||
| 942 | interpreter = pkgs.runtimeShell; | ||
| 943 | inputs = [ pkgs.worktime config.programs.quickshell.package ]; | ||
| 944 | execer = [ | ||
| 945 | "cannot:${lib.getExe' config.programs.quickshell.package "qs"}" | ||
| 946 | ]; | ||
| 947 | } '' | ||
| 948 | worktime-ui && qs ipc call Worktime refresh | ||
| 949 | '')); | ||
| 950 | "Mod+Shift+K".action = spawn (lib.getExe' pkgs.worktime "worktime-stop"); | ||
| 951 | })) | ||
| 952 | (lib.mapAttrsToList (name: cfg: node name [(lib.removeAttrs cfg ["action"])] [cfg.action]) (let | ||
| 953 | shell = obj: leaf "send-unix" [ | ||
| 954 | { path = ''''${XDG_RUNTIME_DIR}/shell.sock''; } | ||
| 955 | (builtins.toJSON obj + "\n") | ||
| 956 | ]; | ||
| 957 | in { | ||
| 958 | "XF86AudioRaiseVolume" = { | ||
| 959 | allow-when-locked = true; | ||
| 960 | action = shell { Volume.volume = "up"; }; | ||
| 961 | }; | ||
| 962 | "XF86AudioLowerVolume" = { | ||
| 963 | allow-when-locked = true; | ||
| 964 | action = shell { Volume.volume = "down"; }; | ||
| 965 | }; | ||
| 966 | "XF86AudioMute" = { | ||
| 967 | allow-when-locked = true; | ||
| 968 | action = shell { Volume.muted = "toggle"; }; | ||
| 969 | }; | ||
| 970 | "XF86AudioMicMute" = { | ||
| 971 | allow-when-locked = true; | ||
| 972 | action = shell { Volume."mic-muted" = "toggle"; }; | ||
| 973 | }; | ||
| 974 | "XF86MonBrightnessUp" = { | ||
| 975 | action = shell { Brightness = "up"; }; | ||
| 976 | allow-when-locked = true; | ||
| 977 | }; | ||
| 978 | "XF86MonBrightnessDown" = { | ||
| 979 | action = shell { Brightness = "down"; }; | ||
| 980 | allow-when-locked = true; | ||
| 981 | }; | ||
| 982 | "Mod+Shift+L".action = shell { LockSession = {}; }; | ||
| 983 | "Mod+Shift+Minus" = { | ||
| 984 | action = shell { Suspend = {}; }; | ||
| 985 | allow-when-locked = true; | ||
| 986 | }; | ||
| 987 | "Mod+Shift+Control+Minus" = { | ||
| 988 | action = shell { Hibernate = {}; }; | ||
| 989 | allow-when-locked = true; | ||
| 990 | }; | ||
| 991 | "Mod+Shift+P" = { | ||
| 992 | action = shell { Mpris = { PauseAll = {}; }; }; | ||
| 993 | allow-when-locked = true; | ||
| 994 | }; | ||
| 995 | "Mod+Semicolon".action = shell { Notifications = { DismissGroup = {}; }; }; | ||
| 996 | "Mod+Shift+Semicolon".action = shell { Notifications = { DismissAll = {}; }; }; | ||
| 997 | "Mod+Print".action = shell { ScreenRecord = { Toggle = {}; }; }; | ||
| 998 | })) | ||
| 999 | (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) | ||
| 1000 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = move-column-to-workspace name; } else null) cfg.scratchspaces) | ||
| 1001 | ] | ||
| 1002 | )) | ||
| 1003 | ]; | ||
| 1004 | }; | ||
| 1005 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/default.nix b/accounts/gkleen@skadhi/shell/default.nix new file mode 100644 index 00000000..09eb6863 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/default.nix | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | { config, pkgs, lib, ... }: | ||
| 2 | |||
| 3 | { | ||
| 4 | config = { | ||
| 5 | programs.quickshell = { | ||
| 6 | enable = true; | ||
| 7 | package = pkgs.symlinkJoin { | ||
| 8 | pname = pkgs.quickshell.pname + "-wrapped"; | ||
| 9 | inherit (pkgs.quickshell) version meta; | ||
| 10 | paths = [ pkgs.quickshell ]; | ||
| 11 | buildInputs = [ pkgs.makeWrapper ]; | ||
| 12 | postBuild = '' | ||
| 13 | for binary in quickshell qs; do | ||
| 14 | wrapProgram $out/bin/$binary \ | ||
| 15 | --prefix QT_PLUGIN_PATH : ${pkgs.qt6.qtimageformats}/${pkgs.qt6.qtbase.qtPluginPrefix} \ | ||
| 16 | --prefix QML_IMPORT_PATH : ${pkgs.qt6Packages.callPackage ./quickshell-plugins {}}/${pkgs.qt6.qtbase.qtQmlPrefix} | ||
| 17 | done | ||
| 18 | ''; | ||
| 19 | }; | ||
| 20 | config = { | ||
| 21 | src = ./quickshell; | ||
| 22 | replacements = { | ||
| 23 | ignore_workspaces = builtins.toJSON (map ({ name, ... }: name) config.programs.niri.scratchspaces); | ||
| 24 | wallpapers = builtins.toJSON (pkgs.stdenvNoCC.mkDerivation { | ||
| 25 | name = "wallpapers"; | ||
| 26 | srcs = [ | ||
| 27 | (pkgs.fetchurl { | ||
| 28 | url = "https://esawebb.org/media/archives/images/publicationtiff10k/carinanebula3.tif"; | ||
| 29 | hash = "sha256-YxZEweDKJfvfrdxb/QFmgJhcZDEJYxotoHrG+RRn1tw="; | ||
| 30 | }) | ||
| 31 | (pkgs.fetchurl { | ||
| 32 | url = "https://esawebb.org/media/archives/images/original/pillarsofcreation_composite.tif"; | ||
| 33 | hash = "sha256-qRiODxR0lZWdxgYXna0fNRFFDErpBJDwOJuQl6sNjRc="; | ||
| 34 | }) | ||
| 35 | (pkgs.fetchurl { | ||
| 36 | url = "https://esawebb.org/media/archives/images/publicationtiff10k/weic2212a.tif"; | ||
| 37 | hash = "sha256-l2fqE/z//C1a0xkvZwsnwPbTSb+WuA11h+SUl3E1dhw="; | ||
| 38 | }) | ||
| 39 | (pkgs.fetchurl { | ||
| 40 | url = "https://esawebb.org/media/archives/images/publicationtiff10k/weic2415a.tif"; | ||
| 41 | hash = "sha256-onBy7cPoUpDuzQStbY2E+qmlGgSLXPwFCLX53ukAb4c="; | ||
| 42 | }) | ||
| 43 | (pkgs.fetchurl { | ||
| 44 | url = "https://esawebb.org/media/archives/images/publicationtiff10k/weic2330a.tif"; | ||
| 45 | hash = "sha256-nn0ZtjZIrPcpj3YcLTsrL7XiXvyh3QYgCSmdDMD+3OM="; | ||
| 46 | }) | ||
| 47 | (pkgs.fetchurl { | ||
| 48 | url = "https://esawebb.org/media/archives/images/original/weic2426a.tif"; | ||
| 49 | hash = "sha256-EDnfPn3GE9jt6XPqiGInP7E2F3Az7d25NqATSWltDv0="; | ||
| 50 | }) | ||
| 51 | (pkgs.fetchurl { | ||
| 52 | url = "https://esawebb.org/media/archives/images/original/weic2503a.tif"; | ||
| 53 | hash = "sha256-3/RX6RQp8naELcgReHPd5/zhJkoCjnA10w5BEnNo+qI="; | ||
| 54 | }) | ||
| 55 | (pkgs.fetchurl { | ||
| 56 | url = "https://esawebb.org/media/archives/images/original/weic2506a.tif"; | ||
| 57 | hash = "sha256-aDld0aoY1owRxDVf7Jcyw71TH42M1foYotxn2thyFYw="; | ||
| 58 | }) | ||
| 59 | (pkgs.fetchurl { | ||
| 60 | url = "https://esawebb.org/media/archives/images/original/weic2514a.tif"; | ||
| 61 | hash = "sha256-jTi1G1Ofo5xsF6ggrbtYJHxqLaCQ7edM5B3uORiVQtg="; | ||
| 62 | }) | ||
| 63 | (pkgs.fetchurl { | ||
| 64 | url = "https://esawebb.org/media/archives/images/original/weic2425c.tif"; | ||
| 65 | hash = "sha256-oaEOexSJHEGj090dJF3ct5HAoR+Y5gRiPrUlxdvnTRo="; | ||
| 66 | }) | ||
| 67 | (pkgs.fetchurl { | ||
| 68 | url = "https://esawebb.org/media/archives/images/original/weic2605c.tif"; | ||
| 69 | hash = "sha256-IwWfgkz84LFXkfk77anb5e0Mf0wWiIszum7UC3yZn0U="; | ||
| 70 | }) | ||
| 71 | ]; | ||
| 72 | |||
| 73 | dontUnpack = true; | ||
| 74 | |||
| 75 | buildInputs = [ pkgs.imagemagick ]; | ||
| 76 | buildPhase = '' | ||
| 77 | runHook preBuild | ||
| 78 | |||
| 79 | typeset sources=($srcs) | ||
| 80 | |||
| 81 | mkdir -p $out | ||
| 82 | magick ''${sources[0]} -crop 10000x5625+0+79 +repage -define webp:target-size=10000000 $out/carinanebula3.webp | ||
| 83 | magick ''${sources[1]} -crop 6716x3778+329+80 +repage -define webp:target-size=10000000 $out/pillarsofcreation_composite.webp | ||
| 84 | magick ''${sources[2]} -crop 10000x5625+0+79 +repage -define webp:target-size=10000000 $out/weic2212a.webp | ||
| 85 | magick ''${sources[3]} -crop 7650x4302+1166+389 +repage -define webp:target-size=10000000 $out/weic2415a.webp | ||
| 86 | magick ''${sources[4]} -crop 8732x4912+0+434 +repage -define webp:target-size=10000000 $out/weic2330a.webp | ||
| 87 | magick ''${sources[5]} -crop 5302x2982+636+0 +repage -define webp:target-size=10000000 $out/weic2426a.webp | ||
| 88 | magick ''${sources[6]} -crop 4328x2434+0+906 +repage -define webp:target-size=10000000 $out/weic2503a.webp | ||
| 89 | magick ''${sources[7]} -crop 4152x2335+0+666 +repage -define webp:target-size=10000000 $out/weic2506a.webp | ||
| 90 | magick ''${sources[8]} -crop 4320x2430+0+0 +repage -define webp:target-size=10000000 $out/weic2514a.webp | ||
| 91 | magick ''${sources[9]} -crop 5863x3298+0+477 +repage -define webp:target-size=10000000 $out/weic2425c.webp | ||
| 92 | magick ''${sources[10]} -crop 3990x2244+0+1379 +repage -define webp:target-size=10000000 $out/weic2605c.webp | ||
| 93 | |||
| 94 | runHook postBuild | ||
| 95 | ''; | ||
| 96 | }); | ||
| 97 | niri_session = builtins.toJSON [ | ||
| 98 | (pkgs.writeShellScript "niri-session" '' | ||
| 99 | exec ${lib.getExe pkgs.dex} -w ${config.programs.niri.package}/share/wayland-sessions/niri.desktop &>/tmp/niri-session-$$.log | ||
| 100 | '') | ||
| 101 | # (lib.getExe pkgs.dex) | ||
| 102 | # "${config.programs.niri.package}/share/wayland-sessions/niri.desktop" | ||
| 103 | ]; | ||
| 104 | username = builtins.toJSON config.home.username; | ||
| 105 | mdi = builtins.toJSON (pkgs.fetchFromGitHub { | ||
| 106 | owner = "Templarian"; | ||
| 107 | repo = "MaterialDesign"; | ||
| 108 | rev = "2424e748e0cc63ab7b9c095a099b9fe239b737c0"; | ||
| 109 | hash = "sha256-QMGl7soAhErrrnY3aKOZpt49yebkSNzy10p/v5OaqQ0="; | ||
| 110 | }); | ||
| 111 | worktime = builtins.toJSON (lib.getExe pkgs.worktime); | ||
| 112 | slurp = builtins.toJSON (lib.getExe pkgs.slurp); | ||
| 113 | wf-recorder = builtins.toJSON (lib.getExe pkgs.wf-recorder); | ||
| 114 | }; | ||
| 115 | }; | ||
| 116 | }; | ||
| 117 | systemd.user.services.quickshell = { | ||
| 118 | Service = { | ||
| 119 | RuntimeDirectory = "quickshell"; | ||
| 120 | }; | ||
| 121 | }; | ||
| 122 | }; | ||
| 123 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/CMakeLists.txt b/accounts/gkleen@skadhi/shell/quickshell-plugins/CMakeLists.txt new file mode 100644 index 00000000..6b4f0d48 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/CMakeLists.txt | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | set(INSTALL_QMLDIR "" CACHE STRING "QML install dir") | ||
| 2 | set(INSTALL_QML_PREFIX "" CACHE STRING "QML install prefix") | ||
| 3 | |||
| 4 | # There doesn't seem to be a standard cross-distro qml install path. | ||
| 5 | if ("${INSTALL_QMLDIR}" STREQUAL "" AND "${INSTALL_QML_PREFIX}" STREQUAL "") | ||
| 6 | message(WARNING "Neither INSTALL_QMLDIR nor INSTALL_QML_PREFIX is set. QML modules will not be installed.") | ||
| 7 | else() | ||
| 8 | if ("${INSTALL_QMLDIR}" STREQUAL "") | ||
| 9 | set(QML_FULL_INSTALLDIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_QML_PREFIX}") | ||
| 10 | else() | ||
| 11 | set(QML_FULL_INSTALLDIR "${INSTALL_QMLDIR}") | ||
| 12 | endif() | ||
| 13 | |||
| 14 | message(STATUS "QML install dir: ${QML_FULL_INSTALLDIR}") | ||
| 15 | endif() | ||
| 16 | |||
| 17 | # Install a given target as a QML module. This is mostly pulled from ECM, as there does not seem | ||
| 18 | # to be an official way to do it. | ||
| 19 | # see https://github.com/KDE/extra-cmake-modules/blob/fe0f606bf7f222e36f7560fd7a2c33ef993e23bb/modules/ECMQmlModule6.cmake#L160 | ||
| 20 | function(install_qml_module arg_TARGET) | ||
| 21 | if (NOT DEFINED QML_FULL_INSTALLDIR) | ||
| 22 | return() | ||
| 23 | endif() | ||
| 24 | |||
| 25 | qt_query_qml_module(${arg_TARGET} | ||
| 26 | URI module_uri | ||
| 27 | VERSION module_version | ||
| 28 | PLUGIN_TARGET module_plugin_target | ||
| 29 | TARGET_PATH module_target_path | ||
| 30 | QMLDIR module_qmldir | ||
| 31 | TYPEINFO module_typeinfo | ||
| 32 | QML_FILES module_qml_files | ||
| 33 | RESOURCES module_resources | ||
| 34 | ) | ||
| 35 | |||
| 36 | set(module_dir "${QML_FULL_INSTALLDIR}/${module_target_path}") | ||
| 37 | |||
| 38 | if (NOT TARGET "${module_plugin_target}") | ||
| 39 | message(FATAL_ERROR "install_qml_modules called for a target without a plugin") | ||
| 40 | endif() | ||
| 41 | |||
| 42 | get_target_property(target_type "${arg_TARGET}" TYPE) | ||
| 43 | if (NOT "${target_type}" STREQUAL "STATIC_LIBRARY") | ||
| 44 | install( | ||
| 45 | TARGETS "${arg_TARGET}" | ||
| 46 | LIBRARY DESTINATION "${module_dir}" | ||
| 47 | RUNTIME DESTINATION "${module_dir}" | ||
| 48 | ) | ||
| 49 | |||
| 50 | install( | ||
| 51 | TARGETS "${module_plugin_target}" | ||
| 52 | LIBRARY DESTINATION "${module_dir}" | ||
| 53 | RUNTIME DESTINATION "${module_dir}" | ||
| 54 | ) | ||
| 55 | endif() | ||
| 56 | |||
| 57 | install(FILES "${module_qmldir}" DESTINATION "${module_dir}") | ||
| 58 | install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") | ||
| 59 | |||
| 60 | # Install QML files | ||
| 61 | list(LENGTH module_qml_files num_files) | ||
| 62 | if (NOT "${module_qml_files}" MATCHES "NOTFOUND" AND ${num_files} GREATER 0) | ||
| 63 | qt_query_qml_module(${arg_TARGET} QML_FILES_DEPLOY_PATHS qml_files_deploy_paths) | ||
| 64 | |||
| 65 | math(EXPR last_index "${num_files} - 1") | ||
| 66 | foreach(i RANGE 0 ${last_index}) | ||
| 67 | list(GET module_qml_files ${i} src_file) | ||
| 68 | list(GET qml_files_deploy_paths ${i} deploy_path) | ||
| 69 | get_filename_component(dst_name "${deploy_path}" NAME) | ||
| 70 | get_filename_component(dest_dir "${deploy_path}" DIRECTORY) | ||
| 71 | install(FILES "${src_file}" DESTINATION "${module_dir}/${dest_dir}" RENAME "${dst_name}") | ||
| 72 | endforeach() | ||
| 73 | endif() | ||
| 74 | |||
| 75 | # Install resources | ||
| 76 | list(LENGTH module_resources num_files) | ||
| 77 | if (NOT "${module_resources}" MATCHES "NOTFOUND" AND ${num_files} GREATER 0) | ||
| 78 | qt_query_qml_module(${arg_TARGET} RESOURCES_DEPLOY_PATHS resources_deploy_paths) | ||
| 79 | |||
| 80 | math(EXPR last_index "${num_files} - 1") | ||
| 81 | foreach(i RANGE 0 ${last_index}) | ||
| 82 | list(GET module_resources ${i} src_file) | ||
| 83 | list(GET resources_deploy_paths ${i} deploy_path) | ||
| 84 | get_filename_component(dst_name "${deploy_path}" NAME) | ||
| 85 | get_filename_component(dest_dir "${deploy_path}" DIRECTORY) | ||
| 86 | install(FILES "${src_file}" DESTINATION "${module_dir}/${dest_dir}" RENAME "${dst_name}") | ||
| 87 | endforeach() | ||
| 88 | endif() | ||
| 89 | endfunction() | ||
| 90 | |||
| 91 | |||
| 92 | cmake_minimum_required(VERSION 3.20) | ||
| 93 | project(custom LANGUAGES CXX) | ||
| 94 | |||
| 95 | find_package(Qt6 REQUIRED COMPONENTS Core Qml DBus) | ||
| 96 | |||
| 97 | qt_standard_project_setup(REQUIRES 6.6) | ||
| 98 | |||
| 99 | qt6_policy(SET QTP0001 NEW) | ||
| 100 | qt6_add_qml_module(customplugin | ||
| 101 | URI "Custom" | ||
| 102 | PLUGIN_TARGET customplugin | ||
| 103 | ) | ||
| 104 | |||
| 105 | set_source_files_properties(org.keepassxc.KeePassXC.MainWindow.xml PROPERTIES | ||
| 106 | CLASSNAME DBusKeePassXC | ||
| 107 | NO_NAMESPACE TRUE | ||
| 108 | ) | ||
| 109 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 110 | org.keepassxc.KeePassXC.MainWindow.xml | ||
| 111 | dbus_keepassxc | ||
| 112 | ) | ||
| 113 | |||
| 114 | set_source_files_properties(org.freedesktop.systemd1.Manager.xml PROPERTIES | ||
| 115 | CLASSNAME DBusSystemdManager | ||
| 116 | NO_NAMESPACE TRUE | ||
| 117 | INCLUDE ListUnitsEntry.hpp | ||
| 118 | ) | ||
| 119 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 120 | org.freedesktop.systemd1.Manager.xml | ||
| 121 | dbus_systemd_manager | ||
| 122 | ) | ||
| 123 | |||
| 124 | set_source_files_properties(org.freedesktop.login1.Manager.xml PROPERTIES | ||
| 125 | CLASSNAME DBusLogindManager | ||
| 126 | NO_NAMESPACE TRUE | ||
| 127 | ) | ||
| 128 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 129 | org.freedesktop.login1.Manager.xml | ||
| 130 | dbus_logind_manager | ||
| 131 | ) | ||
| 132 | |||
| 133 | set_source_files_properties(org.freedesktop.login1.Session.xml PROPERTIES | ||
| 134 | CLASSNAME DBusLogindSession | ||
| 135 | NO_NAMESPACE TRUE | ||
| 136 | ) | ||
| 137 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 138 | org.freedesktop.login1.Session.xml | ||
| 139 | dbus_logind_session | ||
| 140 | ) | ||
| 141 | |||
| 142 | set_source_files_properties(org.freedesktop.systemd1.Unit.xml PROPERTIES | ||
| 143 | CLASSNAME DBusSystemdUnit | ||
| 144 | NO_NAMESPACE TRUE | ||
| 145 | ) | ||
| 146 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 147 | org.freedesktop.systemd1.Unit.xml | ||
| 148 | dbus_systemd_unit | ||
| 149 | ) | ||
| 150 | |||
| 151 | set_source_files_properties(org.freedesktop.systemd1.Service.xml PROPERTIES | ||
| 152 | CLASSNAME DBusSystemdService | ||
| 153 | NO_NAMESPACE TRUE | ||
| 154 | ) | ||
| 155 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 156 | org.freedesktop.systemd1.Service.xml | ||
| 157 | dbus_systemd_service | ||
| 158 | ) | ||
| 159 | |||
| 160 | set_source_files_properties(org.freedesktop.DBus.Properties.xml PROPERTIES | ||
| 161 | CLASSNAME DBusProperties | ||
| 162 | NO_NAMESPACE TRUE | ||
| 163 | ) | ||
| 164 | qt_add_dbus_interface(DBUS_INTERFACES | ||
| 165 | org.freedesktop.DBus.Properties.xml | ||
| 166 | dbus_properties | ||
| 167 | ) | ||
| 168 | |||
| 169 | include_directories(${CMAKE_SOURCE_DIR}/build) | ||
| 170 | include_directories(${QUICKSHELL_SRC}/src) | ||
| 171 | |||
| 172 | target_compile_features(customplugin PUBLIC cxx_std_26) | ||
| 173 | |||
| 174 | target_link_libraries(customplugin PRIVATE | ||
| 175 | Qt6::Core | ||
| 176 | Qt6::Qml | ||
| 177 | Qt6::DBus | ||
| 178 | ) | ||
| 179 | |||
| 180 | target_sources(customplugin PRIVATE | ||
| 181 | Chrono.cpp Chrono.hpp | ||
| 182 | FileSelector.cpp FileSelector.hpp | ||
| 183 | KeePassXC.cpp KeePassXC.hpp | ||
| 184 | Systemd.cpp Systemd.hpp | ||
| 185 | ListUnitsEntry.cpp ListUnitsEntry.hpp | ||
| 186 | ${DBUS_INTERFACES} | ||
| 187 | ${QUICKSHELL_SRC}/src/core/model.cpp ${QUICKSHELL_SRC}/src/core/model.hpp | ||
| 188 | ) | ||
| 189 | |||
| 190 | install_qml_module(customplugin) | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.cpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.cpp new file mode 100644 index 00000000..22b3469b --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.cpp | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | #include "Chrono.hpp" | ||
| 2 | |||
| 3 | #include <format> | ||
| 4 | #include <iostream> | ||
| 5 | #include <cmath> | ||
| 6 | |||
| 7 | Chrono::Chrono(QObject* parent): QObject(parent) { | ||
| 8 | QObject::connect(&this->timer, &QTimer::timeout, this, &Chrono::onTimeout); | ||
| 9 | this->update(); | ||
| 10 | } | ||
| 11 | |||
| 12 | bool Chrono::enabled() const { return this->mEnabled; } | ||
| 13 | |||
| 14 | void Chrono::setEnabled(bool enabled) { | ||
| 15 | if (enabled == this->mEnabled) return; | ||
| 16 | this->mEnabled = enabled; | ||
| 17 | emit this->enabledChanged(); | ||
| 18 | this->update(); | ||
| 19 | } | ||
| 20 | |||
| 21 | Chrono::Precision Chrono::precision() const { return this->mPrecision; } | ||
| 22 | |||
| 23 | void Chrono::setPrecision(Chrono::Precision precision) { | ||
| 24 | if (precision == this->mPrecision) return; | ||
| 25 | this->mPrecision = precision; | ||
| 26 | emit this->precisionChanged(); | ||
| 27 | this->update(); | ||
| 28 | } | ||
| 29 | |||
| 30 | void Chrono::onTimeout() { | ||
| 31 | this->setTime(this->targetTime); | ||
| 32 | this->schedule(this->targetTime); | ||
| 33 | } | ||
| 34 | |||
| 35 | void Chrono::update() { | ||
| 36 | if (this->mEnabled) { | ||
| 37 | this->setTime(std::chrono::time_point<std::chrono::system_clock>()); | ||
| 38 | this->schedule(std::chrono::time_point<std::chrono::system_clock>()); | ||
| 39 | } else { | ||
| 40 | this->timer.stop(); | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | void Chrono::setTime(const std::chrono::time_point<std::chrono::system_clock>& targetTime) { | ||
| 45 | using namespace std::chrono_literals; | ||
| 46 | |||
| 47 | auto currentTime = std::chrono::system_clock::now(); | ||
| 48 | auto offset = std::chrono::duration_cast<std::chrono::milliseconds>(targetTime - currentTime); | ||
| 49 | this->currentTime = abs(offset) < 500ms ? targetTime : currentTime; | ||
| 50 | |||
| 51 | switch (this->mPrecision) { | ||
| 52 | case Chrono::Hours: this->currentTime = std::chrono::time_point_cast<std::chrono::hours>(this->currentTime); | ||
| 53 | case Chrono::Minutes: this->currentTime = std::chrono::time_point_cast<std::chrono::minutes>(this->currentTime); | ||
| 54 | case Chrono::Seconds: this->currentTime = std::chrono::time_point_cast<std::chrono::seconds>(this->currentTime); | ||
| 55 | } | ||
| 56 | |||
| 57 | emit this->dateChanged(); | ||
| 58 | } | ||
| 59 | |||
| 60 | void Chrono::schedule(const std::chrono::time_point<std::chrono::system_clock>& targetTime) { | ||
| 61 | using namespace std::chrono_literals; | ||
| 62 | |||
| 63 | auto currentTime = std::chrono::system_clock::now(); | ||
| 64 | auto offset = std::chrono::duration_cast<std::chrono::milliseconds>(targetTime - currentTime); | ||
| 65 | auto nextTime = abs(offset) < 500ms ? targetTime : currentTime; | ||
| 66 | |||
| 67 | switch (this->mPrecision) { | ||
| 68 | case Chrono::Hours: nextTime = std::chrono::time_point_cast<std::chrono::hours>(nextTime) + 1h; | ||
| 69 | case Chrono::Minutes: nextTime = std::chrono::time_point_cast<std::chrono::minutes>(nextTime) + 1min; | ||
| 70 | case Chrono::Seconds: nextTime = std::chrono::time_point_cast<std::chrono::seconds>(nextTime) + 1s; | ||
| 71 | } | ||
| 72 | |||
| 73 | this->targetTime = nextTime; | ||
| 74 | this->timer.start(std::chrono::duration_cast<std::chrono::milliseconds>(nextTime - currentTime)); | ||
| 75 | } | ||
| 76 | |||
| 77 | QString Chrono::format(const QString& fmt) const { | ||
| 78 | return QString::fromStdString(std::format(std::runtime_format(fmt.toStdString()), std::chrono::zoned_time(std::chrono::current_zone(), std::chrono::time_point_cast<std::chrono::seconds>(this->currentTime)))); | ||
| 79 | } | ||
| 80 | |||
| 81 | QDateTime Chrono::date() const { | ||
| 82 | return QDateTime::fromStdTimePoint(std::chrono::time_point_cast<std::chrono::milliseconds>(this->currentTime)); | ||
| 83 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.hpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.hpp new file mode 100644 index 00000000..04080187 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/Chrono.hpp | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <chrono> | ||
| 4 | |||
| 5 | #include <QDateTime> | ||
| 6 | #include <QObject> | ||
| 7 | #include <QTimer> | ||
| 8 | |||
| 9 | #include <qqmlintegration.h> | ||
| 10 | |||
| 11 | class Chrono : public QObject { | ||
| 12 | Q_OBJECT; | ||
| 13 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged); | ||
| 14 | Q_PROPERTY(Chrono::Precision precision READ precision WRITE setPrecision NOTIFY precisionChanged); | ||
| 15 | Q_PROPERTY(QDateTime date READ date NOTIFY dateChanged) | ||
| 16 | QML_ELEMENT; | ||
| 17 | |||
| 18 | public: | ||
| 19 | enum Precision : quint8 { | ||
| 20 | Hours = 1, | ||
| 21 | Minutes = 2, | ||
| 22 | Seconds = 3, | ||
| 23 | }; | ||
| 24 | Q_ENUM(Precision); | ||
| 25 | |||
| 26 | explicit Chrono(QObject* parent = nullptr); | ||
| 27 | |||
| 28 | bool enabled() const; | ||
| 29 | void setEnabled(bool enabled); | ||
| 30 | |||
| 31 | Chrono::Precision precision() const; | ||
| 32 | void setPrecision(Chrono::Precision precision); | ||
| 33 | |||
| 34 | Q_INVOKABLE QString format(const QString& fmt) const; | ||
| 35 | |||
| 36 | QDateTime date() const; | ||
| 37 | |||
| 38 | signals: | ||
| 39 | void enabledChanged(); | ||
| 40 | void precisionChanged(); | ||
| 41 | void dateChanged(); | ||
| 42 | |||
| 43 | private slots: | ||
| 44 | void onTimeout(); | ||
| 45 | |||
| 46 | private: | ||
| 47 | bool mEnabled = true; | ||
| 48 | Chrono::Precision mPrecision = Chrono::Seconds; | ||
| 49 | QTimer timer; | ||
| 50 | std::chrono::time_point<std::chrono::system_clock> currentTime, targetTime; | ||
| 51 | |||
| 52 | void update(); | ||
| 53 | void setTime(const std::chrono::time_point<std::chrono::system_clock>& targetTime); | ||
| 54 | void schedule(const std::chrono::time_point<std::chrono::system_clock>& targetTime); | ||
| 55 | }; | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.cpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.cpp new file mode 100644 index 00000000..d7051d2a --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.cpp | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | #include "FileSelector.hpp" | ||
| 2 | |||
| 3 | #include <sstream> | ||
| 4 | #include <vector> | ||
| 5 | #include <random> | ||
| 6 | #include <algorithm> | ||
| 7 | |||
| 8 | #include <iostream> | ||
| 9 | #include <format> | ||
| 10 | |||
| 11 | namespace fs = std::filesystem; | ||
| 12 | |||
| 13 | FileSelector::FileSelector(QObject* parent): QObject(parent) { | ||
| 14 | QObject::connect(&this->timer, &QTimer::timeout, this, &FileSelector::onTimeout); | ||
| 15 | this->timer.setTimerType(Qt::PreciseTimer); | ||
| 16 | } | ||
| 17 | |||
| 18 | QString FileSelector::directory() const { | ||
| 19 | return QString::fromStdString(this->mDirectory->string()); | ||
| 20 | } | ||
| 21 | void FileSelector::setDirectory(QString directory) { | ||
| 22 | this->mDirectory = directory.toStdString(); | ||
| 23 | if (this->mDirectory && this->mEpoch) | ||
| 24 | this->update(); | ||
| 25 | emit this->directoryChanged(); | ||
| 26 | } | ||
| 27 | |||
| 28 | unsigned int FileSelector::epoch() const { | ||
| 29 | return std::chrono::duration_cast<std::chrono::milliseconds>(*this->mEpoch).count(); | ||
| 30 | } | ||
| 31 | void FileSelector::setEpoch(unsigned int epoch) { | ||
| 32 | this->mEpoch = std::chrono::milliseconds{epoch}; | ||
| 33 | if (this->mDirectory && this->mEpoch) | ||
| 34 | this->update(); | ||
| 35 | emit this->epochChanged(); | ||
| 36 | } | ||
| 37 | |||
| 38 | QString FileSelector::seed() const { | ||
| 39 | return this->mSeed; | ||
| 40 | } | ||
| 41 | void FileSelector::setSeed(QString seed) { | ||
| 42 | this->mSeed = seed; | ||
| 43 | emit this->seedChanged(); | ||
| 44 | if (this->mDirectory && this->mEpoch) | ||
| 45 | emit this->selectedChanged(); | ||
| 46 | } | ||
| 47 | |||
| 48 | QString FileSelector::selected() const { | ||
| 49 | if (!this->mDirectory || !this->mEpoch) | ||
| 50 | return QString(); | ||
| 51 | |||
| 52 | std::vector<fs::path> shuffled(this->mFiles.begin(), this->mFiles.end()); | ||
| 53 | std::sort(shuffled.begin(), shuffled.end()); | ||
| 54 | |||
| 55 | auto currentTime = std::chrono::system_clock::now(); | ||
| 56 | uint64_t currentEpoch = currentTime.time_since_epoch() / *this->mEpoch; | ||
| 57 | std::chrono::milliseconds timeInEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()) % *this->mEpoch; | ||
| 58 | |||
| 59 | std::ostringstream seed; | ||
| 60 | seed << this->mSeed.size() << ";" << this->mSeed.toStdString() << ";"; | ||
| 61 | seed << *this->mEpoch << ";"; | ||
| 62 | seed << currentEpoch << ";"; | ||
| 63 | seed << this->mDirectory->string().size() << ";" << *this->mDirectory << ";"; | ||
| 64 | seed << this->mFiles.size() << ";"; | ||
| 65 | for (const fs::path& p: this->mFiles) | ||
| 66 | seed << p.string().size() << ";" << p << ";"; | ||
| 67 | |||
| 68 | std::vector<std::seed_seq::result_type> v; | ||
| 69 | v.reserve(seed.str().size()); | ||
| 70 | for (const char& c: seed.str()) | ||
| 71 | v.push_back(c); | ||
| 72 | |||
| 73 | std::seed_seq engine_seed(v.begin(), v.end()); | ||
| 74 | std::mt19937 g(engine_seed); | ||
| 75 | std::shuffle(shuffled.begin(), shuffled.end(), g); | ||
| 76 | |||
| 77 | std::vector<fs::path>::size_type ix = shuffled.size() * timeInEpoch / *this->mEpoch; | ||
| 78 | return QString::fromStdString((*this->mDirectory / shuffled[ix]).string()); | ||
| 79 | } | ||
| 80 | |||
| 81 | void FileSelector::onTimeout() { | ||
| 82 | if (!this->mFiles.size()) | ||
| 83 | return; | ||
| 84 | |||
| 85 | auto currentTime = std::chrono::system_clock::now(); | ||
| 86 | uint64_t currentMinorEpoch = currentTime.time_since_epoch() / (*this->mEpoch / this->mFiles.size()); | ||
| 87 | auto nextTime = std::chrono::time_point<std::chrono::system_clock>((currentMinorEpoch + 1) * (*this->mEpoch / this->mFiles.size())); | ||
| 88 | this->timer.start(std::chrono::duration_cast<std::chrono::milliseconds>(nextTime - currentTime)); | ||
| 89 | |||
| 90 | emit this->selectedChanged(); | ||
| 91 | } | ||
| 92 | |||
| 93 | void FileSelector::update() { | ||
| 94 | this->mFiles = std::set<fs::path>{}; | ||
| 95 | for (const fs::directory_entry& entry: | ||
| 96 | fs::recursive_directory_iterator(*this->mDirectory, fs::directory_options::follow_directory_symlink)) | ||
| 97 | { | ||
| 98 | this->mFiles.insert(fs::relative(entry, *this->mDirectory)); | ||
| 99 | } | ||
| 100 | |||
| 101 | this->onTimeout(); | ||
| 102 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.hpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.hpp new file mode 100644 index 00000000..72c4f2a7 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/FileSelector.hpp | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <filesystem> | ||
| 4 | #include <chrono> | ||
| 5 | #include <set> | ||
| 6 | #include <optional> | ||
| 7 | |||
| 8 | #include <QObject> | ||
| 9 | #include <QTimer> | ||
| 10 | |||
| 11 | #include <qqmlintegration.h> | ||
| 12 | |||
| 13 | class FileSelector : public QObject { | ||
| 14 | Q_OBJECT; | ||
| 15 | Q_PROPERTY(QString directory READ directory WRITE setDirectory NOTIFY directoryChanged REQUIRED); | ||
| 16 | Q_PROPERTY(unsigned int epoch READ epoch WRITE setEpoch NOTIFY epochChanged REQUIRED); | ||
| 17 | Q_PROPERTY(QString seed READ seed WRITE setSeed NOTIFY seedChanged); | ||
| 18 | Q_PROPERTY(QString selected READ selected NOTIFY selectedChanged); | ||
| 19 | QML_ELEMENT; | ||
| 20 | |||
| 21 | public: | ||
| 22 | explicit FileSelector(QObject* parent = nullptr); | ||
| 23 | |||
| 24 | QString directory() const; | ||
| 25 | void setDirectory(QString directory); | ||
| 26 | |||
| 27 | unsigned int epoch() const; | ||
| 28 | void setEpoch(unsigned int epoch); | ||
| 29 | |||
| 30 | QString seed() const; | ||
| 31 | void setSeed(QString seed); | ||
| 32 | |||
| 33 | QString selected() const; | ||
| 34 | |||
| 35 | signals: | ||
| 36 | void directoryChanged(); | ||
| 37 | void epochChanged(); | ||
| 38 | void seedChanged(); | ||
| 39 | void selectedChanged(); | ||
| 40 | |||
| 41 | private slots: | ||
| 42 | void onTimeout(); | ||
| 43 | |||
| 44 | private: | ||
| 45 | std::optional<std::filesystem::path> mDirectory; | ||
| 46 | std::optional<std::chrono::milliseconds> mEpoch; | ||
| 47 | std::set<std::filesystem::path> mFiles; | ||
| 48 | QString mSeed; | ||
| 49 | QTimer timer; | ||
| 50 | |||
| 51 | void update(); | ||
| 52 | }; | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.cpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.cpp new file mode 100644 index 00000000..f6e4dd6e --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.cpp | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #include "KeePassXC.hpp" | ||
| 2 | |||
| 3 | #include <QDBusConnection> | ||
| 4 | |||
| 5 | KeePassXC::KeePassXC() { | ||
| 6 | this->service = new DBusKeePassXC(DBusKeePassXC::staticInterfaceName(), "/keepassxc", QDBusConnection::sessionBus(), this); | ||
| 7 | } | ||
| 8 | KeePassXC::~KeePassXC() { | ||
| 9 | if (this->service) | ||
| 10 | delete this->service; | ||
| 11 | } | ||
| 12 | |||
| 13 | void KeePassXC::lockAllDatabases() { | ||
| 14 | if (!this->service) | ||
| 15 | return; | ||
| 16 | |||
| 17 | this->service->lockAllDatabases(); | ||
| 18 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.hpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.hpp new file mode 100644 index 00000000..c4cd71e0 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/KeePassXC.hpp | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "dbus_keepassxc.h" | ||
| 4 | |||
| 5 | #include <QObject> | ||
| 6 | #include <QtQmlIntegration/qqmlintegration.h> | ||
| 7 | |||
| 8 | class KeePassXC : public QObject { | ||
| 9 | Q_OBJECT; | ||
| 10 | QML_SINGLETON; | ||
| 11 | QML_ELEMENT; | ||
| 12 | |||
| 13 | public: | ||
| 14 | explicit KeePassXC(); | ||
| 15 | ~KeePassXC(); | ||
| 16 | |||
| 17 | Q_INVOKABLE void lockAllDatabases(); | ||
| 18 | |||
| 19 | private: | ||
| 20 | DBusKeePassXC* service = nullptr; | ||
| 21 | }; | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.cpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.cpp new file mode 100644 index 00000000..c1f9537c --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.cpp | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | #include "ListUnitsEntry.hpp" | ||
| 2 | |||
| 3 | void ListUnitsEntry::registerMetaType() { | ||
| 4 | qRegisterMetaType<ListUnitsEntry>("ListUnitsEntry"); | ||
| 5 | qDBusRegisterMetaType<ListUnitsEntry>(); | ||
| 6 | } | ||
| 7 | |||
| 8 | QDBusArgument& operator<<(QDBusArgument& argument, const ListUnitsEntry& entry) { | ||
| 9 | argument.beginStructure(); | ||
| 10 | argument | ||
| 11 | << entry.primaryName | ||
| 12 | << entry.description | ||
| 13 | << entry.loadState | ||
| 14 | << entry.activeState | ||
| 15 | << entry.subState | ||
| 16 | << entry.followingUnit | ||
| 17 | << entry.unitPath | ||
| 18 | << entry.jobId | ||
| 19 | << entry.jobType | ||
| 20 | << entry.jobPath; | ||
| 21 | argument.endStructure(); | ||
| 22 | |||
| 23 | return argument; | ||
| 24 | } | ||
| 25 | const QDBusArgument& operator>>(const QDBusArgument& argument, ListUnitsEntry& entry) { | ||
| 26 | argument.beginStructure(); | ||
| 27 | argument | ||
| 28 | >> entry.primaryName | ||
| 29 | >> entry.description | ||
| 30 | >> entry.loadState | ||
| 31 | >> entry.activeState | ||
| 32 | >> entry.subState | ||
| 33 | >> entry.followingUnit | ||
| 34 | >> entry.unitPath | ||
| 35 | >> entry.jobId | ||
| 36 | >> entry.jobType | ||
| 37 | >> entry.jobPath; | ||
| 38 | argument.endStructure(); | ||
| 39 | |||
| 40 | return argument; | ||
| 41 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.hpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.hpp new file mode 100644 index 00000000..15d789b9 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/ListUnitsEntry.hpp | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QtDBus> | ||
| 4 | #include <QtTypes> | ||
| 5 | |||
| 6 | struct ListUnitsEntry { | ||
| 7 | QString primaryName; | ||
| 8 | QString description; | ||
| 9 | QString loadState; | ||
| 10 | QString activeState; | ||
| 11 | QString subState; | ||
| 12 | QString followingUnit; | ||
| 13 | QDBusObjectPath unitPath; | ||
| 14 | uint jobId; | ||
| 15 | QString jobType; | ||
| 16 | QDBusObjectPath jobPath; | ||
| 17 | |||
| 18 | friend QDBusArgument& operator<<(QDBusArgument& argument, const ListUnitsEntry& entry); | ||
| 19 | friend const QDBusArgument& operator>>(const QDBusArgument& argument, ListUnitsEntry& entry); | ||
| 20 | static void registerMetaType(); | ||
| 21 | }; | ||
| 22 | |||
| 23 | Q_DECLARE_METATYPE(ListUnitsEntry) | ||
| 24 | |||
| 25 | using ListUnitsResult = QList<ListUnitsEntry>; | ||
| 26 | Q_DECLARE_METATYPE(ListUnitsResult) | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.cpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.cpp new file mode 100644 index 00000000..6376b527 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.cpp | |||
| @@ -0,0 +1,288 @@ | |||
| 1 | #include "Systemd.hpp" | ||
| 2 | |||
| 3 | #include <sstream> | ||
| 4 | |||
| 5 | #include <QDBusConnection> | ||
| 6 | #include <QDBusReply> | ||
| 7 | #include <QDebug> | ||
| 8 | #include <QDBusUnixFileDescriptor> | ||
| 9 | #include <QDBusObjectPath> | ||
| 10 | |||
| 11 | #include <set> | ||
| 12 | |||
| 13 | Systemd::Systemd(QObject* parent) : QObject(parent) { | ||
| 14 | ListUnitsEntry::registerMetaType(); | ||
| 15 | qDBusRegisterMetaType<ListUnitsResult>(); | ||
| 16 | |||
| 17 | this->systemdManager = new DBusSystemdManager( | ||
| 18 | "org.freedesktop.systemd1", | ||
| 19 | "/org/freedesktop/systemd1", | ||
| 20 | QDBusConnection::sessionBus(), | ||
| 21 | this | ||
| 22 | ); | ||
| 23 | this->logindManager = new DBusLogindManager( | ||
| 24 | "org.freedesktop.login1", | ||
| 25 | "/org/freedesktop/login1", | ||
| 26 | QDBusConnection::systemBus(), | ||
| 27 | this | ||
| 28 | ); | ||
| 29 | |||
| 30 | |||
| 31 | QDBusReply<QDBusObjectPath> sessionPath = this->logindManager->GetSession("auto"); | ||
| 32 | // qDebug() << sessionPath; | ||
| 33 | this->logindSession = new DBusLogindSession( | ||
| 34 | "org.freedesktop.login1", | ||
| 35 | sessionPath.value().path(), | ||
| 36 | QDBusConnection::systemBus(), | ||
| 37 | this | ||
| 38 | ); | ||
| 39 | this->logindSessionProperties = new DBusProperties( | ||
| 40 | "org.freedesktop.login1", | ||
| 41 | sessionPath.value().path(), | ||
| 42 | QDBusConnection::systemBus(), | ||
| 43 | this | ||
| 44 | ); | ||
| 45 | |||
| 46 | QObject::connect(this->logindManager, &DBusLogindManager::PrepareForShutdown, this, &Systemd::shutdown); | ||
| 47 | QObject::connect(this->logindManager, &DBusLogindManager::PrepareForSleep, this, &Systemd::sleep); | ||
| 48 | QObject::connect(this->logindSession, &DBusLogindSession::Lock, this, &Systemd::lock); | ||
| 49 | QObject::connect(this->logindSession, &DBusLogindSession::Unlock, this, &Systemd::unlock); | ||
| 50 | QObject::connect(this->logindSessionProperties, &DBusProperties::PropertiesChanged, this, &Systemd::onLogindSessionPropertiesChanged); | ||
| 51 | this->systemdManager->Subscribe(); | ||
| 52 | QObject::connect(this->systemdManager, &DBusSystemdManager::UnitNew, this, &Systemd::onUserUnitNew); | ||
| 53 | QObject::connect(this->systemdManager, &DBusSystemdManager::UnitRemoved, this, &Systemd::onUserUnitRemoved); | ||
| 54 | |||
| 55 | for (const auto& unit: this->systemdManager->ListUnits().value()) | ||
| 56 | this->onUserUnitNew(unit.primaryName, unit.unitPath); | ||
| 57 | } | ||
| 58 | |||
| 59 | void Systemd::onLogindSessionPropertiesChanged(const QString& interface_name, const QVariantMap& changed_properties, const QStringList& invalidated_properties) { | ||
| 60 | if (changed_properties.contains("IdleHint") || invalidated_properties.contains("IdleHint")) | ||
| 61 | emit this->idleHintChanged(); | ||
| 62 | if (changed_properties.contains("LockedHint") || invalidated_properties.contains("LockedHint")) | ||
| 63 | emit this->lockedHintChanged(); | ||
| 64 | } | ||
| 65 | void Systemd::onUserUnitNew(const QString& id, const QDBusObjectPath& object_path) { | ||
| 66 | for (auto unit: this->mUserUnits.valueList()) | ||
| 67 | if (unit->path() == object_path) | ||
| 68 | return; | ||
| 69 | |||
| 70 | for (const auto& unit: this->systemdManager->ListUnits().value()) | ||
| 71 | if (unit.unitPath == object_path) { | ||
| 72 | this->mUserUnits.insertObject(new SystemdUnit(this, object_path, id)); | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | void Systemd::onUserUnitRemoved(const QString& id, const QDBusObjectPath& object_path) { | ||
| 77 | std::set<SystemdUnit*> toRemove; | ||
| 78 | for (auto unit: this->mUserUnits.valueList()) | ||
| 79 | if (unit->path() == object_path) | ||
| 80 | toRemove.insert(unit); | ||
| 81 | |||
| 82 | for (auto unit: toRemove) { | ||
| 83 | this->mUserUnits.removeObject(unit); | ||
| 84 | delete unit; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | SystemdUnit::SystemdUnit(QObject* parent, const QDBusObjectPath& path, const QString& id): QObject(parent), mPath(path), mId(id) { | ||
| 89 | this->mUnitProperties = new DBusProperties( | ||
| 90 | "org.freedesktop.systemd1", | ||
| 91 | this->path().path(), | ||
| 92 | QDBusConnection::sessionBus(), | ||
| 93 | this | ||
| 94 | ); | ||
| 95 | } | ||
| 96 | std::unique_ptr<DBusSystemdUnit> SystemdUnit::systemdUnit() { | ||
| 97 | return std::make_unique<DBusSystemdUnit>( | ||
| 98 | "org.freedesktop.systemd1", | ||
| 99 | this->path().path(), | ||
| 100 | QDBusConnection::sessionBus(), | ||
| 101 | nullptr | ||
| 102 | ); | ||
| 103 | } | ||
| 104 | std::unique_ptr<DBusSystemdService> SystemdUnit::systemdService() { | ||
| 105 | if (!this->id().endsWith(".service")) | ||
| 106 | return std::unique_ptr<DBusSystemdService>(); | ||
| 107 | |||
| 108 | return std::make_unique<DBusSystemdService>( | ||
| 109 | "org.freedesktop.systemd1", | ||
| 110 | this->path().path(), | ||
| 111 | QDBusConnection::sessionBus(), | ||
| 112 | nullptr | ||
| 113 | ); | ||
| 114 | } | ||
| 115 | QList<QString> SystemdUnit::runtimeDirectory() { | ||
| 116 | if (std::unique_ptr<DBusSystemdService> systemdService = this->systemdService()) { | ||
| 117 | if (!this->mRuntimeDirectory) | ||
| 118 | this->mRuntimeDirectory = systemdService->runtimeDirectory(); | ||
| 119 | return *this->mRuntimeDirectory; | ||
| 120 | } | ||
| 121 | |||
| 122 | return QList<QString>{}; | ||
| 123 | } | ||
| 124 | QString SystemdUnit::activeState() { | ||
| 125 | if (!this->mActiveState) { | ||
| 126 | QObject::connect(this->mUnitProperties, &DBusProperties::PropertiesChanged, this, &SystemdUnit::onUnitPropertiesChanged); | ||
| 127 | this->mActiveState = this->systemdUnit()->activeState(); | ||
| 128 | } | ||
| 129 | |||
| 130 | return *this->mActiveState; | ||
| 131 | } | ||
| 132 | |||
| 133 | const QDBusObjectPath& SystemdUnit::path() const { return this->mPath; } | ||
| 134 | const QString& SystemdUnit::id() const { return this->mId; } | ||
| 135 | void SystemdUnit::onUnitPropertiesChanged(const QString& interface_name, const QVariantMap& changed_properties, const QStringList& invalidated_properties) { | ||
| 136 | if (changed_properties.contains("ActiveState") || invalidated_properties.contains("ActiveState")) { | ||
| 137 | this->mActiveState = this->systemdUnit()->activeState(); | ||
| 138 | emit this->activeStateChanged(); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | void Systemd::stopUserUnit(const QString& unit, const QString& mode) { this->systemdManager->StopUnit(unit, mode); } | ||
| 143 | |||
| 144 | void Systemd::setBrightness(const QString& subsystem, const QString& name, quint32 brightness) { this->logindSession->SetBrightness(subsystem, name, brightness); } | ||
| 145 | |||
| 146 | bool Systemd::idleHint() { return this->logindSession->idleHint(); } | ||
| 147 | void Systemd::setIdleHint(bool idle) { this->logindSession->SetIdleHint(idle); } | ||
| 148 | bool Systemd::lockedHint() { return this->logindSession->lockedHint(); } | ||
| 149 | void Systemd::setLockedHint(bool locked) { this->logindSession->SetLockedHint(locked); } | ||
| 150 | void Systemd::lockSession() { this->logindSession->call("Lock"); } | ||
| 151 | void Systemd::suspend() { this->logindManager->Suspend(true); } | ||
| 152 | void Systemd::hibernate() { this->logindManager->Hibernate(true); } | ||
| 153 | |||
| 154 | ObjectModel<SystemdUnit>* Systemd::userUnits() { return &this->mUserUnits; } | ||
| 155 | |||
| 156 | std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::WhatItem what) { | ||
| 157 | if (what == SystemdInhibitorParams::Shutdown) | ||
| 158 | return "shutdown"; | ||
| 159 | else if (what == SystemdInhibitorParams::Sleep) | ||
| 160 | return "sleep"; | ||
| 161 | else if (what == SystemdInhibitorParams::Idle) | ||
| 162 | return "idle"; | ||
| 163 | else if (what == SystemdInhibitorParams::HandlePowerKey) | ||
| 164 | return "handle-power-key"; | ||
| 165 | else if (what == SystemdInhibitorParams::HandleSuspendKey) | ||
| 166 | return "handle-suspend-key"; | ||
| 167 | else if (what == SystemdInhibitorParams::HandleHibernateKey) | ||
| 168 | return "handle-hibernate-key"; | ||
| 169 | else if (what == SystemdInhibitorParams::HandleLidSwitch) | ||
| 170 | return "handle-lid-switch"; | ||
| 171 | return ""; | ||
| 172 | } | ||
| 173 | |||
| 174 | std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::What what) { | ||
| 175 | std::ostringstream res; | ||
| 176 | bool first = true; | ||
| 177 | for (const WhatItem& item: SystemdInhibitorParams::allWhatItems) { | ||
| 178 | if (!(what & item)) | ||
| 179 | continue; | ||
| 180 | |||
| 181 | if (!first) | ||
| 182 | res << ":"; | ||
| 183 | else | ||
| 184 | first = false; | ||
| 185 | res << SystemdInhibitorParams::toString(item); | ||
| 186 | } | ||
| 187 | return res.str(); | ||
| 188 | } | ||
| 189 | |||
| 190 | std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::Mode mode) { | ||
| 191 | if (mode == SystemdInhibitorParams::Block) | ||
| 192 | return "block"; | ||
| 193 | else if (mode == SystemdInhibitorParams::BlockWeak) | ||
| 194 | return "block-weak"; | ||
| 195 | else if (mode == SystemdInhibitorParams::Delay) | ||
| 196 | return "delay"; | ||
| 197 | return ""; | ||
| 198 | } | ||
| 199 | |||
| 200 | bool SystemdInhibitor::enabled() const { return static_cast<bool>(this->activeInhibitor); } | ||
| 201 | void SystemdInhibitor::setEnabled(bool enabled) { | ||
| 202 | this->mEnabled = enabled; | ||
| 203 | |||
| 204 | if (enabled) | ||
| 205 | this->update(); | ||
| 206 | else | ||
| 207 | this->release(); | ||
| 208 | } | ||
| 209 | |||
| 210 | SystemdInhibitorParams::What SystemdInhibitor::what() const { return this->mWhat; } | ||
| 211 | void SystemdInhibitor::setWhat(SystemdInhibitorParams::What what) { | ||
| 212 | this->mWhat = what; | ||
| 213 | this->update(); | ||
| 214 | } | ||
| 215 | |||
| 216 | QString SystemdInhibitor::who() const { return this->mWho; } | ||
| 217 | void SystemdInhibitor::setWho(QString who) { | ||
| 218 | this->mWho = who; | ||
| 219 | this->update(); | ||
| 220 | } | ||
| 221 | |||
| 222 | QString SystemdInhibitor::why() const { return this->mWhy; } | ||
| 223 | void SystemdInhibitor::setWhy(QString why) { | ||
| 224 | this->mWhy = why; | ||
| 225 | this->update(); | ||
| 226 | } | ||
| 227 | |||
| 228 | SystemdInhibitorParams::Mode SystemdInhibitor::mode() const { return this->mMode; } | ||
| 229 | void SystemdInhibitor::setMode(SystemdInhibitorParams::Mode mode) { | ||
| 230 | this->mMode = mode; | ||
| 231 | this->update(); | ||
| 232 | } | ||
| 233 | |||
| 234 | SystemdInhibitor::ActiveSystemdInhibitor::ActiveSystemdInhibitor(SystemdInhibitorParams::What what_, QString who_, QString why_, SystemdInhibitorParams::Mode mode_): what(what_), who(who_), why(why_), mode(mode_) { | ||
| 235 | DBusLogindManager logindManager( | ||
| 236 | "org.freedesktop.login1", | ||
| 237 | "/org/freedesktop/login1", | ||
| 238 | QDBusConnection::systemBus() | ||
| 239 | ); | ||
| 240 | QDBusReply<QDBusUnixFileDescriptor> fd_ = logindManager.Inhibit(QString::fromStdString(SystemdInhibitorParams::toString(what)), who, why, QString::fromStdString(SystemdInhibitorParams::toString(mode))); | ||
| 241 | if (fd_.error().isValid()) | ||
| 242 | throw fd_.error(); | ||
| 243 | this->fd = ::dup(fd_.value().fileDescriptor()); | ||
| 244 | } | ||
| 245 | SystemdInhibitor::ActiveSystemdInhibitor::~ActiveSystemdInhibitor() { | ||
| 246 | if (this->fd != -1) | ||
| 247 | ::close(this->fd); | ||
| 248 | } | ||
| 249 | |||
| 250 | void SystemdInhibitor::release() { | ||
| 251 | if (!this->activeInhibitor) | ||
| 252 | return; | ||
| 253 | |||
| 254 | this->activeInhibitor.reset(); | ||
| 255 | emit this->enabledChanged(); | ||
| 256 | } | ||
| 257 | |||
| 258 | void SystemdInhibitor::update() { | ||
| 259 | if (!this->mWhat || this->mWho.isEmpty() || this->mWhy.isEmpty() || !this->mMode || !this->mEnabled) | ||
| 260 | if (this->activeInhibitor) | ||
| 261 | this->release(); | ||
| 262 | else | ||
| 263 | return; | ||
| 264 | |||
| 265 | if (this->activeInhibitor && this->mWhat == this->activeInhibitor->what && this->mWho == this->activeInhibitor->who && this->mWhy == this->activeInhibitor->why && this->mMode == this->activeInhibitor->mode) | ||
| 266 | return; | ||
| 267 | |||
| 268 | std::unique_ptr<ActiveSystemdInhibitor> otherInhibitor; | ||
| 269 | try { | ||
| 270 | otherInhibitor.reset(new SystemdInhibitor::ActiveSystemdInhibitor(this->mWhat, this->mWho, this->mWhy, this->mMode)); | ||
| 271 | } catch (const QDBusError& err) { | ||
| 272 | qCritical().noquote() | ||
| 273 | << err.name().toStdString() << " " << err.message().toStdString(); | ||
| 274 | return; | ||
| 275 | } | ||
| 276 | this->activeInhibitor.swap(otherInhibitor); | ||
| 277 | |||
| 278 | if (!otherInhibitor && this->activeInhibitor) | ||
| 279 | emit this->enabledChanged(); | ||
| 280 | if (otherInhibitor && otherInhibitor->what != this->activeInhibitor->what) | ||
| 281 | emit this->whatChanged(); | ||
| 282 | if (otherInhibitor && otherInhibitor->who != this->activeInhibitor->who) | ||
| 283 | emit this->whoChanged(); | ||
| 284 | if (otherInhibitor && otherInhibitor->why != this->activeInhibitor->why) | ||
| 285 | emit this->whyChanged(); | ||
| 286 | if (otherInhibitor && otherInhibitor->mode != this->activeInhibitor->mode) | ||
| 287 | emit this->modeChanged(); | ||
| 288 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.hpp b/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.hpp new file mode 100644 index 00000000..98f73d8f --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/Systemd.hpp | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <cstdint> | ||
| 4 | #include <memory> | ||
| 5 | #include <string> | ||
| 6 | #include <optional> | ||
| 7 | |||
| 8 | #include <QObject> | ||
| 9 | #include <QDBusInterface> | ||
| 10 | #include <QtQmlIntegration/qqmlintegration.h> | ||
| 11 | |||
| 12 | #include "dbus_systemd_manager.h" | ||
| 13 | #include "dbus_logind_manager.h" | ||
| 14 | #include "dbus_logind_session.h" | ||
| 15 | #include "dbus_systemd_unit.h" | ||
| 16 | #include "dbus_systemd_service.h" | ||
| 17 | #include "dbus_properties.h" | ||
| 18 | |||
| 19 | #include "core/model.hpp" | ||
| 20 | |||
| 21 | class SystemdUnit : public QObject { | ||
| 22 | Q_OBJECT; | ||
| 23 | QML_ELEMENT; | ||
| 24 | QML_UNCREATABLE("SystemdUnits cannot be created directly"); | ||
| 25 | |||
| 26 | public: | ||
| 27 | explicit SystemdUnit(QObject* parent, const QDBusObjectPath& path, const QString& id); | ||
| 28 | |||
| 29 | Q_PROPERTY(QDBusObjectPath path READ path CONSTANT); | ||
| 30 | Q_PROPERTY(QString id READ id CONSTANT); | ||
| 31 | Q_PROPERTY(QList<QString> runtimeDirectory READ runtimeDirectory CONSTANT); | ||
| 32 | Q_PROPERTY(QString activeState READ activeState NOTIFY activeStateChanged); | ||
| 33 | |||
| 34 | const QDBusObjectPath& path() const; | ||
| 35 | const QString& id() const; | ||
| 36 | QList<QString> runtimeDirectory(); | ||
| 37 | QString activeState(); | ||
| 38 | |||
| 39 | signals: | ||
| 40 | void activeStateChanged(); | ||
| 41 | |||
| 42 | private slots: | ||
| 43 | void onUnitPropertiesChanged(const QString& interface_name, const QVariantMap& changed_properties, const QStringList& invalidated_properties); | ||
| 44 | |||
| 45 | private: | ||
| 46 | std::unique_ptr<DBusSystemdUnit> systemdUnit(); | ||
| 47 | std::unique_ptr<DBusSystemdService> systemdService(); | ||
| 48 | |||
| 49 | DBusProperties* mUnitProperties; | ||
| 50 | QDBusObjectPath mPath; | ||
| 51 | QString mId; | ||
| 52 | std::optional<QString> mActiveState; | ||
| 53 | std::optional<QList<QString>> mRuntimeDirectory; | ||
| 54 | }; | ||
| 55 | |||
| 56 | class Systemd : public QObject { | ||
| 57 | Q_OBJECT; | ||
| 58 | QML_SINGLETON; | ||
| 59 | QML_ELEMENT; | ||
| 60 | |||
| 61 | public: | ||
| 62 | explicit Systemd(QObject* parent = nullptr); | ||
| 63 | |||
| 64 | Q_PROPERTY(bool idleHint READ idleHint WRITE setIdleHint NOTIFY idleHintChanged) | ||
| 65 | Q_PROPERTY(bool lockedHint READ lockedHint WRITE setLockedHint NOTIFY lockedHintChanged) | ||
| 66 | Q_PROPERTY(UntypedObjectModel* userUnits READ userUnits CONSTANT) | ||
| 67 | |||
| 68 | Q_INVOKABLE void stopUserUnit(const QString& unit, const QString& mode); | ||
| 69 | Q_INVOKABLE void setBrightness(const QString& subsystem, const QString& name, quint32 brightness); | ||
| 70 | Q_INVOKABLE void setIdleHint(bool idle); | ||
| 71 | Q_INVOKABLE void setLockedHint(bool locked); | ||
| 72 | Q_INVOKABLE void lockSession(); | ||
| 73 | Q_INVOKABLE void suspend(); | ||
| 74 | Q_INVOKABLE void hibernate(); | ||
| 75 | |||
| 76 | bool idleHint(); | ||
| 77 | bool lockedHint(); | ||
| 78 | ObjectModel<SystemdUnit>* userUnits(); | ||
| 79 | |||
| 80 | signals: | ||
| 81 | void shutdown(bool before); | ||
| 82 | void sleep(bool before); | ||
| 83 | void lock(); | ||
| 84 | void unlock(); | ||
| 85 | void idleHintChanged(); | ||
| 86 | void lockedHintChanged(); | ||
| 87 | |||
| 88 | private slots: | ||
| 89 | void onLogindSessionPropertiesChanged(const QString& interface_name, const QVariantMap& changed_properties, const QStringList& invalidated_properties); | ||
| 90 | void onUserUnitNew(const QString& id, const QDBusObjectPath& objectPath); | ||
| 91 | void onUserUnitRemoved(const QString& id, const QDBusObjectPath& objectPath); | ||
| 92 | |||
| 93 | private: | ||
| 94 | DBusSystemdManager* systemdManager; | ||
| 95 | DBusLogindManager* logindManager; | ||
| 96 | DBusLogindSession* logindSession; | ||
| 97 | DBusProperties* logindSessionProperties; | ||
| 98 | |||
| 99 | ObjectModel<SystemdUnit> mUserUnits{this}; | ||
| 100 | }; | ||
| 101 | |||
| 102 | class SystemdInhibitorParams : public QObject { | ||
| 103 | Q_OBJECT; | ||
| 104 | QML_ELEMENT; | ||
| 105 | QML_SINGLETON; | ||
| 106 | |||
| 107 | public: | ||
| 108 | enum WhatItem : uint8_t { | ||
| 109 | Shutdown = 0b1, | ||
| 110 | Sleep = 0b10, | ||
| 111 | Idle = 0b100, | ||
| 112 | HandlePowerKey = 0b1000, | ||
| 113 | HandleSuspendKey = 0b10000, | ||
| 114 | HandleHibernateKey = 0b100000, | ||
| 115 | HandleLidSwitch = 0b1000000, | ||
| 116 | }; | ||
| 117 | Q_ENUM(WhatItem); | ||
| 118 | Q_DECLARE_FLAGS(What, WhatItem); | ||
| 119 | |||
| 120 | enum Mode : uint8_t { | ||
| 121 | Block = 1, | ||
| 122 | BlockWeak = 2, | ||
| 123 | Delay = 3, | ||
| 124 | }; | ||
| 125 | Q_ENUM(Mode); | ||
| 126 | |||
| 127 | Q_INVOKABLE static std::string toString(WhatItem what); | ||
| 128 | Q_INVOKABLE static std::string toString(What what); | ||
| 129 | Q_INVOKABLE static std::string toString(Mode mode); | ||
| 130 | |||
| 131 | static constexpr WhatItem allWhatItems[] = { Shutdown, Sleep, Idle, HandlePowerKey, HandleSuspendKey, HandleHibernateKey, HandleLidSwitch }; | ||
| 132 | }; | ||
| 133 | Q_DECLARE_OPERATORS_FOR_FLAGS(SystemdInhibitorParams::What) | ||
| 134 | |||
| 135 | class SystemdInhibitor : public QObject { | ||
| 136 | Q_OBJECT; | ||
| 137 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged); | ||
| 138 | Q_PROPERTY(SystemdInhibitorParams::What what READ what WRITE setWhat NOTIFY whatChanged); | ||
| 139 | Q_PROPERTY(QString who READ who WRITE setWho NOTIFY whoChanged); | ||
| 140 | Q_PROPERTY(QString why READ why WRITE setWhy NOTIFY whyChanged); | ||
| 141 | Q_PROPERTY(SystemdInhibitorParams::Mode mode READ mode WRITE setMode NOTIFY modeChanged); | ||
| 142 | QML_ELEMENT; | ||
| 143 | |||
| 144 | public: | ||
| 145 | explicit SystemdInhibitor(QObject* parent = nullptr): QObject(parent) {} | ||
| 146 | |||
| 147 | bool enabled() const; | ||
| 148 | void setEnabled(bool enabled); | ||
| 149 | |||
| 150 | SystemdInhibitorParams::What what() const; | ||
| 151 | void setWhat(SystemdInhibitorParams::What what); | ||
| 152 | |||
| 153 | QString who() const; | ||
| 154 | void setWho(QString who); | ||
| 155 | |||
| 156 | QString why() const; | ||
| 157 | void setWhy(QString why); | ||
| 158 | |||
| 159 | SystemdInhibitorParams::Mode mode() const; | ||
| 160 | void setMode(SystemdInhibitorParams::Mode mode); | ||
| 161 | |||
| 162 | Q_INVOKABLE void release(); | ||
| 163 | |||
| 164 | signals: | ||
| 165 | void enabledChanged(); | ||
| 166 | void whatChanged(); | ||
| 167 | void whoChanged(); | ||
| 168 | void whyChanged(); | ||
| 169 | void modeChanged(); | ||
| 170 | |||
| 171 | private: | ||
| 172 | class ActiveSystemdInhibitor { | ||
| 173 | public: | ||
| 174 | uint32_t fd = -1; | ||
| 175 | SystemdInhibitorParams::What what; | ||
| 176 | QString who; | ||
| 177 | QString why; | ||
| 178 | SystemdInhibitorParams::Mode mode; | ||
| 179 | |||
| 180 | ActiveSystemdInhibitor(SystemdInhibitorParams::What what_, QString who_, QString why_, SystemdInhibitorParams::Mode mode_); | ||
| 181 | ~ActiveSystemdInhibitor(); | ||
| 182 | }; | ||
| 183 | |||
| 184 | void update(); | ||
| 185 | |||
| 186 | bool mEnabled = true; | ||
| 187 | std::unique_ptr<ActiveSystemdInhibitor> activeInhibitor; | ||
| 188 | SystemdInhibitorParams::What mWhat = static_cast<SystemdInhibitorParams::What>(0); | ||
| 189 | QString mWho; | ||
| 190 | QString mWhy; | ||
| 191 | SystemdInhibitorParams::Mode mMode = static_cast<SystemdInhibitorParams::Mode>(0); | ||
| 192 | }; | ||
| 193 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/customplugin.h b/accounts/gkleen@skadhi/shell/quickshell-plugins/customplugin.h new file mode 100644 index 00000000..e66ba9e3 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/customplugin.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #include <QQmlEngineExtensionPlugin> | ||
| 2 | |||
| 3 | class CustomPlugin : public QQmlEngineExtensionPlugin | ||
| 4 | { | ||
| 5 | Q_OBJECT | ||
| 6 | Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) | ||
| 7 | }; | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/default.nix b/accounts/gkleen@skadhi/shell/quickshell-plugins/default.nix new file mode 100644 index 00000000..dfe93bca --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/default.nix | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | { lib | ||
| 2 | , stdenv | ||
| 3 | , cmake | ||
| 4 | , qt6 | ||
| 5 | , fmt | ||
| 6 | , keepassxc | ||
| 7 | , systemd | ||
| 8 | , quickshell | ||
| 9 | }: | ||
| 10 | |||
| 11 | stdenv.mkDerivation rec { | ||
| 12 | name = "quickshell-custom"; | ||
| 13 | |||
| 14 | src = ./.; | ||
| 15 | |||
| 16 | prePatch = '' | ||
| 17 | cp ${keepassxc.src}/src/gui/org.keepassxc.KeePassXC.MainWindow.xml . | ||
| 18 | ''; | ||
| 19 | |||
| 20 | nativeBuildInputs = [ cmake qt6.wrapQtAppsHook ]; | ||
| 21 | buildInputs = [ | ||
| 22 | qt6.qtbase | ||
| 23 | qt6.qtdeclarative | ||
| 24 | ]; | ||
| 25 | |||
| 26 | cmakeFlags = [ | ||
| 27 | (lib.cmakeFeature "INSTALL_QML_PREFIX" qt6.qtbase.qtQmlPrefix) | ||
| 28 | (lib.cmakeOptionType "string" "QUICKSHELL_SRC" (toString quickshell.src)) | ||
| 29 | ]; | ||
| 30 | |||
| 31 | LC_ALL = "C.UTF-8"; | ||
| 32 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.DBus.Properties.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.DBus.Properties.xml new file mode 100644 index 00000000..7588e7a5 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.DBus.Properties.xml | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.DBus.Properties"> | ||
| 5 | <method name="Get"> | ||
| 6 | <arg name="interface_name" direction="in" type="s"/> | ||
| 7 | <arg name="property_name" direction="in" type="s"/> | ||
| 8 | <arg name="value" direction="out" type="v"/> | ||
| 9 | </method> | ||
| 10 | <method name="GetAll"> | ||
| 11 | <arg name="interface_name" direction="in" type="s"/> | ||
| 12 | <arg name="props" direction="out" type="a{sv}"/> | ||
| 13 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/> | ||
| 14 | </method> | ||
| 15 | <method name="Set"> | ||
| 16 | <arg name="interface_name" direction="in" type="s"/> | ||
| 17 | <arg name="property_name" direction="in" type="s"/> | ||
| 18 | <arg name="value" direction="in" type="v"/> | ||
| 19 | </method> | ||
| 20 | <signal name="PropertiesChanged"> | ||
| 21 | <arg type="s" name="interface_name"/> | ||
| 22 | <arg type="a{sv}" name="changed_properties"/> | ||
| 23 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/> | ||
| 24 | <arg type="as" name="invalidated_properties"/> | ||
| 25 | </signal> | ||
| 26 | </interface> | ||
| 27 | </node> | ||
| 28 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Manager.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Manager.xml new file mode 100644 index 00000000..120a06d9 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Manager.xml | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.login1.Manager"> | ||
| 5 | <property name="EnableWallMessages" type="b" access="readwrite"> | ||
| 6 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 7 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 8 | </property> | ||
| 9 | <property name="WallMessage" type="s" access="readwrite"> | ||
| 10 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 11 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 12 | </property> | ||
| 13 | <property name="NAutoVTs" type="u" access="read"> | ||
| 14 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 15 | </property> | ||
| 16 | <property name="KillOnlyUsers" type="as" access="read"> | ||
| 17 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 18 | </property> | ||
| 19 | <property name="KillExcludeUsers" type="as" access="read"> | ||
| 20 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 21 | </property> | ||
| 22 | <property name="KillUserProcesses" type="b" access="read"> | ||
| 23 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 24 | </property> | ||
| 25 | <property name="RebootParameter" type="s" access="read"> | ||
| 26 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 27 | </property> | ||
| 28 | <property name="RebootToFirmwareSetup" type="b" access="read"> | ||
| 29 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 30 | </property> | ||
| 31 | <property name="RebootToBootLoaderMenu" type="t" access="read"> | ||
| 32 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 33 | </property> | ||
| 34 | <property name="RebootToBootLoaderEntry" type="s" access="read"> | ||
| 35 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 36 | </property> | ||
| 37 | <property name="BootLoaderEntries" type="as" access="read"> | ||
| 38 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 39 | </property> | ||
| 40 | <property name="IdleHint" type="b" access="read"> | ||
| 41 | </property> | ||
| 42 | <property name="IdleSinceHint" type="t" access="read"> | ||
| 43 | </property> | ||
| 44 | <property name="IdleSinceHintMonotonic" type="t" access="read"> | ||
| 45 | </property> | ||
| 46 | <property name="BlockInhibited" type="s" access="read"> | ||
| 47 | </property> | ||
| 48 | <property name="BlockWeakInhibited" type="s" access="read"> | ||
| 49 | </property> | ||
| 50 | <property name="DelayInhibited" type="s" access="read"> | ||
| 51 | </property> | ||
| 52 | <property name="InhibitDelayMaxUSec" type="t" access="read"> | ||
| 53 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 54 | </property> | ||
| 55 | <property name="UserStopDelayUSec" type="t" access="read"> | ||
| 56 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 57 | </property> | ||
| 58 | <property name="SleepOperation" type="as" access="read"> | ||
| 59 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 60 | </property> | ||
| 61 | <property name="HandlePowerKey" type="s" access="read"> | ||
| 62 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 63 | </property> | ||
| 64 | <property name="HandlePowerKeyLongPress" type="s" access="read"> | ||
| 65 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 66 | </property> | ||
| 67 | <property name="HandleRebootKey" type="s" access="read"> | ||
| 68 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 69 | </property> | ||
| 70 | <property name="HandleRebootKeyLongPress" type="s" access="read"> | ||
| 71 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 72 | </property> | ||
| 73 | <property name="HandleSuspendKey" type="s" access="read"> | ||
| 74 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 75 | </property> | ||
| 76 | <property name="HandleSuspendKeyLongPress" type="s" access="read"> | ||
| 77 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 78 | </property> | ||
| 79 | <property name="HandleHibernateKey" type="s" access="read"> | ||
| 80 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 81 | </property> | ||
| 82 | <property name="HandleHibernateKeyLongPress" type="s" access="read"> | ||
| 83 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 84 | </property> | ||
| 85 | <property name="HandleLidSwitch" type="s" access="read"> | ||
| 86 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 87 | </property> | ||
| 88 | <property name="HandleLidSwitchExternalPower" type="s" access="read"> | ||
| 89 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 90 | </property> | ||
| 91 | <property name="HandleLidSwitchDocked" type="s" access="read"> | ||
| 92 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 93 | </property> | ||
| 94 | <property name="HandleSecureAttentionKey" type="s" access="read"> | ||
| 95 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 96 | </property> | ||
| 97 | <property name="HoldoffTimeoutUSec" type="t" access="read"> | ||
| 98 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 99 | </property> | ||
| 100 | <property name="IdleAction" type="s" access="read"> | ||
| 101 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 102 | </property> | ||
| 103 | <property name="IdleActionUSec" type="t" access="read"> | ||
| 104 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 105 | </property> | ||
| 106 | <property name="PreparingForShutdown" type="b" access="read"> | ||
| 107 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 108 | </property> | ||
| 109 | <property name="PreparingForShutdownWithMetadata" type="a{sv}" access="read"> | ||
| 110 | <annotation name="org.qtproject.QtDBus.QtTypeName" value="QVariantMap"/> | ||
| 111 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 112 | </property> | ||
| 113 | <property name="PreparingForSleep" type="b" access="read"> | ||
| 114 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 115 | </property> | ||
| 116 | <!-- <property name="ScheduledShutdown" type="(st)" access="read"> --> | ||
| 117 | <!-- </property> --> | ||
| 118 | <property name="DesignatedMaintenanceTime" type="s" access="read"> | ||
| 119 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 120 | </property> | ||
| 121 | <property name="Docked" type="b" access="read"> | ||
| 122 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 123 | </property> | ||
| 124 | <property name="LidClosed" type="b" access="read"> | ||
| 125 | </property> | ||
| 126 | <property name="OnExternalPower" type="b" access="read"> | ||
| 127 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 128 | </property> | ||
| 129 | <property name="RemoveIPC" type="b" access="read"> | ||
| 130 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 131 | </property> | ||
| 132 | <property name="RuntimeDirectorySize" type="t" access="read"> | ||
| 133 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 134 | </property> | ||
| 135 | <property name="RuntimeDirectoryInodesMax" type="t" access="read"> | ||
| 136 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 137 | </property> | ||
| 138 | <property name="InhibitorsMax" type="t" access="read"> | ||
| 139 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 140 | </property> | ||
| 141 | <property name="NCurrentInhibitors" type="t" access="read"> | ||
| 142 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 143 | </property> | ||
| 144 | <property name="SessionsMax" type="t" access="read"> | ||
| 145 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 146 | </property> | ||
| 147 | <property name="NCurrentSessions" type="t" access="read"> | ||
| 148 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 149 | </property> | ||
| 150 | <property name="StopIdleSessionUSec" type="t" access="read"> | ||
| 151 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 152 | </property> | ||
| 153 | <method name="GetSession"> | ||
| 154 | <arg type="s" name="session_id" direction="in"/> | ||
| 155 | <arg type="o" name="object_path" direction="out"/> | ||
| 156 | </method> | ||
| 157 | <method name="GetSessionByPID"> | ||
| 158 | <arg type="u" name="pid" direction="in"/> | ||
| 159 | <arg type="o" name="object_path" direction="out"/> | ||
| 160 | </method> | ||
| 161 | <method name="GetUser"> | ||
| 162 | <arg type="u" name="uid" direction="in"/> | ||
| 163 | <arg type="o" name="object_path" direction="out"/> | ||
| 164 | </method> | ||
| 165 | <method name="GetUserByPID"> | ||
| 166 | <arg type="u" name="pid" direction="in"/> | ||
| 167 | <arg type="o" name="object_path" direction="out"/> | ||
| 168 | </method> | ||
| 169 | <method name="GetSeat"> | ||
| 170 | <arg type="s" name="seat_id" direction="in"/> | ||
| 171 | <arg type="o" name="object_path" direction="out"/> | ||
| 172 | </method> | ||
| 173 | <!-- <method name="ListSessions"> --> | ||
| 174 | <!-- <arg type="a(susso)" name="sessions" direction="out"/> --> | ||
| 175 | <!-- </method> --> | ||
| 176 | <!-- <method name="ListSessionsEx"> --> | ||
| 177 | <!-- <arg type="a(sussussbto)" name="sessions" direction="out"/> --> | ||
| 178 | <!-- </method> --> | ||
| 179 | <!-- <method name="ListUsers"> --> | ||
| 180 | <!-- <arg type="a(uso)" name="users" direction="out"/> --> | ||
| 181 | <!-- </method> --> | ||
| 182 | <!-- <method name="ListSeats"> --> | ||
| 183 | <!-- <arg type="a(so)" name="seats" direction="out"/> --> | ||
| 184 | <!-- </method> --> | ||
| 185 | <!-- <method name="ListInhibitors"> --> | ||
| 186 | <!-- <arg type="a(ssssuu)" name="inhibitors" direction="out"/> --> | ||
| 187 | <!-- </method> --> | ||
| 188 | <!-- <method name="CreateSession"> --> | ||
| 189 | <!-- <arg type="u" name="uid" direction="in"/> --> | ||
| 190 | <!-- <arg type="u" name="pid" direction="in"/> --> | ||
| 191 | <!-- <arg type="s" name="service" direction="in"/> --> | ||
| 192 | <!-- <arg type="s" name="type" direction="in"/> --> | ||
| 193 | <!-- <arg type="s" name="class" direction="in"/> --> | ||
| 194 | <!-- <arg type="s" name="desktop" direction="in"/> --> | ||
| 195 | <!-- <arg type="s" name="seat_id" direction="in"/> --> | ||
| 196 | <!-- <arg type="u" name="vtnr" direction="in"/> --> | ||
| 197 | <!-- <arg type="s" name="tty" direction="in"/> --> | ||
| 198 | <!-- <arg type="s" name="display" direction="in"/> --> | ||
| 199 | <!-- <arg type="b" name="remote" direction="in"/> --> | ||
| 200 | <!-- <arg type="s" name="remote_user" direction="in"/> --> | ||
| 201 | <!-- <arg type="s" name="remote_host" direction="in"/> --> | ||
| 202 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 203 | <!-- <arg type="s" name="session_id" direction="out"/> --> | ||
| 204 | <!-- <arg type="o" name="object_path" direction="out"/> --> | ||
| 205 | <!-- <arg type="s" name="runtime_path" direction="out"/> --> | ||
| 206 | <!-- <arg type="h" name="fifo_fd" direction="out"/> --> | ||
| 207 | <!-- <arg type="u" name="uid" direction="out"/> --> | ||
| 208 | <!-- <arg type="s" name="seat_id" direction="out"/> --> | ||
| 209 | <!-- <arg type="u" name="vtnr" direction="out"/> --> | ||
| 210 | <!-- <arg type="b" name="existing" direction="out"/> --> | ||
| 211 | <!-- <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> --> | ||
| 212 | <!-- </method> --> | ||
| 213 | <!-- <method name="CreateSessionWithPIDFD"> --> | ||
| 214 | <!-- <arg type="u" name="uid" direction="in"/> --> | ||
| 215 | <!-- <arg type="h" name="pidfd" direction="in"/> --> | ||
| 216 | <!-- <arg type="s" name="service" direction="in"/> --> | ||
| 217 | <!-- <arg type="s" name="type" direction="in"/> --> | ||
| 218 | <!-- <arg type="s" name="class" direction="in"/> --> | ||
| 219 | <!-- <arg type="s" name="desktop" direction="in"/> --> | ||
| 220 | <!-- <arg type="s" name="seat_id" direction="in"/> --> | ||
| 221 | <!-- <arg type="u" name="vtnr" direction="in"/> --> | ||
| 222 | <!-- <arg type="s" name="tty" direction="in"/> --> | ||
| 223 | <!-- <arg type="s" name="display" direction="in"/> --> | ||
| 224 | <!-- <arg type="b" name="remote" direction="in"/> --> | ||
| 225 | <!-- <arg type="s" name="remote_user" direction="in"/> --> | ||
| 226 | <!-- <arg type="s" name="remote_host" direction="in"/> --> | ||
| 227 | <!-- <arg type="t" name="flags" direction="in"/> --> | ||
| 228 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 229 | <!-- <arg type="s" name="session_id" direction="out"/> --> | ||
| 230 | <!-- <arg type="o" name="object_path" direction="out"/> --> | ||
| 231 | <!-- <arg type="s" name="runtime_path" direction="out"/> --> | ||
| 232 | <!-- <arg type="h" name="fifo_fd" direction="out"/> --> | ||
| 233 | <!-- <arg type="u" name="uid" direction="out"/> --> | ||
| 234 | <!-- <arg type="s" name="seat_id" direction="out"/> --> | ||
| 235 | <!-- <arg type="u" name="vtnr" direction="out"/> --> | ||
| 236 | <!-- <arg type="b" name="existing" direction="out"/> --> | ||
| 237 | <!-- <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> --> | ||
| 238 | <!-- </method> --> | ||
| 239 | <method name="ReleaseSession"> | ||
| 240 | <arg type="s" name="session_id" direction="in"/> | ||
| 241 | </method> | ||
| 242 | <method name="ActivateSession"> | ||
| 243 | <arg type="s" name="session_id" direction="in"/> | ||
| 244 | </method> | ||
| 245 | <method name="ActivateSessionOnSeat"> | ||
| 246 | <arg type="s" name="session_id" direction="in"/> | ||
| 247 | <arg type="s" name="seat_id" direction="in"/> | ||
| 248 | </method> | ||
| 249 | <method name="LockSession"> | ||
| 250 | <arg type="s" name="session_id" direction="in"/> | ||
| 251 | </method> | ||
| 252 | <method name="UnlockSession"> | ||
| 253 | <arg type="s" name="session_id" direction="in"/> | ||
| 254 | </method> | ||
| 255 | <method name="LockSessions"> | ||
| 256 | </method> | ||
| 257 | <method name="UnlockSessions"> | ||
| 258 | </method> | ||
| 259 | <method name="KillSession"> | ||
| 260 | <arg type="s" name="session_id" direction="in"/> | ||
| 261 | <arg type="s" name="whom" direction="in"/> | ||
| 262 | <arg type="i" name="signal_number" direction="in"/> | ||
| 263 | </method> | ||
| 264 | <method name="KillUser"> | ||
| 265 | <arg type="u" name="uid" direction="in"/> | ||
| 266 | <arg type="i" name="signal_number" direction="in"/> | ||
| 267 | </method> | ||
| 268 | <method name="TerminateSession"> | ||
| 269 | <arg type="s" name="session_id" direction="in"/> | ||
| 270 | </method> | ||
| 271 | <method name="TerminateUser"> | ||
| 272 | <arg type="u" name="uid" direction="in"/> | ||
| 273 | </method> | ||
| 274 | <method name="TerminateSeat"> | ||
| 275 | <arg type="s" name="seat_id" direction="in"/> | ||
| 276 | </method> | ||
| 277 | <method name="SetUserLinger"> | ||
| 278 | <arg type="u" name="uid" direction="in"/> | ||
| 279 | <arg type="b" name="enable" direction="in"/> | ||
| 280 | <arg type="b" name="interactive" direction="in"/> | ||
| 281 | </method> | ||
| 282 | <method name="AttachDevice"> | ||
| 283 | <arg type="s" name="seat_id" direction="in"/> | ||
| 284 | <arg type="s" name="sysfs_path" direction="in"/> | ||
| 285 | <arg type="b" name="interactive" direction="in"/> | ||
| 286 | </method> | ||
| 287 | <method name="FlushDevices"> | ||
| 288 | <arg type="b" name="interactive" direction="in"/> | ||
| 289 | </method> | ||
| 290 | <method name="PowerOff"> | ||
| 291 | <arg type="b" name="interactive" direction="in"/> | ||
| 292 | </method> | ||
| 293 | <method name="PowerOffWithFlags"> | ||
| 294 | <arg type="t" name="flags" direction="in"/> | ||
| 295 | </method> | ||
| 296 | <method name="Reboot"> | ||
| 297 | <arg type="b" name="interactive" direction="in"/> | ||
| 298 | </method> | ||
| 299 | <method name="RebootWithFlags"> | ||
| 300 | <arg type="t" name="flags" direction="in"/> | ||
| 301 | </method> | ||
| 302 | <method name="Halt"> | ||
| 303 | <arg type="b" name="interactive" direction="in"/> | ||
| 304 | </method> | ||
| 305 | <method name="HaltWithFlags"> | ||
| 306 | <arg type="t" name="flags" direction="in"/> | ||
| 307 | </method> | ||
| 308 | <method name="Suspend"> | ||
| 309 | <arg type="b" name="interactive" direction="in"/> | ||
| 310 | </method> | ||
| 311 | <method name="SuspendWithFlags"> | ||
| 312 | <arg type="t" name="flags" direction="in"/> | ||
| 313 | </method> | ||
| 314 | <method name="Hibernate"> | ||
| 315 | <arg type="b" name="interactive" direction="in"/> | ||
| 316 | </method> | ||
| 317 | <method name="HibernateWithFlags"> | ||
| 318 | <arg type="t" name="flags" direction="in"/> | ||
| 319 | </method> | ||
| 320 | <method name="HybridSleep"> | ||
| 321 | <arg type="b" name="interactive" direction="in"/> | ||
| 322 | </method> | ||
| 323 | <method name="HybridSleepWithFlags"> | ||
| 324 | <arg type="t" name="flags" direction="in"/> | ||
| 325 | </method> | ||
| 326 | <method name="SuspendThenHibernate"> | ||
| 327 | <arg type="b" name="interactive" direction="in"/> | ||
| 328 | </method> | ||
| 329 | <method name="SuspendThenHibernateWithFlags"> | ||
| 330 | <arg type="t" name="flags" direction="in"/> | ||
| 331 | </method> | ||
| 332 | <method name="Sleep"> | ||
| 333 | <arg type="t" name="flags" direction="in"/> | ||
| 334 | </method> | ||
| 335 | <method name="CanPowerOff"> | ||
| 336 | <arg type="s" name="result" direction="out"/> | ||
| 337 | </method> | ||
| 338 | <method name="CanReboot"> | ||
| 339 | <arg type="s" name="result" direction="out"/> | ||
| 340 | </method> | ||
| 341 | <method name="CanHalt"> | ||
| 342 | <arg type="s" name="result" direction="out"/> | ||
| 343 | </method> | ||
| 344 | <method name="CanSuspend"> | ||
| 345 | <arg type="s" name="result" direction="out"/> | ||
| 346 | </method> | ||
| 347 | <method name="CanHibernate"> | ||
| 348 | <arg type="s" name="result" direction="out"/> | ||
| 349 | </method> | ||
| 350 | <method name="CanHybridSleep"> | ||
| 351 | <arg type="s" name="result" direction="out"/> | ||
| 352 | </method> | ||
| 353 | <method name="CanSuspendThenHibernate"> | ||
| 354 | <arg type="s" name="result" direction="out"/> | ||
| 355 | </method> | ||
| 356 | <method name="CanSleep"> | ||
| 357 | <arg type="s" name="result" direction="out"/> | ||
| 358 | </method> | ||
| 359 | <method name="ScheduleShutdown"> | ||
| 360 | <arg type="s" name="type" direction="in"/> | ||
| 361 | <arg type="t" name="usec" direction="in"/> | ||
| 362 | </method> | ||
| 363 | <method name="CancelScheduledShutdown"> | ||
| 364 | <arg type="b" name="cancelled" direction="out"/> | ||
| 365 | </method> | ||
| 366 | <method name="Inhibit"> | ||
| 367 | <arg type="s" name="what" direction="in"/> | ||
| 368 | <arg type="s" name="who" direction="in"/> | ||
| 369 | <arg type="s" name="why" direction="in"/> | ||
| 370 | <arg type="s" name="mode" direction="in"/> | ||
| 371 | <arg type="h" name="pipe_fd" direction="out"/> | ||
| 372 | </method> | ||
| 373 | <method name="CanRebootParameter"> | ||
| 374 | <arg type="s" name="result" direction="out"/> | ||
| 375 | </method> | ||
| 376 | <method name="SetRebootParameter"> | ||
| 377 | <arg type="s" name="parameter" direction="in"/> | ||
| 378 | </method> | ||
| 379 | <method name="CanRebootToFirmwareSetup"> | ||
| 380 | <arg type="s" name="result" direction="out"/> | ||
| 381 | </method> | ||
| 382 | <method name="SetRebootToFirmwareSetup"> | ||
| 383 | <arg type="b" name="enable" direction="in"/> | ||
| 384 | </method> | ||
| 385 | <method name="CanRebootToBootLoaderMenu"> | ||
| 386 | <arg type="s" name="result" direction="out"/> | ||
| 387 | </method> | ||
| 388 | <method name="SetRebootToBootLoaderMenu"> | ||
| 389 | <arg type="t" name="timeout" direction="in"/> | ||
| 390 | </method> | ||
| 391 | <method name="CanRebootToBootLoaderEntry"> | ||
| 392 | <arg type="s" name="result" direction="out"/> | ||
| 393 | </method> | ||
| 394 | <method name="SetRebootToBootLoaderEntry"> | ||
| 395 | <arg type="s" name="boot_loader_entry" direction="in"/> | ||
| 396 | </method> | ||
| 397 | <method name="SetWallMessage"> | ||
| 398 | <arg type="s" name="wall_message" direction="in"/> | ||
| 399 | <arg type="b" name="enable" direction="in"/> | ||
| 400 | </method> | ||
| 401 | <signal name="SecureAttentionKey"> | ||
| 402 | <arg type="s" name="seat_id"/> | ||
| 403 | <arg type="o" name="object_path"/> | ||
| 404 | </signal> | ||
| 405 | <signal name="SessionNew"> | ||
| 406 | <arg type="s" name="session_id"/> | ||
| 407 | <arg type="o" name="object_path"/> | ||
| 408 | </signal> | ||
| 409 | <signal name="SessionRemoved"> | ||
| 410 | <arg type="s" name="session_id"/> | ||
| 411 | <arg type="o" name="object_path"/> | ||
| 412 | </signal> | ||
| 413 | <signal name="UserNew"> | ||
| 414 | <arg type="u" name="uid"/> | ||
| 415 | <arg type="o" name="object_path"/> | ||
| 416 | </signal> | ||
| 417 | <signal name="UserRemoved"> | ||
| 418 | <arg type="u" name="uid"/> | ||
| 419 | <arg type="o" name="object_path"/> | ||
| 420 | </signal> | ||
| 421 | <signal name="SeatNew"> | ||
| 422 | <arg type="s" name="seat_id"/> | ||
| 423 | <arg type="o" name="object_path"/> | ||
| 424 | </signal> | ||
| 425 | <signal name="SeatRemoved"> | ||
| 426 | <arg type="s" name="seat_id"/> | ||
| 427 | <arg type="o" name="object_path"/> | ||
| 428 | </signal> | ||
| 429 | <signal name="PrepareForShutdown"> | ||
| 430 | <arg type="b" name="start"/> | ||
| 431 | </signal> | ||
| 432 | <signal name="PrepareForShutdownWithMetadata"> | ||
| 433 | <arg type="b" name="start"/> | ||
| 434 | <arg type="a{sv}" name="metadata"/> | ||
| 435 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/> | ||
| 436 | </signal> | ||
| 437 | <signal name="PrepareForSleep"> | ||
| 438 | <arg type="b" name="start"/> | ||
| 439 | </signal> | ||
| 440 | </interface> | ||
| 441 | <node name="user"/> | ||
| 442 | <node name="session"/> | ||
| 443 | <node name="seat"/> | ||
| 444 | </node> | ||
| 445 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Session.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Session.xml new file mode 100644 index 00000000..7d6fc8ee --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.login1.Session.xml | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.login1.Session"> | ||
| 5 | <property name="Id" type="s" access="read"> | ||
| 6 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 7 | </property> | ||
| 8 | <property name="User" type="o" access="read"> | ||
| 9 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 10 | </property> | ||
| 11 | <property name="Name" type="s" access="read"> | ||
| 12 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 13 | </property> | ||
| 14 | <property name="Timestamp" type="t" access="read"> | ||
| 15 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 16 | </property> | ||
| 17 | <property name="TimestampMonotonic" type="t" access="read"> | ||
| 18 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 19 | </property> | ||
| 20 | <property name="VTNr" type="u" access="read"> | ||
| 21 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 22 | </property> | ||
| 23 | <property name="Seat" type="o" access="read"> | ||
| 24 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 25 | </property> | ||
| 26 | <property name="TTY" type="s" access="read"> | ||
| 27 | </property> | ||
| 28 | <property name="Display" type="s" access="read"> | ||
| 29 | </property> | ||
| 30 | <property name="Remote" type="b" access="read"> | ||
| 31 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 32 | </property> | ||
| 33 | <property name="RemoteHost" type="s" access="read"> | ||
| 34 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 35 | </property> | ||
| 36 | <property name="RemoteUser" type="s" access="read"> | ||
| 37 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 38 | </property> | ||
| 39 | <property name="Service" type="s" access="read"> | ||
| 40 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 41 | </property> | ||
| 42 | <property name="Desktop" type="s" access="read"> | ||
| 43 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 44 | </property> | ||
| 45 | <property name="Scope" type="s" access="read"> | ||
| 46 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 47 | </property> | ||
| 48 | <property name="Leader" type="u" access="read"> | ||
| 49 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 50 | </property> | ||
| 51 | <property name="Audit" type="u" access="read"> | ||
| 52 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 53 | </property> | ||
| 54 | <property name="Type" type="s" access="read"> | ||
| 55 | </property> | ||
| 56 | <!-- <property name="Class" type="s" access="read"> --> | ||
| 57 | <!-- </property> --> | ||
| 58 | <property name="Active" type="b" access="read"> | ||
| 59 | </property> | ||
| 60 | <property name="State" type="s" access="read"> | ||
| 61 | </property> | ||
| 62 | <property name="IdleHint" type="b" access="read"> | ||
| 63 | </property> | ||
| 64 | <property name="IdleSinceHint" type="t" access="read"> | ||
| 65 | </property> | ||
| 66 | <property name="IdleSinceHintMonotonic" type="t" access="read"> | ||
| 67 | </property> | ||
| 68 | <property name="CanIdle" type="b" access="read"> | ||
| 69 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 70 | </property> | ||
| 71 | <property name="CanLock" type="b" access="read"> | ||
| 72 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 73 | </property> | ||
| 74 | <property name="LockedHint" type="b" access="read"> | ||
| 75 | </property> | ||
| 76 | <method name="Terminate"> | ||
| 77 | </method> | ||
| 78 | <method name="Activate"> | ||
| 79 | </method> | ||
| 80 | <!-- <method name="Lock"> --> | ||
| 81 | <!-- </method> --> | ||
| 82 | <!-- <method name="Unlock"> --> | ||
| 83 | <!-- </method> --> | ||
| 84 | <method name="SetIdleHint"> | ||
| 85 | <arg type="b" name="idle" direction="in"/> | ||
| 86 | </method> | ||
| 87 | <method name="SetLockedHint"> | ||
| 88 | <arg type="b" name="locked" direction="in"/> | ||
| 89 | </method> | ||
| 90 | <method name="Kill"> | ||
| 91 | <arg type="s" name="whom" direction="in"/> | ||
| 92 | <arg type="i" name="signal_number" direction="in"/> | ||
| 93 | </method> | ||
| 94 | <method name="TakeControl"> | ||
| 95 | <arg type="b" name="force" direction="in"/> | ||
| 96 | </method> | ||
| 97 | <method name="ReleaseControl"> | ||
| 98 | </method> | ||
| 99 | <method name="SetType"> | ||
| 100 | <arg type="s" name="type" direction="in"/> | ||
| 101 | </method> | ||
| 102 | <!-- <method name="SetClass"> --> | ||
| 103 | <!-- <arg type="s" name="class" direction="in"/> --> | ||
| 104 | <!-- </method> --> | ||
| 105 | <method name="SetDisplay"> | ||
| 106 | <arg type="s" name="display" direction="in"/> | ||
| 107 | </method> | ||
| 108 | <method name="SetTTY"> | ||
| 109 | <arg type="h" name="tty_fd" direction="in"/> | ||
| 110 | </method> | ||
| 111 | <method name="TakeDevice"> | ||
| 112 | <arg type="u" name="major" direction="in"/> | ||
| 113 | <arg type="u" name="minor" direction="in"/> | ||
| 114 | <arg type="h" name="fd" direction="out"/> | ||
| 115 | <arg type="b" name="inactive" direction="out"/> | ||
| 116 | </method> | ||
| 117 | <method name="ReleaseDevice"> | ||
| 118 | <arg type="u" name="major" direction="in"/> | ||
| 119 | <arg type="u" name="minor" direction="in"/> | ||
| 120 | </method> | ||
| 121 | <method name="PauseDeviceComplete"> | ||
| 122 | <arg type="u" name="major" direction="in"/> | ||
| 123 | <arg type="u" name="minor" direction="in"/> | ||
| 124 | </method> | ||
| 125 | <method name="SetBrightness"> | ||
| 126 | <arg type="s" name="subsystem" direction="in"/> | ||
| 127 | <arg type="s" name="name" direction="in"/> | ||
| 128 | <arg type="u" name="brightness" direction="in"/> | ||
| 129 | </method> | ||
| 130 | <signal name="PauseDevice"> | ||
| 131 | <arg type="u" name="major"/> | ||
| 132 | <arg type="u" name="minor"/> | ||
| 133 | <arg type="s" name="type"/> | ||
| 134 | </signal> | ||
| 135 | <signal name="ResumeDevice"> | ||
| 136 | <arg type="u" name="major"/> | ||
| 137 | <arg type="u" name="minor"/> | ||
| 138 | <arg type="h" name="fd"/> | ||
| 139 | </signal> | ||
| 140 | <signal name="Lock"> | ||
| 141 | </signal> | ||
| 142 | <signal name="Unlock"> | ||
| 143 | </signal> | ||
| 144 | </interface> | ||
| 145 | </node> | ||
| 146 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Manager.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Manager.xml new file mode 100644 index 00000000..1dadbc55 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Manager.xml | |||
| @@ -0,0 +1,821 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.systemd1.Manager"> | ||
| 5 | <property name="Version" type="s" access="read"> | ||
| 6 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 7 | </property> | ||
| 8 | <property name="Features" type="s" access="read"> | ||
| 9 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 10 | </property> | ||
| 11 | <property name="Virtualization" type="s" access="read"> | ||
| 12 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 13 | </property> | ||
| 14 | <property name="ConfidentialVirtualization" type="s" access="read"> | ||
| 15 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 16 | </property> | ||
| 17 | <property name="Architecture" type="s" access="read"> | ||
| 18 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 19 | </property> | ||
| 20 | <property name="Tainted" type="s" access="read"> | ||
| 21 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 22 | </property> | ||
| 23 | <property name="FirmwareTimestamp" type="t" access="read"> | ||
| 24 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 25 | </property> | ||
| 26 | <property name="FirmwareTimestampMonotonic" type="t" access="read"> | ||
| 27 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 28 | </property> | ||
| 29 | <property name="LoaderTimestamp" type="t" access="read"> | ||
| 30 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 31 | </property> | ||
| 32 | <property name="LoaderTimestampMonotonic" type="t" access="read"> | ||
| 33 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 34 | </property> | ||
| 35 | <property name="KernelTimestamp" type="t" access="read"> | ||
| 36 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 37 | </property> | ||
| 38 | <property name="KernelTimestampMonotonic" type="t" access="read"> | ||
| 39 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 40 | </property> | ||
| 41 | <property name="InitRDTimestamp" type="t" access="read"> | ||
| 42 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 43 | </property> | ||
| 44 | <property name="InitRDTimestampMonotonic" type="t" access="read"> | ||
| 45 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 46 | </property> | ||
| 47 | <property name="UserspaceTimestamp" type="t" access="read"> | ||
| 48 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 49 | </property> | ||
| 50 | <property name="UserspaceTimestampMonotonic" type="t" access="read"> | ||
| 51 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 52 | </property> | ||
| 53 | <property name="FinishTimestamp" type="t" access="read"> | ||
| 54 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 55 | </property> | ||
| 56 | <property name="FinishTimestampMonotonic" type="t" access="read"> | ||
| 57 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 58 | </property> | ||
| 59 | <property name="ShutdownStartTimestamp" type="t" access="read"> | ||
| 60 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 61 | </property> | ||
| 62 | <property name="ShutdownStartTimestampMonotonic" type="t" access="read"> | ||
| 63 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 64 | </property> | ||
| 65 | <property name="SecurityStartTimestamp" type="t" access="read"> | ||
| 66 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 67 | </property> | ||
| 68 | <property name="SecurityStartTimestampMonotonic" type="t" access="read"> | ||
| 69 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 70 | </property> | ||
| 71 | <property name="SecurityFinishTimestamp" type="t" access="read"> | ||
| 72 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 73 | </property> | ||
| 74 | <property name="SecurityFinishTimestampMonotonic" type="t" access="read"> | ||
| 75 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 76 | </property> | ||
| 77 | <property name="GeneratorsStartTimestamp" type="t" access="read"> | ||
| 78 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 79 | </property> | ||
| 80 | <property name="GeneratorsStartTimestampMonotonic" type="t" access="read"> | ||
| 81 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 82 | </property> | ||
| 83 | <property name="GeneratorsFinishTimestamp" type="t" access="read"> | ||
| 84 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 85 | </property> | ||
| 86 | <property name="GeneratorsFinishTimestampMonotonic" type="t" access="read"> | ||
| 87 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 88 | </property> | ||
| 89 | <property name="UnitsLoadStartTimestamp" type="t" access="read"> | ||
| 90 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 91 | </property> | ||
| 92 | <property name="UnitsLoadStartTimestampMonotonic" type="t" access="read"> | ||
| 93 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 94 | </property> | ||
| 95 | <property name="UnitsLoadFinishTimestamp" type="t" access="read"> | ||
| 96 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 97 | </property> | ||
| 98 | <property name="UnitsLoadFinishTimestampMonotonic" type="t" access="read"> | ||
| 99 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 100 | </property> | ||
| 101 | <property name="UnitsLoadTimestamp" type="t" access="read"> | ||
| 102 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 103 | </property> | ||
| 104 | <property name="UnitsLoadTimestampMonotonic" type="t" access="read"> | ||
| 105 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 106 | </property> | ||
| 107 | <property name="InitRDSecurityStartTimestamp" type="t" access="read"> | ||
| 108 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 109 | </property> | ||
| 110 | <property name="InitRDSecurityStartTimestampMonotonic" type="t" access="read"> | ||
| 111 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 112 | </property> | ||
| 113 | <property name="InitRDSecurityFinishTimestamp" type="t" access="read"> | ||
| 114 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 115 | </property> | ||
| 116 | <property name="InitRDSecurityFinishTimestampMonotonic" type="t" access="read"> | ||
| 117 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 118 | </property> | ||
| 119 | <property name="InitRDGeneratorsStartTimestamp" type="t" access="read"> | ||
| 120 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 121 | </property> | ||
| 122 | <property name="InitRDGeneratorsStartTimestampMonotonic" type="t" access="read"> | ||
| 123 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 124 | </property> | ||
| 125 | <property name="InitRDGeneratorsFinishTimestamp" type="t" access="read"> | ||
| 126 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 127 | </property> | ||
| 128 | <property name="InitRDGeneratorsFinishTimestampMonotonic" type="t" access="read"> | ||
| 129 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 130 | </property> | ||
| 131 | <property name="InitRDUnitsLoadStartTimestamp" type="t" access="read"> | ||
| 132 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 133 | </property> | ||
| 134 | <property name="InitRDUnitsLoadStartTimestampMonotonic" type="t" access="read"> | ||
| 135 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 136 | </property> | ||
| 137 | <property name="InitRDUnitsLoadFinishTimestamp" type="t" access="read"> | ||
| 138 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 139 | </property> | ||
| 140 | <property name="InitRDUnitsLoadFinishTimestampMonotonic" type="t" access="read"> | ||
| 141 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 142 | </property> | ||
| 143 | <property name="LogLevel" type="s" access="readwrite"> | ||
| 144 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 145 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 146 | </property> | ||
| 147 | <property name="LogTarget" type="s" access="readwrite"> | ||
| 148 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 149 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 150 | </property> | ||
| 151 | <property name="NNames" type="u" access="read"> | ||
| 152 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 153 | </property> | ||
| 154 | <property name="NFailedUnits" type="u" access="read"> | ||
| 155 | </property> | ||
| 156 | <property name="NJobs" type="u" access="read"> | ||
| 157 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 158 | </property> | ||
| 159 | <property name="NInstalledJobs" type="u" access="read"> | ||
| 160 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 161 | </property> | ||
| 162 | <property name="NFailedJobs" type="u" access="read"> | ||
| 163 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 164 | </property> | ||
| 165 | <property name="Progress" type="d" access="read"> | ||
| 166 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 167 | </property> | ||
| 168 | <property name="Environment" type="as" access="read"> | ||
| 169 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 170 | </property> | ||
| 171 | <property name="ConfirmSpawn" type="b" access="read"> | ||
| 172 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 173 | </property> | ||
| 174 | <property name="ShowStatus" type="b" access="read"> | ||
| 175 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 176 | </property> | ||
| 177 | <property name="UnitPath" type="as" access="read"> | ||
| 178 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 179 | </property> | ||
| 180 | <property name="DefaultStandardOutput" type="s" access="read"> | ||
| 181 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 182 | </property> | ||
| 183 | <property name="DefaultStandardError" type="s" access="read"> | ||
| 184 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 185 | </property> | ||
| 186 | <property name="WatchdogDevice" type="s" access="read"> | ||
| 187 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 188 | </property> | ||
| 189 | <property name="WatchdogLastPingTimestamp" type="t" access="read"> | ||
| 190 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 191 | </property> | ||
| 192 | <property name="WatchdogLastPingTimestampMonotonic" type="t" access="read"> | ||
| 193 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 194 | </property> | ||
| 195 | <property name="RuntimeWatchdogUSec" type="t" access="readwrite"> | ||
| 196 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 197 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 198 | </property> | ||
| 199 | <property name="RuntimeWatchdogPreUSec" type="t" access="readwrite"> | ||
| 200 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 201 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 202 | </property> | ||
| 203 | <property name="RuntimeWatchdogPreGovernor" type="s" access="readwrite"> | ||
| 204 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 205 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 206 | </property> | ||
| 207 | <property name="RebootWatchdogUSec" type="t" access="readwrite"> | ||
| 208 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 209 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 210 | </property> | ||
| 211 | <property name="KExecWatchdogUSec" type="t" access="readwrite"> | ||
| 212 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 213 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 214 | </property> | ||
| 215 | <property name="ServiceWatchdogs" type="b" access="readwrite"> | ||
| 216 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 217 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 218 | </property> | ||
| 219 | <property name="ControlGroup" type="s" access="read"> | ||
| 220 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 221 | </property> | ||
| 222 | <property name="SystemState" type="s" access="read"> | ||
| 223 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 224 | </property> | ||
| 225 | <property name="ExitCode" type="y" access="read"> | ||
| 226 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 227 | </property> | ||
| 228 | <property name="DefaultTimerAccuracyUSec" type="t" access="read"> | ||
| 229 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 230 | </property> | ||
| 231 | <property name="DefaultTimeoutStartUSec" type="t" access="read"> | ||
| 232 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 233 | </property> | ||
| 234 | <property name="DefaultTimeoutStopUSec" type="t" access="read"> | ||
| 235 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 236 | </property> | ||
| 237 | <property name="DefaultTimeoutAbortUSec" type="t" access="read"> | ||
| 238 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 239 | </property> | ||
| 240 | <property name="DefaultDeviceTimeoutUSec" type="t" access="read"> | ||
| 241 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 242 | </property> | ||
| 243 | <property name="DefaultRestartUSec" type="t" access="read"> | ||
| 244 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 245 | </property> | ||
| 246 | <property name="DefaultStartLimitIntervalUSec" type="t" access="read"> | ||
| 247 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 248 | </property> | ||
| 249 | <property name="DefaultStartLimitBurst" type="u" access="read"> | ||
| 250 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 251 | </property> | ||
| 252 | <property name="DefaultCPUAccounting" type="b" access="read"> | ||
| 253 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 254 | </property> | ||
| 255 | <property name="DefaultBlockIOAccounting" type="b" access="read"> | ||
| 256 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 257 | </property> | ||
| 258 | <property name="DefaultIOAccounting" type="b" access="read"> | ||
| 259 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 260 | </property> | ||
| 261 | <property name="DefaultIPAccounting" type="b" access="read"> | ||
| 262 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 263 | </property> | ||
| 264 | <property name="DefaultMemoryAccounting" type="b" access="read"> | ||
| 265 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 266 | </property> | ||
| 267 | <property name="DefaultTasksAccounting" type="b" access="read"> | ||
| 268 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 269 | </property> | ||
| 270 | <property name="DefaultLimitCPU" type="t" access="read"> | ||
| 271 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 272 | </property> | ||
| 273 | <property name="DefaultLimitCPUSoft" type="t" access="read"> | ||
| 274 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 275 | </property> | ||
| 276 | <property name="DefaultLimitFSIZE" type="t" access="read"> | ||
| 277 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 278 | </property> | ||
| 279 | <property name="DefaultLimitFSIZESoft" type="t" access="read"> | ||
| 280 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 281 | </property> | ||
| 282 | <property name="DefaultLimitDATA" type="t" access="read"> | ||
| 283 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 284 | </property> | ||
| 285 | <property name="DefaultLimitDATASoft" type="t" access="read"> | ||
| 286 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 287 | </property> | ||
| 288 | <property name="DefaultLimitSTACK" type="t" access="read"> | ||
| 289 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 290 | </property> | ||
| 291 | <property name="DefaultLimitSTACKSoft" type="t" access="read"> | ||
| 292 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 293 | </property> | ||
| 294 | <property name="DefaultLimitCORE" type="t" access="read"> | ||
| 295 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 296 | </property> | ||
| 297 | <property name="DefaultLimitCORESoft" type="t" access="read"> | ||
| 298 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 299 | </property> | ||
| 300 | <property name="DefaultLimitRSS" type="t" access="read"> | ||
| 301 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 302 | </property> | ||
| 303 | <property name="DefaultLimitRSSSoft" type="t" access="read"> | ||
| 304 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 305 | </property> | ||
| 306 | <property name="DefaultLimitNOFILE" type="t" access="read"> | ||
| 307 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 308 | </property> | ||
| 309 | <property name="DefaultLimitNOFILESoft" type="t" access="read"> | ||
| 310 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 311 | </property> | ||
| 312 | <property name="DefaultLimitAS" type="t" access="read"> | ||
| 313 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 314 | </property> | ||
| 315 | <property name="DefaultLimitASSoft" type="t" access="read"> | ||
| 316 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 317 | </property> | ||
| 318 | <property name="DefaultLimitNPROC" type="t" access="read"> | ||
| 319 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 320 | </property> | ||
| 321 | <property name="DefaultLimitNPROCSoft" type="t" access="read"> | ||
| 322 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 323 | </property> | ||
| 324 | <property name="DefaultLimitMEMLOCK" type="t" access="read"> | ||
| 325 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 326 | </property> | ||
| 327 | <property name="DefaultLimitMEMLOCKSoft" type="t" access="read"> | ||
| 328 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 329 | </property> | ||
| 330 | <property name="DefaultLimitLOCKS" type="t" access="read"> | ||
| 331 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 332 | </property> | ||
| 333 | <property name="DefaultLimitLOCKSSoft" type="t" access="read"> | ||
| 334 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 335 | </property> | ||
| 336 | <property name="DefaultLimitSIGPENDING" type="t" access="read"> | ||
| 337 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 338 | </property> | ||
| 339 | <property name="DefaultLimitSIGPENDINGSoft" type="t" access="read"> | ||
| 340 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 341 | </property> | ||
| 342 | <property name="DefaultLimitMSGQUEUE" type="t" access="read"> | ||
| 343 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 344 | </property> | ||
| 345 | <property name="DefaultLimitMSGQUEUESoft" type="t" access="read"> | ||
| 346 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 347 | </property> | ||
| 348 | <property name="DefaultLimitNICE" type="t" access="read"> | ||
| 349 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 350 | </property> | ||
| 351 | <property name="DefaultLimitNICESoft" type="t" access="read"> | ||
| 352 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 353 | </property> | ||
| 354 | <property name="DefaultLimitRTPRIO" type="t" access="read"> | ||
| 355 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 356 | </property> | ||
| 357 | <property name="DefaultLimitRTPRIOSoft" type="t" access="read"> | ||
| 358 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 359 | </property> | ||
| 360 | <property name="DefaultLimitRTTIME" type="t" access="read"> | ||
| 361 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 362 | </property> | ||
| 363 | <property name="DefaultLimitRTTIMESoft" type="t" access="read"> | ||
| 364 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 365 | </property> | ||
| 366 | <property name="DefaultTasksMax" type="t" access="read"> | ||
| 367 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 368 | </property> | ||
| 369 | <property name="DefaultMemoryPressureThresholdUSec" type="t" access="read"> | ||
| 370 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 371 | </property> | ||
| 372 | <property name="DefaultMemoryPressureWatch" type="s" access="read"> | ||
| 373 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 374 | </property> | ||
| 375 | <property name="TimerSlackNSec" type="t" access="read"> | ||
| 376 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 377 | </property> | ||
| 378 | <property name="DefaultOOMPolicy" type="s" access="read"> | ||
| 379 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 380 | </property> | ||
| 381 | <property name="DefaultOOMScoreAdjust" type="i" access="read"> | ||
| 382 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 383 | </property> | ||
| 384 | <property name="CtrlAltDelBurstAction" type="s" access="read"> | ||
| 385 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 386 | </property> | ||
| 387 | <property name="SoftRebootsCount" type="u" access="read"> | ||
| 388 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 389 | </property> | ||
| 390 | <method name="GetUnit"> | ||
| 391 | <arg type="s" name="name" direction="in"/> | ||
| 392 | <arg type="o" name="unit" direction="out"/> | ||
| 393 | </method> | ||
| 394 | <method name="GetUnitByPID"> | ||
| 395 | <arg type="u" name="pid" direction="in"/> | ||
| 396 | <arg type="o" name="unit" direction="out"/> | ||
| 397 | </method> | ||
| 398 | <method name="GetUnitByInvocationID"> | ||
| 399 | <arg type="ay" name="invocation_id" direction="in"/> | ||
| 400 | <arg type="o" name="unit" direction="out"/> | ||
| 401 | </method> | ||
| 402 | <method name="GetUnitByControlGroup"> | ||
| 403 | <arg type="s" name="cgroup" direction="in"/> | ||
| 404 | <arg type="o" name="unit" direction="out"/> | ||
| 405 | </method> | ||
| 406 | <method name="GetUnitByPIDFD"> | ||
| 407 | <arg type="h" name="pidfd" direction="in"/> | ||
| 408 | <arg type="o" name="unit" direction="out"/> | ||
| 409 | <arg type="s" name="unit_id" direction="out"/> | ||
| 410 | <arg type="ay" name="invocation_id" direction="out"/> | ||
| 411 | </method> | ||
| 412 | <method name="LoadUnit"> | ||
| 413 | <arg type="s" name="name" direction="in"/> | ||
| 414 | <arg type="o" name="unit" direction="out"/> | ||
| 415 | </method> | ||
| 416 | <method name="StartUnit"> | ||
| 417 | <arg type="s" name="name" direction="in"/> | ||
| 418 | <arg type="s" name="mode" direction="in"/> | ||
| 419 | <arg type="o" name="job" direction="out"/> | ||
| 420 | </method> | ||
| 421 | <method name="StartUnitWithFlags"> | ||
| 422 | <arg type="s" name="name" direction="in"/> | ||
| 423 | <arg type="s" name="mode" direction="in"/> | ||
| 424 | <arg type="t" name="flags" direction="in"/> | ||
| 425 | <arg type="o" name="job" direction="out"/> | ||
| 426 | </method> | ||
| 427 | <method name="StartUnitReplace"> | ||
| 428 | <arg type="s" name="old_unit" direction="in"/> | ||
| 429 | <arg type="s" name="new_unit" direction="in"/> | ||
| 430 | <arg type="s" name="mode" direction="in"/> | ||
| 431 | <arg type="o" name="job" direction="out"/> | ||
| 432 | </method> | ||
| 433 | <method name="StopUnit"> | ||
| 434 | <arg type="s" name="name" direction="in"/> | ||
| 435 | <arg type="s" name="mode" direction="in"/> | ||
| 436 | <arg type="o" name="job" direction="out"/> | ||
| 437 | </method> | ||
| 438 | <method name="ReloadUnit"> | ||
| 439 | <arg type="s" name="name" direction="in"/> | ||
| 440 | <arg type="s" name="mode" direction="in"/> | ||
| 441 | <arg type="o" name="job" direction="out"/> | ||
| 442 | </method> | ||
| 443 | <method name="RestartUnit"> | ||
| 444 | <arg type="s" name="name" direction="in"/> | ||
| 445 | <arg type="s" name="mode" direction="in"/> | ||
| 446 | <arg type="o" name="job" direction="out"/> | ||
| 447 | </method> | ||
| 448 | <method name="TryRestartUnit"> | ||
| 449 | <arg type="s" name="name" direction="in"/> | ||
| 450 | <arg type="s" name="mode" direction="in"/> | ||
| 451 | <arg type="o" name="job" direction="out"/> | ||
| 452 | </method> | ||
| 453 | <method name="ReloadOrRestartUnit"> | ||
| 454 | <arg type="s" name="name" direction="in"/> | ||
| 455 | <arg type="s" name="mode" direction="in"/> | ||
| 456 | <arg type="o" name="job" direction="out"/> | ||
| 457 | </method> | ||
| 458 | <method name="ReloadOrTryRestartUnit"> | ||
| 459 | <arg type="s" name="name" direction="in"/> | ||
| 460 | <arg type="s" name="mode" direction="in"/> | ||
| 461 | <arg type="o" name="job" direction="out"/> | ||
| 462 | </method> | ||
| 463 | <!-- <method name="EnqueueUnitJob"> --> | ||
| 464 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 465 | <!-- <arg type="s" name="job_type" direction="in"/> --> | ||
| 466 | <!-- <arg type="s" name="job_mode" direction="in"/> --> | ||
| 467 | <!-- <arg type="u" name="job_id" direction="out"/> --> | ||
| 468 | <!-- <arg type="o" name="job_path" direction="out"/> --> | ||
| 469 | <!-- <arg type="s" name="unit_id" direction="out"/> --> | ||
| 470 | <!-- <arg type="o" name="unit_path" direction="out"/> --> | ||
| 471 | <!-- <arg type="s" name="job_type" direction="out"/> --> | ||
| 472 | <!-- <arg type="a(uosos)" name="affected_jobs" direction="out"/> --> | ||
| 473 | <!-- </method> --> | ||
| 474 | <method name="KillUnit"> | ||
| 475 | <arg type="s" name="name" direction="in"/> | ||
| 476 | <arg type="s" name="whom" direction="in"/> | ||
| 477 | <arg type="i" name="signal" direction="in"/> | ||
| 478 | </method> | ||
| 479 | <method name="QueueSignalUnit"> | ||
| 480 | <arg type="s" name="name" direction="in"/> | ||
| 481 | <arg type="s" name="whom" direction="in"/> | ||
| 482 | <arg type="i" name="signal" direction="in"/> | ||
| 483 | <arg type="i" name="value" direction="in"/> | ||
| 484 | </method> | ||
| 485 | <method name="CleanUnit"> | ||
| 486 | <arg type="s" name="name" direction="in"/> | ||
| 487 | <arg type="as" name="mask" direction="in"/> | ||
| 488 | </method> | ||
| 489 | <method name="FreezeUnit"> | ||
| 490 | <arg type="s" name="name" direction="in"/> | ||
| 491 | </method> | ||
| 492 | <method name="ThawUnit"> | ||
| 493 | <arg type="s" name="name" direction="in"/> | ||
| 494 | </method> | ||
| 495 | <method name="ResetFailedUnit"> | ||
| 496 | <arg type="s" name="name" direction="in"/> | ||
| 497 | </method> | ||
| 498 | <!-- <method name="SetUnitProperties"> --> | ||
| 499 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 500 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 501 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 502 | <!-- </method> --> | ||
| 503 | <method name="BindMountUnit"> | ||
| 504 | <arg type="s" name="name" direction="in"/> | ||
| 505 | <arg type="s" name="source" direction="in"/> | ||
| 506 | <arg type="s" name="destination" direction="in"/> | ||
| 507 | <arg type="b" name="read_only" direction="in"/> | ||
| 508 | <arg type="b" name="mkdir" direction="in"/> | ||
| 509 | </method> | ||
| 510 | <!-- <method name="MountImageUnit"> --> | ||
| 511 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 512 | <!-- <arg type="s" name="source" direction="in"/> --> | ||
| 513 | <!-- <arg type="s" name="destination" direction="in"/> --> | ||
| 514 | <!-- <arg type="b" name="read_only" direction="in"/> --> | ||
| 515 | <!-- <arg type="b" name="mkdir" direction="in"/> --> | ||
| 516 | <!-- <arg type="a(ss)" name="options" direction="in"/> --> | ||
| 517 | <!-- </method> --> | ||
| 518 | <method name="RefUnit"> | ||
| 519 | <arg type="s" name="name" direction="in"/> | ||
| 520 | </method> | ||
| 521 | <method name="UnrefUnit"> | ||
| 522 | <arg type="s" name="name" direction="in"/> | ||
| 523 | </method> | ||
| 524 | <!-- <method name="StartTransientUnit"> --> | ||
| 525 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 526 | <!-- <arg type="s" name="mode" direction="in"/> --> | ||
| 527 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 528 | <!-- <arg type="a(sa(sv))" name="aux" direction="in"/> --> | ||
| 529 | <!-- <arg type="o" name="job" direction="out"/> --> | ||
| 530 | <!-- </method> --> | ||
| 531 | <!-- <method name="GetUnitProcesses"> --> | ||
| 532 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 533 | <!-- <arg type="a(sus)" name="processes" direction="out"/> --> | ||
| 534 | <!-- </method> --> | ||
| 535 | <!-- <method name="AttachProcessesToUnit"> --> | ||
| 536 | <!-- <arg type="s" name="unit_name" direction="in"/> --> | ||
| 537 | <!-- <arg type="s" name="subcgroup" direction="in"/> --> | ||
| 538 | <!-- <arg type="au" name="pids" direction="in"/> --> | ||
| 539 | <!-- </method> --> | ||
| 540 | <method name="AbandonScope"> | ||
| 541 | <arg type="s" name="name" direction="in"/> | ||
| 542 | </method> | ||
| 543 | <method name="GetJob"> | ||
| 544 | <arg type="u" name="id" direction="in"/> | ||
| 545 | <arg type="o" name="job" direction="out"/> | ||
| 546 | </method> | ||
| 547 | <!-- <method name="GetJobAfter"> --> | ||
| 548 | <!-- <arg type="u" name="id" direction="in"/> --> | ||
| 549 | <!-- <arg type="a(usssoo)" name="jobs" direction="out"/> --> | ||
| 550 | <!-- </method> --> | ||
| 551 | <!-- <method name="GetJobBefore"> --> | ||
| 552 | <!-- <arg type="u" name="id" direction="in"/> --> | ||
| 553 | <!-- <arg type="a(usssoo)" name="jobs" direction="out"/> --> | ||
| 554 | <!-- </method> --> | ||
| 555 | <method name="CancelJob"> | ||
| 556 | <arg type="u" name="id" direction="in"/> | ||
| 557 | </method> | ||
| 558 | <method name="ClearJobs"> | ||
| 559 | </method> | ||
| 560 | <method name="ResetFailed"> | ||
| 561 | </method> | ||
| 562 | <method name="SetShowStatus"> | ||
| 563 | <arg type="s" name="mode" direction="in"/> | ||
| 564 | </method> | ||
| 565 | <method name="ListUnits"> | ||
| 566 | <arg type="a(ssssssouso)" name="units" direction="out"/> | ||
| 567 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ListUnitsResult"/> | ||
| 568 | </method> | ||
| 569 | <method name="ListUnitsFiltered"> | ||
| 570 | <arg type="as" name="states" direction="in"/> | ||
| 571 | <arg type="a(ssssssouso)" name="units" direction="out"/> | ||
| 572 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ListUnitsResult"/> | ||
| 573 | </method> | ||
| 574 | <method name="ListUnitsByPatterns"> | ||
| 575 | <arg type="as" name="states" direction="in"/> | ||
| 576 | <arg type="as" name="patterns" direction="in"/> | ||
| 577 | <arg type="a(ssssssouso)" name="units" direction="out"/> | ||
| 578 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ListUnitsResult"/> | ||
| 579 | </method> | ||
| 580 | <method name="ListUnitsByNames"> | ||
| 581 | <arg type="as" name="names" direction="in"/> | ||
| 582 | <arg type="a(ssssssouso)" name="units" direction="out"/> | ||
| 583 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ListUnitsResult"/> | ||
| 584 | </method> | ||
| 585 | <!-- <method name="ListJobs"> --> | ||
| 586 | <!-- <arg type="a(usssoo)" name="jobs" direction="out"/> --> | ||
| 587 | <!-- </method> --> | ||
| 588 | <method name="Subscribe"> | ||
| 589 | </method> | ||
| 590 | <method name="Unsubscribe"> | ||
| 591 | </method> | ||
| 592 | <method name="Dump"> | ||
| 593 | <arg type="s" name="output" direction="out"/> | ||
| 594 | </method> | ||
| 595 | <method name="DumpUnitsMatchingPatterns"> | ||
| 596 | <arg type="as" name="patterns" direction="in"/> | ||
| 597 | <arg type="s" name="output" direction="out"/> | ||
| 598 | </method> | ||
| 599 | <method name="DumpByFileDescriptor"> | ||
| 600 | <arg type="h" name="fd" direction="out"/> | ||
| 601 | </method> | ||
| 602 | <method name="DumpUnitsMatchingPatternsByFileDescriptor"> | ||
| 603 | <arg type="as" name="patterns" direction="in"/> | ||
| 604 | <arg type="h" name="fd" direction="out"/> | ||
| 605 | </method> | ||
| 606 | <method name="Reload"> | ||
| 607 | </method> | ||
| 608 | <method name="Reexecute"> | ||
| 609 | <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> | ||
| 610 | </method> | ||
| 611 | <method name="Exit"> | ||
| 612 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 613 | </method> | ||
| 614 | <method name="Reboot"> | ||
| 615 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 616 | </method> | ||
| 617 | <method name="SoftReboot"> | ||
| 618 | <arg type="s" name="new_root" direction="in"/> | ||
| 619 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 620 | </method> | ||
| 621 | <method name="PowerOff"> | ||
| 622 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 623 | </method> | ||
| 624 | <method name="Halt"> | ||
| 625 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 626 | </method> | ||
| 627 | <method name="KExec"> | ||
| 628 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 629 | </method> | ||
| 630 | <method name="SwitchRoot"> | ||
| 631 | <arg type="s" name="new_root" direction="in"/> | ||
| 632 | <arg type="s" name="init" direction="in"/> | ||
| 633 | <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> | ||
| 634 | </method> | ||
| 635 | <method name="SetEnvironment"> | ||
| 636 | <arg type="as" name="assignments" direction="in"/> | ||
| 637 | </method> | ||
| 638 | <method name="UnsetEnvironment"> | ||
| 639 | <arg type="as" name="names" direction="in"/> | ||
| 640 | </method> | ||
| 641 | <method name="UnsetAndSetEnvironment"> | ||
| 642 | <arg type="as" name="names" direction="in"/> | ||
| 643 | <arg type="as" name="assignments" direction="in"/> | ||
| 644 | </method> | ||
| 645 | <method name="EnqueueMarkedJobs"> | ||
| 646 | <arg type="ao" name="jobs" direction="out"/> | ||
| 647 | </method> | ||
| 648 | <!-- <method name="ListUnitFiles"> --> | ||
| 649 | <!-- <arg type="a(ss)" name="unit_files" direction="out"/> --> | ||
| 650 | <!-- </method> --> | ||
| 651 | <!-- <method name="ListUnitFilesByPatterns"> --> | ||
| 652 | <!-- <arg type="as" name="states" direction="in"/> --> | ||
| 653 | <!-- <arg type="as" name="patterns" direction="in"/> --> | ||
| 654 | <!-- <arg type="a(ss)" name="unit_files" direction="out"/> --> | ||
| 655 | <!-- </method> --> | ||
| 656 | <method name="GetUnitFileState"> | ||
| 657 | <arg type="s" name="file" direction="in"/> | ||
| 658 | <arg type="s" name="state" direction="out"/> | ||
| 659 | </method> | ||
| 660 | <!-- <method name="EnableUnitFiles"> --> | ||
| 661 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 662 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 663 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 664 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 665 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 666 | <!-- </method> --> | ||
| 667 | <!-- <method name="DisableUnitFiles"> --> | ||
| 668 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 669 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 670 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 671 | <!-- </method> --> | ||
| 672 | <!-- <method name="EnableUnitFilesWithFlags"> --> | ||
| 673 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 674 | <!-- <arg type="t" name="flags" direction="in"/> --> | ||
| 675 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 676 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 677 | <!-- </method> --> | ||
| 678 | <!-- <method name="DisableUnitFilesWithFlags"> --> | ||
| 679 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 680 | <!-- <arg type="t" name="flags" direction="in"/> --> | ||
| 681 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 682 | <!-- </method> --> | ||
| 683 | <!-- <method name="DisableUnitFilesWithFlagsAndInstallInfo"> --> | ||
| 684 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 685 | <!-- <arg type="t" name="flags" direction="in"/> --> | ||
| 686 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 687 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 688 | <!-- </method> --> | ||
| 689 | <!-- <method name="ReenableUnitFiles"> --> | ||
| 690 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 691 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 692 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 693 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 694 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 695 | <!-- </method> --> | ||
| 696 | <!-- <method name="LinkUnitFiles"> --> | ||
| 697 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 698 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 699 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 700 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 701 | <!-- </method> --> | ||
| 702 | <!-- <method name="PresetUnitFiles"> --> | ||
| 703 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 704 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 705 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 706 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 707 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 708 | <!-- </method> --> | ||
| 709 | <!-- <method name="PresetUnitFilesWithMode"> --> | ||
| 710 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 711 | <!-- <arg type="s" name="mode" direction="in"/> --> | ||
| 712 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 713 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 714 | <!-- <arg type="b" name="carries_install_info" direction="out"/> --> | ||
| 715 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 716 | <!-- </method> --> | ||
| 717 | <!-- <method name="MaskUnitFiles"> --> | ||
| 718 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 719 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 720 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 721 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 722 | <!-- </method> --> | ||
| 723 | <!-- <method name="UnmaskUnitFiles"> --> | ||
| 724 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 725 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 726 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 727 | <!-- </method> --> | ||
| 728 | <!-- <method name="RevertUnitFiles"> --> | ||
| 729 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 730 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 731 | <!-- </method> --> | ||
| 732 | <!-- <method name="SetDefaultTarget"> --> | ||
| 733 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 734 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 735 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 736 | <!-- </method> --> | ||
| 737 | <method name="GetDefaultTarget"> | ||
| 738 | <arg type="s" name="name" direction="out"/> | ||
| 739 | </method> | ||
| 740 | <!-- <method name="PresetAllUnitFiles"> --> | ||
| 741 | <!-- <arg type="s" name="mode" direction="in"/> --> | ||
| 742 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 743 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 744 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 745 | <!-- </method> --> | ||
| 746 | <!-- <method name="AddDependencyUnitFiles"> --> | ||
| 747 | <!-- <arg type="as" name="files" direction="in"/> --> | ||
| 748 | <!-- <arg type="s" name="target" direction="in"/> --> | ||
| 749 | <!-- <arg type="s" name="type" direction="in"/> --> | ||
| 750 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 751 | <!-- <arg type="b" name="force" direction="in"/> --> | ||
| 752 | <!-- <arg type="a(sss)" name="changes" direction="out"/> --> | ||
| 753 | <!-- </method> --> | ||
| 754 | <method name="GetUnitFileLinks"> | ||
| 755 | <arg type="s" name="name" direction="in"/> | ||
| 756 | <arg type="b" name="runtime" direction="in"/> | ||
| 757 | <arg type="as" name="links" direction="out"/> | ||
| 758 | </method> | ||
| 759 | <method name="SetExitCode"> | ||
| 760 | <arg type="y" name="number" direction="in"/> | ||
| 761 | </method> | ||
| 762 | <method name="LookupDynamicUserByName"> | ||
| 763 | <arg type="s" name="name" direction="in"/> | ||
| 764 | <arg type="u" name="uid" direction="out"/> | ||
| 765 | </method> | ||
| 766 | <method name="LookupDynamicUserByUID"> | ||
| 767 | <arg type="u" name="uid" direction="in"/> | ||
| 768 | <arg type="s" name="name" direction="out"/> | ||
| 769 | </method> | ||
| 770 | <!-- <method name="GetDynamicUsers"> --> | ||
| 771 | <!-- <arg type="a(us)" name="users" direction="out"/> --> | ||
| 772 | <!-- </method> --> | ||
| 773 | <!-- <method name="DumpUnitFileDescriptorStore"> --> | ||
| 774 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 775 | <!-- <arg type="a(suuutuusu)" name="entries" direction="out"/> --> | ||
| 776 | <!-- </method> --> | ||
| 777 | <!-- <method name="StartAuxiliaryScope"> --> | ||
| 778 | <!-- <arg type="s" name="name" direction="in"/> --> | ||
| 779 | <!-- <arg type="ah" name="pidfds" direction="in"/> --> | ||
| 780 | <!-- <arg type="t" name="flags" direction="in"/> --> | ||
| 781 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 782 | <!-- <arg type="o" name="job" direction="out"/> --> | ||
| 783 | <!-- <annotation name="org.freedesktop.DBus.Deprecated" value="true"/> --> | ||
| 784 | <!-- </method> --> | ||
| 785 | <signal name="UnitNew"> | ||
| 786 | <arg type="s" name="id"/> | ||
| 787 | <arg type="o" name="unit"/> | ||
| 788 | </signal> | ||
| 789 | <signal name="UnitRemoved"> | ||
| 790 | <arg type="s" name="id"/> | ||
| 791 | <arg type="o" name="unit"/> | ||
| 792 | </signal> | ||
| 793 | <signal name="JobNew"> | ||
| 794 | <arg type="u" name="id"/> | ||
| 795 | <arg type="o" name="job"/> | ||
| 796 | <arg type="s" name="unit"/> | ||
| 797 | </signal> | ||
| 798 | <signal name="JobRemoved"> | ||
| 799 | <arg type="u" name="id"/> | ||
| 800 | <arg type="o" name="job"/> | ||
| 801 | <arg type="s" name="unit"/> | ||
| 802 | <arg type="s" name="result"/> | ||
| 803 | </signal> | ||
| 804 | <signal name="StartupFinished"> | ||
| 805 | <arg type="t" name="firmware"/> | ||
| 806 | <arg type="t" name="loader"/> | ||
| 807 | <arg type="t" name="kernel"/> | ||
| 808 | <arg type="t" name="initrd"/> | ||
| 809 | <arg type="t" name="userspace"/> | ||
| 810 | <arg type="t" name="total"/> | ||
| 811 | </signal> | ||
| 812 | <signal name="UnitFilesChanged"> | ||
| 813 | </signal> | ||
| 814 | <signal name="Reloading"> | ||
| 815 | <arg type="b" name="active"/> | ||
| 816 | </signal> | ||
| 817 | </interface> | ||
| 818 | <node name="unit"/> | ||
| 819 | <node name="job"/> | ||
| 820 | </node> | ||
| 821 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Service.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Service.xml new file mode 100644 index 00000000..316dd080 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Service.xml | |||
| @@ -0,0 +1,1100 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.systemd1.Service"> | ||
| 5 | <property name="Type" type="s" access="read"> | ||
| 6 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 7 | </property> | ||
| 8 | <property name="ExitType" type="s" access="read"> | ||
| 9 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 10 | </property> | ||
| 11 | <property name="Restart" type="s" access="read"> | ||
| 12 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 13 | </property> | ||
| 14 | <property name="RestartMode" type="s" access="read"> | ||
| 15 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 16 | </property> | ||
| 17 | <property name="PIDFile" type="s" access="read"> | ||
| 18 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 19 | </property> | ||
| 20 | <property name="NotifyAccess" type="s" access="read"> | ||
| 21 | </property> | ||
| 22 | <property name="RestartUSec" type="t" access="read"> | ||
| 23 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 24 | </property> | ||
| 25 | <property name="RestartSteps" type="u" access="read"> | ||
| 26 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 27 | </property> | ||
| 28 | <property name="RestartMaxDelayUSec" type="t" access="read"> | ||
| 29 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 30 | </property> | ||
| 31 | <property name="RestartUSecNext" type="t" access="read"> | ||
| 32 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 33 | </property> | ||
| 34 | <property name="TimeoutStartUSec" type="t" access="read"> | ||
| 35 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 36 | </property> | ||
| 37 | <property name="TimeoutStopUSec" type="t" access="read"> | ||
| 38 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 39 | </property> | ||
| 40 | <property name="TimeoutAbortUSec" type="t" access="read"> | ||
| 41 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 42 | </property> | ||
| 43 | <property name="TimeoutStartFailureMode" type="s" access="read"> | ||
| 44 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 45 | </property> | ||
| 46 | <property name="TimeoutStopFailureMode" type="s" access="read"> | ||
| 47 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 48 | </property> | ||
| 49 | <property name="RuntimeMaxUSec" type="t" access="read"> | ||
| 50 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 51 | </property> | ||
| 52 | <property name="RuntimeRandomizedExtraUSec" type="t" access="read"> | ||
| 53 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 54 | </property> | ||
| 55 | <property name="WatchdogUSec" type="t" access="read"> | ||
| 56 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 57 | </property> | ||
| 58 | <property name="WatchdogTimestamp" type="t" access="read"> | ||
| 59 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 60 | </property> | ||
| 61 | <property name="WatchdogTimestampMonotonic" type="t" access="read"> | ||
| 62 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 63 | </property> | ||
| 64 | <property name="RootDirectoryStartOnly" type="b" access="read"> | ||
| 65 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 66 | </property> | ||
| 67 | <property name="RemainAfterExit" type="b" access="read"> | ||
| 68 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 69 | </property> | ||
| 70 | <property name="GuessMainPID" type="b" access="read"> | ||
| 71 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 72 | </property> | ||
| 73 | <!-- <property name="RestartPreventExitStatus" type="(aiai)" access="read"> --> | ||
| 74 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 75 | <!-- </property> --> | ||
| 76 | <!-- <property name="RestartForceExitStatus" type="(aiai)" access="read"> --> | ||
| 77 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 78 | <!-- </property> --> | ||
| 79 | <!-- <property name="SuccessExitStatus" type="(aiai)" access="read"> --> | ||
| 80 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 81 | <!-- </property> --> | ||
| 82 | <property name="MainPID" type="u" access="read"> | ||
| 83 | </property> | ||
| 84 | <property name="ControlPID" type="u" access="read"> | ||
| 85 | </property> | ||
| 86 | <property name="BusName" type="s" access="read"> | ||
| 87 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 88 | </property> | ||
| 89 | <property name="FileDescriptorStoreMax" type="u" access="read"> | ||
| 90 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 91 | </property> | ||
| 92 | <property name="NFileDescriptorStore" type="u" access="read"> | ||
| 93 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 94 | </property> | ||
| 95 | <property name="FileDescriptorStorePreserve" type="s" access="read"> | ||
| 96 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 97 | </property> | ||
| 98 | <property name="StatusText" type="s" access="read"> | ||
| 99 | </property> | ||
| 100 | <property name="StatusErrno" type="i" access="read"> | ||
| 101 | </property> | ||
| 102 | <property name="StatusBusError" type="s" access="read"> | ||
| 103 | </property> | ||
| 104 | <property name="StatusVarlinkError" type="s" access="read"> | ||
| 105 | </property> | ||
| 106 | <property name="Result" type="s" access="read"> | ||
| 107 | </property> | ||
| 108 | <property name="ReloadResult" type="s" access="read"> | ||
| 109 | </property> | ||
| 110 | <property name="CleanResult" type="s" access="read"> | ||
| 111 | </property> | ||
| 112 | <property name="LiveMountResult" type="s" access="read"> | ||
| 113 | </property> | ||
| 114 | <property name="USBFunctionDescriptors" type="s" access="read"> | ||
| 115 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 116 | </property> | ||
| 117 | <property name="USBFunctionStrings" type="s" access="read"> | ||
| 118 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 119 | </property> | ||
| 120 | <property name="UID" type="u" access="read"> | ||
| 121 | </property> | ||
| 122 | <property name="GID" type="u" access="read"> | ||
| 123 | </property> | ||
| 124 | <property name="NRestarts" type="u" access="read"> | ||
| 125 | </property> | ||
| 126 | <property name="OOMPolicy" type="s" access="read"> | ||
| 127 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 128 | </property> | ||
| 129 | <!-- <property name="OpenFile" type="a(sst)" access="read"> --> | ||
| 130 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 131 | <!-- </property> --> | ||
| 132 | <property name="ExtraFileDescriptorNames" type="as" access="read"> | ||
| 133 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 134 | </property> | ||
| 135 | <property name="ReloadSignal" type="i" access="read"> | ||
| 136 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 137 | </property> | ||
| 138 | <property name="RefreshOnReload" type="as" access="read"> | ||
| 139 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 140 | </property> | ||
| 141 | <property name="ExecMainStartTimestamp" type="t" access="read"> | ||
| 142 | </property> | ||
| 143 | <property name="ExecMainStartTimestampMonotonic" type="t" access="read"> | ||
| 144 | </property> | ||
| 145 | <property name="ExecMainExitTimestamp" type="t" access="read"> | ||
| 146 | </property> | ||
| 147 | <property name="ExecMainExitTimestampMonotonic" type="t" access="read"> | ||
| 148 | </property> | ||
| 149 | <property name="ExecMainHandoffTimestamp" type="t" access="read"> | ||
| 150 | </property> | ||
| 151 | <property name="ExecMainHandoffTimestampMonotonic" type="t" access="read"> | ||
| 152 | </property> | ||
| 153 | <property name="ExecMainPID" type="u" access="read"> | ||
| 154 | </property> | ||
| 155 | <property name="ExecMainCode" type="i" access="read"> | ||
| 156 | </property> | ||
| 157 | <property name="ExecMainStatus" type="i" access="read"> | ||
| 158 | </property> | ||
| 159 | <!-- <property name="ExecCondition" type="a(sasbttttuii)" access="read"> --> | ||
| 160 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 161 | <!-- </property> --> | ||
| 162 | <!-- <property name="ExecConditionEx" type="a(sasasttttuii)" access="read"> --> | ||
| 163 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 164 | <!-- </property> --> | ||
| 165 | <!-- <property name="ExecStartPre" type="a(sasbttttuii)" access="read"> --> | ||
| 166 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 167 | <!-- </property> --> | ||
| 168 | <!-- <property name="ExecStartPreEx" type="a(sasasttttuii)" access="read"> --> | ||
| 169 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 170 | <!-- </property> --> | ||
| 171 | <!-- <property name="ExecStart" type="a(sasbttttuii)" access="read"> --> | ||
| 172 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 173 | <!-- </property> --> | ||
| 174 | <!-- <property name="ExecStartEx" type="a(sasasttttuii)" access="read"> --> | ||
| 175 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 176 | <!-- </property> --> | ||
| 177 | <!-- <property name="ExecStartPost" type="a(sasbttttuii)" access="read"> --> | ||
| 178 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 179 | <!-- </property> --> | ||
| 180 | <!-- <property name="ExecStartPostEx" type="a(sasasttttuii)" access="read"> --> | ||
| 181 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 182 | <!-- </property> --> | ||
| 183 | <!-- <property name="ExecReload" type="a(sasbttttuii)" access="read"> --> | ||
| 184 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 185 | <!-- </property> --> | ||
| 186 | <!-- <property name="ExecReloadEx" type="a(sasasttttuii)" access="read"> --> | ||
| 187 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 188 | <!-- </property> --> | ||
| 189 | <!-- <property name="ExecReloadPost" type="a(sasbttttuii)" access="read"> --> | ||
| 190 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 191 | <!-- </property> --> | ||
| 192 | <!-- <property name="ExecReloadPostEx" type="a(sasasttttuii)" access="read"> --> | ||
| 193 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 194 | <!-- </property> --> | ||
| 195 | <!-- <property name="ExecStop" type="a(sasbttttuii)" access="read"> --> | ||
| 196 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 197 | <!-- </property> --> | ||
| 198 | <!-- <property name="ExecStopEx" type="a(sasasttttuii)" access="read"> --> | ||
| 199 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 200 | <!-- </property> --> | ||
| 201 | <!-- <property name="ExecStopPost" type="a(sasbttttuii)" access="read"> --> | ||
| 202 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 203 | <!-- </property> --> | ||
| 204 | <!-- <property name="ExecStopPostEx" type="a(sasasttttuii)" access="read"> --> | ||
| 205 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 206 | <!-- </property> --> | ||
| 207 | <method name="BindMount"> | ||
| 208 | <arg type="s" name="source" direction="in"/> | ||
| 209 | <arg type="s" name="destination" direction="in"/> | ||
| 210 | <arg type="b" name="read_only" direction="in"/> | ||
| 211 | <arg type="b" name="mkdir" direction="in"/> | ||
| 212 | </method> | ||
| 213 | <!-- <method name="MountImage"> --> | ||
| 214 | <!-- <arg type="s" name="source" direction="in"/> --> | ||
| 215 | <!-- <arg type="s" name="destination" direction="in"/> --> | ||
| 216 | <!-- <arg type="b" name="read_only" direction="in"/> --> | ||
| 217 | <!-- <arg type="b" name="mkdir" direction="in"/> --> | ||
| 218 | <!-- <arg type="a(ss)" name="options" direction="in"/> --> | ||
| 219 | <!-- </method> --> | ||
| 220 | <!-- <method name="DumpFileDescriptorStore"> --> | ||
| 221 | <!-- <arg type="a(suuutuusu)" name="entries" direction="out"/> --> | ||
| 222 | <!-- </method> --> | ||
| 223 | <property name="Slice" type="s" access="read"> | ||
| 224 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 225 | </property> | ||
| 226 | <property name="ControlGroup" type="s" access="read"> | ||
| 227 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 228 | </property> | ||
| 229 | <property name="ControlGroupId" type="t" access="read"> | ||
| 230 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 231 | </property> | ||
| 232 | <property name="MemoryCurrent" type="t" access="read"> | ||
| 233 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 234 | </property> | ||
| 235 | <property name="MemoryPeak" type="t" access="read"> | ||
| 236 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 237 | </property> | ||
| 238 | <property name="MemorySwapCurrent" type="t" access="read"> | ||
| 239 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 240 | </property> | ||
| 241 | <property name="MemorySwapPeak" type="t" access="read"> | ||
| 242 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 243 | </property> | ||
| 244 | <property name="MemoryZSwapCurrent" type="t" access="read"> | ||
| 245 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 246 | </property> | ||
| 247 | <property name="MemoryAvailable" type="t" access="read"> | ||
| 248 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 249 | </property> | ||
| 250 | <property name="EffectiveMemoryMax" type="t" access="read"> | ||
| 251 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 252 | </property> | ||
| 253 | <property name="EffectiveMemoryHigh" type="t" access="read"> | ||
| 254 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 255 | </property> | ||
| 256 | <property name="CPUUsageNSec" type="t" access="read"> | ||
| 257 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 258 | </property> | ||
| 259 | <property name="EffectiveCPUs" type="ay" access="read"> | ||
| 260 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 261 | </property> | ||
| 262 | <property name="EffectiveMemoryNodes" type="ay" access="read"> | ||
| 263 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 264 | </property> | ||
| 265 | <property name="TasksCurrent" type="t" access="read"> | ||
| 266 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 267 | </property> | ||
| 268 | <property name="EffectiveTasksMax" type="t" access="read"> | ||
| 269 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 270 | </property> | ||
| 271 | <property name="IPIngressBytes" type="t" access="read"> | ||
| 272 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 273 | </property> | ||
| 274 | <property name="IPIngressPackets" type="t" access="read"> | ||
| 275 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 276 | </property> | ||
| 277 | <property name="IPEgressBytes" type="t" access="read"> | ||
| 278 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 279 | </property> | ||
| 280 | <property name="IPEgressPackets" type="t" access="read"> | ||
| 281 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 282 | </property> | ||
| 283 | <property name="IOReadBytes" type="t" access="read"> | ||
| 284 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 285 | </property> | ||
| 286 | <property name="IOReadOperations" type="t" access="read"> | ||
| 287 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 288 | </property> | ||
| 289 | <property name="IOWriteBytes" type="t" access="read"> | ||
| 290 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 291 | </property> | ||
| 292 | <property name="IOWriteOperations" type="t" access="read"> | ||
| 293 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 294 | </property> | ||
| 295 | <property name="OOMKills" type="t" access="read"> | ||
| 296 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 297 | </property> | ||
| 298 | <property name="ManagedOOMKills" type="t" access="read"> | ||
| 299 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 300 | </property> | ||
| 301 | <!-- <method name="GetProcesses"> --> | ||
| 302 | <!-- <arg type="a(sus)" name="processes" direction="out"/> --> | ||
| 303 | <!-- </method> --> | ||
| 304 | <!-- <method name="AttachProcesses"> --> | ||
| 305 | <!-- <arg type="s" name="subcgroup" direction="in"/> --> | ||
| 306 | <!-- <arg type="au" name="pids" direction="in"/> --> | ||
| 307 | <!-- </method> --> | ||
| 308 | <method name="RemoveSubgroup"> | ||
| 309 | <arg type="s" name="subcgroup" direction="in"/> | ||
| 310 | <arg type="t" name="flags" direction="in"/> | ||
| 311 | </method> | ||
| 312 | <property name="Delegate" type="b" access="read"> | ||
| 313 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 314 | </property> | ||
| 315 | <property name="DelegateControllers" type="as" access="read"> | ||
| 316 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 317 | </property> | ||
| 318 | <property name="DelegateSubgroup" type="s" access="read"> | ||
| 319 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 320 | </property> | ||
| 321 | <property name="CPUWeight" type="t" access="read"> | ||
| 322 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 323 | </property> | ||
| 324 | <property name="StartupCPUWeight" type="t" access="read"> | ||
| 325 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 326 | </property> | ||
| 327 | <property name="CPUQuotaPerSecUSec" type="t" access="read"> | ||
| 328 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 329 | </property> | ||
| 330 | <property name="CPUQuotaPeriodUSec" type="t" access="read"> | ||
| 331 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 332 | </property> | ||
| 333 | <property name="AllowedCPUs" type="ay" access="read"> | ||
| 334 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 335 | </property> | ||
| 336 | <property name="StartupAllowedCPUs" type="ay" access="read"> | ||
| 337 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 338 | </property> | ||
| 339 | <property name="AllowedMemoryNodes" type="ay" access="read"> | ||
| 340 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 341 | </property> | ||
| 342 | <property name="StartupAllowedMemoryNodes" type="ay" access="read"> | ||
| 343 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 344 | </property> | ||
| 345 | <property name="IOAccounting" type="b" access="read"> | ||
| 346 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 347 | </property> | ||
| 348 | <property name="IOWeight" type="t" access="read"> | ||
| 349 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 350 | </property> | ||
| 351 | <property name="StartupIOWeight" type="t" access="read"> | ||
| 352 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 353 | </property> | ||
| 354 | <!-- <property name="IODeviceWeight" type="a(st)" access="read"> --> | ||
| 355 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 356 | <!-- </property> --> | ||
| 357 | <!-- <property name="IOReadBandwidthMax" type="a(st)" access="read"> --> | ||
| 358 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 359 | <!-- </property> --> | ||
| 360 | <!-- <property name="IOWriteBandwidthMax" type="a(st)" access="read"> --> | ||
| 361 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 362 | <!-- </property> --> | ||
| 363 | <!-- <property name="IOReadIOPSMax" type="a(st)" access="read"> --> | ||
| 364 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 365 | <!-- </property> --> | ||
| 366 | <!-- <property name="IOWriteIOPSMax" type="a(st)" access="read"> --> | ||
| 367 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 368 | <!-- </property> --> | ||
| 369 | <!-- <property name="IODeviceLatencyTargetUSec" type="a(st)" access="read"> --> | ||
| 370 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 371 | <!-- </property> --> | ||
| 372 | <property name="MemoryAccounting" type="b" access="read"> | ||
| 373 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 374 | </property> | ||
| 375 | <property name="MemoryMin" type="t" access="read"> | ||
| 376 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 377 | </property> | ||
| 378 | <property name="MemoryLow" type="t" access="read"> | ||
| 379 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 380 | </property> | ||
| 381 | <property name="StartupMemoryLow" type="t" access="read"> | ||
| 382 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 383 | </property> | ||
| 384 | <property name="MemoryHigh" type="t" access="read"> | ||
| 385 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 386 | </property> | ||
| 387 | <property name="StartupMemoryHigh" type="t" access="read"> | ||
| 388 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 389 | </property> | ||
| 390 | <property name="MemoryMax" type="t" access="read"> | ||
| 391 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 392 | </property> | ||
| 393 | <property name="StartupMemoryMax" type="t" access="read"> | ||
| 394 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 395 | </property> | ||
| 396 | <property name="MemorySwapMax" type="t" access="read"> | ||
| 397 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 398 | </property> | ||
| 399 | <property name="StartupMemorySwapMax" type="t" access="read"> | ||
| 400 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 401 | </property> | ||
| 402 | <property name="MemoryZSwapMax" type="t" access="read"> | ||
| 403 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 404 | </property> | ||
| 405 | <property name="StartupMemoryZSwapMax" type="t" access="read"> | ||
| 406 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 407 | </property> | ||
| 408 | <property name="MemoryZSwapWriteback" type="b" access="read"> | ||
| 409 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 410 | </property> | ||
| 411 | <property name="DevicePolicy" type="s" access="read"> | ||
| 412 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 413 | </property> | ||
| 414 | <!-- <property name="DeviceAllow" type="a(ss)" access="read"> --> | ||
| 415 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 416 | <!-- </property> --> | ||
| 417 | <property name="TasksAccounting" type="b" access="read"> | ||
| 418 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 419 | </property> | ||
| 420 | <property name="TasksMax" type="t" access="read"> | ||
| 421 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 422 | </property> | ||
| 423 | <property name="IPAccounting" type="b" access="read"> | ||
| 424 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 425 | </property> | ||
| 426 | <!-- <property name="IPAddressAllow" type="a(iayu)" access="read"> --> | ||
| 427 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 428 | <!-- </property> --> | ||
| 429 | <!-- <property name="IPAddressDeny" type="a(iayu)" access="read"> --> | ||
| 430 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 431 | <!-- </property> --> | ||
| 432 | <property name="IPIngressFilterPath" type="as" access="read"> | ||
| 433 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 434 | </property> | ||
| 435 | <property name="IPEgressFilterPath" type="as" access="read"> | ||
| 436 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 437 | </property> | ||
| 438 | <property name="DisableControllers" type="as" access="read"> | ||
| 439 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 440 | </property> | ||
| 441 | <property name="ManagedOOMSwap" type="s" access="read"> | ||
| 442 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 443 | </property> | ||
| 444 | <property name="ManagedOOMMemoryPressure" type="s" access="read"> | ||
| 445 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 446 | </property> | ||
| 447 | <property name="ManagedOOMMemoryPressureLimit" type="u" access="read"> | ||
| 448 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 449 | </property> | ||
| 450 | <property name="ManagedOOMMemoryPressureDurationUSec" type="t" access="read"> | ||
| 451 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 452 | </property> | ||
| 453 | <property name="ManagedOOMPreference" type="s" access="read"> | ||
| 454 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 455 | </property> | ||
| 456 | <!-- <property name="BPFProgram" type="a(ss)" access="read"> --> | ||
| 457 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 458 | <!-- </property> --> | ||
| 459 | <!-- <property name="SocketBindAllow" type="a(iiqq)" access="read"> --> | ||
| 460 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 461 | <!-- </property> --> | ||
| 462 | <!-- <property name="SocketBindDeny" type="a(iiqq)" access="read"> --> | ||
| 463 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 464 | <!-- </property> --> | ||
| 465 | <!-- <property name="RestrictNetworkInterfaces" type="(bas)" access="read"> --> | ||
| 466 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 467 | <!-- </property> --> | ||
| 468 | <property name="BindNetworkInterface" type="s" access="read"> | ||
| 469 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 470 | </property> | ||
| 471 | <property name="MemoryPressureWatch" type="s" access="read"> | ||
| 472 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 473 | </property> | ||
| 474 | <property name="MemoryPressureThresholdUSec" type="t" access="read"> | ||
| 475 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 476 | </property> | ||
| 477 | <!-- <property name="NFTSet" type="a(iiss)" access="read"> --> | ||
| 478 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 479 | <!-- </property> --> | ||
| 480 | <property name="CoredumpReceive" type="b" access="read"> | ||
| 481 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 482 | </property> | ||
| 483 | <property name="Environment" type="as" access="read"> | ||
| 484 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 485 | </property> | ||
| 486 | <!-- <property name="EnvironmentFiles" type="a(sb)" access="read"> --> | ||
| 487 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 488 | <!-- </property> --> | ||
| 489 | <property name="PassEnvironment" type="as" access="read"> | ||
| 490 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 491 | </property> | ||
| 492 | <property name="UnsetEnvironment" type="as" access="read"> | ||
| 493 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 494 | </property> | ||
| 495 | <property name="UMask" type="u" access="read"> | ||
| 496 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 497 | </property> | ||
| 498 | <property name="LimitCPU" type="t" access="read"> | ||
| 499 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 500 | </property> | ||
| 501 | <property name="LimitCPUSoft" type="t" access="read"> | ||
| 502 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 503 | </property> | ||
| 504 | <property name="LimitFSIZE" type="t" access="read"> | ||
| 505 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 506 | </property> | ||
| 507 | <property name="LimitFSIZESoft" type="t" access="read"> | ||
| 508 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 509 | </property> | ||
| 510 | <property name="LimitDATA" type="t" access="read"> | ||
| 511 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 512 | </property> | ||
| 513 | <property name="LimitDATASoft" type="t" access="read"> | ||
| 514 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 515 | </property> | ||
| 516 | <property name="LimitSTACK" type="t" access="read"> | ||
| 517 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 518 | </property> | ||
| 519 | <property name="LimitSTACKSoft" type="t" access="read"> | ||
| 520 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 521 | </property> | ||
| 522 | <property name="LimitCORE" type="t" access="read"> | ||
| 523 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 524 | </property> | ||
| 525 | <property name="LimitCORESoft" type="t" access="read"> | ||
| 526 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 527 | </property> | ||
| 528 | <property name="LimitRSS" type="t" access="read"> | ||
| 529 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 530 | </property> | ||
| 531 | <property name="LimitRSSSoft" type="t" access="read"> | ||
| 532 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 533 | </property> | ||
| 534 | <property name="LimitNOFILE" type="t" access="read"> | ||
| 535 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 536 | </property> | ||
| 537 | <property name="LimitNOFILESoft" type="t" access="read"> | ||
| 538 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 539 | </property> | ||
| 540 | <property name="LimitAS" type="t" access="read"> | ||
| 541 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 542 | </property> | ||
| 543 | <property name="LimitASSoft" type="t" access="read"> | ||
| 544 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 545 | </property> | ||
| 546 | <property name="LimitNPROC" type="t" access="read"> | ||
| 547 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 548 | </property> | ||
| 549 | <property name="LimitNPROCSoft" type="t" access="read"> | ||
| 550 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 551 | </property> | ||
| 552 | <property name="LimitMEMLOCK" type="t" access="read"> | ||
| 553 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 554 | </property> | ||
| 555 | <property name="LimitMEMLOCKSoft" type="t" access="read"> | ||
| 556 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 557 | </property> | ||
| 558 | <property name="LimitLOCKS" type="t" access="read"> | ||
| 559 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 560 | </property> | ||
| 561 | <property name="LimitLOCKSSoft" type="t" access="read"> | ||
| 562 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 563 | </property> | ||
| 564 | <property name="LimitSIGPENDING" type="t" access="read"> | ||
| 565 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 566 | </property> | ||
| 567 | <property name="LimitSIGPENDINGSoft" type="t" access="read"> | ||
| 568 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 569 | </property> | ||
| 570 | <property name="LimitMSGQUEUE" type="t" access="read"> | ||
| 571 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 572 | </property> | ||
| 573 | <property name="LimitMSGQUEUESoft" type="t" access="read"> | ||
| 574 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 575 | </property> | ||
| 576 | <property name="LimitNICE" type="t" access="read"> | ||
| 577 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 578 | </property> | ||
| 579 | <property name="LimitNICESoft" type="t" access="read"> | ||
| 580 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 581 | </property> | ||
| 582 | <property name="LimitRTPRIO" type="t" access="read"> | ||
| 583 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 584 | </property> | ||
| 585 | <property name="LimitRTPRIOSoft" type="t" access="read"> | ||
| 586 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 587 | </property> | ||
| 588 | <property name="LimitRTTIME" type="t" access="read"> | ||
| 589 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 590 | </property> | ||
| 591 | <property name="LimitRTTIMESoft" type="t" access="read"> | ||
| 592 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 593 | </property> | ||
| 594 | <property name="WorkingDirectory" type="s" access="read"> | ||
| 595 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 596 | </property> | ||
| 597 | <property name="RootDirectory" type="s" access="read"> | ||
| 598 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 599 | </property> | ||
| 600 | <property name="RootImage" type="s" access="read"> | ||
| 601 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 602 | </property> | ||
| 603 | <!-- <property name="RootImageOptions" type="a(ss)" access="read"> --> | ||
| 604 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 605 | <!-- </property> --> | ||
| 606 | <property name="RootHash" type="ay" access="read"> | ||
| 607 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 608 | </property> | ||
| 609 | <property name="RootHashPath" type="s" access="read"> | ||
| 610 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 611 | </property> | ||
| 612 | <property name="RootHashSignature" type="ay" access="read"> | ||
| 613 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 614 | </property> | ||
| 615 | <property name="RootHashSignaturePath" type="s" access="read"> | ||
| 616 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 617 | </property> | ||
| 618 | <property name="RootVerity" type="s" access="read"> | ||
| 619 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 620 | </property> | ||
| 621 | <property name="RootEphemeral" type="b" access="read"> | ||
| 622 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 623 | </property> | ||
| 624 | <property name="RootMStack" type="s" access="read"> | ||
| 625 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 626 | </property> | ||
| 627 | <property name="ExtensionDirectories" type="as" access="read"> | ||
| 628 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 629 | </property> | ||
| 630 | <!-- <property name="ExtensionImages" type="a(sba(ss))" access="read"> --> | ||
| 631 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 632 | <!-- </property> --> | ||
| 633 | <!-- <property name="MountImages" type="a(ssba(ss))" access="read"> --> | ||
| 634 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 635 | <!-- </property> --> | ||
| 636 | <property name="OOMScoreAdjust" type="i" access="read"> | ||
| 637 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 638 | </property> | ||
| 639 | <property name="CoredumpFilter" type="t" access="read"> | ||
| 640 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 641 | </property> | ||
| 642 | <property name="Nice" type="i" access="read"> | ||
| 643 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 644 | </property> | ||
| 645 | <property name="IOSchedulingClass" type="i" access="read"> | ||
| 646 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 647 | </property> | ||
| 648 | <property name="IOSchedulingPriority" type="i" access="read"> | ||
| 649 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 650 | </property> | ||
| 651 | <property name="CPUSchedulingPolicy" type="i" access="read"> | ||
| 652 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 653 | </property> | ||
| 654 | <property name="CPUSchedulingPriority" type="i" access="read"> | ||
| 655 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 656 | </property> | ||
| 657 | <property name="CPUAffinity" type="ay" access="read"> | ||
| 658 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 659 | </property> | ||
| 660 | <property name="CPUAffinityFromNUMA" type="b" access="read"> | ||
| 661 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 662 | </property> | ||
| 663 | <property name="NUMAPolicy" type="i" access="read"> | ||
| 664 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 665 | </property> | ||
| 666 | <property name="NUMAMask" type="ay" access="read"> | ||
| 667 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 668 | </property> | ||
| 669 | <property name="TimerSlackNSec" type="t" access="read"> | ||
| 670 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 671 | </property> | ||
| 672 | <property name="CPUSchedulingResetOnFork" type="b" access="read"> | ||
| 673 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 674 | </property> | ||
| 675 | <property name="NonBlocking" type="b" access="read"> | ||
| 676 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 677 | </property> | ||
| 678 | <property name="StandardInput" type="s" access="read"> | ||
| 679 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 680 | </property> | ||
| 681 | <property name="StandardInputFileDescriptorName" type="s" access="read"> | ||
| 682 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 683 | </property> | ||
| 684 | <property name="StandardInputData" type="ay" access="read"> | ||
| 685 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 686 | </property> | ||
| 687 | <property name="StandardOutput" type="s" access="read"> | ||
| 688 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 689 | </property> | ||
| 690 | <property name="StandardOutputFileDescriptorName" type="s" access="read"> | ||
| 691 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 692 | </property> | ||
| 693 | <property name="StandardError" type="s" access="read"> | ||
| 694 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 695 | </property> | ||
| 696 | <property name="StandardErrorFileDescriptorName" type="s" access="read"> | ||
| 697 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 698 | </property> | ||
| 699 | <property name="TTYPath" type="s" access="read"> | ||
| 700 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 701 | </property> | ||
| 702 | <property name="TTYReset" type="b" access="read"> | ||
| 703 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 704 | </property> | ||
| 705 | <property name="TTYVHangup" type="b" access="read"> | ||
| 706 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 707 | </property> | ||
| 708 | <property name="TTYVTDisallocate" type="b" access="read"> | ||
| 709 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 710 | </property> | ||
| 711 | <property name="TTYRows" type="q" access="read"> | ||
| 712 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 713 | </property> | ||
| 714 | <property name="TTYColumns" type="q" access="read"> | ||
| 715 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 716 | </property> | ||
| 717 | <property name="SyslogPriority" type="i" access="read"> | ||
| 718 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 719 | </property> | ||
| 720 | <property name="SyslogIdentifier" type="s" access="read"> | ||
| 721 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 722 | </property> | ||
| 723 | <property name="SyslogLevelPrefix" type="b" access="read"> | ||
| 724 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 725 | </property> | ||
| 726 | <property name="SyslogLevel" type="i" access="read"> | ||
| 727 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 728 | </property> | ||
| 729 | <property name="SyslogFacility" type="i" access="read"> | ||
| 730 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 731 | </property> | ||
| 732 | <property name="LogLevelMax" type="i" access="read"> | ||
| 733 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 734 | </property> | ||
| 735 | <property name="LogRateLimitIntervalUSec" type="t" access="read"> | ||
| 736 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 737 | </property> | ||
| 738 | <property name="LogRateLimitBurst" type="u" access="read"> | ||
| 739 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 740 | </property> | ||
| 741 | <!-- <property name="LogExtraFields" type="aay" access="read"> --> | ||
| 742 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 743 | <!-- </property> --> | ||
| 744 | <!-- <property name="LogFilterPatterns" type="a(bs)" access="read"> --> | ||
| 745 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 746 | <!-- </property> --> | ||
| 747 | <property name="LogNamespace" type="s" access="read"> | ||
| 748 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 749 | </property> | ||
| 750 | <property name="SecureBits" type="i" access="read"> | ||
| 751 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 752 | </property> | ||
| 753 | <property name="CapabilityBoundingSet" type="t" access="read"> | ||
| 754 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 755 | </property> | ||
| 756 | <property name="AmbientCapabilities" type="t" access="read"> | ||
| 757 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 758 | </property> | ||
| 759 | <property name="User" type="s" access="read"> | ||
| 760 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 761 | </property> | ||
| 762 | <property name="Group" type="s" access="read"> | ||
| 763 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 764 | </property> | ||
| 765 | <property name="DynamicUser" type="b" access="read"> | ||
| 766 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 767 | </property> | ||
| 768 | <property name="SetLoginEnvironment" type="b" access="read"> | ||
| 769 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 770 | </property> | ||
| 771 | <property name="RemoveIPC" type="b" access="read"> | ||
| 772 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 773 | </property> | ||
| 774 | <!-- <property name="SetCredential" type="a(say)" access="read"> --> | ||
| 775 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 776 | <!-- </property> --> | ||
| 777 | <!-- <property name="SetCredentialEncrypted" type="a(say)" access="read"> --> | ||
| 778 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 779 | <!-- </property> --> | ||
| 780 | <!-- <property name="LoadCredential" type="a(ss)" access="read"> --> | ||
| 781 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 782 | <!-- </property> --> | ||
| 783 | <!-- <property name="LoadCredentialEncrypted" type="a(ss)" access="read"> --> | ||
| 784 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 785 | <!-- </property> --> | ||
| 786 | <property name="ImportCredential" type="as" access="read"> | ||
| 787 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 788 | </property> | ||
| 789 | <!-- <property name="ImportCredentialEx" type="a(ss)" access="read"> --> | ||
| 790 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 791 | <!-- </property> --> | ||
| 792 | <property name="SupplementaryGroups" type="as" access="read"> | ||
| 793 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 794 | </property> | ||
| 795 | <property name="PAMName" type="s" access="read"> | ||
| 796 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 797 | </property> | ||
| 798 | <property name="ReadWritePaths" type="as" access="read"> | ||
| 799 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 800 | </property> | ||
| 801 | <property name="ReadOnlyPaths" type="as" access="read"> | ||
| 802 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 803 | </property> | ||
| 804 | <property name="InaccessiblePaths" type="as" access="read"> | ||
| 805 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 806 | </property> | ||
| 807 | <property name="ExecPaths" type="as" access="read"> | ||
| 808 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 809 | </property> | ||
| 810 | <property name="NoExecPaths" type="as" access="read"> | ||
| 811 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 812 | </property> | ||
| 813 | <property name="ExecSearchPath" type="as" access="read"> | ||
| 814 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 815 | </property> | ||
| 816 | <property name="MountFlags" type="t" access="read"> | ||
| 817 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 818 | </property> | ||
| 819 | <property name="PrivateTmp" type="b" access="read"> | ||
| 820 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 821 | </property> | ||
| 822 | <property name="PrivateTmpEx" type="s" access="read"> | ||
| 823 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 824 | </property> | ||
| 825 | <property name="PrivateDevices" type="b" access="read"> | ||
| 826 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 827 | </property> | ||
| 828 | <property name="ProtectClock" type="b" access="read"> | ||
| 829 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 830 | </property> | ||
| 831 | <property name="ProtectKernelTunables" type="b" access="read"> | ||
| 832 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 833 | </property> | ||
| 834 | <property name="ProtectKernelModules" type="b" access="read"> | ||
| 835 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 836 | </property> | ||
| 837 | <property name="ProtectKernelLogs" type="b" access="read"> | ||
| 838 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 839 | </property> | ||
| 840 | <property name="ProtectControlGroups" type="b" access="read"> | ||
| 841 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 842 | </property> | ||
| 843 | <property name="ProtectControlGroupsEx" type="s" access="read"> | ||
| 844 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 845 | </property> | ||
| 846 | <property name="PrivateNetwork" type="b" access="read"> | ||
| 847 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 848 | </property> | ||
| 849 | <property name="PrivateUsers" type="b" access="read"> | ||
| 850 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 851 | </property> | ||
| 852 | <property name="PrivateUsersEx" type="s" access="read"> | ||
| 853 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 854 | </property> | ||
| 855 | <property name="PrivateMounts" type="b" access="read"> | ||
| 856 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 857 | </property> | ||
| 858 | <property name="PrivateIPC" type="b" access="read"> | ||
| 859 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 860 | </property> | ||
| 861 | <property name="PrivatePIDs" type="s" access="read"> | ||
| 862 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 863 | </property> | ||
| 864 | <property name="ProtectHome" type="s" access="read"> | ||
| 865 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 866 | </property> | ||
| 867 | <property name="ProtectSystem" type="s" access="read"> | ||
| 868 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 869 | </property> | ||
| 870 | <property name="SameProcessGroup" type="b" access="read"> | ||
| 871 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 872 | </property> | ||
| 873 | <property name="UtmpIdentifier" type="s" access="read"> | ||
| 874 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 875 | </property> | ||
| 876 | <property name="UtmpMode" type="s" access="read"> | ||
| 877 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 878 | </property> | ||
| 879 | <!-- <property name="SELinuxContext" type="(bs)" access="read"> --> | ||
| 880 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 881 | <!-- </property> --> | ||
| 882 | <!-- <property name="AppArmorProfile" type="(bs)" access="read"> --> | ||
| 883 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 884 | <!-- </property> --> | ||
| 885 | <!-- <property name="SmackProcessLabel" type="(bs)" access="read"> --> | ||
| 886 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 887 | <!-- </property> --> | ||
| 888 | <property name="IgnoreSIGPIPE" type="b" access="read"> | ||
| 889 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 890 | </property> | ||
| 891 | <property name="NoNewPrivileges" type="b" access="read"> | ||
| 892 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 893 | </property> | ||
| 894 | <!-- <property name="SystemCallFilter" type="(bas)" access="read"> --> | ||
| 895 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 896 | <!-- </property> --> | ||
| 897 | <property name="SystemCallArchitectures" type="as" access="read"> | ||
| 898 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 899 | </property> | ||
| 900 | <property name="SystemCallErrorNumber" type="i" access="read"> | ||
| 901 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 902 | </property> | ||
| 903 | <!-- <property name="SystemCallLog" type="(bas)" access="read"> --> | ||
| 904 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 905 | <!-- </property> --> | ||
| 906 | <property name="Personality" type="s" access="read"> | ||
| 907 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 908 | </property> | ||
| 909 | <property name="LockPersonality" type="b" access="read"> | ||
| 910 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 911 | </property> | ||
| 912 | <!-- <property name="RestrictAddressFamilies" type="(bas)" access="read"> --> | ||
| 913 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 914 | <!-- </property> --> | ||
| 915 | <!-- <property name="RuntimeDirectorySymlink" type="a(sst)" access="read"> --> | ||
| 916 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 917 | <!-- </property> --> | ||
| 918 | <property name="RuntimeDirectoryPreserve" type="s" access="read"> | ||
| 919 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 920 | </property> | ||
| 921 | <property name="RuntimeDirectoryMode" type="u" access="read"> | ||
| 922 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 923 | </property> | ||
| 924 | <property name="RuntimeDirectory" type="as" access="read"> | ||
| 925 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 926 | </property> | ||
| 927 | <!-- <property name="StateDirectorySymlink" type="a(sst)" access="read"> --> | ||
| 928 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 929 | <!-- </property> --> | ||
| 930 | <property name="StateDirectoryMode" type="u" access="read"> | ||
| 931 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 932 | </property> | ||
| 933 | <property name="StateDirectoryAccounting" type="b" access="read"> | ||
| 934 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 935 | </property> | ||
| 936 | <!-- <property name="StateDirectoryQuota" type="(tus)" access="read"> --> | ||
| 937 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 938 | <!-- </property> --> | ||
| 939 | <property name="StateDirectory" type="as" access="read"> | ||
| 940 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 941 | </property> | ||
| 942 | <!-- <property name="CacheDirectorySymlink" type="a(sst)" access="read"> --> | ||
| 943 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 944 | <!-- </property> --> | ||
| 945 | <property name="CacheDirectoryMode" type="u" access="read"> | ||
| 946 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 947 | </property> | ||
| 948 | <property name="CacheDirectoryAccounting" type="b" access="read"> | ||
| 949 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 950 | </property> | ||
| 951 | <!-- <property name="CacheDirectoryQuota" type="(tus)" access="read"> --> | ||
| 952 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 953 | <!-- </property> --> | ||
| 954 | <property name="CacheDirectory" type="as" access="read"> | ||
| 955 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 956 | </property> | ||
| 957 | <!-- <property name="LogsDirectorySymlink" type="a(sst)" access="read"> --> | ||
| 958 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 959 | <!-- </property> --> | ||
| 960 | <property name="LogsDirectoryMode" type="u" access="read"> | ||
| 961 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 962 | </property> | ||
| 963 | <property name="LogsDirectoryAccounting" type="b" access="read"> | ||
| 964 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 965 | </property> | ||
| 966 | <!-- <property name="LogsDirectoryQuota" type="(tus)" access="read"> --> | ||
| 967 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 968 | <!-- </property> --> | ||
| 969 | <property name="LogsDirectory" type="as" access="read"> | ||
| 970 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 971 | </property> | ||
| 972 | <property name="ConfigurationDirectoryMode" type="u" access="read"> | ||
| 973 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 974 | </property> | ||
| 975 | <property name="ConfigurationDirectory" type="as" access="read"> | ||
| 976 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 977 | </property> | ||
| 978 | <property name="TimeoutCleanUSec" type="t" access="read"> | ||
| 979 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 980 | </property> | ||
| 981 | <property name="MemoryDenyWriteExecute" type="b" access="read"> | ||
| 982 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 983 | </property> | ||
| 984 | <property name="RestrictRealtime" type="b" access="read"> | ||
| 985 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 986 | </property> | ||
| 987 | <property name="RestrictSUIDSGID" type="b" access="read"> | ||
| 988 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 989 | </property> | ||
| 990 | <property name="RestrictNamespaces" type="t" access="read"> | ||
| 991 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 992 | </property> | ||
| 993 | <property name="DelegateNamespaces" type="t" access="read"> | ||
| 994 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 995 | </property> | ||
| 996 | <!-- <property name="RestrictFileSystems" type="(bas)" access="read"> --> | ||
| 997 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 998 | <!-- </property> --> | ||
| 999 | <!-- <property name="BindPaths" type="a(ssbt)" access="read"> --> | ||
| 1000 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 1001 | <!-- </property> --> | ||
| 1002 | <!-- <property name="BindReadOnlyPaths" type="a(ssbt)" access="read"> --> | ||
| 1003 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 1004 | <!-- </property> --> | ||
| 1005 | <!-- <property name="TemporaryFileSystem" type="a(ss)" access="read"> --> | ||
| 1006 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 1007 | <!-- </property> --> | ||
| 1008 | <property name="MountAPIVFS" type="b" access="read"> | ||
| 1009 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1010 | </property> | ||
| 1011 | <property name="BindLogSockets" type="b" access="read"> | ||
| 1012 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1013 | </property> | ||
| 1014 | <property name="KeyringMode" type="s" access="read"> | ||
| 1015 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1016 | </property> | ||
| 1017 | <property name="ProtectProc" type="s" access="read"> | ||
| 1018 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1019 | </property> | ||
| 1020 | <property name="ProcSubset" type="s" access="read"> | ||
| 1021 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1022 | </property> | ||
| 1023 | <property name="ProtectHostname" type="b" access="read"> | ||
| 1024 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1025 | </property> | ||
| 1026 | <!-- <property name="ProtectHostnameEx" type="(ss)" access="read"> --> | ||
| 1027 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 1028 | <!-- </property> --> | ||
| 1029 | <property name="PrivateBPF" type="s" access="read"> | ||
| 1030 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1031 | </property> | ||
| 1032 | <property name="BPFDelegateCommands" type="s" access="read"> | ||
| 1033 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1034 | </property> | ||
| 1035 | <property name="BPFDelegateMaps" type="s" access="read"> | ||
| 1036 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1037 | </property> | ||
| 1038 | <property name="BPFDelegatePrograms" type="s" access="read"> | ||
| 1039 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1040 | </property> | ||
| 1041 | <property name="BPFDelegateAttachments" type="s" access="read"> | ||
| 1042 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1043 | </property> | ||
| 1044 | <property name="MemoryKSM" type="b" access="read"> | ||
| 1045 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1046 | </property> | ||
| 1047 | <property name="MemoryTHP" type="s" access="read"> | ||
| 1048 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1049 | </property> | ||
| 1050 | <property name="UserNamespacePath" type="s" access="read"> | ||
| 1051 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1052 | </property> | ||
| 1053 | <property name="NetworkNamespacePath" type="s" access="read"> | ||
| 1054 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1055 | </property> | ||
| 1056 | <property name="IPCNamespacePath" type="s" access="read"> | ||
| 1057 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1058 | </property> | ||
| 1059 | <property name="RootImagePolicy" type="s" access="read"> | ||
| 1060 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1061 | </property> | ||
| 1062 | <property name="MountImagePolicy" type="s" access="read"> | ||
| 1063 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1064 | </property> | ||
| 1065 | <property name="ExtensionImagePolicy" type="s" access="read"> | ||
| 1066 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1067 | </property> | ||
| 1068 | <!-- <property name="StateDirectoryQuotaUsage" type="(tt)" access="read"> --> | ||
| 1069 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 1070 | <!-- </property> --> | ||
| 1071 | <!-- <property name="CacheDirectoryQuotaUsage" type="(tt)" access="read"> --> | ||
| 1072 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 1073 | <!-- </property> --> | ||
| 1074 | <!-- <property name="LogsDirectoryQuotaUsage" type="(tt)" access="read"> --> | ||
| 1075 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> --> | ||
| 1076 | <!-- </property> --> | ||
| 1077 | <property name="KillMode" type="s" access="read"> | ||
| 1078 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1079 | </property> | ||
| 1080 | <property name="KillSignal" type="i" access="read"> | ||
| 1081 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1082 | </property> | ||
| 1083 | <property name="RestartKillSignal" type="i" access="read"> | ||
| 1084 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1085 | </property> | ||
| 1086 | <property name="FinalKillSignal" type="i" access="read"> | ||
| 1087 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1088 | </property> | ||
| 1089 | <property name="SendSIGKILL" type="b" access="read"> | ||
| 1090 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1091 | </property> | ||
| 1092 | <property name="SendSIGHUP" type="b" access="read"> | ||
| 1093 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1094 | </property> | ||
| 1095 | <property name="WatchdogSignal" type="i" access="read"> | ||
| 1096 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 1097 | </property> | ||
| 1098 | </interface> | ||
| 1099 | </node> | ||
| 1100 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Unit.xml b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Unit.xml new file mode 100644 index 00000000..a554f513 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell-plugins/org.freedesktop.systemd1.Unit.xml | |||
| @@ -0,0 +1,359 @@ | |||
| 1 | <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" | ||
| 2 | "https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> | ||
| 3 | <node> | ||
| 4 | <interface name="org.freedesktop.systemd1.Unit"> | ||
| 5 | <property name="Id" type="s" access="read"> | ||
| 6 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 7 | </property> | ||
| 8 | <property name="Names" type="as" access="read"> | ||
| 9 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 10 | </property> | ||
| 11 | <property name="Following" type="s" access="read"> | ||
| 12 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 13 | </property> | ||
| 14 | <!-- <property name="Requires" type="as" access="read"> --> | ||
| 15 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 16 | <!-- </property> --> | ||
| 17 | <property name="Requisite" type="as" access="read"> | ||
| 18 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 19 | </property> | ||
| 20 | <property name="Wants" type="as" access="read"> | ||
| 21 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 22 | </property> | ||
| 23 | <property name="BindsTo" type="as" access="read"> | ||
| 24 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 25 | </property> | ||
| 26 | <property name="PartOf" type="as" access="read"> | ||
| 27 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 28 | </property> | ||
| 29 | <property name="Upholds" type="as" access="read"> | ||
| 30 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 31 | </property> | ||
| 32 | <property name="RequiredBy" type="as" access="read"> | ||
| 33 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 34 | </property> | ||
| 35 | <property name="RequisiteOf" type="as" access="read"> | ||
| 36 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 37 | </property> | ||
| 38 | <property name="WantedBy" type="as" access="read"> | ||
| 39 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 40 | </property> | ||
| 41 | <property name="BoundBy" type="as" access="read"> | ||
| 42 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 43 | </property> | ||
| 44 | <property name="UpheldBy" type="as" access="read"> | ||
| 45 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 46 | </property> | ||
| 47 | <property name="ConsistsOf" type="as" access="read"> | ||
| 48 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 49 | </property> | ||
| 50 | <property name="Conflicts" type="as" access="read"> | ||
| 51 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 52 | </property> | ||
| 53 | <property name="ConflictedBy" type="as" access="read"> | ||
| 54 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 55 | </property> | ||
| 56 | <property name="Before" type="as" access="read"> | ||
| 57 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 58 | </property> | ||
| 59 | <property name="After" type="as" access="read"> | ||
| 60 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 61 | </property> | ||
| 62 | <property name="OnSuccess" type="as" access="read"> | ||
| 63 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 64 | </property> | ||
| 65 | <property name="OnSuccessOf" type="as" access="read"> | ||
| 66 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 67 | </property> | ||
| 68 | <property name="OnFailure" type="as" access="read"> | ||
| 69 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 70 | </property> | ||
| 71 | <property name="OnFailureOf" type="as" access="read"> | ||
| 72 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 73 | </property> | ||
| 74 | <property name="Triggers" type="as" access="read"> | ||
| 75 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 76 | </property> | ||
| 77 | <property name="TriggeredBy" type="as" access="read"> | ||
| 78 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 79 | </property> | ||
| 80 | <property name="PropagatesReloadTo" type="as" access="read"> | ||
| 81 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 82 | </property> | ||
| 83 | <property name="ReloadPropagatedFrom" type="as" access="read"> | ||
| 84 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 85 | </property> | ||
| 86 | <property name="PropagatesStopTo" type="as" access="read"> | ||
| 87 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 88 | </property> | ||
| 89 | <property name="StopPropagatedFrom" type="as" access="read"> | ||
| 90 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 91 | </property> | ||
| 92 | <property name="JoinsNamespaceOf" type="as" access="read"> | ||
| 93 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 94 | </property> | ||
| 95 | <property name="SliceOf" type="as" access="read"> | ||
| 96 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 97 | </property> | ||
| 98 | <property name="RequiresMountsFor" type="as" access="read"> | ||
| 99 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 100 | </property> | ||
| 101 | <property name="WantsMountsFor" type="as" access="read"> | ||
| 102 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 103 | </property> | ||
| 104 | <property name="Documentation" type="as" access="read"> | ||
| 105 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 106 | </property> | ||
| 107 | <property name="Description" type="s" access="read"> | ||
| 108 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 109 | </property> | ||
| 110 | <property name="AccessSELinuxContext" type="s" access="read"> | ||
| 111 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 112 | </property> | ||
| 113 | <property name="LoadState" type="s" access="read"> | ||
| 114 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 115 | </property> | ||
| 116 | <property name="ActiveState" type="s" access="read"> | ||
| 117 | </property> | ||
| 118 | <property name="FreezerState" type="s" access="read"> | ||
| 119 | </property> | ||
| 120 | <property name="SubState" type="s" access="read"> | ||
| 121 | </property> | ||
| 122 | <property name="FragmentPath" type="s" access="read"> | ||
| 123 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 124 | </property> | ||
| 125 | <property name="SourcePath" type="s" access="read"> | ||
| 126 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 127 | </property> | ||
| 128 | <property name="DropInPaths" type="as" access="read"> | ||
| 129 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 130 | </property> | ||
| 131 | <property name="UnitFileState" type="s" access="read"> | ||
| 132 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 133 | </property> | ||
| 134 | <property name="UnitFilePreset" type="s" access="read"> | ||
| 135 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 136 | </property> | ||
| 137 | <property name="StateChangeTimestamp" type="t" access="read"> | ||
| 138 | </property> | ||
| 139 | <property name="StateChangeTimestampMonotonic" type="t" access="read"> | ||
| 140 | </property> | ||
| 141 | <property name="InactiveExitTimestamp" type="t" access="read"> | ||
| 142 | </property> | ||
| 143 | <property name="InactiveExitTimestampMonotonic" type="t" access="read"> | ||
| 144 | </property> | ||
| 145 | <property name="ActiveEnterTimestamp" type="t" access="read"> | ||
| 146 | </property> | ||
| 147 | <property name="ActiveEnterTimestampMonotonic" type="t" access="read"> | ||
| 148 | </property> | ||
| 149 | <property name="ActiveExitTimestamp" type="t" access="read"> | ||
| 150 | </property> | ||
| 151 | <property name="ActiveExitTimestampMonotonic" type="t" access="read"> | ||
| 152 | </property> | ||
| 153 | <property name="InactiveEnterTimestamp" type="t" access="read"> | ||
| 154 | </property> | ||
| 155 | <property name="InactiveEnterTimestampMonotonic" type="t" access="read"> | ||
| 156 | </property> | ||
| 157 | <property name="CanStart" type="b" access="read"> | ||
| 158 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 159 | </property> | ||
| 160 | <property name="CanStop" type="b" access="read"> | ||
| 161 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 162 | </property> | ||
| 163 | <property name="CanReload" type="b" access="read"> | ||
| 164 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 165 | </property> | ||
| 166 | <property name="CanIsolate" type="b" access="read"> | ||
| 167 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 168 | </property> | ||
| 169 | <property name="CanClean" type="as" access="read"> | ||
| 170 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 171 | </property> | ||
| 172 | <property name="CanFreeze" type="b" access="read"> | ||
| 173 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 174 | </property> | ||
| 175 | <property name="CanLiveMount" type="b" access="read"> | ||
| 176 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 177 | </property> | ||
| 178 | <!-- <property name="Job" type="(uo)" access="read"> --> | ||
| 179 | <!-- </property> --> | ||
| 180 | <property name="StopWhenUnneeded" type="b" access="read"> | ||
| 181 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 182 | </property> | ||
| 183 | <property name="RefuseManualStart" type="b" access="read"> | ||
| 184 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 185 | </property> | ||
| 186 | <property name="RefuseManualStop" type="b" access="read"> | ||
| 187 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 188 | </property> | ||
| 189 | <property name="AllowIsolate" type="b" access="read"> | ||
| 190 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 191 | </property> | ||
| 192 | <property name="DefaultDependencies" type="b" access="read"> | ||
| 193 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 194 | </property> | ||
| 195 | <property name="SurviveFinalKillSignal" type="b" access="read"> | ||
| 196 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 197 | </property> | ||
| 198 | <property name="OnSuccessJobMode" type="s" access="read"> | ||
| 199 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 200 | </property> | ||
| 201 | <property name="OnFailureJobMode" type="s" access="read"> | ||
| 202 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 203 | </property> | ||
| 204 | <property name="IgnoreOnIsolate" type="b" access="read"> | ||
| 205 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 206 | </property> | ||
| 207 | <property name="NeedDaemonReload" type="b" access="read"> | ||
| 208 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 209 | </property> | ||
| 210 | <property name="Markers" type="as" access="read"> | ||
| 211 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 212 | </property> | ||
| 213 | <property name="JobTimeoutUSec" type="t" access="read"> | ||
| 214 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 215 | </property> | ||
| 216 | <property name="JobRunningTimeoutUSec" type="t" access="read"> | ||
| 217 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 218 | </property> | ||
| 219 | <property name="JobTimeoutAction" type="s" access="read"> | ||
| 220 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 221 | </property> | ||
| 222 | <property name="JobTimeoutRebootArgument" type="s" access="read"> | ||
| 223 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 224 | </property> | ||
| 225 | <property name="ConditionResult" type="b" access="read"> | ||
| 226 | </property> | ||
| 227 | <property name="AssertResult" type="b" access="read"> | ||
| 228 | </property> | ||
| 229 | <property name="ConditionTimestamp" type="t" access="read"> | ||
| 230 | </property> | ||
| 231 | <property name="ConditionTimestampMonotonic" type="t" access="read"> | ||
| 232 | </property> | ||
| 233 | <property name="AssertTimestamp" type="t" access="read"> | ||
| 234 | </property> | ||
| 235 | <property name="AssertTimestampMonotonic" type="t" access="read"> | ||
| 236 | </property> | ||
| 237 | <!-- <property name="Conditions" type="a(sbbsi)" access="read"> --> | ||
| 238 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 239 | <!-- </property> --> | ||
| 240 | <!-- <property name="Asserts" type="a(sbbsi)" access="read"> --> | ||
| 241 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/> --> | ||
| 242 | <!-- </property> --> | ||
| 243 | <!-- <property name="LoadError" type="(ss)" access="read"> --> | ||
| 244 | <!-- <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> --> | ||
| 245 | <!-- </property> --> | ||
| 246 | <property name="Transient" type="b" access="read"> | ||
| 247 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 248 | </property> | ||
| 249 | <property name="Perpetual" type="b" access="read"> | ||
| 250 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 251 | </property> | ||
| 252 | <property name="StartLimitIntervalUSec" type="t" access="read"> | ||
| 253 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 254 | </property> | ||
| 255 | <property name="StartLimitBurst" type="u" access="read"> | ||
| 256 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 257 | </property> | ||
| 258 | <property name="StartLimitAction" type="s" access="read"> | ||
| 259 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 260 | </property> | ||
| 261 | <property name="FailureAction" type="s" access="read"> | ||
| 262 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 263 | </property> | ||
| 264 | <property name="FailureActionExitStatus" type="i" access="read"> | ||
| 265 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 266 | </property> | ||
| 267 | <property name="SuccessAction" type="s" access="read"> | ||
| 268 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 269 | </property> | ||
| 270 | <property name="SuccessActionExitStatus" type="i" access="read"> | ||
| 271 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 272 | </property> | ||
| 273 | <property name="RebootArgument" type="s" access="read"> | ||
| 274 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 275 | </property> | ||
| 276 | <property name="InvocationID" type="ay" access="read"> | ||
| 277 | </property> | ||
| 278 | <property name="CollectMode" type="s" access="read"> | ||
| 279 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> | ||
| 280 | </property> | ||
| 281 | <property name="Refs" type="as" access="read"> | ||
| 282 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 283 | </property> | ||
| 284 | <!-- <property name="ActivationDetails" type="a(ss)" access="read"> --> | ||
| 285 | <!-- </property> --> | ||
| 286 | <property name="DebugInvocation" type="b" access="read"> | ||
| 287 | <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> | ||
| 288 | </property> | ||
| 289 | <method name="Start"> | ||
| 290 | <arg type="s" name="mode" direction="in"/> | ||
| 291 | <arg type="o" name="job" direction="out"/> | ||
| 292 | </method> | ||
| 293 | <method name="Stop"> | ||
| 294 | <arg type="s" name="mode" direction="in"/> | ||
| 295 | <arg type="o" name="job" direction="out"/> | ||
| 296 | </method> | ||
| 297 | <method name="Reload"> | ||
| 298 | <arg type="s" name="mode" direction="in"/> | ||
| 299 | <arg type="o" name="job" direction="out"/> | ||
| 300 | </method> | ||
| 301 | <method name="Restart"> | ||
| 302 | <arg type="s" name="mode" direction="in"/> | ||
| 303 | <arg type="o" name="job" direction="out"/> | ||
| 304 | </method> | ||
| 305 | <method name="TryRestart"> | ||
| 306 | <arg type="s" name="mode" direction="in"/> | ||
| 307 | <arg type="o" name="job" direction="out"/> | ||
| 308 | </method> | ||
| 309 | <method name="ReloadOrRestart"> | ||
| 310 | <arg type="s" name="mode" direction="in"/> | ||
| 311 | <arg type="o" name="job" direction="out"/> | ||
| 312 | </method> | ||
| 313 | <method name="ReloadOrTryRestart"> | ||
| 314 | <arg type="s" name="mode" direction="in"/> | ||
| 315 | <arg type="o" name="job" direction="out"/> | ||
| 316 | </method> | ||
| 317 | <!-- <method name="EnqueueJob"> --> | ||
| 318 | <!-- <arg type="s" name="job_type" direction="in"/> --> | ||
| 319 | <!-- <arg type="s" name="job_mode" direction="in"/> --> | ||
| 320 | <!-- <arg type="u" name="job_id" direction="out"/> --> | ||
| 321 | <!-- <arg type="o" name="job_path" direction="out"/> --> | ||
| 322 | <!-- <arg type="s" name="unit_id" direction="out"/> --> | ||
| 323 | <!-- <arg type="o" name="unit_path" direction="out"/> --> | ||
| 324 | <!-- <arg type="s" name="job_type" direction="out"/> --> | ||
| 325 | <!-- <arg type="a(uosos)" name="affected_jobs" direction="out"/> --> | ||
| 326 | <!-- </method> --> | ||
| 327 | <method name="Kill"> | ||
| 328 | <arg type="s" name="whom" direction="in"/> | ||
| 329 | <arg type="i" name="signal" direction="in"/> | ||
| 330 | </method> | ||
| 331 | <method name="KillSubgroup"> | ||
| 332 | <arg type="s" name="subgroup" direction="in"/> | ||
| 333 | <arg type="i" name="signal" direction="in"/> | ||
| 334 | </method> | ||
| 335 | <method name="QueueSignal"> | ||
| 336 | <arg type="s" name="whom" direction="in"/> | ||
| 337 | <arg type="i" name="signal" direction="in"/> | ||
| 338 | <arg type="i" name="value" direction="in"/> | ||
| 339 | </method> | ||
| 340 | <method name="ResetFailed"> | ||
| 341 | </method> | ||
| 342 | <!-- <method name="SetProperties"> --> | ||
| 343 | <!-- <arg type="b" name="runtime" direction="in"/> --> | ||
| 344 | <!-- <arg type="a(sv)" name="properties" direction="in"/> --> | ||
| 345 | <!-- </method> --> | ||
| 346 | <method name="Ref"> | ||
| 347 | </method> | ||
| 348 | <method name="Unref"> | ||
| 349 | </method> | ||
| 350 | <method name="Clean"> | ||
| 351 | <arg type="as" name="mask" direction="in"/> | ||
| 352 | </method> | ||
| 353 | <method name="Freeze"> | ||
| 354 | </method> | ||
| 355 | <method name="Thaw"> | ||
| 356 | </method> | ||
| 357 | </interface> | ||
| 358 | </node> | ||
| 359 | |||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/ActiveWindowDisplay.qml b/accounts/gkleen@skadhi/shell/quickshell/ActiveWindowDisplay.qml new file mode 100644 index 00000000..ac1cbf3a --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/ActiveWindowDisplay.qml | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | import QtQuick | ||
| 2 | import qs.Services | ||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Widgets | ||
| 5 | |||
| 6 | Item { | ||
| 7 | id: activeWindowDisplay | ||
| 8 | |||
| 9 | required property int maxWidth | ||
| 10 | required property var screen | ||
| 11 | |||
| 12 | property var activeWindow: { | ||
| 13 | let currWindowId = Array.from(NiriService.workspaces).find(ws => { | ||
| 14 | return ws.output === screen?.name && ws.is_active; | ||
| 15 | })?.active_window_id; | ||
| 16 | |||
| 17 | return currWindowId ? Array.from(NiriService.windows).find(win => win.id == currWindowId) : null; | ||
| 18 | } | ||
| 19 | property var windowEntry: activeWindow ? DesktopEntries.heuristicLookup(activeWindow.app_id) : null | ||
| 20 | |||
| 21 | anchors.verticalCenter: parent.verticalCenter | ||
| 22 | width: activeWindowDisplayContent.width | ||
| 23 | height: parent.height | ||
| 24 | |||
| 25 | WrapperMouseArea { | ||
| 26 | id: widgetMouseArea | ||
| 27 | |||
| 28 | anchors.fill: parent | ||
| 29 | |||
| 30 | hoverEnabled: true | ||
| 31 | |||
| 32 | Item { | ||
| 33 | anchors.fill: parent | ||
| 34 | |||
| 35 | Row { | ||
| 36 | id: activeWindowDisplayContent | ||
| 37 | |||
| 38 | width: childrenRect.width | ||
| 39 | height: parent.height | ||
| 40 | anchors.verticalCenter: parent.verticalCenter | ||
| 41 | spacing: 8 | ||
| 42 | |||
| 43 | IconImage { | ||
| 44 | id: activeWindowIcon | ||
| 45 | |||
| 46 | implicitSize: 14 | ||
| 47 | |||
| 48 | anchors.verticalCenter: parent.verticalCenter | ||
| 49 | |||
| 50 | source: { | ||
| 51 | let icon = activeWindowDisplay.windowEntry?.icon | ||
| 52 | if (typeof icon === 'string' || icon instanceof String) { | ||
| 53 | if (icon.includes("?path=")) { | ||
| 54 | const split = icon.split("?path=") | ||
| 55 | if (split.length !== 2) | ||
| 56 | return icon | ||
| 57 | const name = split[0] | ||
| 58 | const path = split[1] | ||
| 59 | const fileName = name.substring( | ||
| 60 | name.lastIndexOf("/") + 1) | ||
| 61 | return `file://${path}/${fileName}` | ||
| 62 | } else | ||
| 63 | icon = Quickshell.iconPath(icon); | ||
| 64 | return icon | ||
| 65 | } | ||
| 66 | return "" | ||
| 67 | } | ||
| 68 | asynchronous: true | ||
| 69 | smooth: true | ||
| 70 | mipmap: true | ||
| 71 | } | ||
| 72 | |||
| 73 | Text { | ||
| 74 | id: windowTitle | ||
| 75 | |||
| 76 | width: Math.min(implicitWidth, activeWindowDisplay.maxWidth - activeWindowIcon.width - activeWindowDisplayContent.spacing) | ||
| 77 | |||
| 78 | property var appAliases: { "Firefox": "Mozilla Firefox", "mpv Media Player": "mpv", "Thunderbird": "Mozilla Thunderbird", "Thunderbird (LMU)": "Mozilla Thunderbird" } | ||
| 79 | |||
| 80 | elide: Text.ElideRight | ||
| 81 | maximumLineCount: 1 | ||
| 82 | color: "white" | ||
| 83 | anchors.verticalCenter: parent.verticalCenter | ||
| 84 | text: { | ||
| 85 | if (!activeWindowDisplay.activeWindow) | ||
| 86 | return ""; | ||
| 87 | |||
| 88 | var title = activeWindowDisplay.activeWindow.title; | ||
| 89 | var appName = activeWindowDisplay.windowEntry?.name; | ||
| 90 | if (appAliases[appName]) | ||
| 91 | appName = appAliases[appName]; | ||
| 92 | if (appName && title.endsWith(appName)) { | ||
| 93 | const oldTitle = title; | ||
| 94 | title = title.substring(0, title.length - appName.length); | ||
| 95 | title = title.replace(/\s*(—|-)\s*$/, ""); | ||
| 96 | if (!title) | ||
| 97 | title = oldTitle; | ||
| 98 | } | ||
| 99 | return title; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | Loader { | ||
| 107 | id: tooltipLoader | ||
| 108 | |||
| 109 | active: false | ||
| 110 | |||
| 111 | Connections { | ||
| 112 | target: widgetMouseArea | ||
| 113 | function onContainsMouseChanged() { | ||
| 114 | if (widgetMouseArea.containsMouse) | ||
| 115 | tooltipLoader.active = true; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | PopupWindow { | ||
| 120 | id: tooltip | ||
| 121 | |||
| 122 | property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse | ||
| 123 | |||
| 124 | anchor { | ||
| 125 | item: widgetMouseArea | ||
| 126 | edges: Edges.Bottom | Edges.Left | ||
| 127 | } | ||
| 128 | visible: false | ||
| 129 | |||
| 130 | onNextVisibleChanged: hangTimer.restart() | ||
| 131 | |||
| 132 | Timer { | ||
| 133 | id: hangTimer | ||
| 134 | interval: tooltip.visible ? 100 : 500 | ||
| 135 | onTriggered: { | ||
| 136 | tooltip.visible = tooltip.nextVisible; | ||
| 137 | if (!tooltip.visible) | ||
| 138 | tooltipLoader.active = false; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | implicitWidth: widgetTooltipText.contentWidth + 16 | ||
| 143 | implicitHeight: widgetTooltipText.contentHeight + 16 | ||
| 144 | color: "black" | ||
| 145 | |||
| 146 | WrapperMouseArea { | ||
| 147 | id: tooltipMouseArea | ||
| 148 | |||
| 149 | hoverEnabled: true | ||
| 150 | enabled: true | ||
| 151 | |||
| 152 | anchors.fill: parent | ||
| 153 | |||
| 154 | Item { | ||
| 155 | anchors.fill: parent | ||
| 156 | |||
| 157 | Text { | ||
| 158 | id: widgetTooltipText | ||
| 159 | |||
| 160 | anchors.centerIn: parent | ||
| 161 | |||
| 162 | font.pointSize: 10 | ||
| 163 | font.family: "Fira Mono" | ||
| 164 | color: "white" | ||
| 165 | |||
| 166 | text: JSON.stringify(Object.assign({}, activeWindowDisplay.activeWindow), null, 2) | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Bar.qml b/accounts/gkleen@skadhi/shell/quickshell/Bar.qml new file mode 100644 index 00000000..33909884 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Bar.qml | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | import Quickshell | ||
| 2 | import Quickshell.Wayland | ||
| 3 | import QtQuick | ||
| 4 | import qs.Services | ||
| 5 | |||
| 6 | PanelWindow { | ||
| 7 | id: bar | ||
| 8 | |||
| 9 | WlrLayershell.namespace: "bar" | ||
| 10 | |||
| 11 | property bool haveMaximizedWindow: { | ||
| 12 | let currWindowId = Array.from(NiriService.workspaces).find(ws => { | ||
| 13 | return ws.output === bar.screen.name && ws.is_active; | ||
| 14 | })?.active_window_id; | ||
| 15 | let activeWindowTileSize = Array.from(NiriService.windows).find(win => win.id == currWindowId)?.layout?.tile_size; | ||
| 16 | |||
| 17 | if (!activeWindowTileSize) | ||
| 18 | return false; | ||
| 19 | return activeWindowTileSize[0] >= bar.screen.width && activeWindowTileSize[1] >= bar.screen.height - bar.height; | ||
| 20 | } | ||
| 21 | |||
| 22 | anchors { | ||
| 23 | top: true | ||
| 24 | left: true | ||
| 25 | right: true | ||
| 26 | } | ||
| 27 | margins { | ||
| 28 | left: bar.haveMaximizedWindow ? 0 : 26 + 8 | ||
| 29 | right: bar.haveMaximizedWindow ? 0 : 26 + 8 | ||
| 30 | } | ||
| 31 | |||
| 32 | implicitHeight: 21 | ||
| 33 | color: "transparent" | ||
| 34 | |||
| 35 | property bool haveScreenshare: Array.from(NiriService.casts).some(cast => cast.target.Output?.name == bar.screen.name) | ||
| 36 | |||
| 37 | Rectangle { | ||
| 38 | color: { | ||
| 39 | if (bar.haveScreenshare) | ||
| 40 | return bar.haveMaximizedWindow ? Qt.rgba(0.2, 0, 0, 1) : Qt.rgba(0.2, 0, 0, 0.75); | ||
| 41 | return bar.haveMaximizedWindow ? "black" : Qt.rgba(0, 0, 0, 0.75); | ||
| 42 | } | ||
| 43 | anchors.fill: parent | ||
| 44 | // bottomLeftRadius: 8 | ||
| 45 | // bottomRightRadius: 8 | ||
| 46 | } | ||
| 47 | |||
| 48 | Row { | ||
| 49 | id: left | ||
| 50 | |||
| 51 | height: parent.height | ||
| 52 | width: childrenRect.width | ||
| 53 | anchors.left: parent.left | ||
| 54 | anchors.leftMargin: 8 | ||
| 55 | anchors.verticalCenter: parent.verticalCenter | ||
| 56 | spacing: 8 | ||
| 57 | |||
| 58 | WorkspaceSwitcher { | ||
| 59 | screen: bar.screen | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | Row { | ||
| 64 | id: center | ||
| 65 | |||
| 66 | height: parent.height | ||
| 67 | width: childrenRect.width | ||
| 68 | anchors.centerIn: parent | ||
| 69 | spacing: 5 | ||
| 70 | |||
| 71 | ActiveWindowDisplay { | ||
| 72 | screen: bar.screen | ||
| 73 | maxWidth: bar.width - 2*Math.max(left.width, right.width) - 2*8 | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | Row { | ||
| 78 | id: right | ||
| 79 | |||
| 80 | height: parent.height | ||
| 81 | width: childrenRect.width | ||
| 82 | anchors.right: parent.right | ||
| 83 | anchors.rightMargin: 8 | ||
| 84 | anchors.verticalCenter: parent.verticalCenter | ||
| 85 | spacing: 0 | ||
| 86 | |||
| 87 | WorktimeWidget {} | ||
| 88 | |||
| 89 | KeyboardLayout {} | ||
| 90 | |||
| 91 | Item { | ||
| 92 | visible: privacy.visible || ytDlp.visible | ||
| 93 | height: parent.height | ||
| 94 | width: 8 - 4 | ||
| 95 | } | ||
| 96 | |||
| 97 | PrivacyWidget { | ||
| 98 | id: privacy | ||
| 99 | } | ||
| 100 | |||
| 101 | Item { | ||
| 102 | visible: privacy.visible && ytDlp.visible | ||
| 103 | height: parent.height | ||
| 104 | width: 8 - 4 | ||
| 105 | } | ||
| 106 | |||
| 107 | YtDlpWidget { | ||
| 108 | id: ytDlp | ||
| 109 | } | ||
| 110 | |||
| 111 | Item { | ||
| 112 | visible: privacy.visible || ytDlp.visible | ||
| 113 | height: parent.height | ||
| 114 | width: 8 - 4 | ||
| 115 | } | ||
| 116 | |||
| 117 | SystemTray {} | ||
| 118 | |||
| 119 | PipewireWidget {} | ||
| 120 | |||
| 121 | BrightnessWidget {} | ||
| 122 | |||
| 123 | BatteryWidget {} | ||
| 124 | |||
| 125 | LockscreenInhibitorWidget {} | ||
| 126 | |||
| 127 | WaylandInhibitorWidget { | ||
| 128 | window: bar | ||
| 129 | } | ||
| 130 | |||
| 131 | LidSwitchInhibitorWidget {} | ||
| 132 | |||
| 133 | NotificationInhibitorWidget {} | ||
| 134 | |||
| 135 | Item { | ||
| 136 | height: parent.height | ||
| 137 | width: 8 - 4 | ||
| 138 | } | ||
| 139 | |||
| 140 | Clock {} | ||
| 141 | } | ||
| 142 | } \ No newline at end of file | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/BatteryWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/BatteryWidget.qml new file mode 100644 index 00000000..f465fa20 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/BatteryWidget.qml | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | import QtQuick | ||
| 2 | import Quickshell | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import Quickshell.Services.UPower | ||
| 5 | |||
| 6 | Item { | ||
| 7 | id: root | ||
| 8 | |||
| 9 | height: parent.height | ||
| 10 | width: batteryIcon.width + 8 | ||
| 11 | anchors.verticalCenter: parent.verticalCenter | ||
| 12 | |||
| 13 | property var batteryDevice: Array.from(UPower.devices.values).find(dev => dev.isLaptopBattery) | ||
| 14 | |||
| 15 | WrapperMouseArea { | ||
| 16 | id: widgetMouseArea | ||
| 17 | |||
| 18 | anchors.fill: parent | ||
| 19 | |||
| 20 | hoverEnabled: true | ||
| 21 | |||
| 22 | Item { | ||
| 23 | anchors.fill: parent | ||
| 24 | |||
| 25 | MaterialDesignIcon { | ||
| 26 | id: batteryIcon | ||
| 27 | |||
| 28 | implicitSize: 14 | ||
| 29 | anchors.centerIn: parent | ||
| 30 | |||
| 31 | icon: { | ||
| 32 | if (!root.batteryDevice?.ready) | ||
| 33 | return "battery-unknown"; | ||
| 34 | |||
| 35 | if (root.batteryDevice.state == UPowerDeviceState.FullyCharged) | ||
| 36 | return "power-plug-battery"; | ||
| 37 | |||
| 38 | const perdec = 10 * Math.max(1, Math.ceil(root.batteryDevice.percentage * 10)); | ||
| 39 | if (root.batteryDevice.state == UPowerDeviceState.Charging) | ||
| 40 | return `battery-charging-${perdec}`; | ||
| 41 | if (perdec == 100) | ||
| 42 | return "battery"; | ||
| 43 | return `battery-${perdec}`; | ||
| 44 | } | ||
| 45 | color: { | ||
| 46 | if (!root.batteryDevice?.ready) | ||
| 47 | return "#555"; | ||
| 48 | |||
| 49 | if (root.batteryDevice.state != UPowerDeviceState.FullyCharged && root.batteryDevice.state != UPowerDeviceState.Charging && root.batteryDevice.timeToEmpty < 20 * 60) | ||
| 50 | return "#f2201f"; | ||
| 51 | if (root.batteryDevice.state != UPowerDeviceState.FullyCharged && root.batteryDevice.state != UPowerDeviceState.Charging && root.batteryDevice.timeToEmpty < 40 * 60) | ||
| 52 | return "#f28a21"; | ||
| 53 | if (root.batteryDevice.state != UPowerDeviceState.FullyCharged) | ||
| 54 | return "#fff"; | ||
| 55 | return "#555"; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | PopupWindow { | ||
| 62 | id: tooltip | ||
| 63 | |||
| 64 | property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse | ||
| 65 | |||
| 66 | anchor { | ||
| 67 | item: widgetMouseArea | ||
| 68 | edges: Edges.Bottom | Edges.Left | ||
| 69 | } | ||
| 70 | visible: false | ||
| 71 | |||
| 72 | onNextVisibleChanged: hangTimer.restart() | ||
| 73 | |||
| 74 | Timer { | ||
| 75 | id: hangTimer | ||
| 76 | interval: 100 | ||
| 77 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 78 | } | ||
| 79 | |||
| 80 | implicitWidth: widgetTooltipText.contentWidth + 16 | ||
| 81 | implicitHeight: widgetTooltipText.contentHeight + 16 | ||
| 82 | color: "black" | ||
| 83 | |||
| 84 | WrapperMouseArea { | ||
| 85 | id: tooltipMouseArea | ||
| 86 | |||
| 87 | hoverEnabled: true | ||
| 88 | enabled: true | ||
| 89 | |||
| 90 | anchors.fill: parent | ||
| 91 | |||
| 92 | Item { | ||
| 93 | anchors.fill: parent | ||
| 94 | |||
| 95 | Text { | ||
| 96 | id: widgetTooltipText | ||
| 97 | |||
| 98 | anchors.centerIn: parent | ||
| 99 | |||
| 100 | font.pointSize: 10 | ||
| 101 | font.family: "Fira Sans" | ||
| 102 | color: "white" | ||
| 103 | |||
| 104 | text: { | ||
| 105 | if (!root.batteryDevice?.ready) | ||
| 106 | return "Not ready"; | ||
| 107 | |||
| 108 | const stateStr = UPowerDeviceState.toString(root.batteryDevice.state); | ||
| 109 | var outStr = stateStr; | ||
| 110 | if (root.batteryDevice.state !== UPowerDeviceState.FullyCharged) | ||
| 111 | outStr += ` ${Math.round(root.batteryDevice.percentage * 100)}%`; | ||
| 112 | |||
| 113 | function formatTime(t) { | ||
| 114 | var res = ""; | ||
| 115 | for (const unit of [{ "s": "h", "v": 3600 }, { "s": "m", "v": 60 }, { "s": "s", "v": 1 }]) { | ||
| 116 | if (t < unit.v) | ||
| 117 | continue; | ||
| 118 | res += Math.floor(t / unit.v) + unit.s; | ||
| 119 | t %= unit.v; | ||
| 120 | } | ||
| 121 | return res; | ||
| 122 | } | ||
| 123 | if (root.batteryDevice.timeToEmpty != 0) { | ||
| 124 | const tStr = formatTime(Math.floor(root.batteryDevice.timeToEmpty / 60) * 60); | ||
| 125 | if (tStr) | ||
| 126 | outStr += " " + tStr; | ||
| 127 | } else if (root.batteryDevice.timeToFull != 0) { | ||
| 128 | const tStr = formatTime(Math.ceil(root.batteryDevice.timeToFull / 60) * 60); | ||
| 129 | if (tStr) | ||
| 130 | outStr += " " + tStr; | ||
| 131 | } | ||
| 132 | |||
| 133 | return outStr; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/BrightnessOSD.qml b/accounts/gkleen@skadhi/shell/quickshell/BrightnessOSD.qml new file mode 100644 index 00000000..a432179e --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/BrightnessOSD.qml | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Layouts | ||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Widgets | ||
| 5 | import qs.Services | ||
| 6 | |||
| 7 | Scope { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | property bool show: false | ||
| 11 | property bool inhibited: true | ||
| 12 | |||
| 13 | Connections { | ||
| 14 | target: Brightness | ||
| 15 | |||
| 16 | function onCurrBrightnessChanged() { | ||
| 17 | root.show = true; | ||
| 18 | hideTimer.restart(); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | onShowChanged: { | ||
| 23 | if (show) | ||
| 24 | hideTimer.restart(); | ||
| 25 | } | ||
| 26 | |||
| 27 | Timer { | ||
| 28 | id: hideTimer | ||
| 29 | interval: 1000 | ||
| 30 | onTriggered: root.show = false | ||
| 31 | } | ||
| 32 | |||
| 33 | Timer { | ||
| 34 | id: startInhibit | ||
| 35 | interval: 100 | ||
| 36 | running: true | ||
| 37 | onTriggered: { | ||
| 38 | root.show = false; | ||
| 39 | root.inhibited = false; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | LazyLoader { | ||
| 44 | active: root.show && !root.inhibited | ||
| 45 | |||
| 46 | Variants { | ||
| 47 | model: Quickshell.screens | ||
| 48 | |||
| 49 | delegate: Scope { | ||
| 50 | id: screenScope | ||
| 51 | |||
| 52 | required property var modelData | ||
| 53 | |||
| 54 | PanelWindow { | ||
| 55 | id: window | ||
| 56 | |||
| 57 | screen: screenScope.modelData | ||
| 58 | |||
| 59 | anchors.top: true | ||
| 60 | margins.top: screen.height / 2 - 50 + 3.5 | ||
| 61 | exclusiveZone: 0 | ||
| 62 | exclusionMode: ExclusionMode.Ignore | ||
| 63 | |||
| 64 | implicitWidth: 400 | ||
| 65 | implicitHeight: 50 | ||
| 66 | |||
| 67 | mask: Region {} | ||
| 68 | |||
| 69 | color: "transparent" | ||
| 70 | |||
| 71 | Rectangle { | ||
| 72 | anchors.fill: parent | ||
| 73 | color: Qt.rgba(0, 0, 0, 0.75) | ||
| 74 | } | ||
| 75 | |||
| 76 | RowLayout { | ||
| 77 | id: layout | ||
| 78 | |||
| 79 | anchors.centerIn: parent | ||
| 80 | |||
| 81 | height: 50 - 8*2 | ||
| 82 | width: 400 - 8*2 | ||
| 83 | |||
| 84 | MaterialDesignIcon { | ||
| 85 | id: volumeIcon | ||
| 86 | |||
| 87 | implicitWidth: parent.height | ||
| 88 | implicitHeight: parent.height | ||
| 89 | |||
| 90 | icon: `brightness-${Math.min(7, Math.floor(Brightness.currBrightness * 7) + 1)}` | ||
| 91 | } | ||
| 92 | |||
| 93 | Rectangle { | ||
| 94 | Layout.fillWidth: true | ||
| 95 | |||
| 96 | implicitHeight: 10 | ||
| 97 | |||
| 98 | color: "#50ffffff" | ||
| 99 | |||
| 100 | Rectangle { | ||
| 101 | anchors { | ||
| 102 | left: parent.left | ||
| 103 | top: parent.top | ||
| 104 | bottom: parent.bottom | ||
| 105 | } | ||
| 106 | |||
| 107 | color: "white" | ||
| 108 | |||
| 109 | implicitWidth: parent.width * Brightness.currBrightness | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/BrightnessWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/BrightnessWidget.qml new file mode 100644 index 00000000..3bb5a80e --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/BrightnessWidget.qml | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | import QtQuick | ||
| 2 | import Quickshell | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import qs.Services | ||
| 5 | |||
| 6 | Item { | ||
| 7 | height: parent.height | ||
| 8 | width: brightnessIcon.width + 8 | ||
| 9 | anchors.verticalCenter: parent.verticalCenter | ||
| 10 | |||
| 11 | WrapperMouseArea { | ||
| 12 | id: widgetMouseArea | ||
| 13 | |||
| 14 | anchors.fill: parent | ||
| 15 | |||
| 16 | hoverEnabled: true | ||
| 17 | |||
| 18 | property real sensitivity: (1 / 50) / 120 | ||
| 19 | onWheel: event => Brightness.currBrightness += event.angleDelta.y * sensitivity | ||
| 20 | |||
| 21 | Item { | ||
| 22 | anchors.fill: parent | ||
| 23 | |||
| 24 | MaterialDesignIcon { | ||
| 25 | id: brightnessIcon | ||
| 26 | |||
| 27 | implicitSize: 14 | ||
| 28 | anchors.centerIn: parent | ||
| 29 | |||
| 30 | icon: `brightness-${Math.min(7, Math.floor(Brightness.currBrightness * 7) + 1)}` | ||
| 31 | color: "#555" | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | PopupWindow { | ||
| 37 | id: tooltip | ||
| 38 | |||
| 39 | property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse | ||
| 40 | |||
| 41 | anchor { | ||
| 42 | item: widgetMouseArea | ||
| 43 | edges: Edges.Bottom | Edges.Left | ||
| 44 | } | ||
| 45 | visible: false | ||
| 46 | |||
| 47 | onNextVisibleChanged: hangTimer.restart() | ||
| 48 | |||
| 49 | Timer { | ||
| 50 | id: hangTimer | ||
| 51 | interval: 100 | ||
| 52 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 53 | } | ||
| 54 | |||
| 55 | implicitWidth: widgetTooltipText.contentWidth + 16 | ||
| 56 | implicitHeight: widgetTooltipText.contentHeight + 16 | ||
| 57 | color: "black" | ||
| 58 | |||
| 59 | WrapperMouseArea { | ||
| 60 | id: tooltipMouseArea | ||
| 61 | |||
| 62 | hoverEnabled: true | ||
| 63 | enabled: true | ||
| 64 | |||
| 65 | anchors.fill: parent | ||
| 66 | |||
| 67 | Item { | ||
| 68 | anchors.fill: parent | ||
| 69 | |||
| 70 | Text { | ||
| 71 | id: widgetTooltipText | ||
| 72 | |||
| 73 | anchors.centerIn: parent | ||
| 74 | |||
| 75 | font.pointSize: 10 | ||
| 76 | font.family: "Fira Sans" | ||
| 77 | color: "white" | ||
| 78 | |||
| 79 | text: `${Math.round(Brightness.currBrightness * 100)}%` | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Clock.qml b/accounts/gkleen@skadhi/shell/quickshell/Clock.qml new file mode 100644 index 00000000..58a80b8b --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Clock.qml | |||
| @@ -0,0 +1,295 @@ | |||
| 1 | import QtQml | ||
| 2 | import QtQuick | ||
| 3 | import Quickshell | ||
| 4 | import Custom as Custom | ||
| 5 | import QtQuick.Controls | ||
| 6 | import QtQuick.Layouts | ||
| 7 | import Quickshell.Widgets | ||
| 8 | |||
| 9 | Item { | ||
| 10 | id: clockItem | ||
| 11 | |||
| 12 | property bool calendarPopup: true | ||
| 13 | |||
| 14 | width: clock.contentWidth | ||
| 15 | height: parent.height | ||
| 16 | anchors.verticalCenter: parent.verticalCenter | ||
| 17 | |||
| 18 | WrapperMouseArea { | ||
| 19 | id: clockMouseArea | ||
| 20 | |||
| 21 | anchors.fill: parent | ||
| 22 | hoverEnabled: true | ||
| 23 | enabled: clockItem.calendarPopup | ||
| 24 | |||
| 25 | Item { | ||
| 26 | anchors.fill: parent | ||
| 27 | |||
| 28 | Text { | ||
| 29 | id: clock | ||
| 30 | color: "white" | ||
| 31 | |||
| 32 | anchors.verticalCenter: parent.verticalCenter | ||
| 33 | |||
| 34 | Custom.Chrono { | ||
| 35 | id: chrono | ||
| 36 | |||
| 37 | onDateChanged: clock.text = format("W{0:%V-%u} {0:%F} {0:%H:%M:%S%Ez}") | ||
| 38 | } | ||
| 39 | |||
| 40 | font.pointSize: 10 | ||
| 41 | font.family: "Fira Sans" | ||
| 42 | font.features: { "tnum": 1 } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | Loader { | ||
| 48 | id: tooltipLoader | ||
| 49 | |||
| 50 | active: false | ||
| 51 | |||
| 52 | Connections { | ||
| 53 | target: clockMouseArea | ||
| 54 | function onContainsMouseChanged() { | ||
| 55 | if (clockMouseArea.containsMouse) | ||
| 56 | tooltipLoader.active = true; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | sourceComponent: PopupWindow { | ||
| 61 | id: tooltip | ||
| 62 | |||
| 63 | property bool nextVisible: clockMouseArea.containsMouse || tooltipMouseArea.containsMouse | ||
| 64 | |||
| 65 | anchor { | ||
| 66 | item: clockMouseArea | ||
| 67 | edges: Edges.Bottom | Edges.Left | ||
| 68 | } | ||
| 69 | visible: false | ||
| 70 | |||
| 71 | onNextVisibleChanged: hangTimer.restart() | ||
| 72 | |||
| 73 | Timer { | ||
| 74 | id: hangTimer | ||
| 75 | interval: 100 | ||
| 76 | onTriggered: { | ||
| 77 | tooltip.visible = tooltip.nextVisible; | ||
| 78 | if (!tooltip.visible) | ||
| 79 | tooltipLoader.active = false; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | implicitWidth: tooltipLayout.childrenRect.width + 16 | ||
| 84 | implicitHeight: tooltipLayout.childrenRect.height + 16 | ||
| 85 | color: "black" | ||
| 86 | |||
| 87 | onVisibleChanged: { | ||
| 88 | yearCalendar.year = chrono.date.getFullYear(); | ||
| 89 | yearCalendar.angleRem = 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | WrapperMouseArea { | ||
| 93 | id: tooltipMouseArea | ||
| 94 | |||
| 95 | hoverEnabled: true | ||
| 96 | enabled: true | ||
| 97 | |||
| 98 | onWheel: event => yearCalendar.scrollYear(event) | ||
| 99 | |||
| 100 | anchors.fill: parent | ||
| 101 | |||
| 102 | Item { | ||
| 103 | id: clockTooltipContent | ||
| 104 | |||
| 105 | anchors.fill: parent | ||
| 106 | |||
| 107 | ColumnLayout { | ||
| 108 | id: tooltipLayout | ||
| 109 | |||
| 110 | anchors { | ||
| 111 | left: parent.left | ||
| 112 | top: parent.top | ||
| 113 | leftMargin: 8 | ||
| 114 | topMargin: 8 | ||
| 115 | } | ||
| 116 | |||
| 117 | Text { | ||
| 118 | id: yearLabel | ||
| 119 | |||
| 120 | horizontalAlignment: Text.AlignHCenter | ||
| 121 | |||
| 122 | font.pointSize: 14 | ||
| 123 | font.family: "Fira Sans" | ||
| 124 | font.features: { "tnum": 1 } | ||
| 125 | color: "white" | ||
| 126 | |||
| 127 | text: yearCalendar.year | ||
| 128 | |||
| 129 | Layout.fillWidth: true | ||
| 130 | Layout.bottomMargin: 8 | ||
| 131 | } | ||
| 132 | |||
| 133 | GridLayout { | ||
| 134 | property int year: chrono.date.getFullYear() | ||
| 135 | |||
| 136 | id: yearCalendar | ||
| 137 | |||
| 138 | columns: 3 | ||
| 139 | columnSpacing: 16 | ||
| 140 | rowSpacing: 16 | ||
| 141 | |||
| 142 | Layout.alignment: Qt.AlignHCenter | ||
| 143 | Layout.fillWidth: false | ||
| 144 | |||
| 145 | property real angleRem: 0 | ||
| 146 | property real sensitivity: 1 / 120 | ||
| 147 | |||
| 148 | function scrollYear(event) { | ||
| 149 | angleRem += event.angleDelta.y; | ||
| 150 | const d = Math.round(angleRem * sensitivity); | ||
| 151 | yearCalendar.year -= d; | ||
| 152 | angleRem -= d / sensitivity; | ||
| 153 | } | ||
| 154 | |||
| 155 | Connections { | ||
| 156 | target: clockMouseArea | ||
| 157 | function onWheel(event) { yearCalendar.scrollYear(event); } | ||
| 158 | } | ||
| 159 | |||
| 160 | Repeater { | ||
| 161 | model: 12 | ||
| 162 | |||
| 163 | GridLayout { | ||
| 164 | columns: 2 | ||
| 165 | |||
| 166 | required property int index | ||
| 167 | property int month: index | ||
| 168 | |||
| 169 | id: monthCalendar | ||
| 170 | |||
| 171 | Layout.alignment: Qt.AlignTop | Qt.AlignRight | ||
| 172 | Layout.fillWidth: false | ||
| 173 | |||
| 174 | Text { | ||
| 175 | Layout.column: 1 | ||
| 176 | Layout.fillWidth: true | ||
| 177 | |||
| 178 | horizontalAlignment: Text.AlignHCenter | ||
| 179 | |||
| 180 | font.pointSize: 10 | ||
| 181 | font.family: "Fira Sans" | ||
| 182 | |||
| 183 | text: new Date(yearCalendar.year, monthCalendar.month, 1).toLocaleString(Qt.locale("en_DK"), "MMMM") | ||
| 184 | |||
| 185 | color: "#ffead3" | ||
| 186 | } | ||
| 187 | |||
| 188 | DayOfWeekRow { | ||
| 189 | locale: grid.locale | ||
| 190 | |||
| 191 | Layout.row: 1 | ||
| 192 | Layout.column: 1 | ||
| 193 | Layout.fillWidth: true | ||
| 194 | |||
| 195 | delegate: WrapperItem { | ||
| 196 | required property string shortName | ||
| 197 | |||
| 198 | width: dowLabel.contentWidth + 6 | ||
| 199 | |||
| 200 | Text { | ||
| 201 | id: dowLabel | ||
| 202 | |||
| 203 | anchors.fill: parent | ||
| 204 | |||
| 205 | font.pointSize: 10 | ||
| 206 | font.family: "Fira Sans" | ||
| 207 | |||
| 208 | text: parent.shortName | ||
| 209 | color: "#ffcc66" | ||
| 210 | |||
| 211 | horizontalAlignment: Text.AlignHCenter | ||
| 212 | verticalAlignment: Text.AlignVCenter | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | WeekNumberColumn { | ||
| 218 | month: grid.month | ||
| 219 | year: grid.year | ||
| 220 | locale: grid.locale | ||
| 221 | |||
| 222 | Layout.fillHeight: true | ||
| 223 | |||
| 224 | delegate: Text { | ||
| 225 | required property int weekNumber | ||
| 226 | |||
| 227 | opacity: { | ||
| 228 | const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7); | ||
| 229 | const dayOfWeek = simple.getDay(); | ||
| 230 | const isoWeekStart = simple; | ||
| 231 | |||
| 232 | isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1); | ||
| 233 | if (dayOfWeek > 4) { | ||
| 234 | isoWeekStart.setDate(isoWeekStart.getDate() + 7); | ||
| 235 | } | ||
| 236 | |||
| 237 | for (let i = 0; i < 7; i++) { | ||
| 238 | const dayInWeek = new Date(isoWeekStart); | ||
| 239 | dayInWeek.setDate(dayInWeek.getDate() + i); | ||
| 240 | if (dayInWeek.getMonth() == monthCalendar.month) | ||
| 241 | return 1; | ||
| 242 | } | ||
| 243 | |||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | font.pointSize: 10 | ||
| 248 | font.family: "Fira Sans" | ||
| 249 | font.features: { "tnum": 1 } | ||
| 250 | |||
| 251 | text: weekNumber | ||
| 252 | color: "#99ffdd" | ||
| 253 | |||
| 254 | horizontalAlignment: Text.AlignRight | ||
| 255 | verticalAlignment: Text.AlignVCenter | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | MonthGrid { | ||
| 260 | id: grid | ||
| 261 | |||
| 262 | year: yearCalendar.year | ||
| 263 | month: monthCalendar.month | ||
| 264 | locale: Qt.locale("en_DK") | ||
| 265 | |||
| 266 | Layout.fillWidth: true | ||
| 267 | Layout.fillHeight: true | ||
| 268 | |||
| 269 | delegate: Text { | ||
| 270 | required property var model | ||
| 271 | |||
| 272 | opacity: model.month === monthCalendar.month ? 1 : 0 | ||
| 273 | |||
| 274 | font.pointSize: 10 | ||
| 275 | font.family: "Fira Sans" | ||
| 276 | font.features: { "tnum": 1 } | ||
| 277 | |||
| 278 | property bool today: chrono.date.getFullYear() == model.year && chrono.date.getMonth() == model.month && chrono.date.getDate() == model.day | ||
| 279 | |||
| 280 | text: model.day | ||
| 281 | color: today ? "#ff6699" : "white" | ||
| 282 | |||
| 283 | horizontalAlignment: Text.AlignRight | ||
| 284 | verticalAlignment: Text.AlignVCenter | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } | ||
| 289 | } | ||
| 290 | } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | } | ||
| 295 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/KeyboardLayout.qml b/accounts/gkleen@skadhi/shell/quickshell/KeyboardLayout.qml new file mode 100644 index 00000000..46302e54 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/KeyboardLayout.qml | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import qs.Services | ||
| 4 | import Quickshell.Widgets | ||
| 5 | |||
| 6 | Item { | ||
| 7 | width: kbdLabel.contentWidth + 8 | ||
| 8 | height: parent.height | ||
| 9 | anchors.verticalCenter: parent.verticalCenter | ||
| 10 | |||
| 11 | WrapperMouseArea { | ||
| 12 | id: kbdMouseArea | ||
| 13 | |||
| 14 | anchors.fill: parent | ||
| 15 | |||
| 16 | hoverEnabled: true | ||
| 17 | cursorShape: Qt.PointingHandCursor | ||
| 18 | enabled: true | ||
| 19 | onClicked: { | ||
| 20 | NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": "Next" } } }, _ => {}) | ||
| 21 | } | ||
| 22 | onWheel: event => { | ||
| 23 | NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": event.angleDelta > 0 ? "Next" : "Prev" } } }, _ => {}) | ||
| 24 | } | ||
| 25 | |||
| 26 | Rectangle { | ||
| 27 | id: kbdWidget | ||
| 28 | |||
| 29 | property var keyboardAbbrev: { "English (programmer Dvorak)": "dvp", "English (US)": "us" } | ||
| 30 | |||
| 31 | anchors.fill: parent | ||
| 32 | color: { | ||
| 33 | if (kbdMouseArea.containsMouse) { | ||
| 34 | return "#33808080"; | ||
| 35 | } | ||
| 36 | return "transparent"; | ||
| 37 | } | ||
| 38 | |||
| 39 | Text { | ||
| 40 | id: kbdLabel | ||
| 41 | |||
| 42 | font.pointSize: 10 | ||
| 43 | font.family: "Fira Sans" | ||
| 44 | color: { | ||
| 45 | if (NiriService.keyboardLayouts?.current_idx === 0) | ||
| 46 | return "#555"; | ||
| 47 | return "white"; | ||
| 48 | } | ||
| 49 | anchors.centerIn: parent | ||
| 50 | |||
| 51 | text: { | ||
| 52 | const currentLayout = NiriService.keyboardLayouts?.names?.[NiriService.keyboardLayouts.current_idx]; | ||
| 53 | if (!currentLayout) | ||
| 54 | return ""; | ||
| 55 | return kbdWidget.keyboardAbbrev[currentLayout] ? kbdWidget.keyboardAbbrev[currentLayout] : currentLayout; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | PopupWindow { | ||
| 62 | id: tooltip | ||
| 63 | |||
| 64 | property bool nextVisible: kbdMouseArea.containsMouse || tooltipMouseArea.containsMouse | ||
| 65 | |||
| 66 | anchor { | ||
| 67 | item: kbdMouseArea | ||
| 68 | edges: Edges.Bottom | Edges.Left | ||
| 69 | } | ||
| 70 | visible: false | ||
| 71 | |||
| 72 | onNextVisibleChanged: hangTimer.restart() | ||
| 73 | |||
| 74 | Timer { | ||
| 75 | id: hangTimer | ||
| 76 | interval: 100 | ||
| 77 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 78 | } | ||
| 79 | |||
| 80 | implicitWidth: kbdTooltipText.contentWidth + 16 | ||
| 81 | implicitHeight: kbdTooltipText.contentHeight + 16 | ||
| 82 | color: "black" | ||
| 83 | |||
| 84 | WrapperMouseArea { | ||
| 85 | id: tooltipMouseArea | ||
| 86 | |||
| 87 | hoverEnabled: true | ||
| 88 | enabled: true | ||
| 89 | |||
| 90 | anchors.fill: parent | ||
| 91 | |||
| 92 | Item { | ||
| 93 | anchors.fill: parent | ||
| 94 | |||
| 95 | Text { | ||
| 96 | id: kbdTooltipText | ||
| 97 | |||
| 98 | anchors.centerIn: parent | ||
| 99 | |||
| 100 | font.pointSize: 10 | ||
| 101 | font.family: "Fira Sans" | ||
| 102 | color: "white" | ||
| 103 | |||
| 104 | text: { | ||
| 105 | const currentLayout = NiriService.keyboardLayouts?.names?.[NiriService.keyboardLayouts.current_idx]; | ||
| 106 | return currentLayout || ""; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/LidSwitchInhibitorWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/LidSwitchInhibitorWidget.qml new file mode 100644 index 00000000..8410dcda --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/LidSwitchInhibitorWidget.qml | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import qs.Services | ||
| 5 | |||
| 6 | Item { | ||
| 7 | id: root | ||
| 8 | |||
| 9 | width: icon.width + 8 | ||
| 10 | height: parent.height | ||
| 11 | anchors.verticalCenter: parent.verticalCenter | ||
| 12 | |||
| 13 | WrapperMouseArea { | ||
| 14 | id: widgetMouseArea | ||
| 15 | |||
| 16 | anchors.fill: parent | ||
| 17 | |||
| 18 | hoverEnabled: true | ||
| 19 | cursorShape: Qt.PointingHandCursor | ||
| 20 | |||
| 21 | onClicked: InhibitorState.lidSwitchInhibited = !InhibitorState.lidSwitchInhibited | ||
| 22 | |||
| 23 | Rectangle { | ||
| 24 | anchors.fill: parent | ||
| 25 | color: { | ||
| 26 | if (widgetMouseArea.containsMouse) { | ||
| 27 | return "#33808080"; | ||
| 28 | } | ||
| 29 | return "transparent"; | ||
| 30 | } | ||
| 31 | |||
| 32 | Item { | ||
| 33 | anchors.fill: parent | ||
| 34 | |||
| 35 | MaterialDesignIcon { | ||
| 36 | id: icon | ||
| 37 | |||
| 38 | implicitSize: 14 | ||
| 39 | anchors.centerIn: parent | ||
| 40 | |||
| 41 | icon: InhibitorState.lidSwitchInhibited ? "laptop-off" : "laptop" | ||
| 42 | color: InhibitorState.lidSwitchInhibited ? "#f28a21" : "#555" | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/LockSurface.qml b/accounts/gkleen@skadhi/shell/quickshell/LockSurface.qml new file mode 100644 index 00000000..f4f8f0cd --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/LockSurface.qml | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | import Quickshell.Widgets | ||
| 2 | import QtQuick.Effects | ||
| 3 | import QtQuick.Layouts | ||
| 4 | import QtQuick | ||
| 5 | import QtQuick.Controls | ||
| 6 | import QtQuick.Controls.Fusion | ||
| 7 | import qs.Services | ||
| 8 | import QtQml | ||
| 9 | |||
| 10 | Item { | ||
| 11 | id: lockSurface | ||
| 12 | |||
| 13 | property var screen | ||
| 14 | property list<var> messages: [] | ||
| 15 | property bool responseRequired: false | ||
| 16 | property bool responseVisible: false | ||
| 17 | property string currentText: "" | ||
| 18 | property bool authRunning: false | ||
| 19 | |||
| 20 | signal response(string responseText) | ||
| 21 | |||
| 22 | anchors.fill: parent | ||
| 23 | |||
| 24 | Item { | ||
| 25 | id: background | ||
| 26 | |||
| 27 | anchors.fill: parent | ||
| 28 | |||
| 29 | property Img current: one | ||
| 30 | property string source: selector.selected | ||
| 31 | |||
| 32 | WallpaperSelector { | ||
| 33 | id: selector | ||
| 34 | seed: lockSurface.screen?.name || "" | ||
| 35 | } | ||
| 36 | |||
| 37 | onSourceChanged: { | ||
| 38 | if (!source) | ||
| 39 | current = null; | ||
| 40 | else if (current === one) | ||
| 41 | two.update() | ||
| 42 | else | ||
| 43 | one.update() | ||
| 44 | } | ||
| 45 | |||
| 46 | Img { id: one } | ||
| 47 | Img { id: two } | ||
| 48 | |||
| 49 | component Img: Item { | ||
| 50 | id: img | ||
| 51 | |||
| 52 | property string source | ||
| 53 | |||
| 54 | function update() { | ||
| 55 | source = background.source || "" | ||
| 56 | } | ||
| 57 | |||
| 58 | anchors.fill: parent | ||
| 59 | |||
| 60 | Image { | ||
| 61 | id: imageSource | ||
| 62 | |||
| 63 | source: img.source | ||
| 64 | sourceSize: Qt.size(parent.width, parent.height) | ||
| 65 | fillMode: Image.PreserveAspectCrop | ||
| 66 | smooth: true | ||
| 67 | visible: false | ||
| 68 | asynchronous: true | ||
| 69 | cache: false | ||
| 70 | |||
| 71 | onStatusChanged: { | ||
| 72 | if (status === Image.Ready) { | ||
| 73 | background.current = img | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | MultiEffect { | ||
| 79 | id: imageEffect | ||
| 80 | |||
| 81 | source: imageSource | ||
| 82 | anchors.fill: parent | ||
| 83 | blurEnabled: true | ||
| 84 | blur: 1 | ||
| 85 | blurMax: 64 | ||
| 86 | blurMultiplier: 2 | ||
| 87 | |||
| 88 | opacity: 0 | ||
| 89 | |||
| 90 | states: State { | ||
| 91 | name: "visible" | ||
| 92 | when: background.current === img | ||
| 93 | |||
| 94 | PropertyChanges { | ||
| 95 | imageEffect.opacity: 1 | ||
| 96 | } | ||
| 97 | StateChangeScript { | ||
| 98 | name: "unloadOther" | ||
| 99 | script: { | ||
| 100 | if (img === one) | ||
| 101 | two.source = "" | ||
| 102 | if (img === two) | ||
| 103 | one.source = "" | ||
| 104 | } | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | transitions: Transition { | ||
| 109 | SequentialAnimation { | ||
| 110 | NumberAnimation { | ||
| 111 | target: imageEffect | ||
| 112 | properties: "opacity" | ||
| 113 | duration: { | ||
| 114 | if (img === one && two.source == "" || img === two && one.source == "") | ||
| 115 | return 0; | ||
| 116 | return 5000; | ||
| 117 | } | ||
| 118 | easing.type: Easing.OutCubic | ||
| 119 | } | ||
| 120 | ScriptAction { | ||
| 121 | scriptName: "unloadOther" | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | Item { | ||
| 130 | anchors { | ||
| 131 | top: lockSurface.top | ||
| 132 | left: lockSurface.left | ||
| 133 | right: lockSurface.right | ||
| 134 | } | ||
| 135 | |||
| 136 | implicitWidth: lockSurface.width | ||
| 137 | implicitHeight: 21 | ||
| 138 | |||
| 139 | Rectangle { | ||
| 140 | anchors.fill: parent | ||
| 141 | color: Qt.rgba(0, 0, 0, 0.75) | ||
| 142 | } | ||
| 143 | |||
| 144 | Clock { | ||
| 145 | anchors.centerIn: parent | ||
| 146 | calendarPopup: false | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | WrapperRectangle { | ||
| 151 | id: unlockUi | ||
| 152 | |||
| 153 | Keys.onPressed: event => { | ||
| 154 | if (!lockSurface.authRunning) { | ||
| 155 | event.accepted = true; | ||
| 156 | lockSurface.authRunning = true; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | focus: !passwordBox.visible | ||
| 160 | |||
| 161 | visible: lockSurface.authRunning | ||
| 162 | |||
| 163 | color: Qt.rgba(0, 0, 0, 0.75) | ||
| 164 | margin: 8 | ||
| 165 | |||
| 166 | anchors.centerIn: parent | ||
| 167 | |||
| 168 | ColumnLayout { | ||
| 169 | spacing: 4 | ||
| 170 | |||
| 171 | BusyIndicator { | ||
| 172 | visible: running | ||
| 173 | running: !Array.from(lockSurface.messages).length && !lockSurface.responseRequired | ||
| 174 | } | ||
| 175 | |||
| 176 | Repeater { | ||
| 177 | model: lockSurface.messages | ||
| 178 | |||
| 179 | Text { | ||
| 180 | required property var modelData | ||
| 181 | |||
| 182 | font.pointSize: 10 | ||
| 183 | font.family: "Fira Sans" | ||
| 184 | color: modelData.error ? "#f28a21" : "#ffffff" | ||
| 185 | |||
| 186 | text: String(modelData.text).trim() | ||
| 187 | |||
| 188 | Layout.fillWidth: true | ||
| 189 | horizontalAlignment: Text.AlignHCenter | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | TextField { | ||
| 194 | id: passwordBox | ||
| 195 | |||
| 196 | visible: lockSurface.responseRequired | ||
| 197 | echoMode: lockSurface.responseVisible ? TextInput.Normal : TextInput.Password | ||
| 198 | inputMethodHints: Qt.ImhSensitiveData | ||
| 199 | |||
| 200 | onTextChanged: lockSurface.currentText = passwordBox.text | ||
| 201 | onAccepted: { | ||
| 202 | passwordBox.readOnly = true; | ||
| 203 | lockSurface.response(lockSurface.currentText); | ||
| 204 | } | ||
| 205 | |||
| 206 | Connections { | ||
| 207 | target: lockSurface | ||
| 208 | function onCurrentTextChanged() { | ||
| 209 | passwordBox.text = lockSurface.currentText | ||
| 210 | } | ||
| 211 | } | ||
| 212 | Connections { | ||
| 213 | target: lockSurface | ||
| 214 | function onResponseRequiredChanged() { | ||
| 215 | if (lockSurface.responseRequired) | ||
| 216 | passwordBox.readOnly = false; | ||
| 217 | passwordBox.focus = true; | ||
| 218 | passwordBox.selectAll(); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | Layout.topMargin: 4 | ||
| 223 | Layout.fillWidth: true | ||
| 224 | } | ||
| 225 | } | ||
| 226 | } | ||
| 227 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Lockscreen.qml b/accounts/gkleen@skadhi/shell/quickshell/Lockscreen.qml new file mode 100644 index 00000000..0b4a68b2 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Lockscreen.qml | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | import Quickshell | ||
| 2 | import Quickshell.Wayland | ||
| 3 | import Quickshell.Io | ||
| 4 | import Quickshell.Services.Pam | ||
| 5 | import Quickshell.Services.Mpris | ||
| 6 | import Custom as Custom | ||
| 7 | import qs.Services | ||
| 8 | import QtQml | ||
| 9 | |||
| 10 | Scope { | ||
| 11 | id: lockscreen | ||
| 12 | |||
| 13 | property string currentText: "" | ||
| 14 | |||
| 15 | PamContext { | ||
| 16 | id: pam | ||
| 17 | |||
| 18 | property list<var> messages: [] | ||
| 19 | |||
| 20 | config: "quickshell" | ||
| 21 | onCompleted: result => { | ||
| 22 | if (result === PamResult.Success) { | ||
| 23 | lock.locked = false; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | onPamMessage: { | ||
| 27 | messages = Array.from(messages).concat([{ "text": pam.message, "error": pam.messageIsError }]) | ||
| 28 | } | ||
| 29 | onActiveChanged: { | ||
| 30 | messages = []; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | Connections { | ||
| 35 | target: Custom.Systemd | ||
| 36 | function onSleep(before: bool) { | ||
| 37 | console.log(`received prepare for sleep ${before}`); | ||
| 38 | if (before) { | ||
| 39 | lock.locked = true; | ||
| 40 | if (pam.active) | ||
| 41 | pam.abort(); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | function onLock() { lock.locked = true; } | ||
| 45 | function onUnlock() { lock.locked = false; } | ||
| 46 | } | ||
| 47 | |||
| 48 | IdleMonitor { | ||
| 49 | id: idleMonitor | ||
| 50 | enabled: !lock.secure && !InhibitorState.lockscreenInhibited | ||
| 51 | timeout: 600 | ||
| 52 | respectInhibitors: true | ||
| 53 | |||
| 54 | onIsIdleChanged: { | ||
| 55 | if (idleMonitor.isIdle) | ||
| 56 | lock.locked = true; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | Custom.SystemdInhibitor { | ||
| 61 | enabled: !lock.secure | ||
| 62 | |||
| 63 | what: Custom.SystemdInhibitorParams.Sleep | ||
| 64 | who: "quickshell" | ||
| 65 | why: "Lock session" | ||
| 66 | mode: Custom.SystemdInhibitorParams.Delay | ||
| 67 | } | ||
| 68 | |||
| 69 | Binding { | ||
| 70 | target: NotificationManager | ||
| 71 | property: "lockscreenActive" | ||
| 72 | value: lock.locked | ||
| 73 | } | ||
| 74 | |||
| 75 | WlSessionLock { | ||
| 76 | id: lock | ||
| 77 | |||
| 78 | onLockStateChanged: { | ||
| 79 | if (!locked && pam.active) | ||
| 80 | pam.abort(); | ||
| 81 | |||
| 82 | if (locked) { | ||
| 83 | NiriService.sendCommand({ "Action": { "PowerOffMonitors": {} } }, _ => {}); | ||
| 84 | Custom.KeePassXC.lockAllDatabases(); | ||
| 85 | Array.from(MprisProxy.players).forEach(player => { | ||
| 86 | if (player.canPause && player.isPlaying) | ||
| 87 | player.pause(); | ||
| 88 | }); | ||
| 89 | // Custom.Systemd.stopUserUnit("gpg-agent.service", "replace"); | ||
| 90 | GpgAgent.reloadAgent(); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | Component.onCompleted: { (_ => {})(MprisProxy.players); } | ||
| 94 | |||
| 95 | onSecureStateChanged: Custom.Systemd.lockedHint = lock.secure | ||
| 96 | |||
| 97 | WlSessionLockSurface { | ||
| 98 | id: lockSurface | ||
| 99 | |||
| 100 | color: "black" | ||
| 101 | |||
| 102 | LockSurface { | ||
| 103 | id: surfaceContent | ||
| 104 | |||
| 105 | onResponse: responseText => pam.respond(responseText) | ||
| 106 | onAuthRunningChanged: { | ||
| 107 | if (authRunning) | ||
| 108 | pam.start(); | ||
| 109 | } | ||
| 110 | Connections { | ||
| 111 | target: pam | ||
| 112 | function onMessagesChanged() { surfaceContent.messages = pam.messages; } | ||
| 113 | function onResponseRequiredChanged() { surfaceContent.responseRequired = pam.responseRequired; } | ||
| 114 | function onActiveChanged() { surfaceContent.authRunning = pam.active; } | ||
| 115 | } | ||
| 116 | onCurrentTextChanged: lockscreen.currentText = currentText | ||
| 117 | Connections { | ||
| 118 | target: lockscreen | ||
| 119 | function onCurrentTextChanged() { surfaceContent.currentText = lockscreen.currentText; } | ||
| 120 | } | ||
| 121 | Connections { | ||
| 122 | target: lockSurface | ||
| 123 | function onScreenChanged() { surfaceContent.screen = lockSurface.screen; } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/LockscreenInhibitorWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/LockscreenInhibitorWidget.qml new file mode 100644 index 00000000..1cbf3f16 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/LockscreenInhibitorWidget.qml | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import qs.Services | ||
| 5 | |||
| 6 | Item { | ||
| 7 | id: root | ||
| 8 | |||
| 9 | width: icon.width + 8 | ||
| 10 | height: parent.height | ||
| 11 | anchors.verticalCenter: parent.verticalCenter | ||
| 12 | |||
| 13 | WrapperMouseArea { | ||
| 14 | id: widgetMouseArea | ||
| 15 | |||
| 16 | anchors.fill: parent | ||
| 17 | |||
| 18 | // enabled: InhibitorState.lockscreenInhibited || !InhibitorState.waylandIdleInhibited | ||
| 19 | hoverEnabled: true | ||
| 20 | cursorShape: widgetMouseArea.enabled ? Qt.PointingHandCursor : undefined | ||
| 21 | |||
| 22 | onClicked: InhibitorState.lockscreenInhibited = !InhibitorState.lockscreenInhibited | ||
| 23 | |||
| 24 | Rectangle { | ||
| 25 | anchors.fill: parent | ||
| 26 | color: { | ||
| 27 | if (widgetMouseArea.containsMouse) { | ||
| 28 | return "#33808080"; | ||
| 29 | } | ||
| 30 | return "transparent"; | ||
| 31 | } | ||
| 32 | |||
| 33 | Item { | ||
| 34 | anchors.fill: parent | ||
| 35 | |||
| 36 | MaterialDesignIcon { | ||
| 37 | id: icon | ||
| 38 | |||
| 39 | implicitSize: 14 | ||
| 40 | anchors.centerIn: parent | ||
| 41 | |||
| 42 | icon: InhibitorState.lockscreenInhibited || InhibitorState.waylandIdleInhibited ? "lock-off" : "lock" | ||
| 43 | color: InhibitorState.lockscreenInhibited ? "#f28a21" : "#555" | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/MaterialDesignIcon.qml b/accounts/gkleen@skadhi/shell/quickshell/MaterialDesignIcon.qml new file mode 100644 index 00000000..155a009e --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/MaterialDesignIcon.qml | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Effects | ||
| 3 | |||
| 4 | Item { | ||
| 5 | id: root | ||
| 6 | |||
| 7 | required property string icon | ||
| 8 | property color color: "white" | ||
| 9 | |||
| 10 | property real implicitSize: 0 | ||
| 11 | |||
| 12 | readonly property real actualSize: Math.min(root.width, root.height) | ||
| 13 | |||
| 14 | implicitWidth: root.implicitSize | ||
| 15 | implicitHeight: root.implicitSize | ||
| 16 | |||
| 17 | Image { | ||
| 18 | id: sourceImage | ||
| 19 | source: "file://" + @mdi@ + "/svg/" + root.icon + ".svg" | ||
| 20 | anchors.fill: parent | ||
| 21 | fillMode: Image.PreserveAspectFit | ||
| 22 | |||
| 23 | sourceSize.width: root.actualSize | ||
| 24 | sourceSize.height: root.actualSize | ||
| 25 | |||
| 26 | layer.enabled: true | ||
| 27 | layer.effect: MultiEffect { | ||
| 28 | id: effect | ||
| 29 | |||
| 30 | brightness: 1 | ||
| 31 | colorization: 1 | ||
| 32 | colorizationColor: root.color | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/NiriIdle.qml b/accounts/gkleen@skadhi/shell/quickshell/NiriIdle.qml new file mode 100644 index 00000000..beff205c --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/NiriIdle.qml | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | import QtQml | ||
| 2 | import Quickshell | ||
| 3 | import Quickshell.Wayland | ||
| 4 | import qs.Services | ||
| 5 | import Custom as Custom | ||
| 6 | |||
| 7 | Scope { | ||
| 8 | IdleMonitor { | ||
| 9 | id: idleMonitor30 | ||
| 10 | timeout: 30 | ||
| 11 | |||
| 12 | onIsIdleChanged: Custom.Systemd.setIdleHint(idleMonitor30.isIdle) | ||
| 13 | } | ||
| 14 | IdleMonitor { | ||
| 15 | id: idleMonitor540 | ||
| 16 | timeout: 540 | ||
| 17 | |||
| 18 | onIsIdleChanged: { | ||
| 19 | if (idleMonitor540.isIdle) | ||
| 20 | NiriService.sendCommand({ "Action": { "PowerOffMonitors": {} } }, _ => {}); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | Connections { | ||
| 24 | target: Custom.Systemd | ||
| 25 | function onSleep(before: bool) { | ||
| 26 | if (!before) | ||
| 27 | NiriService.sendCommand({ "Action": { "PowerOnMonitors": {} } }, _ => {}); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/NotificationDisplay.qml b/accounts/gkleen@skadhi/shell/quickshell/NotificationDisplay.qml new file mode 100644 index 00000000..cc0e49b1 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/NotificationDisplay.qml | |||
| @@ -0,0 +1,340 @@ | |||
| 1 | import QtQml | ||
| 2 | import QtQml.Models | ||
| 3 | import QtQuick | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Widgets | ||
| 6 | import Quickshell.Wayland | ||
| 7 | import qs.Services | ||
| 8 | import QtQuick.Layouts | ||
| 9 | import Quickshell.Services.Notifications | ||
| 10 | |||
| 11 | Scope { | ||
| 12 | id: root | ||
| 13 | |||
| 14 | property var activeScreen: Array.from(Quickshell.screens).find(screen => screen.name === Array.from(NiriService.workspaces).find(ws => ws.is_focused)?.output) ?? null | ||
| 15 | |||
| 16 | Instantiator { | ||
| 17 | id: notifsRepeater | ||
| 18 | |||
| 19 | model: ScriptModel { | ||
| 20 | values: NotificationManager.groups | ||
| 21 | } | ||
| 22 | |||
| 23 | delegate: PanelWindow { | ||
| 24 | id: notifWindow | ||
| 25 | |||
| 26 | visible: NotificationManager.active | ||
| 27 | |||
| 28 | screen: root.activeScreen | ||
| 29 | |||
| 30 | WlrLayershell.namespace: "notifications" | ||
| 31 | |||
| 32 | required property var modelData | ||
| 33 | required property var index | ||
| 34 | |||
| 35 | property int activeIx: modelData.length - 1 | ||
| 36 | onModelDataChanged: { | ||
| 37 | notifWindow.activeIx = modelData.length - 1; | ||
| 38 | } | ||
| 39 | |||
| 40 | property color textColor: { | ||
| 41 | if (notifWindow.modelData?.[notifWindow.activeIx]?.urgency == NotificationUrgency.Low) | ||
| 42 | return "#ff999999"; | ||
| 43 | return "white"; | ||
| 44 | } | ||
| 45 | property color backgroundColor: { | ||
| 46 | if (notifWindow.modelData?.[notifWindow.activeIx]?.urgency == NotificationUrgency.Critical) | ||
| 47 | return "#dd900000"; | ||
| 48 | return "black"; | ||
| 49 | } | ||
| 50 | |||
| 51 | anchors { | ||
| 52 | right: true | ||
| 53 | top: true | ||
| 54 | } | ||
| 55 | |||
| 56 | readonly property real spaceAbove: { | ||
| 57 | var res = 0; | ||
| 58 | for (let i = 0; i < notifWindow.index; i++) { | ||
| 59 | (_ => {})(notifsRepeater.objectAt(i).modelData); | ||
| 60 | res += notifsRepeater.objectAt(i).height + 8; | ||
| 61 | } | ||
| 62 | return res; | ||
| 63 | } | ||
| 64 | |||
| 65 | margins { | ||
| 66 | right: 26 + 8 | ||
| 67 | top: 8 + spaceAbove | ||
| 68 | } | ||
| 69 | |||
| 70 | color: "transparent" | ||
| 71 | |||
| 72 | implicitHeight: Math.max(notifCount.visible ? notifCount.contentHeight : 0, notifSummary.contentHeight) + (notifBody.visible ? 8 + notifBody.contentHeight : 0) + (notifActions.visible ? 8 + notifActions.height : 0) + (notifTime.visible ? 8 + notifTime.contentHeight : 0) + 16 | ||
| 73 | implicitWidth: 400 | ||
| 74 | |||
| 75 | WrapperMouseArea { | ||
| 76 | enabled: true | ||
| 77 | |||
| 78 | anchors.fill: parent | ||
| 79 | |||
| 80 | cursorShape: Qt.PointingHandCursor | ||
| 81 | |||
| 82 | onClicked: { | ||
| 83 | for (const notif of notifWindow.modelData) | ||
| 84 | notif.dismiss(); | ||
| 85 | } | ||
| 86 | |||
| 87 | property real angleRem: 0 | ||
| 88 | property real sensitivity: 1 / 120 | ||
| 89 | onWheel: event => { | ||
| 90 | angleRem += event.angleDelta.y; | ||
| 91 | const d = Math.round(angleRem * sensitivity); | ||
| 92 | angleRem -= d / sensitivity; | ||
| 93 | notifWindow.activeIx = ((notifWindow.modelData?.length ?? 1) + notifWindow.activeIx - d) % (notifWindow.modelData?.length ?? 1); | ||
| 94 | } | ||
| 95 | |||
| 96 | Rectangle { | ||
| 97 | color: notifWindow.backgroundColor | ||
| 98 | anchors.fill: parent | ||
| 99 | border { | ||
| 100 | color: Qt.hsla(195/360, 1, 0.45, 1) | ||
| 101 | width: 2 | ||
| 102 | } | ||
| 103 | |||
| 104 | GridLayout { | ||
| 105 | id: notifLayout | ||
| 106 | |||
| 107 | width: 400 - 16 | ||
| 108 | anchors.fill: parent | ||
| 109 | anchors.margins: 8 | ||
| 110 | columnSpacing: 8 | ||
| 111 | rowSpacing: 8 | ||
| 112 | |||
| 113 | columns: notifImage.visible ? 3 : 2 | ||
| 114 | rows: { | ||
| 115 | var res = 1; | ||
| 116 | if (notifBody.visible) | ||
| 117 | res += 1; | ||
| 118 | if (notifActions.visible) | ||
| 119 | res += 1; | ||
| 120 | if (notifTime.visible) | ||
| 121 | res += 1; | ||
| 122 | return res; | ||
| 123 | } | ||
| 124 | |||
| 125 | Text { | ||
| 126 | id: notifCount | ||
| 127 | |||
| 128 | visible: notifWindow.modelData?.length > 1 ?? false | ||
| 129 | text: `${notifWindow.activeIx + 1}/${notifWindow.modelData?.length ?? ""}` | ||
| 130 | |||
| 131 | font.pointSize: 10 | ||
| 132 | font.family: "Fira Sans" | ||
| 133 | font.bold: true | ||
| 134 | font.features: { "tnum": 1 } | ||
| 135 | color: notifWindow.textColor | ||
| 136 | maximumLineCount: 1 | ||
| 137 | |||
| 138 | Layout.fillWidth: false | ||
| 139 | Layout.row: 0 | ||
| 140 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 141 | } | ||
| 142 | |||
| 143 | Text { | ||
| 144 | id: notifSummary | ||
| 145 | |||
| 146 | text: notifWindow.modelData?.[notifWindow.activeIx]?.summary ?? "" | ||
| 147 | |||
| 148 | font.pointSize: 10 | ||
| 149 | font.family: "Fira Sans" | ||
| 150 | font.italic: true | ||
| 151 | color: notifWindow.textColor | ||
| 152 | maximumLineCount: 1 | ||
| 153 | elide: Text.ElideRight | ||
| 154 | |||
| 155 | Layout.fillWidth: true | ||
| 156 | Layout.row: 0 | ||
| 157 | Layout.column: (notifCount.visible ? 1 : 0) + (notifImage.visible ? 1 : 0) | ||
| 158 | Layout.columnSpan: notifCount.visible ? 1 : 2 | ||
| 159 | } | ||
| 160 | |||
| 161 | Image { | ||
| 162 | id: notifImage | ||
| 163 | |||
| 164 | visible: (notifWindow.modelData?.[notifWindow.activeIx]?.image || notifWindow.modelData?.[notifWindow.activeIx]?.appIcon) ?? false | ||
| 165 | |||
| 166 | onStatusChanged: { | ||
| 167 | if (notifImage.status == Image.Error) | ||
| 168 | notifImage.visible = false; | ||
| 169 | } | ||
| 170 | |||
| 171 | source: (notifWindow.modelData?.[notifWindow.activeIx]?.image || notifWindow.modelData?.[notifWindow.activeIx]?.appIcon) ?? "" | ||
| 172 | fillMode: Image.PreserveAspectFit | ||
| 173 | asynchronous: true | ||
| 174 | smooth: true | ||
| 175 | mipmap: true | ||
| 176 | |||
| 177 | Layout.maximumWidth: 50 | ||
| 178 | Layout.column: 0 | ||
| 179 | Layout.row: 0 | ||
| 180 | Layout.fillHeight: true | ||
| 181 | Layout.rowSpan: 1 + (notifBody.visible ? 1 : 0) + (notifTime.visible ? 1 : 0) | ||
| 182 | } | ||
| 183 | |||
| 184 | Text { | ||
| 185 | id: notifBody | ||
| 186 | |||
| 187 | visible: notifWindow.modelData?.[notifWindow.activeIx]?.body ?? false | ||
| 188 | text: notifWindow.modelData?.[notifWindow.activeIx]?.body ?? "" | ||
| 189 | textFormat: Text.RichText | ||
| 190 | wrapMode: Text.Wrap | ||
| 191 | |||
| 192 | font.pointSize: 10 | ||
| 193 | font.family: "Fira Sans" | ||
| 194 | color: notifWindow.textColor | ||
| 195 | |||
| 196 | Layout.fillWidth: true | ||
| 197 | Layout.row: 1 | ||
| 198 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 199 | Layout.columnSpan: notifCount.visible ? 2 : 1 | ||
| 200 | } | ||
| 201 | |||
| 202 | Text { | ||
| 203 | id: notifTime | ||
| 204 | |||
| 205 | Connections { | ||
| 206 | target: NotificationManager.clock | ||
| 207 | function onDateChanged() { | ||
| 208 | notifTime.text = NotificationManager.formatTime(notifWindow.modelData?.[notifWindow.activeIx]?.receivedTime); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | visible: notifTime.text && notifTime.text !== "now" | ||
| 213 | text: NotificationManager.formatTime(notifWindow.modelData?.[notifWindow.activeIx]?.receivedTime) | ||
| 214 | |||
| 215 | font.pointSize: 8 | ||
| 216 | font.family: "Fira Sans" | ||
| 217 | font.italic: true | ||
| 218 | color: "#555" | ||
| 219 | maximumLineCount: 1 | ||
| 220 | horizontalAlignment: Text.AlignRight | ||
| 221 | |||
| 222 | Layout.fillWidth: true | ||
| 223 | Layout.row: notifBody.visible ? 2 : 1 | ||
| 224 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 225 | Layout.columnSpan: 2 | ||
| 226 | } | ||
| 227 | |||
| 228 | RowLayout { | ||
| 229 | id: notifActions | ||
| 230 | |||
| 231 | visible: notifWindow.modelData?.[notifWindow.activeIx]?.actions.length > 0 ?? false | ||
| 232 | |||
| 233 | spacing: 8 | ||
| 234 | uniformCellSizes: true | ||
| 235 | |||
| 236 | width: 400 - 16 | ||
| 237 | Layout.row: 1 + (notifBody.visible ? 1 : 0) + (notifTime.visible ? 1 : 0) | ||
| 238 | Layout.column: 0 | ||
| 239 | Layout.columnSpan: 2 + (notifImage.visible ? 1 : 0) | ||
| 240 | |||
| 241 | Repeater { | ||
| 242 | model: ScriptModel { | ||
| 243 | values: notifWindow.modelData?.[notifWindow.activeIx]?.actions | ||
| 244 | } | ||
| 245 | |||
| 246 | delegate: WrapperMouseArea { | ||
| 247 | id: actionMouseArea | ||
| 248 | |||
| 249 | required property var modelData | ||
| 250 | |||
| 251 | height: actionLabelWrapper.implicitHeight | ||
| 252 | Layout.fillWidth: true | ||
| 253 | Layout.horizontalStretchFactor: 1 | ||
| 254 | |||
| 255 | hoverEnabled: true | ||
| 256 | cursorShape: Qt.PointingHandCursor | ||
| 257 | |||
| 258 | onClicked: actionMouseArea.modelData?.invoke() | ||
| 259 | |||
| 260 | Rectangle { | ||
| 261 | anchors.fill: parent | ||
| 262 | |||
| 263 | color: actionMouseArea.containsMouse ? "#20ffffff" : "transparent" | ||
| 264 | |||
| 265 | border { | ||
| 266 | width: 2 | ||
| 267 | color: "#20ffffff" | ||
| 268 | } | ||
| 269 | |||
| 270 | WrapperItem { | ||
| 271 | id: actionLabelWrapper | ||
| 272 | |||
| 273 | margin: 8 | ||
| 274 | anchors.centerIn: parent | ||
| 275 | |||
| 276 | RowLayout { | ||
| 277 | id: actionLabelLayout | ||
| 278 | |||
| 279 | spacing: 8 | ||
| 280 | |||
| 281 | IconImage { | ||
| 282 | id: actionIcon | ||
| 283 | |||
| 284 | visible: notifWindow.modelData?.[notifWindow.activeIx]?.hasActionIcons | ||
| 285 | |||
| 286 | onStatusChanged: { | ||
| 287 | if (actionIcon.status == Image.Error) | ||
| 288 | actionIcon.visible = false; | ||
| 289 | } | ||
| 290 | |||
| 291 | implicitSize: 16 | ||
| 292 | source: { | ||
| 293 | if (!actionIcon.visible) | ||
| 294 | return ""; | ||
| 295 | |||
| 296 | let icon = actionMouseArea.modelData?.identifier ?? "" | ||
| 297 | if (icon.includes("?path=")) { | ||
| 298 | const split = icon.split("?path=") | ||
| 299 | if (split.length !== 2) | ||
| 300 | return icon | ||
| 301 | const name = split[0] | ||
| 302 | const path = split[1] | ||
| 303 | const fileName = name.substring( | ||
| 304 | name.lastIndexOf("/") + 1) | ||
| 305 | return `file://${path}/${fileName}` | ||
| 306 | } | ||
| 307 | return icon | ||
| 308 | } | ||
| 309 | asynchronous: true | ||
| 310 | smooth: true | ||
| 311 | mipmap: true | ||
| 312 | |||
| 313 | Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter | ||
| 314 | } | ||
| 315 | |||
| 316 | Text { | ||
| 317 | id: actionLabel | ||
| 318 | |||
| 319 | visible: actionMouseArea.modelData?.text ?? false | ||
| 320 | |||
| 321 | text: actionMouseArea.modelData?.text ?? "" | ||
| 322 | |||
| 323 | font.pointSize: 10 | ||
| 324 | font.family: "Fira Sans" | ||
| 325 | color: notifWindow.textColor | ||
| 326 | maximumLineCount: 1 | ||
| 327 | elide: Text.ElideRight | ||
| 328 | } | ||
| 329 | } | ||
| 330 | } | ||
| 331 | } | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | } | ||
| 340 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml new file mode 100644 index 00000000..80cbba19 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml | |||
| @@ -0,0 +1,266 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import qs.Services | ||
| 5 | import QtQuick.Controls | ||
| 6 | import QtQuick.Layouts | ||
| 7 | import QtQuick.Shapes | ||
| 8 | |||
| 9 | Item { | ||
| 10 | id: root | ||
| 11 | |||
| 12 | width: icon.width + 8 | ||
| 13 | height: parent.height | ||
| 14 | anchors.verticalCenter: parent.verticalCenter | ||
| 15 | |||
| 16 | WrapperMouseArea { | ||
| 17 | id: widgetMouseArea | ||
| 18 | |||
| 19 | anchors.fill: parent | ||
| 20 | |||
| 21 | hoverEnabled: true | ||
| 22 | cursorShape: Qt.PointingHandCursor | ||
| 23 | |||
| 24 | onClicked: NotificationManager.displayInhibited = !NotificationManager.displayInhibited | ||
| 25 | |||
| 26 | Rectangle { | ||
| 27 | anchors.fill: parent | ||
| 28 | color: { | ||
| 29 | if (widgetMouseArea.containsMouse) { | ||
| 30 | return "#33808080"; | ||
| 31 | } | ||
| 32 | return "transparent"; | ||
| 33 | } | ||
| 34 | |||
| 35 | Item { | ||
| 36 | anchors.fill: parent | ||
| 37 | |||
| 38 | MaterialDesignIcon { | ||
| 39 | id: icon | ||
| 40 | |||
| 41 | implicitSize: 14 | ||
| 42 | anchors.centerIn: parent | ||
| 43 | |||
| 44 | icon: NotificationManager.active ? "message" : "message-off" | ||
| 45 | color: { | ||
| 46 | if (!NotificationManager.active && !NotificationManager.displayInhibited) | ||
| 47 | return "#f28a21"; | ||
| 48 | if (NotificationManager.displayInhibited) | ||
| 49 | return "white"; | ||
| 50 | return "#555"; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | Loader { | ||
| 58 | id: tooltipLoader | ||
| 59 | |||
| 60 | active: false | ||
| 61 | |||
| 62 | Connections { | ||
| 63 | target: widgetMouseArea | ||
| 64 | function onContainsMouseChanged() { | ||
| 65 | if (widgetMouseArea.containsMouse) | ||
| 66 | tooltipLoader.active = true; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | sourceComponent: PopupWindow { | ||
| 71 | id: tooltip | ||
| 72 | |||
| 73 | property bool nextVisible: NotificationManager.active && NotificationManager.history.length > 0 && (widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse) | ||
| 74 | |||
| 75 | anchor { | ||
| 76 | item: widgetMouseArea | ||
| 77 | edges: Edges.Bottom | Edges.Left | ||
| 78 | } | ||
| 79 | visible: false | ||
| 80 | |||
| 81 | onNextVisibleChanged: hangTimer.restart() | ||
| 82 | |||
| 83 | Timer { | ||
| 84 | id: hangTimer | ||
| 85 | interval: tooltip.visible ? 100 : 500 | ||
| 86 | onTriggered: { | ||
| 87 | tooltip.visible = tooltip.nextVisible; | ||
| 88 | if (!tooltip.visible) | ||
| 89 | tooltipLoader.active = false; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | implicitWidth: 400 | ||
| 94 | implicitHeight: Math.min(tooltip.screen.height * 0.66, Math.max(100, scroll.contentHeight + 16)) | ||
| 95 | color: "black" | ||
| 96 | |||
| 97 | WrapperMouseArea { | ||
| 98 | id: tooltipMouseArea | ||
| 99 | |||
| 100 | hoverEnabled: true | ||
| 101 | enabled: true | ||
| 102 | |||
| 103 | anchors.fill: parent | ||
| 104 | |||
| 105 | WrapperItem { | ||
| 106 | margin: 8 | ||
| 107 | |||
| 108 | ScrollView { | ||
| 109 | id: scroll | ||
| 110 | |||
| 111 | contentWidth: availableWidth | ||
| 112 | // ScrollBar.vertical.policy: ScrollBar.AlwaysOn | ||
| 113 | |||
| 114 | ColumnLayout { | ||
| 115 | id: historyLayout | ||
| 116 | anchors { | ||
| 117 | left: parent.left | ||
| 118 | right: parent.right | ||
| 119 | } | ||
| 120 | |||
| 121 | spacing: 8 | ||
| 122 | |||
| 123 | Repeater { | ||
| 124 | model: ScriptModel { | ||
| 125 | values: [...NotificationManager.history].reverse().map(o => o.notification) | ||
| 126 | } | ||
| 127 | |||
| 128 | delegate: GridLayout { | ||
| 129 | id: notif | ||
| 130 | |||
| 131 | Layout.fillWidth: true | ||
| 132 | Layout.preferredHeight: notifSummary.contentHeight + (notifBody.visible ? notifBody.contentHeight + 8 : 0) + (notifSep.visible ? notifSep.height + 8 : 0) + notifTime.contentHeight + 8 | ||
| 133 | |||
| 134 | required property var modelData | ||
| 135 | required property int index | ||
| 136 | |||
| 137 | columnSpacing: 8 | ||
| 138 | rowSpacing: 8 | ||
| 139 | |||
| 140 | columns: notifImage.visible ? 2 : 1 | ||
| 141 | rows: { | ||
| 142 | var res = 2; | ||
| 143 | if (notifBody.visible) | ||
| 144 | res += 1; | ||
| 145 | if (notifSep.visible) | ||
| 146 | res += 1; | ||
| 147 | return res; | ||
| 148 | } | ||
| 149 | |||
| 150 | Shape { | ||
| 151 | id: notifSep | ||
| 152 | |||
| 153 | visible: notif.index != 0 | ||
| 154 | |||
| 155 | height: 2 | ||
| 156 | width: 400 - 32 | ||
| 157 | |||
| 158 | ShapePath { | ||
| 159 | strokeWidth: 2 | ||
| 160 | strokeColor: "#20ffffff" | ||
| 161 | startX: 0; startY: 0; | ||
| 162 | PathLine { x: 400 - 32; y: 0; } | ||
| 163 | } | ||
| 164 | |||
| 165 | Layout.row: 0 | ||
| 166 | Layout.column: 0 | ||
| 167 | Layout.columnSpan: notifImage.visible ? 2 : 1 | ||
| 168 | Layout.alignment: Qt.AlignHCenter | ||
| 169 | } | ||
| 170 | |||
| 171 | Text { | ||
| 172 | id: notifSummary | ||
| 173 | |||
| 174 | text: notif.modelData?.summary ?? "" | ||
| 175 | |||
| 176 | font.pointSize: 10 | ||
| 177 | font.family: "Fira Sans" | ||
| 178 | font.italic: true | ||
| 179 | color: "white" | ||
| 180 | maximumLineCount: 1 | ||
| 181 | elide: Text.ElideRight | ||
| 182 | |||
| 183 | Layout.fillWidth: true | ||
| 184 | Layout.row: notifSep.visible ? 1 : 0 | ||
| 185 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 186 | } | ||
| 187 | |||
| 188 | Image { | ||
| 189 | id: notifImage | ||
| 190 | |||
| 191 | visible: (notif.modelData?.image || notif.modelData?.appIcon) ?? false | ||
| 192 | |||
| 193 | onStatusChanged: { | ||
| 194 | if (notifImage.status == Image.Error) | ||
| 195 | notifImage.visible = false; | ||
| 196 | } | ||
| 197 | |||
| 198 | source: (notif.modelData?.image || notif.modelData?.appIcon) ?? "" | ||
| 199 | fillMode: Image.PreserveAspectFit | ||
| 200 | asynchronous: true | ||
| 201 | smooth: true | ||
| 202 | mipmap: true | ||
| 203 | |||
| 204 | Layout.maximumWidth: 50 | ||
| 205 | Layout.column: 0 | ||
| 206 | Layout.row: notifSep.visible ? 1 : 0 | ||
| 207 | Layout.fillHeight: true | ||
| 208 | Layout.rowSpan: notifBody.visible ? 3 : 2 | ||
| 209 | } | ||
| 210 | |||
| 211 | Text { | ||
| 212 | id: notifBody | ||
| 213 | |||
| 214 | visible: notif.modelData?.body ?? false | ||
| 215 | text: notif.modelData?.body ?? "" | ||
| 216 | textFormat: Text.RichText | ||
| 217 | wrapMode: Text.Wrap | ||
| 218 | |||
| 219 | font.pointSize: 10 | ||
| 220 | font.family: "Fira Sans" | ||
| 221 | color: "white" | ||
| 222 | |||
| 223 | Layout.fillWidth: true | ||
| 224 | Layout.row: notifSep.visible ? 2 : 1 | ||
| 225 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 226 | } | ||
| 227 | |||
| 228 | Text { | ||
| 229 | id: notifTime | ||
| 230 | |||
| 231 | Connections { | ||
| 232 | target: NotificationManager.clock | ||
| 233 | function onDateChanged() { | ||
| 234 | notifTime.text = NotificationManager.formatTime(notif.modelData?.receivedTime); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | text: NotificationManager.formatTime(notif.modelData?.receivedTime) | ||
| 239 | |||
| 240 | font.pointSize: 8 | ||
| 241 | font.family: "Fira Sans" | ||
| 242 | font.italic: true | ||
| 243 | color: "#555" | ||
| 244 | maximumLineCount: 1 | ||
| 245 | horizontalAlignment: Text.AlignRight | ||
| 246 | |||
| 247 | Layout.fillWidth: true | ||
| 248 | Layout.row: { | ||
| 249 | var res = 1; | ||
| 250 | if (notifSep.visible) | ||
| 251 | res += 1; | ||
| 252 | if (notifBody.visible) | ||
| 253 | res += 1; | ||
| 254 | return res; | ||
| 255 | } | ||
| 256 | Layout.column: notifImage.visible ? 1 : 0 | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | } | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/PipewireWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/PipewireWidget.qml new file mode 100644 index 00000000..9c6b65a4 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/PipewireWidget.qml | |||
| @@ -0,0 +1,483 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Layouts | ||
| 3 | import QtQuick.Controls.Fusion | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Services.Pipewire | ||
| 6 | import Quickshell.Widgets | ||
| 7 | |||
| 8 | Item { | ||
| 9 | height: parent.height | ||
| 10 | width: volumeIcon.width + 8 | ||
| 11 | anchors.verticalCenter: parent.verticalCenter | ||
| 12 | |||
| 13 | PwObjectTracker { | ||
| 14 | objects: [Pipewire.defaultAudioSink] | ||
| 15 | } | ||
| 16 | |||
| 17 | WrapperMouseArea { | ||
| 18 | id: widgetMouseArea | ||
| 19 | |||
| 20 | anchors.fill: parent | ||
| 21 | hoverEnabled: true | ||
| 22 | cursorShape: Qt.PointingHandCursor | ||
| 23 | |||
| 24 | onClicked: { | ||
| 25 | if (!Pipewire.defaultAudioSink) | ||
| 26 | return; | ||
| 27 | Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted; | ||
| 28 | } | ||
| 29 | |||
| 30 | property real sensitivity: (1 / 40) / 120 | ||
| 31 | onWheel: event => { | ||
| 32 | if (!Pipewire.defaultAudioSink) | ||
| 33 | return; | ||
| 34 | Pipewire.defaultAudioSink.audio.volume += event.angleDelta.y * sensitivity; | ||
| 35 | } | ||
| 36 | |||
| 37 | Rectangle { | ||
| 38 | id: volumeWidget | ||
| 39 | |||
| 40 | anchors.fill: parent | ||
| 41 | color: { | ||
| 42 | if (widgetMouseArea.containsMouse) | ||
| 43 | return "#33808080"; | ||
| 44 | return "transparent"; | ||
| 45 | } | ||
| 46 | |||
| 47 | Item { | ||
| 48 | anchors.fill: parent | ||
| 49 | |||
| 50 | MaterialDesignIcon { | ||
| 51 | id: volumeIcon | ||
| 52 | |||
| 53 | implicitSize: 14 | ||
| 54 | anchors.centerIn: parent | ||
| 55 | |||
| 56 | icon: { | ||
| 57 | if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) | ||
| 58 | return "volume-off"; | ||
| 59 | if (Pipewire.defaultAudioSink.audio.volume <= 0.33) | ||
| 60 | return "volume-low"; | ||
| 61 | if (Pipewire.defaultAudioSink.audio.volume <= 0.67) | ||
| 62 | return "volume-medium"; | ||
| 63 | return "volume-high"; | ||
| 64 | } | ||
| 65 | color: "#555" | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | Loader { | ||
| 72 | id: tooltipLoader | ||
| 73 | |||
| 74 | active: false | ||
| 75 | |||
| 76 | Connections { | ||
| 77 | target: widgetMouseArea | ||
| 78 | function onContainsMouseChanged() { | ||
| 79 | if (widgetMouseArea.containsMouse) | ||
| 80 | tooltipLoader.active = true; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | PwObjectTracker { | ||
| 85 | objects: Pipewire.devices | ||
| 86 | } | ||
| 87 | PwObjectTracker { | ||
| 88 | objects: Pipewire.nodes | ||
| 89 | } | ||
| 90 | |||
| 91 | sourceComponent: PopupWindow { | ||
| 92 | id: tooltip | ||
| 93 | |||
| 94 | property bool openPopup: false | ||
| 95 | property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse || openPopup | ||
| 96 | |||
| 97 | anchor { | ||
| 98 | item: widgetMouseArea | ||
| 99 | edges: Edges.Bottom | Edges.Left | ||
| 100 | } | ||
| 101 | visible: false | ||
| 102 | |||
| 103 | onNextVisibleChanged: hangTimer.restart() | ||
| 104 | |||
| 105 | Timer { | ||
| 106 | id: hangTimer | ||
| 107 | interval: 100 | ||
| 108 | onTriggered: { | ||
| 109 | tooltip.visible = tooltip.nextVisible; | ||
| 110 | if (!tooltip.visible) | ||
| 111 | tooltipLoader.active = false; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | implicitWidth: tooltipContent.width | ||
| 116 | implicitHeight: tooltipContent.height | ||
| 117 | color: "transparent" | ||
| 118 | |||
| 119 | Rectangle { | ||
| 120 | width: tooltip.width | ||
| 121 | height: tooltipLayout.childrenRect.height + 16 | ||
| 122 | color: "black" | ||
| 123 | } | ||
| 124 | |||
| 125 | WrapperItem { | ||
| 126 | id: tooltipContent | ||
| 127 | |||
| 128 | bottomMargin: Math.max(0, 200 - tooltipLayout.implicitHeight) | ||
| 129 | |||
| 130 | WrapperMouseArea { | ||
| 131 | id: tooltipMouseArea | ||
| 132 | |||
| 133 | hoverEnabled: true | ||
| 134 | enabled: true | ||
| 135 | |||
| 136 | WrapperItem { | ||
| 137 | margin: 8 | ||
| 138 | bottomMargin: 8 | ||
| 139 | |||
| 140 | GridLayout { | ||
| 141 | id: tooltipLayout | ||
| 142 | |||
| 143 | columns: 4 | ||
| 144 | |||
| 145 | Repeater { | ||
| 146 | model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") | ||
| 147 | |||
| 148 | Item { | ||
| 149 | id: descItem | ||
| 150 | |||
| 151 | required property var modelData | ||
| 152 | required property int index | ||
| 153 | |||
| 154 | Layout.column: 0 | ||
| 155 | Layout.row: index | ||
| 156 | |||
| 157 | implicitWidth: descText.contentWidth | ||
| 158 | implicitHeight: descText.contentHeight | ||
| 159 | |||
| 160 | Text { | ||
| 161 | id: descText | ||
| 162 | |||
| 163 | color: "white" | ||
| 164 | font.pointSize: 10 | ||
| 165 | font.family: "Fira Sans" | ||
| 166 | |||
| 167 | text: descItem.modelData.description | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | Repeater { | ||
| 173 | id: defaultSinkRepeater | ||
| 174 | |||
| 175 | model: { | ||
| 176 | Array.from(Pipewire.devices.values) | ||
| 177 | .filter(dev => dev.type == "Audio/Device") | ||
| 178 | .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSink && node.device?.id == device.id )); | ||
| 179 | } | ||
| 180 | |||
| 181 | Item { | ||
| 182 | id: defaultSinkItem | ||
| 183 | |||
| 184 | required property var modelData | ||
| 185 | required property int index | ||
| 186 | |||
| 187 | visible: Boolean(modelData) | ||
| 188 | |||
| 189 | PwObjectTracker { | ||
| 190 | objects: [defaultSinkItem.modelData] | ||
| 191 | } | ||
| 192 | |||
| 193 | Layout.column: 1 | ||
| 194 | Layout.row: index | ||
| 195 | |||
| 196 | Layout.fillHeight: true | ||
| 197 | |||
| 198 | implicitWidth: 16 + 8 | ||
| 199 | |||
| 200 | WrapperMouseArea { | ||
| 201 | id: defaultSinkMouseArea | ||
| 202 | |||
| 203 | anchors.fill: parent | ||
| 204 | hoverEnabled: true | ||
| 205 | cursorShape: Qt.PointingHandCursor | ||
| 206 | |||
| 207 | onClicked: { | ||
| 208 | Pipewire.preferredDefaultAudioSink = defaultSinkItem.modelData | ||
| 209 | } | ||
| 210 | |||
| 211 | onWheel: event => scrollVolume(event); | ||
| 212 | property real sensitivity: (1 / 40) / 120 | ||
| 213 | function scrollVolume(event) { | ||
| 214 | defaultSinkItem.modelData.audio.volume += event.angleDelta.y * sensitivity; | ||
| 215 | } | ||
| 216 | |||
| 217 | Rectangle { | ||
| 218 | id: defaultSinkWidget | ||
| 219 | |||
| 220 | anchors.fill: parent | ||
| 221 | color: { | ||
| 222 | if (defaultSinkMouseArea.containsMouse) | ||
| 223 | return "#33808080"; | ||
| 224 | return "transparent"; | ||
| 225 | } | ||
| 226 | |||
| 227 | MaterialDesignIcon { | ||
| 228 | width: 16 | ||
| 229 | height: 16 | ||
| 230 | anchors.centerIn: parent | ||
| 231 | |||
| 232 | icon: { | ||
| 233 | if (defaultSinkItem.modelData?.id == Pipewire.defaultAudioSink?.id) | ||
| 234 | return "speaker"; | ||
| 235 | return "speaker-off"; | ||
| 236 | } | ||
| 237 | color: icon == "speaker" ? "white" : "#555" | ||
| 238 | } | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | PopupWindow { | ||
| 243 | id: volumeTooltip | ||
| 244 | |||
| 245 | property bool nextVisible: defaultSinkMouseArea.containsMouse || volumeTooltipMouseArea.containsMouse | ||
| 246 | |||
| 247 | anchor { | ||
| 248 | item: defaultSinkMouseArea | ||
| 249 | edges: Edges.Bottom | Edges.Left | ||
| 250 | } | ||
| 251 | visible: false | ||
| 252 | |||
| 253 | onNextVisibleChanged: volumeHangTimer.restart() | ||
| 254 | |||
| 255 | onVisibleChanged: tooltip.openPopup = volumeTooltip.visible | ||
| 256 | |||
| 257 | Timer { | ||
| 258 | id: volumeHangTimer | ||
| 259 | interval: 100 | ||
| 260 | onTriggered: volumeTooltip.visible = volumeTooltip.nextVisible | ||
| 261 | } | ||
| 262 | |||
| 263 | implicitWidth: volumeTooltipText.contentWidth + 16 | ||
| 264 | implicitHeight: volumeTooltipText.contentHeight + 16 | ||
| 265 | color: "black" | ||
| 266 | |||
| 267 | WrapperMouseArea { | ||
| 268 | id: volumeTooltipMouseArea | ||
| 269 | |||
| 270 | hoverEnabled: true | ||
| 271 | enabled: true | ||
| 272 | |||
| 273 | onWheel: event => defaultSinkMouseArea.scrollVolume(event); | ||
| 274 | |||
| 275 | anchors.fill: parent | ||
| 276 | |||
| 277 | Item { | ||
| 278 | anchors.fill: parent | ||
| 279 | |||
| 280 | Text { | ||
| 281 | id: volumeTooltipText | ||
| 282 | |||
| 283 | anchors.centerIn: parent | ||
| 284 | |||
| 285 | font.pointSize: 10 | ||
| 286 | font.family: "Fira Sans" | ||
| 287 | color: "white" | ||
| 288 | |||
| 289 | text: `${Math.round(defaultSinkItem.modelData?.audio?.volume * 100)}%` | ||
| 290 | } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | Repeater { | ||
| 298 | id: defaultSourceRepeater | ||
| 299 | |||
| 300 | model: { | ||
| 301 | Array.from(Pipewire.devices.values) | ||
| 302 | .filter(dev => dev.type == "Audio/Device") | ||
| 303 | .map(device => Array.from(Pipewire.nodes.values).find(node => node.type == PwNodeType.AudioSource && node.device?.id == device.id )); | ||
| 304 | } | ||
| 305 | |||
| 306 | Item { | ||
| 307 | id: defaultSourceItem | ||
| 308 | |||
| 309 | required property var modelData | ||
| 310 | required property int index | ||
| 311 | |||
| 312 | visible: Boolean(modelData) | ||
| 313 | |||
| 314 | PwObjectTracker { | ||
| 315 | objects: [defaultSourceItem.modelData] | ||
| 316 | } | ||
| 317 | |||
| 318 | Layout.column: 2 | ||
| 319 | Layout.row: index | ||
| 320 | |||
| 321 | Layout.fillHeight: true | ||
| 322 | |||
| 323 | implicitWidth: 16 + 8 | ||
| 324 | |||
| 325 | WrapperMouseArea { | ||
| 326 | id: defaultSourceMouseArea | ||
| 327 | |||
| 328 | anchors.fill: parent | ||
| 329 | hoverEnabled: true | ||
| 330 | cursorShape: Qt.PointingHandCursor | ||
| 331 | |||
| 332 | onClicked: { | ||
| 333 | Pipewire.preferredDefaultAudioSource = defaultSourceItem.modelData | ||
| 334 | } | ||
| 335 | |||
| 336 | onWheel: event => scrollVolume(event); | ||
| 337 | property real sensitivity: (1 / 40) / 120 | ||
| 338 | function scrollVolume(event) { | ||
| 339 | defaultSourceItem.modelData.audio.volume += event.angleDelta.y * sensitivity; | ||
| 340 | } | ||
| 341 | |||
| 342 | Rectangle { | ||
| 343 | id: defaultSourceWidget | ||
| 344 | |||
| 345 | anchors.fill: parent | ||
| 346 | color: { | ||
| 347 | if (defaultSourceMouseArea.containsMouse) | ||
| 348 | return "#33808080"; | ||
| 349 | return "transparent"; | ||
| 350 | } | ||
| 351 | |||
| 352 | MaterialDesignIcon { | ||
| 353 | width: 16 | ||
| 354 | height: 16 | ||
| 355 | anchors.centerIn: parent | ||
| 356 | |||
| 357 | icon: { | ||
| 358 | if (defaultSourceItem.modelData?.id == Pipewire.defaultAudioSource?.id) | ||
| 359 | return "microphone"; | ||
| 360 | return "microphone-off"; | ||
| 361 | } | ||
| 362 | color: icon == "microphone" ? "white" : "#555" | ||
| 363 | } | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | PopupWindow { | ||
| 368 | id: volumeTooltip | ||
| 369 | |||
| 370 | property bool nextVisible: defaultSourceMouseArea.containsMouse || volumeTooltipMouseArea.containsMouse | ||
| 371 | |||
| 372 | anchor { | ||
| 373 | item: defaultSourceMouseArea | ||
| 374 | edges: Edges.Bottom | Edges.Left | ||
| 375 | } | ||
| 376 | visible: false | ||
| 377 | |||
| 378 | onNextVisibleChanged: volumeHangTimer.restart() | ||
| 379 | |||
| 380 | onVisibleChanged: tooltip.openPopup = volumeTooltip.visible | ||
| 381 | |||
| 382 | Timer { | ||
| 383 | id: volumeHangTimer | ||
| 384 | interval: 100 | ||
| 385 | onTriggered: volumeTooltip.visible = volumeTooltip.nextVisible | ||
| 386 | } | ||
| 387 | |||
| 388 | implicitWidth: volumeTooltipText.contentWidth + 16 | ||
| 389 | implicitHeight: volumeTooltipText.contentHeight + 16 | ||
| 390 | color: "black" | ||
| 391 | |||
| 392 | WrapperMouseArea { | ||
| 393 | id: volumeTooltipMouseArea | ||
| 394 | |||
| 395 | hoverEnabled: true | ||
| 396 | enabled: true | ||
| 397 | |||
| 398 | onWheel: event => defaultSourceMouseArea.scrollVolume(event); | ||
| 399 | |||
| 400 | anchors.fill: parent | ||
| 401 | |||
| 402 | Item { | ||
| 403 | anchors.fill: parent | ||
| 404 | |||
| 405 | Text { | ||
| 406 | id: volumeTooltipText | ||
| 407 | |||
| 408 | anchors.centerIn: parent | ||
| 409 | |||
| 410 | font.pointSize: 10 | ||
| 411 | font.family: "Fira Sans" | ||
| 412 | color: "white" | ||
| 413 | |||
| 414 | text: `${Math.round(defaultSourceItem.modelData?.audio?.volume * 100)}%` | ||
| 415 | } | ||
| 416 | } | ||
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | Repeater { | ||
| 423 | id: profileRepeater | ||
| 424 | |||
| 425 | model: Array.from(Pipewire.devices.values).filter(dev => dev.type == "Audio/Device") | ||
| 426 | |||
| 427 | Item { | ||
| 428 | id: profileItem | ||
| 429 | |||
| 430 | required property var modelData | ||
| 431 | required property int index | ||
| 432 | |||
| 433 | PwObjectTracker { | ||
| 434 | objects: [profileItem.modelData] | ||
| 435 | } | ||
| 436 | |||
| 437 | Layout.column: 3 | ||
| 438 | Layout.row: index | ||
| 439 | |||
| 440 | Layout.fillWidth: true | ||
| 441 | |||
| 442 | implicitWidth: Math.max(profileBox.implicitWidth, 300) | ||
| 443 | implicitHeight: profileBox.height | ||
| 444 | |||
| 445 | ComboBox { | ||
| 446 | id: profileBox | ||
| 447 | |||
| 448 | model: profileItem.modelData.profiles | ||
| 449 | |||
| 450 | textRole: "description" | ||
| 451 | valueRole: "index" | ||
| 452 | onActivated: profileItem.modelData.setProfile(currentValue) | ||
| 453 | |||
| 454 | anchors.fill: parent | ||
| 455 | |||
| 456 | implicitContentWidthPolicy: ComboBox.WidestText | ||
| 457 | |||
| 458 | Connections { | ||
| 459 | target: profileItem.modelData | ||
| 460 | function onCurrentProfileChanged() { | ||
| 461 | profileBox.currentIndex = Array.from(profileItem.modelData.profiles).findIndex(profile => profile.index == profileItem.modelData.currentProfile); | ||
| 462 | } | ||
| 463 | } | ||
| 464 | Component.onCompleted: { | ||
| 465 | profileBox.currentIndex = Array.from(profileItem.modelData.profiles).findIndex(profile => profile.index == profileItem.modelData.currentProfile); | ||
| 466 | } | ||
| 467 | |||
| 468 | Connections { | ||
| 469 | target: profileBox.popup | ||
| 470 | function onVisibleChanged() { | ||
| 471 | tooltip.openPopup = profileBox.popup.visible | ||
| 472 | } | ||
| 473 | } | ||
| 474 | } | ||
| 475 | } | ||
| 476 | } | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | ||
| 480 | } | ||
| 481 | } | ||
| 482 | } | ||
| 483 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/PrivacyWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/PrivacyWidget.qml new file mode 100644 index 00000000..d7ffadfe --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/PrivacyWidget.qml | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Layouts | ||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Widgets | ||
| 5 | import qs.Services | ||
| 6 | |||
| 7 | Item { | ||
| 8 | height: parent.height | ||
| 9 | width: layout.childrenRect.width | ||
| 10 | anchors.verticalCenter: parent.verticalCenter | ||
| 11 | |||
| 12 | visible: Array.from(Privacy.activeItems).length > 0 | ||
| 13 | |||
| 14 | RowLayout { | ||
| 15 | id: layout | ||
| 16 | |||
| 17 | anchors.fill: parent | ||
| 18 | |||
| 19 | spacing: 8 | ||
| 20 | |||
| 21 | Repeater { | ||
| 22 | model: Privacy.activeItems | ||
| 23 | |||
| 24 | Item { | ||
| 25 | id: privacyItem | ||
| 26 | |||
| 27 | required property var modelData; | ||
| 28 | |||
| 29 | height: parent.height | ||
| 30 | width: icon.width | ||
| 31 | |||
| 32 | MaterialDesignIcon { | ||
| 33 | id: icon | ||
| 34 | |||
| 35 | implicitSize: 14 | ||
| 36 | anchors.centerIn: parent | ||
| 37 | |||
| 38 | icon: { | ||
| 39 | if (privacyItem.modelData == Privacy.Item.Microphone) | ||
| 40 | return "microphone"; | ||
| 41 | if (privacyItem.modelData == Privacy.Item.Screensharing) | ||
| 42 | return "monitor-share"; | ||
| 43 | } | ||
| 44 | color: "#f2201f" | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/Brightness.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/Brightness.qml new file mode 100644 index 00000000..f3ae6804 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/Brightness.qml | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import QtQml | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Io | ||
| 6 | import Custom as Custom | ||
| 7 | import qs.Services | ||
| 8 | |||
| 9 | Singleton { | ||
| 10 | id: root | ||
| 11 | |||
| 12 | property string subsystem: "backlight" | ||
| 13 | property string device: "intel_backlight" | ||
| 14 | |||
| 15 | property real currBrightness | ||
| 16 | property real exponent: 4 | ||
| 17 | |||
| 18 | function calcCurrBrightness() { | ||
| 19 | if (!currFile.loaded || !maxFile.loaded) | ||
| 20 | return undefined; | ||
| 21 | const curr = Number(currFile.text()); | ||
| 22 | const max = Number(maxFile.text()); | ||
| 23 | const val = Math.pow(curr / max, 1 / root.exponent); | ||
| 24 | return val; | ||
| 25 | } | ||
| 26 | |||
| 27 | Connections { | ||
| 28 | target: currFile | ||
| 29 | function onLoaded() { | ||
| 30 | const b = root.calcCurrBrightness(); | ||
| 31 | if (typeof b !== 'undefined') | ||
| 32 | root.currBrightness = b; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | Connections { | ||
| 36 | target: maxFile | ||
| 37 | function onLoaded() { | ||
| 38 | const b = root.calcCurrBrightness(); | ||
| 39 | if (typeof b !== 'undefined') | ||
| 40 | root.currBrightness = b; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | onCurrBrightnessChanged: { | ||
| 45 | root.currBrightness = Math.max(0, Math.min(1, root.currBrightness)); | ||
| 46 | |||
| 47 | const prev = root.calcCurrBrightness(); | ||
| 48 | if (typeof prev === 'undefined' || Math.abs(root.currBrightness - prev) < 0.01) | ||
| 49 | return; | ||
| 50 | |||
| 51 | const max = Number(maxFile.text()); | ||
| 52 | const actual = Number(currFile.text()); | ||
| 53 | let curr = Math.max(0, Math.min(max, Math.pow(root.currBrightness, root.exponent) * max)); | ||
| 54 | if (Math.round(curr) == actual && curr < actual) | ||
| 55 | curr = Math.max(0, actual - 1); | ||
| 56 | else if (Math.round(curr) == actual && curr > actual) | ||
| 57 | curr = Math.min(max, actual + 1); | ||
| 58 | // root.currBrightness = Math.pow(curr / max, 1 / root.exponent); | ||
| 59 | Custom.Systemd.setBrightness(root.subsystem, root.device, Math.round(curr)); | ||
| 60 | } | ||
| 61 | |||
| 62 | FileView { | ||
| 63 | id: currFile | ||
| 64 | path: `/sys/class/${root.subsystem}/${root.device}/brightness` | ||
| 65 | blockAllReads: true | ||
| 66 | watchChanges: true | ||
| 67 | onFileChanged: reload() | ||
| 68 | } | ||
| 69 | FileView { | ||
| 70 | id: maxFile | ||
| 71 | path: `/sys/class/${root.subsystem}/${root.device}/max_brightness` | ||
| 72 | blockAllReads: true | ||
| 73 | watchChanges: true | ||
| 74 | onFileChanged: reload() | ||
| 75 | } | ||
| 76 | |||
| 77 | |||
| 78 | Timer { | ||
| 79 | id: startupDelay | ||
| 80 | interval: 500 | ||
| 81 | running: true | ||
| 82 | repeat: false | ||
| 83 | } | ||
| 84 | property bool onlyInternal: true | ||
| 85 | Connections { | ||
| 86 | target: NiriService | ||
| 87 | function onOutputsChanged() { | ||
| 88 | root.onlyInternal = Object.keys(NiriService.outputs).every(oname => oname == "eDP-1"); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | onOnlyInternalChanged: { | ||
| 92 | if (startupDelay.running) | ||
| 93 | return; | ||
| 94 | |||
| 95 | if (!root.onlyInternal) | ||
| 96 | root.currBrightness = 1 | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
| 100 | IpcHandler { | ||
| 101 | target: "Brightness" | ||
| 102 | |||
| 103 | function set(brightness: real): void { | ||
| 104 | root.currBrightness = brightness; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/GpgAgent.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/GpgAgent.qml new file mode 100644 index 00000000..3de69535 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/GpgAgent.qml | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Io | ||
| 5 | |||
| 6 | Singleton { | ||
| 7 | id: root | ||
| 8 | |||
| 9 | Socket { | ||
| 10 | id: agentSocket | ||
| 11 | connected: true | ||
| 12 | path: `${Quickshell.env("XDG_RUNTIME_DIR")}/gnupg/S.gpg-agent` | ||
| 13 | } | ||
| 14 | |||
| 15 | function reloadAgent() { | ||
| 16 | agentSocket.write("RELOADAGENT\n") | ||
| 17 | } | ||
| 18 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/InhibitorState.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/InhibitorState.qml new file mode 100644 index 00000000..60202a29 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/InhibitorState.qml | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Custom as Custom | ||
| 5 | |||
| 6 | Singleton { | ||
| 7 | id: inhibitorState | ||
| 8 | |||
| 9 | property bool waylandIdleInhibited: false | ||
| 10 | property alias lidSwitchInhibited: lidSwitchInhibitor.enabled | ||
| 11 | property bool lockscreenInhibited: false | ||
| 12 | |||
| 13 | Custom.SystemdInhibitor { | ||
| 14 | id: lidSwitchInhibitor | ||
| 15 | |||
| 16 | enabled: false | ||
| 17 | |||
| 18 | what: Custom.SystemdInhibitorParams.HandleLidSwitch | ||
| 19 | who: "quickshell" | ||
| 20 | why: "User request" | ||
| 21 | mode: Custom.SystemdInhibitorParams.BlockWeak | ||
| 22 | } | ||
| 23 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/MprisProxy.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/MprisProxy.qml new file mode 100644 index 00000000..e3ab9755 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/MprisProxy.qml | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Services.Mpris | ||
| 5 | |||
| 6 | Scope { | ||
| 7 | property list<var> players: Mpris.players.values | ||
| 8 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/NiriService.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/NiriService.qml new file mode 100644 index 00000000..e9e86f95 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/NiriService.qml | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Io | ||
| 5 | import QtQuick | ||
| 6 | |||
| 7 | Singleton { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | property var workspaces: [] | ||
| 11 | property var outputs: {} | ||
| 12 | property var keyboardLayouts: {} | ||
| 13 | property var windows: [] | ||
| 14 | property var casts: [] | ||
| 15 | readonly property string socketPath: Quickshell.env("NIRI_SOCKET") | ||
| 16 | |||
| 17 | function refreshOutputs() { | ||
| 18 | commandSocket.sendCommand("Outputs", data => { | ||
| 19 | outputs = data.Ok.Outputs; | ||
| 20 | }); | ||
| 21 | } | ||
| 22 | |||
| 23 | function sendCommand(command, callback) { | ||
| 24 | commandSocket.sendCommand(command, callback); | ||
| 25 | } | ||
| 26 | |||
| 27 | Socket { | ||
| 28 | id: eventStreamSocket | ||
| 29 | path: root.socketPath | ||
| 30 | connected: true | ||
| 31 | |||
| 32 | property bool acked: false | ||
| 33 | |||
| 34 | onConnectionStateChanged: { | ||
| 35 | if (connected) { | ||
| 36 | acked = false; | ||
| 37 | write('"EventStream"\n'); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | parser: SplitParser { | ||
| 42 | onRead: line => { | ||
| 43 | try { | ||
| 44 | const event = JSON.parse(line) | ||
| 45 | |||
| 46 | // console.log(JSON.stringify(event)) | ||
| 47 | |||
| 48 | if (event.WorkspacesChanged) { | ||
| 49 | root.workspaces = event.WorkspacesChanged.workspaces | ||
| 50 | root.refreshOutputs(); | ||
| 51 | } else if (event.WorkspaceActivated) | ||
| 52 | eventWorkspaceActivated(event.WorkspaceActivated); | ||
| 53 | else if (event.WorkspaceUrgencyChanged) | ||
| 54 | eventWorkspaceUrgencyChanged(event.WorkspaceUrgencyChanged); | ||
| 55 | else if (event.WorkspaceActiveWindowChanged) | ||
| 56 | eventWorkspaceActiveWindowChanged(event.WorkspaceActiveWindowChanged); | ||
| 57 | else if (event.KeyboardLayoutsChanged) | ||
| 58 | root.keyboardLayouts = event.KeyboardLayoutsChanged.keyboard_layouts; | ||
| 59 | else if (event.KeyboardLayoutSwitched) | ||
| 60 | root.keyboardLayouts = Object.assign({}, root.keyboardLayouts, {"current_idx": event.KeyboardLayoutSwitched.idx }); | ||
| 61 | else if (event.WindowsChanged) | ||
| 62 | root.windows = event.WindowsChanged.windows | ||
| 63 | else if (event.WindowOpenedOrChanged) | ||
| 64 | eventWindowOpenedOrChanged(event.WindowOpenedOrChanged); | ||
| 65 | else if (event.WindowClosed) | ||
| 66 | eventWindowClosed(event.WindowClosed); | ||
| 67 | else if (event.WindowFocusChanged) | ||
| 68 | eventWindowFocusChanged(event.WindowFocusChanged); | ||
| 69 | else if (event.WindowUrgencyChanged) | ||
| 70 | eventWindowUrgencyChanged(event.WindowUrgencyChanged); | ||
| 71 | else if (event.WindowLayoutsChanged) | ||
| 72 | eventWindowLayoutsChanged(event.WindowLayoutsChanged); | ||
| 73 | else if (event.WindowFocusTimestampChanged) | ||
| 74 | eventWindowFocusTimestampChanged(event.WindowFocusTimestampChanged); | ||
| 75 | else if (event.CastsChanged) | ||
| 76 | root.casts = event.CastsChanged.casts | ||
| 77 | else if (event.CastStartedOrChanged) | ||
| 78 | eventCastStartedOrChanged(event.CastStartedOrChanged); | ||
| 79 | else if (event.CastStopped) | ||
| 80 | eventCastStopped(event.CastStopped); | ||
| 81 | else if (event.Ok && !eventStreamSocket.acked) { eventStreamSocket.acked = true; } | ||
| 82 | else if (event.OverviewOpenedOrClosed) {} | ||
| 83 | else if (event.ScreenshotCaptured) {} | ||
| 84 | else if (event.ConfigLoaded) {} | ||
| 85 | else | ||
| 86 | console.log(JSON.stringify(event)); | ||
| 87 | } catch (e) { | ||
| 88 | console.warn("NiriService: Failed to parse event:", line, e) | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | Socket { | ||
| 95 | id: commandSocket | ||
| 96 | path: root.socketPath | ||
| 97 | connected: true | ||
| 98 | |||
| 99 | property var awaitingAnswer: null | ||
| 100 | property var cmdQueue: [] | ||
| 101 | |||
| 102 | parser: SplitParser { | ||
| 103 | onRead: line => { | ||
| 104 | if (commandSocket.awaitingAnswer === null) | ||
| 105 | return; | ||
| 106 | |||
| 107 | try { | ||
| 108 | const response = JSON.parse(line); | ||
| 109 | commandSocket.awaitingAnswer.callback(response); | ||
| 110 | commandSocket.awaitingAnswer = null; | ||
| 111 | } catch (e) { | ||
| 112 | console.warn("NiriService: Failed to parse response:", line, e) | ||
| 113 | } | ||
| 114 | commandSocket._handleQueue(); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | onCmdQueueChanged: { | ||
| 119 | _handleQueue(); | ||
| 120 | } | ||
| 121 | onAwaitingAnswerChanged: { | ||
| 122 | _handleQueue(); | ||
| 123 | } | ||
| 124 | |||
| 125 | function _handleQueue() { | ||
| 126 | if (cmdQueue.length <= 0 || awaitingAnswer !== null) | ||
| 127 | return; | ||
| 128 | |||
| 129 | let localQueue = Array.from(cmdQueue); | ||
| 130 | awaitingAnswer = localQueue.shift(); | ||
| 131 | cmdQueue = localQueue; | ||
| 132 | write(JSON.stringify(awaitingAnswer.command) + '\n'); | ||
| 133 | } | ||
| 134 | |||
| 135 | function sendCommand(command, callback) { | ||
| 136 | cmdQueue = Array.from(cmdQueue).concat([{ "command": command, "callback": callback }]) | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | function eventWorkspaceActivated(data) { | ||
| 141 | let relevant_output = null; | ||
| 142 | Array.from(root.workspaces).forEach(ws => { | ||
| 143 | if (data.id === ws.id) | ||
| 144 | relevant_output = ws.output; | ||
| 145 | }); | ||
| 146 | root.workspaces = Array.from(root.workspaces).map(ws => { | ||
| 147 | if (data.focused) | ||
| 148 | ws.is_focused = false; | ||
| 149 | if (ws.output === relevant_output) | ||
| 150 | ws.is_active = false; | ||
| 151 | if (data.id === ws.id) { | ||
| 152 | ws.is_active = true; | ||
| 153 | ws.is_focused = data.focused; | ||
| 154 | } | ||
| 155 | return ws; | ||
| 156 | }); | ||
| 157 | } | ||
| 158 | function eventWorkspaceUrgencyChanged(data) { | ||
| 159 | root.workspaces = Array.from(root.workspaces).map(ws => { | ||
| 160 | if (data.id == ws.id) | ||
| 161 | ws.is_urgent = data.urgent; | ||
| 162 | return ws; | ||
| 163 | }); | ||
| 164 | } | ||
| 165 | function eventWorkspaceActiveWindowChanged(data) { | ||
| 166 | root.workspaces = Array.from(root.workspaces).map(ws => { | ||
| 167 | if (data.workspace_id === ws.id) | ||
| 168 | ws.active_window_id = data.active_window_id; | ||
| 169 | return ws; | ||
| 170 | }); | ||
| 171 | } | ||
| 172 | function eventWindowOpenedOrChanged(data) { | ||
| 173 | root.windows = Array.from(root.windows).map(win => { | ||
| 174 | if (data.window.is_focused) | ||
| 175 | win.is_focused = false; | ||
| 176 | return win; | ||
| 177 | }).filter(win => win.id !== data.window.id).concat([data.window]); | ||
| 178 | } | ||
| 179 | function eventWindowClosed(data) { | ||
| 180 | root.windows = Array.from(root.windows).filter(win => win.id !== data.id); | ||
| 181 | } | ||
| 182 | function eventWindowFocusChanged(data) { | ||
| 183 | root.windows = Array.from(root.windows).map(win => { | ||
| 184 | win.is_focused = win.id === data.id; | ||
| 185 | return win; | ||
| 186 | }); | ||
| 187 | } | ||
| 188 | function eventWindowUrgencyChanged(data) { | ||
| 189 | root.windows = Array.from(root.windows).map(win => { | ||
| 190 | if (win.id === data.id) | ||
| 191 | win.is_urgent = data.urgent; | ||
| 192 | return win; | ||
| 193 | }); | ||
| 194 | } | ||
| 195 | function eventWindowLayoutsChanged(data) { | ||
| 196 | root.windows = Array.from(root.windows).map(win => { | ||
| 197 | Array.from(data.changes).forEach(change => { | ||
| 198 | if (win.id === change[0]) | ||
| 199 | win.layout = change[1]; | ||
| 200 | }); | ||
| 201 | return win; | ||
| 202 | }); | ||
| 203 | } | ||
| 204 | function eventWindowFocusTimestampChanged(data) { | ||
| 205 | root.windows = Array.from(root.windows).map(win => { | ||
| 206 | if (win.id === data.id) | ||
| 207 | win.focus_timestamp = data.focus_timestamp; | ||
| 208 | return win; | ||
| 209 | }); | ||
| 210 | } | ||
| 211 | function eventCastStartedOrChanged(data) { | ||
| 212 | root.casts = [...Array.from(root.casts).filter(cast => cast.stream_id !== data.cast.stream_id), data.cast]; | ||
| 213 | } | ||
| 214 | function eventCastStopped(data) { | ||
| 215 | root.casts = Array.from(root.casts).filter(cast => cast.stream_id !== data.stream_id); | ||
| 216 | } | ||
| 217 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/NotificationManager.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/NotificationManager.qml new file mode 100644 index 00000000..5f8ff419 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/NotificationManager.qml | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import QtQml | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Services.Notifications | ||
| 6 | |||
| 7 | Singleton { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | readonly property bool active: !root.lockscreenActive && !root.displayInhibited | ||
| 11 | property bool lockscreenActive: false | ||
| 12 | property bool displayInhibited: false | ||
| 13 | property alias trackedNotifications: server.trackedNotifications | ||
| 14 | readonly property var groups: { | ||
| 15 | function matchesGroupKey(notif, groupKey) { | ||
| 16 | var matches = true; | ||
| 17 | for (const prop in groupKey.test) { | ||
| 18 | if (notif[prop] !== groupKey.test[prop]) { | ||
| 19 | matches = false; | ||
| 20 | break; | ||
| 21 | } | ||
| 22 | } | ||
| 23 | return matches; | ||
| 24 | } | ||
| 25 | |||
| 26 | var groups = new Map(); | ||
| 27 | var notifs = new Array(); | ||
| 28 | for (const [ix, notif] of server.trackedNotifications.values.entries()) { | ||
| 29 | var didGroup = false; | ||
| 30 | for (const groupKey of root.groupKeys) { | ||
| 31 | if (!matchesGroupKey(notif, groupKey)) | ||
| 32 | continue; | ||
| 33 | |||
| 34 | const key = JSON.stringify({ | ||
| 35 | "key": groupKey, | ||
| 36 | "values": Object.assign({}, ...(Array.from(groupKey["group-by"]).map(prop => { | ||
| 37 | var res = {}; | ||
| 38 | res[prop] = notif[prop]; | ||
| 39 | return res; | ||
| 40 | }))) | ||
| 41 | }); | ||
| 42 | if (!groups.has(key)) | ||
| 43 | groups.set(key, new Array()); | ||
| 44 | groups.get(key).push({ "ix": ix, "notif": notif }); | ||
| 45 | didGroup = true; | ||
| 46 | break; | ||
| 47 | } | ||
| 48 | |||
| 49 | if (!didGroup) | ||
| 50 | notifs.push([{ "ix": ix, "notif": notif }]); | ||
| 51 | } | ||
| 52 | notifs.push(...groups.values()); | ||
| 53 | notifs.sort((as, bs) => Math.min(...(as.map(o => o.ix))) - Math.min(...(bs.map(o => o.ix)))); | ||
| 54 | return notifs.map(ns => ns.map(n => n.notif)); | ||
| 55 | } | ||
| 56 | |||
| 57 | property var groupKeys: [ | ||
| 58 | { "test": { "appName": "Element" }, "group-by": [ "summary" ] } | ||
| 59 | ]; | ||
| 60 | |||
| 61 | property int historyLimit: 100 | ||
| 62 | property var history: [] | ||
| 63 | |||
| 64 | Component { | ||
| 65 | id: expirationTimer | ||
| 66 | |||
| 67 | QtObject { | ||
| 68 | id: timer | ||
| 69 | |||
| 70 | required property QtObject parent | ||
| 71 | required property int expirationTime | ||
| 72 | |||
| 73 | property list<QtObject> data: [ | ||
| 74 | Timer { | ||
| 75 | running: root.active && !timer.expired | ||
| 76 | interval: timer.expirationTime | ||
| 77 | onTriggered: { | ||
| 78 | timer.parent.expirationTimer.destroy(); | ||
| 79 | timer.parent.expirationTimer = null; | ||
| 80 | timer.parent.expire(); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | ] | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | Component { | ||
| 88 | id: notificationLock | ||
| 89 | |||
| 90 | RetainableLock {} | ||
| 91 | } | ||
| 92 | |||
| 93 | readonly property SystemClock clock: SystemClock { | ||
| 94 | precision: SystemClock.Minutes | ||
| 95 | } | ||
| 96 | |||
| 97 | function formatTime(time) { | ||
| 98 | const now = root.clock.date; | ||
| 99 | const diff = now - time; | ||
| 100 | const minutes = Math.ceil(diff / 60000); | ||
| 101 | const hours = Math.floor(minutes / 60); | ||
| 102 | |||
| 103 | if (hours < 1) { | ||
| 104 | if (minutes < 1) | ||
| 105 | return "now"; | ||
| 106 | if (minutes == 1) | ||
| 107 | return "1 minute"; | ||
| 108 | return `${minutes} minutes`; | ||
| 109 | } | ||
| 110 | |||
| 111 | const nowDate = new Date(now.getFullYear(), now.getMonth(), now.getDate()) | ||
| 112 | const timeDate = new Date(time.getFullYear(), time.getMonth(), time.getDate()) | ||
| 113 | const days = Math.floor((nowDate - timeDate) / (1000 * 86400)) | ||
| 114 | |||
| 115 | const timeStr = time.toLocaleTimeString(Qt.locale(), "HH:mm"); | ||
| 116 | |||
| 117 | if (days === 0) | ||
| 118 | return timeStr; | ||
| 119 | if (days === 1) | ||
| 120 | return `yesterday ${timeStr}`; | ||
| 121 | |||
| 122 | const dateStr = time.toLocaleDateString(Qt.locale(), "YYYY-MM-DD"); | ||
| 123 | return `${dateStr} ${timeStr}`; | ||
| 124 | } | ||
| 125 | |||
| 126 | NotificationServer { | ||
| 127 | id: server | ||
| 128 | |||
| 129 | bodySupported: true | ||
| 130 | actionsSupported: true | ||
| 131 | actionIconsSupported: true | ||
| 132 | imageSupported: true | ||
| 133 | bodyMarkupSupported: true | ||
| 134 | bodyImagesSupported: true | ||
| 135 | |||
| 136 | onNotification: notification => { | ||
| 137 | var timeout = notification.expireTimeout * 1000; | ||
| 138 | if (notification.appName == "poweralertd") | ||
| 139 | timeout = 2000; | ||
| 140 | if (timeout > 0) { | ||
| 141 | Object.defineProperty(notification, "expirationTimer", { configurable: true, enumerable: true, writable: true }); | ||
| 142 | notification.expirationTimer = expirationTimer.createObject(notification, { parent: notification, expirationTime: timeout }); | ||
| 143 | } | ||
| 144 | Object.defineProperty(notification, "receivedTime", { configurable: true, enumerable: true, writable: true }); | ||
| 145 | notification.receivedTime = root.clock.date; | ||
| 146 | notification.closed.connect((reason) => server.onNotificationClosed(notification, reason)); | ||
| 147 | notification.tracked = true; | ||
| 148 | } | ||
| 149 | |||
| 150 | function onNotificationClosed(notification, reason) { | ||
| 151 | while (root.history.length >= root.historyLimit) { | ||
| 152 | root.history[0].lock.locked = false; | ||
| 153 | root.history.shift(); | ||
| 154 | } | ||
| 155 | |||
| 156 | root.history.push({ | ||
| 157 | lock: notificationLock.createObject(root, { locked: true, object: notification }), | ||
| 158 | notification: notification | ||
| 159 | }); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/Privacy.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/Privacy.qml new file mode 100644 index 00000000..9c813e49 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/Privacy.qml | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import QtQml | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Services.Pipewire | ||
| 6 | |||
| 7 | Singleton { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | PwObjectTracker { | ||
| 11 | objects: Pipewire.nodes.values | ||
| 12 | } | ||
| 13 | |||
| 14 | enum Item { | ||
| 15 | Microphone, | ||
| 16 | Screensharing | ||
| 17 | } | ||
| 18 | |||
| 19 | readonly property list<var> activeItems: { | ||
| 20 | var items = []; | ||
| 21 | if (microphoneActive) | ||
| 22 | items.push(Privacy.Item.Microphone); | ||
| 23 | if (screensharingActive) | ||
| 24 | items.push(Privacy.Item.Screensharing); | ||
| 25 | return items; | ||
| 26 | } | ||
| 27 | |||
| 28 | readonly property bool microphoneActive: { | ||
| 29 | if (!Pipewire.ready || !Pipewire.nodes?.values) { | ||
| 30 | return false | ||
| 31 | } | ||
| 32 | |||
| 33 | for (const node of Pipewire.nodes.values) { | ||
| 34 | if (!node || (node.type & PwNodeType.AudioInStream) != PwNodeType.AudioInStream) | ||
| 35 | continue; | ||
| 36 | |||
| 37 | if (node.properties?.["stream.monitor"] === "true") | ||
| 38 | continue; | ||
| 39 | |||
| 40 | if (node.audio?.muted) | ||
| 41 | continue; | ||
| 42 | |||
| 43 | return true; | ||
| 44 | } | ||
| 45 | |||
| 46 | return false; | ||
| 47 | } | ||
| 48 | |||
| 49 | readonly property bool screensharingActive: { | ||
| 50 | if (!Pipewire.ready || !Pipewire.nodes?.values) { | ||
| 51 | return false | ||
| 52 | } | ||
| 53 | |||
| 54 | for (const node of Pipewire.nodes.values) { | ||
| 55 | if (!node || (node.type & PwNodeType.VideoInStream) != PwNodeType.VideoInStream) | ||
| 56 | continue; | ||
| 57 | |||
| 58 | return true; | ||
| 59 | } | ||
| 60 | |||
| 61 | return false; | ||
| 62 | } | ||
| 63 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/ScreenRecord.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/ScreenRecord.qml new file mode 100644 index 00000000..eb415452 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/ScreenRecord.qml | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Io | ||
| 5 | |||
| 6 | Singleton { | ||
| 7 | id: root | ||
| 8 | property bool active: false | ||
| 9 | property bool slurpSuccess: false | ||
| 10 | |||
| 11 | onActiveChanged: { | ||
| 12 | if (!active) { | ||
| 13 | slurp.running = false; | ||
| 14 | screenRecorder.running = false; | ||
| 15 | } | ||
| 16 | if (active) | ||
| 17 | slurp.running = true; | ||
| 18 | } | ||
| 19 | |||
| 20 | Process { | ||
| 21 | id: screenRecorder | ||
| 22 | running: false | ||
| 23 | onRunningChanged: { | ||
| 24 | console.log("wf-recorder running: ", screenRecorder.running); | ||
| 25 | |||
| 26 | if (!screenRecorder.running && !slurp.running) | ||
| 27 | root.active = false; | ||
| 28 | } | ||
| 29 | stderr: SplitParser { | ||
| 30 | onRead: line => console.log("wf-recorder stderr: ", line) | ||
| 31 | } | ||
| 32 | stdout: SplitParser { | ||
| 33 | onRead: line => console.log("wf-recorder stdout: ", line) | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | Process { | ||
| 38 | id: slurp | ||
| 39 | running: false | ||
| 40 | command: [ @slurp@, "-o", "-d" ] | ||
| 41 | stdout: StdioCollector {} | ||
| 42 | stderr: SplitParser { | ||
| 43 | onRead: line => console.log("slurp stderr: ", line) | ||
| 44 | } | ||
| 45 | onExited: exitCode => { | ||
| 46 | if (exitCode !== 0) { | ||
| 47 | console.log("slurp failed: ", exitCode); | ||
| 48 | root.active = false; | ||
| 49 | return; | ||
| 50 | } | ||
| 51 | console.log("slurp succeeded: ", slurp.stdout.text); | ||
| 52 | |||
| 53 | const nowDate = new Date(); | ||
| 54 | |||
| 55 | screenRecorder.command = [ | ||
| 56 | @wf-recorder@, | ||
| 57 | "-g", slurp.stdout.text, | ||
| 58 | "-f", `${Quickshell.env("HOME")}/screenshots/${nowDate.toLocaleString(Qt.locale(), "yyyy-MM-ddThh:mm:ss")}.mkv`, | ||
| 59 | ]; | ||
| 60 | screenRecorder.running = true; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/WallpaperSelector.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/WallpaperSelector.qml new file mode 100644 index 00000000..c71a9cca --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/WallpaperSelector.qml | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | import Custom as Custom | ||
| 2 | |||
| 3 | Custom.FileSelector { | ||
| 4 | id: root | ||
| 5 | |||
| 6 | directory: @wallpapers@ | ||
| 7 | epoch: 79200000 | ||
| 8 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/Services/Worktime.qml b/accounts/gkleen@skadhi/shell/quickshell/Services/Worktime.qml new file mode 100644 index 00000000..d98378f1 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/Services/Worktime.qml | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | pragma Singleton | ||
| 2 | |||
| 3 | import QtQuick | ||
| 4 | import Quickshell | ||
| 5 | import Quickshell.Io | ||
| 6 | import QtQml | ||
| 7 | |||
| 8 | Singleton { | ||
| 9 | id: root | ||
| 10 | |||
| 11 | property alias time: timeState | ||
| 12 | property alias today: todayState | ||
| 13 | |||
| 14 | CommandState { | ||
| 15 | id: timeState | ||
| 16 | command: "time" | ||
| 17 | } | ||
| 18 | CommandState { | ||
| 19 | id: todayState | ||
| 20 | command: "today" | ||
| 21 | } | ||
| 22 | |||
| 23 | IpcHandler { | ||
| 24 | target: "Worktime" | ||
| 25 | |||
| 26 | function refresh(): void { | ||
| 27 | time.running = true; | ||
| 28 | today.running = true; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | component CommandState : Scope { | ||
| 33 | id: commandState | ||
| 34 | |||
| 35 | required property string command | ||
| 36 | property var state: null | ||
| 37 | |||
| 38 | property bool strikeout: !strikeoutTimer.running | ||
| 39 | property alias running: process.running | ||
| 40 | property alias updating: updateTimer.running | ||
| 41 | |||
| 42 | Process { | ||
| 43 | id: process | ||
| 44 | running: true | ||
| 45 | command: [ @worktime@, commandState.command, "--waybar" ] | ||
| 46 | stdout: StdioCollector { | ||
| 47 | id: processCollector | ||
| 48 | onStreamFinished: { | ||
| 49 | try { | ||
| 50 | commandState.state = JSON.parse(processCollector.text); | ||
| 51 | strikeoutTimer.restart(); | ||
| 52 | } catch (e) { | ||
| 53 | console.warn("Worktime: Failed to parse output:", processCollector.text, e); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | Timer { | ||
| 60 | id: updateTimer | ||
| 61 | running: commandState.state?.class == "running" || commandState.state?.class == "over" | ||
| 62 | interval: 60000 | ||
| 63 | repeat: true | ||
| 64 | onTriggered: process.running = true | ||
| 65 | } | ||
| 66 | |||
| 67 | Timer { | ||
| 68 | id: strikeoutTimer | ||
| 69 | running: false | ||
| 70 | interval: 5 * updateTimer.interval | ||
| 71 | repeat: false | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | Timer { | ||
| 76 | running: Boolean(timeState.state) && Boolean(todayState.state) && timeState.strikeout && todayState.strikeout | ||
| 77 | interval: 1000 | ||
| 78 | repeat: false | ||
| 79 | onTriggered: { | ||
| 80 | timeState.state = null; | ||
| 81 | todayState.state = null; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/SystemTray.qml b/accounts/gkleen@skadhi/shell/quickshell/SystemTray.qml new file mode 100644 index 00000000..f0c50632 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/SystemTray.qml | |||
| @@ -0,0 +1,201 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Effects | ||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Widgets | ||
| 5 | import Quickshell.Services.SystemTray | ||
| 6 | |||
| 7 | Item { | ||
| 8 | anchors.verticalCenter: parent.verticalCenter | ||
| 9 | width: systemTrayRow.childrenRect.width | ||
| 10 | height: parent.height | ||
| 11 | clip: true | ||
| 12 | |||
| 13 | Row { | ||
| 14 | id: systemTrayRow | ||
| 15 | anchors.centerIn: parent | ||
| 16 | width: childrenRect.width | ||
| 17 | height: parent.height | ||
| 18 | spacing: 0 | ||
| 19 | |||
| 20 | Repeater { | ||
| 21 | model: ScriptModel { | ||
| 22 | values: { | ||
| 23 | var trayItems = Array.from(SystemTray.items.values).filter(item => item.status !== Status.Passive && !(["Fcitx"].includes(item.id))); | ||
| 24 | trayItems.sort((a, b) => a.category !== b.category ? b.category - a.category : a.id.localeCompare(b.id)) | ||
| 25 | return trayItems; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | delegate: Item { | ||
| 30 | id: trayItemWrapper | ||
| 31 | |||
| 32 | required property var modelData | ||
| 33 | required property int index | ||
| 34 | |||
| 35 | property var trayItem: modelData | ||
| 36 | property string iconSource: { | ||
| 37 | let icon = trayItem && trayItem.icon | ||
| 38 | if (typeof icon === 'string' || icon instanceof String) { | ||
| 39 | if (icon.includes("?path=")) { | ||
| 40 | const split = icon.split("?path=") | ||
| 41 | if (split.length !== 2) | ||
| 42 | return icon | ||
| 43 | const name = split[0] | ||
| 44 | const path = split[1] | ||
| 45 | const fileName = name.substring( | ||
| 46 | name.lastIndexOf("/") + 1) | ||
| 47 | return `file://${path}/${fileName}` | ||
| 48 | } | ||
| 49 | return icon | ||
| 50 | } | ||
| 51 | return "" | ||
| 52 | } | ||
| 53 | |||
| 54 | width: icon.width + 6 | ||
| 55 | height: parent.height | ||
| 56 | anchors.verticalCenter: parent.verticalCenter | ||
| 57 | |||
| 58 | WrapperMouseArea { | ||
| 59 | id: trayItemArea | ||
| 60 | |||
| 61 | anchors.fill: parent | ||
| 62 | acceptedButtons: Qt.LeftButton | Qt.RightButton | ||
| 63 | hoverEnabled: true | ||
| 64 | cursorShape: trayItem.onlyMenu ? Qt.ArrowCursor : Qt.PointingHandCursor | ||
| 65 | onClicked: mouse => { | ||
| 66 | if (!trayItem) | ||
| 67 | return | ||
| 68 | |||
| 69 | if (mouse.button === Qt.LeftButton | ||
| 70 | && !trayItem.onlyMenu) { | ||
| 71 | trayItem.activate() | ||
| 72 | return | ||
| 73 | } | ||
| 74 | |||
| 75 | if (trayItem.hasMenu) { | ||
| 76 | var globalPos = mapToGlobal(0, 0) | ||
| 77 | var currentScreen = screen || Screen | ||
| 78 | var screenX = currentScreen.x || 0 | ||
| 79 | var relativeX = globalPos.x - screenX | ||
| 80 | menuAnchor.menu = trayItem.menu | ||
| 81 | menuAnchor.anchor.window = bar | ||
| 82 | menuAnchor.anchor.rect = Qt.rect( | ||
| 83 | relativeX, | ||
| 84 | 21, | ||
| 85 | parent.width, 1) | ||
| 86 | menuAnchor.open() | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | Rectangle { | ||
| 91 | anchors.fill: parent | ||
| 92 | color: { | ||
| 93 | if (trayItemArea.containsMouse) | ||
| 94 | return "#33808080"; | ||
| 95 | return "transparent"; | ||
| 96 | } | ||
| 97 | |||
| 98 | Item { | ||
| 99 | anchors.fill: parent | ||
| 100 | |||
| 101 | layer.enabled: true | ||
| 102 | layer.effect: MultiEffect { | ||
| 103 | colorization: 1 | ||
| 104 | colorizationColor: "#555" | ||
| 105 | } | ||
| 106 | |||
| 107 | IconImage { | ||
| 108 | id: icon | ||
| 109 | |||
| 110 | anchors.centerIn: parent | ||
| 111 | implicitSize: 16 | ||
| 112 | source: trayItemWrapper.iconSource | ||
| 113 | asynchronous: true | ||
| 114 | smooth: true | ||
| 115 | mipmap: true | ||
| 116 | |||
| 117 | layer.enabled: true | ||
| 118 | layer.effect: MultiEffect { | ||
| 119 | id: effect | ||
| 120 | |||
| 121 | brightness: 1 | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | PopupWindow { | ||
| 129 | id: tooltip | ||
| 130 | |||
| 131 | property bool nextVisible: (trayItem.tooltipTitle || trayItem.tooltipDescription) && (trayItemArea.containsMouse || tooltipMouseArea.containsMouse) && !menuAnchor.visible | ||
| 132 | |||
| 133 | anchor { | ||
| 134 | item: trayItemArea | ||
| 135 | edges: Edges.Bottom | ||
| 136 | } | ||
| 137 | |||
| 138 | visible: false | ||
| 139 | onNextVisibleChanged: hangTimer.restart() | ||
| 140 | |||
| 141 | Timer { | ||
| 142 | id: hangTimer | ||
| 143 | interval: 100 | ||
| 144 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 145 | } | ||
| 146 | |||
| 147 | color: "black" | ||
| 148 | |||
| 149 | implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16 | ||
| 150 | implicitHeight: (trayItem.tooltipTitle ? tooltipTitle.contentHeight : 0) + (trayItem.tooltipDescription ? tooltipDescription.contentHeight : 0) + 16 | ||
| 151 | |||
| 152 | WrapperMouseArea { | ||
| 153 | id: tooltipMouseArea | ||
| 154 | |||
| 155 | hoverEnabled: true | ||
| 156 | enabled: true | ||
| 157 | |||
| 158 | margin: 4 | ||
| 159 | |||
| 160 | anchors.fill: parent | ||
| 161 | |||
| 162 | Item { | ||
| 163 | anchors.fill: parent | ||
| 164 | |||
| 165 | Column { | ||
| 166 | anchors.centerIn: parent | ||
| 167 | Text { | ||
| 168 | id: tooltipTitle | ||
| 169 | |||
| 170 | enabled: trayItem.tooltipTitle | ||
| 171 | |||
| 172 | font.pointSize: 10 | ||
| 173 | font.family: "Fira Sans" | ||
| 174 | font.bold: true | ||
| 175 | color: "white" | ||
| 176 | |||
| 177 | text: trayItem.tooltipTitle | ||
| 178 | } | ||
| 179 | |||
| 180 | Text { | ||
| 181 | id: tooltipDescription | ||
| 182 | |||
| 183 | enabled: trayItem.tooltipDescription | ||
| 184 | |||
| 185 | font.pointSize: 10 | ||
| 186 | font.family: "Fira Sans" | ||
| 187 | color: "white" | ||
| 188 | |||
| 189 | text: trayItem.tooltipDescription | ||
| 190 | } | ||
| 191 | } | ||
| 192 | } | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | QsMenuAnchor { | ||
| 199 | id: menuAnchor | ||
| 200 | } | ||
| 201 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/UnixIPC.qml b/accounts/gkleen@skadhi/shell/quickshell/UnixIPC.qml new file mode 100644 index 00000000..3d950031 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/UnixIPC.qml | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | import Quickshell | ||
| 2 | import Quickshell.Io | ||
| 3 | import Quickshell.Services.Pipewire | ||
| 4 | import Quickshell.Services.Mpris | ||
| 5 | import qs.Services | ||
| 6 | import Custom as Custom | ||
| 7 | import QtQml | ||
| 8 | |||
| 9 | Scope { | ||
| 10 | id: root | ||
| 11 | |||
| 12 | SocketServer { | ||
| 13 | active: true | ||
| 14 | path: `${Quickshell.env("XDG_RUNTIME_DIR")}/shell.sock` | ||
| 15 | handler: Socket { | ||
| 16 | parser: SplitParser { | ||
| 17 | onRead: line => { | ||
| 18 | const command = (() => { | ||
| 19 | try { | ||
| 20 | return JSON.parse(line); | ||
| 21 | } catch (e) { | ||
| 22 | console.warn("UnixIPC: Failed to parse command:", line, e); | ||
| 23 | } | ||
| 24 | })(); | ||
| 25 | if (!command) | ||
| 26 | return; | ||
| 27 | |||
| 28 | if (command.Volume) | ||
| 29 | root.onCommandVolume(command.Volume); | ||
| 30 | else if (command.Brightness) | ||
| 31 | root.onCommandBrightness(command.Brightness); | ||
| 32 | else if (command.LockSession) | ||
| 33 | Custom.Systemd.lockSession(); | ||
| 34 | else if (command.Suspend) | ||
| 35 | Custom.Systemd.suspend(); | ||
| 36 | else if (command.Hibernate) | ||
| 37 | Custom.Systemd.hibernate(); | ||
| 38 | else if (command.Mpris) | ||
| 39 | root.onCommandMpris(command.Mpris); | ||
| 40 | else if (command.Notifications) | ||
| 41 | root.onCommandNotifications(command.Notifications); | ||
| 42 | else if (command.ScreenRecord) | ||
| 43 | root.onCommandScreenRecord(command.ScreenRecord); | ||
| 44 | else | ||
| 45 | console.warn("UnixIPC: Command not handled:", JSON.stringify(command)); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | onError: e => { | ||
| 50 | if (e == 1) | ||
| 51 | return; | ||
| 52 | console.warn("QLocalSocket::LocalSocketError", e); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | PwObjectTracker { | ||
| 58 | objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ] | ||
| 59 | } | ||
| 60 | function onCommandVolume(command) { | ||
| 61 | if (command.muted === "toggle") | ||
| 62 | Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted; | ||
| 63 | if (command.volume === "up") | ||
| 64 | Pipewire.defaultAudioSink.audio.volume += 0.02; | ||
| 65 | if (command.volume === "down") | ||
| 66 | Pipewire.defaultAudioSink.audio.volume -= 0.02; | ||
| 67 | |||
| 68 | if (command["mic-muted"] === "toggle") | ||
| 69 | Pipewire.defaultAudioSource.audio.muted = !Pipewire.defaultAudioSource.audio.muted; | ||
| 70 | } | ||
| 71 | |||
| 72 | function onCommandBrightness(command) { | ||
| 73 | if (command === "up") | ||
| 74 | Brightness.currBrightness += 0.02 | ||
| 75 | if (command === "down") | ||
| 76 | Brightness.currBrightness -= 0.02 | ||
| 77 | } | ||
| 78 | |||
| 79 | function onCommandMpris(command) { | ||
| 80 | if (command.PauseAll) | ||
| 81 | Array.from(MprisProxy.players).forEach(player => { | ||
| 82 | if (player.canPause && player.isPlaying) | ||
| 83 | player.pause(); | ||
| 84 | }); | ||
| 85 | } | ||
| 86 | Component.onCompleted: { (_ => {})(MprisProxy.players); } | ||
| 87 | |||
| 88 | function onCommandNotifications(command) { | ||
| 89 | if (command.DismissGroup && NotificationManager.active) { | ||
| 90 | if (NotificationManager.groups.length > 0) | ||
| 91 | for (const notif of [...NotificationManager.groups[0]]) | ||
| 92 | notif.dismiss(); | ||
| 93 | } | ||
| 94 | if (command.DismissAll && NotificationManager.active) { | ||
| 95 | for (const notif of [...NotificationManager.trackedNotifications.values]) | ||
| 96 | notif.dismiss(); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | function onCommandScreenRecord(command) { | ||
| 101 | if (command.Toggle) | ||
| 102 | ScreenRecord.active = !ScreenRecord.active; | ||
| 103 | else | ||
| 104 | console.warn("UnixIPC.ScreenRecord: Command not handled:", JSON.stringify(command)); | ||
| 105 | } | ||
| 106 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml b/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml new file mode 100644 index 00000000..91dc9591 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/VolumeOSD.qml | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | import QtQuick | ||
| 2 | import QtQuick.Layouts | ||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Services.Pipewire | ||
| 5 | import Quickshell.Widgets | ||
| 6 | |||
| 7 | Scope { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | property string show: "" | ||
| 11 | property bool inhibited: true | ||
| 12 | |||
| 13 | PwObjectTracker { | ||
| 14 | objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ] | ||
| 15 | } | ||
| 16 | |||
| 17 | Connections { | ||
| 18 | enabled: Pipewire.defaultAudioSink | ||
| 19 | target: Pipewire.defaultAudioSink?.audio || null | ||
| 20 | |||
| 21 | function onVolumeChanged() { | ||
| 22 | root.show = "sink"; | ||
| 23 | hideTimer.restart(); | ||
| 24 | } | ||
| 25 | function onMutedChanged() { | ||
| 26 | root.show = "sink"; | ||
| 27 | hideTimer.restart(); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | Connections { | ||
| 32 | enabled: Pipewire.defaultAudioSource | ||
| 33 | target: Pipewire.defaultAudioSource?.audio || null | ||
| 34 | |||
| 35 | function onVolumeChanged() { | ||
| 36 | root.show = "source"; | ||
| 37 | hideTimer.restart(); | ||
| 38 | } | ||
| 39 | function onMutedChanged() { | ||
| 40 | root.show = "source"; | ||
| 41 | hideTimer.restart(); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | onShowChanged: { | ||
| 46 | if (show) | ||
| 47 | hideTimer.restart(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Timer { | ||
| 51 | id: hideTimer | ||
| 52 | interval: 1000 | ||
| 53 | onTriggered: root.show = "" | ||
| 54 | } | ||
| 55 | |||
| 56 | Timer { | ||
| 57 | id: startInhibit | ||
| 58 | interval: 100 | ||
| 59 | running: true | ||
| 60 | onTriggered: { | ||
| 61 | root.show = ""; | ||
| 62 | root.inhibited = false; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | LazyLoader { | ||
| 67 | active: root.show && !root.inhibited | ||
| 68 | |||
| 69 | Variants { | ||
| 70 | model: Quickshell.screens | ||
| 71 | |||
| 72 | delegate: Scope { | ||
| 73 | id: screenScope | ||
| 74 | |||
| 75 | required property var modelData | ||
| 76 | |||
| 77 | PanelWindow { | ||
| 78 | id: window | ||
| 79 | |||
| 80 | screen: screenScope.modelData | ||
| 81 | |||
| 82 | anchors.top: true | ||
| 83 | margins.top: screen.height / 2 - 50 + 3.5 | ||
| 84 | exclusiveZone: 0 | ||
| 85 | exclusionMode: ExclusionMode.Ignore | ||
| 86 | |||
| 87 | implicitWidth: 400 | ||
| 88 | implicitHeight: 50 | ||
| 89 | |||
| 90 | mask: Region {} | ||
| 91 | |||
| 92 | color: "transparent" | ||
| 93 | |||
| 94 | Rectangle { | ||
| 95 | anchors.fill: parent | ||
| 96 | color: Qt.rgba(0, 0, 0, 0.75) | ||
| 97 | } | ||
| 98 | |||
| 99 | RowLayout { | ||
| 100 | id: layout | ||
| 101 | |||
| 102 | anchors.centerIn: parent | ||
| 103 | |||
| 104 | height: 50 - 8*2 | ||
| 105 | width: 400 - 8*2 | ||
| 106 | |||
| 107 | MaterialDesignIcon { | ||
| 108 | id: volumeIcon | ||
| 109 | |||
| 110 | implicitWidth: parent.height | ||
| 111 | implicitHeight: parent.height | ||
| 112 | |||
| 113 | icon: { | ||
| 114 | if (root.show == "sink") { | ||
| 115 | if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) | ||
| 116 | return "volume-off"; | ||
| 117 | if (Pipewire.defaultAudioSink.audio.volume <= 0.33) | ||
| 118 | return "volume-low"; | ||
| 119 | if (Pipewire.defaultAudioSink.audio.volume <= 0.67) | ||
| 120 | return "volume-medium"; | ||
| 121 | return "volume-high"; | ||
| 122 | } else if (root.show == "source") { | ||
| 123 | if (!Pipewire.defaultAudioSource || Pipewire.defaultAudioSource.audio.muted) | ||
| 124 | return "microphone-off"; | ||
| 125 | if (Pipewire.defaultAudioSource.audio.volume > 1) | ||
| 126 | return "microphone-plus"; | ||
| 127 | return "microphone"; | ||
| 128 | } | ||
| 129 | return "volume-high"; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | Rectangle { | ||
| 134 | Layout.fillWidth: true | ||
| 135 | |||
| 136 | implicitHeight: 10 | ||
| 137 | |||
| 138 | color: "#50ffffff" | ||
| 139 | |||
| 140 | Rectangle { | ||
| 141 | anchors { | ||
| 142 | left: parent.left | ||
| 143 | top: parent.top | ||
| 144 | bottom: parent.bottom | ||
| 145 | } | ||
| 146 | |||
| 147 | color: Pipewire.defaultAudioSink?.audio.muted ? "#70ffffff" : "white" | ||
| 148 | |||
| 149 | implicitWidth: { | ||
| 150 | if (root.show == "sink") | ||
| 151 | return parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0); | ||
| 152 | else if (root.show == "source") | ||
| 153 | return parent.width * Math.min(1, (Pipewire.defaultAudioSource?.audio.volume ?? 0)); | ||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| 163 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/WallpaperBackground.qml b/accounts/gkleen@skadhi/shell/quickshell/WallpaperBackground.qml new file mode 100644 index 00000000..4f85a900 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/WallpaperBackground.qml | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | import QtQuick | ||
| 2 | import Quickshell | ||
| 3 | import qs.Services | ||
| 4 | |||
| 5 | Item { | ||
| 6 | id: root | ||
| 7 | |||
| 8 | anchors.fill: parent | ||
| 9 | |||
| 10 | required property string screen | ||
| 11 | |||
| 12 | property Img current: one | ||
| 13 | property string source: selector.selected | ||
| 14 | |||
| 15 | WallpaperSelector { | ||
| 16 | id: selector | ||
| 17 | seed: screen | ||
| 18 | } | ||
| 19 | |||
| 20 | onSourceChanged: { | ||
| 21 | if (!source) | ||
| 22 | current = null; | ||
| 23 | else if (current === one) | ||
| 24 | two.update() | ||
| 25 | else | ||
| 26 | one.update() | ||
| 27 | } | ||
| 28 | |||
| 29 | Img { id: one } | ||
| 30 | Img { id: two } | ||
| 31 | |||
| 32 | component Img: Image { | ||
| 33 | id: img | ||
| 34 | |||
| 35 | function update() { | ||
| 36 | source = root.source || "" | ||
| 37 | } | ||
| 38 | |||
| 39 | anchors.fill: parent | ||
| 40 | fillMode: Image.PreserveAspectCrop | ||
| 41 | smooth: true | ||
| 42 | asynchronous: true | ||
| 43 | cache: false | ||
| 44 | |||
| 45 | opacity: 0 | ||
| 46 | |||
| 47 | onStatusChanged: { | ||
| 48 | if (status === Image.Ready) { | ||
| 49 | root.current = this | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | states: State { | ||
| 54 | name: "visible" | ||
| 55 | when: root.current === img | ||
| 56 | |||
| 57 | PropertyChanges { | ||
| 58 | img.opacity: 1 | ||
| 59 | } | ||
| 60 | StateChangeScript { | ||
| 61 | name: "unloadOther" | ||
| 62 | script: { | ||
| 63 | if (img === one) | ||
| 64 | two.source = "" | ||
| 65 | if (img === two) | ||
| 66 | one.source = "" | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | transitions: Transition { | ||
| 72 | SequentialAnimation { | ||
| 73 | NumberAnimation { | ||
| 74 | target: img | ||
| 75 | properties: "opacity" | ||
| 76 | duration: { | ||
| 77 | if (img === one && two.source == "" || img === two && one.source == "") | ||
| 78 | return 0; | ||
| 79 | return 5000; | ||
| 80 | } | ||
| 81 | easing.type: Easing.OutCubic | ||
| 82 | } | ||
| 83 | ScriptAction { | ||
| 84 | scriptName: "unloadOther" | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/WaylandInhibitorWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/WaylandInhibitorWidget.qml new file mode 100644 index 00000000..0512ff51 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/WaylandInhibitorWidget.qml | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import Quickshell.Widgets | ||
| 4 | import Quickshell.Wayland | ||
| 5 | import qs.Services | ||
| 6 | |||
| 7 | Item { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | required property var window | ||
| 11 | |||
| 12 | width: icon.width + 8 | ||
| 13 | height: parent.height | ||
| 14 | anchors.verticalCenter: parent.verticalCenter | ||
| 15 | |||
| 16 | IdleInhibitor { | ||
| 17 | id: inhibitor | ||
| 18 | enabled: InhibitorState.waylandIdleInhibited | ||
| 19 | window: root.window | ||
| 20 | } | ||
| 21 | |||
| 22 | WrapperMouseArea { | ||
| 23 | id: widgetMouseArea | ||
| 24 | |||
| 25 | anchors.fill: parent | ||
| 26 | |||
| 27 | hoverEnabled: true | ||
| 28 | cursorShape: Qt.PointingHandCursor | ||
| 29 | |||
| 30 | onClicked: InhibitorState.waylandIdleInhibited = !InhibitorState.waylandIdleInhibited | ||
| 31 | |||
| 32 | Rectangle { | ||
| 33 | anchors.fill: parent | ||
| 34 | color: { | ||
| 35 | if (widgetMouseArea.containsMouse) { | ||
| 36 | return "#33808080"; | ||
| 37 | } | ||
| 38 | return "transparent"; | ||
| 39 | } | ||
| 40 | |||
| 41 | Item { | ||
| 42 | anchors.fill: parent | ||
| 43 | |||
| 44 | MaterialDesignIcon { | ||
| 45 | id: icon | ||
| 46 | |||
| 47 | implicitSize: 14 | ||
| 48 | anchors.centerIn: parent | ||
| 49 | |||
| 50 | icon: inhibitor.enabled ? "eye" : "eye-off" | ||
| 51 | color: inhibitor.enabled ? "white" : "#555" | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/WorkspaceSwitcher.qml b/accounts/gkleen@skadhi/shell/quickshell/WorkspaceSwitcher.qml new file mode 100644 index 00000000..a893937a --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/WorkspaceSwitcher.qml | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | import Quickshell | ||
| 2 | import QtQuick | ||
| 3 | import qs.Services | ||
| 4 | import Quickshell.Widgets | ||
| 5 | import QtQuick.Layouts | ||
| 6 | |||
| 7 | Row { | ||
| 8 | id: workspaces | ||
| 9 | |||
| 10 | required property var screen | ||
| 11 | |||
| 12 | property var ignoreWorkspaces: @ignore_workspaces@ | ||
| 13 | |||
| 14 | height: parent.height | ||
| 15 | anchors.verticalCenter: parent.verticalCenter | ||
| 16 | spacing: 0 | ||
| 17 | |||
| 18 | Repeater { | ||
| 19 | model: ScriptModel { | ||
| 20 | values: { | ||
| 21 | let currWorkspaces = NiriService.workspaces; | ||
| 22 | const ignoreWorkspaces = Array.from(workspaces.ignoreWorkspaces); | ||
| 23 | currWorkspaces = currWorkspaces.filter(ws => ws.output == workspaces.screen?.name).filter(ws => ws.is_active || ignoreWorkspaces.every(iws => iws !== ws.name)); | ||
| 24 | currWorkspaces.sort((a, b) => { | ||
| 25 | if (NiriService.outputs?.[a.output]?.logical?.x !== NiriService.outputs?.[b.output]?.logical?.x) | ||
| 26 | return NiriService.outputs?.[a.output]?.logical?.x - NiriService.outputs?.[b.output]?.logical?.x | ||
| 27 | if (NiriService.outputs?.[a.output]?.logical?.y !== NiriService.outputs?.[b.output]?.logical?.y) | ||
| 28 | return NiriService.outputs?.[a.output]?.logical?.y - NiriService.outputs?.[b.output]?.logical?.y | ||
| 29 | return a.idx - b.idx; | ||
| 30 | }); | ||
| 31 | return currWorkspaces.map(o => Object.assign({}, o)); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | Item { | ||
| 36 | id: wsItem | ||
| 37 | |||
| 38 | property var workspaceData: modelData | ||
| 39 | |||
| 40 | width: wsLabel.contentWidth + 8 | ||
| 41 | height: parent.height | ||
| 42 | anchors.verticalCenter: parent.verticalCenter | ||
| 43 | |||
| 44 | WrapperMouseArea { | ||
| 45 | id: mouseArea | ||
| 46 | |||
| 47 | anchors.fill: parent | ||
| 48 | |||
| 49 | hoverEnabled: true | ||
| 50 | cursorShape: Qt.PointingHandCursor | ||
| 51 | enabled: true | ||
| 52 | onClicked: { | ||
| 53 | NiriService.sendCommand({ "Action": { "FocusWorkspace": { "reference": { "Id": workspaceData.id } } } }, _ => {}); | ||
| 54 | } | ||
| 55 | |||
| 56 | Rectangle { | ||
| 57 | anchors.fill: parent | ||
| 58 | |||
| 59 | color: { | ||
| 60 | if (mouseArea.containsMouse) { | ||
| 61 | return "#33808080"; | ||
| 62 | } | ||
| 63 | return "transparent"; | ||
| 64 | } | ||
| 65 | |||
| 66 | Text { | ||
| 67 | id: wsLabel | ||
| 68 | |||
| 69 | anchors.centerIn: parent | ||
| 70 | |||
| 71 | font.pointSize: 10 | ||
| 72 | font.family: "Fira Sans" | ||
| 73 | color: { | ||
| 74 | if (workspaceData.is_active) | ||
| 75 | return "#23fd00"; | ||
| 76 | if (workspaceData.active_window_id === null) | ||
| 77 | return "#555"; | ||
| 78 | return "white"; | ||
| 79 | } | ||
| 80 | |||
| 81 | text: workspaceData.name ? workspaceData.name : workspaceData.idx | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | PopupWindow { | ||
| 87 | id: tooltip | ||
| 88 | |||
| 89 | property bool nextVisible: (mouseArea.containsMouse || tooltipMouseArea.containsMouse) && [...windowsModel.values].length > 0 | ||
| 90 | |||
| 91 | anchor { | ||
| 92 | item: mouseArea | ||
| 93 | edges: Edges.Bottom | Edges.Left | ||
| 94 | } | ||
| 95 | visible: false | ||
| 96 | |||
| 97 | onNextVisibleChanged: hangTimer.restart() | ||
| 98 | |||
| 99 | Timer { | ||
| 100 | id: hangTimer | ||
| 101 | interval: 100 | ||
| 102 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 103 | } | ||
| 104 | |||
| 105 | implicitWidth: tooltipContent.implicitWidth | ||
| 106 | implicitHeight: tooltipContent.implicitHeight | ||
| 107 | color: "black" | ||
| 108 | |||
| 109 | WrapperMouseArea { | ||
| 110 | id: tooltipMouseArea | ||
| 111 | |||
| 112 | hoverEnabled: true | ||
| 113 | enabled: true | ||
| 114 | |||
| 115 | anchors.fill: parent | ||
| 116 | |||
| 117 | WrapperItem { | ||
| 118 | id: tooltipContent | ||
| 119 | |||
| 120 | margin: 0 | ||
| 121 | |||
| 122 | ColumnLayout { | ||
| 123 | spacing: 0 | ||
| 124 | |||
| 125 | Repeater { | ||
| 126 | model: ScriptModel { | ||
| 127 | id: windowsModel | ||
| 128 | |||
| 129 | values: { | ||
| 130 | let currWindows = NiriService.windows.filter(win => win.workspace_id == wsItem.workspaceData.id); | ||
| 131 | currWindows.sort((a, b) => { | ||
| 132 | if (a.is_floating !== b.is_floating) | ||
| 133 | return b.is_floating - a.is_floating; | ||
| 134 | if (a.layout.tile_pos_in_workspace_view?.[0] !== b.layout.tile_pos_in_workspace_view?.[0]) | ||
| 135 | return a.layout.tile_pos_in_workspace_view?.[0] - b.layout.tile_pos_in_workspace_view?.[0] | ||
| 136 | if (a.layout.tile_pos_in_workspace_view?.[1] !== b.layout.tile_pos_in_workspace_view?.[1]) | ||
| 137 | return a.layout.tile_pos_in_workspace_view?.[1] - b.layout.tile_pos_in_workspace_view?.[1] | ||
| 138 | if (a.layout.pos_in_scrolling_layout?.[0] !== b.layout.pos_in_scrolling_layout?.[0]) | ||
| 139 | return a.layout.pos_in_scrolling_layout?.[0] - b.layout.pos_in_scrolling_layout?.[0] | ||
| 140 | if (a.layout.pos_in_scrolling_layout?.[1] !== b.layout.pos_in_scrolling_layout?.[1]) | ||
| 141 | return a.layout.pos_in_scrolling_layout?.[1] - b.layout.pos_in_scrolling_layout?.[1] | ||
| 142 | if (a.app_id !== b.app_id) | ||
| 143 | return a.app_id?.localeCompare(b.app_id); | ||
| 144 | |||
| 145 | return a.title.localeCompare(b.title); | ||
| 146 | }); | ||
| 147 | return currWindows.map(o => Object.assign({}, o)); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | WrapperMouseArea { | ||
| 152 | id: windowMouseArea | ||
| 153 | |||
| 154 | required property int index | ||
| 155 | required property var modelData | ||
| 156 | property var windowData: modelData | ||
| 157 | |||
| 158 | hoverEnabled: true | ||
| 159 | cursorShape: Qt.PointingHandCursor | ||
| 160 | enabled: true | ||
| 161 | |||
| 162 | Layout.fillWidth: true | ||
| 163 | |||
| 164 | onClicked: { | ||
| 165 | NiriService.sendCommand({ "Action": { "FocusWindow": { "id": windowData.id } } }, _ => {}) | ||
| 166 | } | ||
| 167 | |||
| 168 | WrapperRectangle { | ||
| 169 | color: windowMouseArea.containsMouse ? "#33808080" : "transparent"; | ||
| 170 | |||
| 171 | WrapperItem { | ||
| 172 | rightMargin: 8 | ||
| 173 | leftMargin: 8 | ||
| 174 | topMargin: windowMouseArea.index == 0 ? 8 : 4 | ||
| 175 | bottomMargin: windowMouseArea.index == windowsModel.values.length - 1 ? 8 : 4 | ||
| 176 | |||
| 177 | Text { | ||
| 178 | id: windowLabel | ||
| 179 | |||
| 180 | font.pointSize: 10 | ||
| 181 | font.family: "Fira Sans" | ||
| 182 | color: { | ||
| 183 | if (windowData.is_focused) | ||
| 184 | return "#23fd00"; | ||
| 185 | if (NiriService.workspaces.find(ws => ws.id == windowData.workspace_id)?.active_window_id == windowData.id) | ||
| 186 | return "white"; | ||
| 187 | return "#555"; | ||
| 188 | } | ||
| 189 | |||
| 190 | text: windowData.title | ||
| 191 | |||
| 192 | horizontalAlignment: Text.AlignLeft | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/WorktimeWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/WorktimeWidget.qml new file mode 100644 index 00000000..b7baee34 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/WorktimeWidget.qml | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | import QtQml | ||
| 2 | import Quickshell | ||
| 3 | import QtQuick | ||
| 4 | import Quickshell.Widgets | ||
| 5 | import qs.Services | ||
| 6 | |||
| 7 | Item { | ||
| 8 | id: root | ||
| 9 | |||
| 10 | height: parent.height | ||
| 11 | width: (timeWidget.visible ? timeWidget.label.contentWidth + 8 : 0) + (todayWidget.visible ? todayWidget.label.contentWidth + 8 : 0) + (icon.visible ? icon.implicitWidth + 8 : 0) | ||
| 12 | anchors.verticalCenter: parent.verticalCenter | ||
| 13 | |||
| 14 | component TextWidget : Item { | ||
| 15 | id: textWidget | ||
| 16 | |||
| 17 | visible: textWidget.state.state?.text ?? false | ||
| 18 | |||
| 19 | required property var state | ||
| 20 | property alias label: label | ||
| 21 | property alias mouseArea: mouseArea | ||
| 22 | |||
| 23 | anchors.verticalCenter: parent.verticalCenter | ||
| 24 | implicitWidth: label.contentWidth + 8 | ||
| 25 | height: parent.height | ||
| 26 | |||
| 27 | WrapperMouseArea { | ||
| 28 | id: mouseArea | ||
| 29 | |||
| 30 | anchors.fill: parent | ||
| 31 | |||
| 32 | enabled: true | ||
| 33 | hoverEnabled: true | ||
| 34 | acceptedButtons: Qt.NoButton | ||
| 35 | cursorShape: Qt.PointingHandCursor | ||
| 36 | |||
| 37 | Item { | ||
| 38 | anchors.fill: parent | ||
| 39 | |||
| 40 | Text { | ||
| 41 | id: label | ||
| 42 | |||
| 43 | anchors.centerIn: parent | ||
| 44 | |||
| 45 | text: textWidget.state.state?.text ?? "" | ||
| 46 | |||
| 47 | font.pointSize: 10 | ||
| 48 | font.family: "Fira Sans" | ||
| 49 | font.strikeout: textWidget.state.strikeout | ||
| 50 | color: { | ||
| 51 | if (textWidget.state.state?.class == "running") | ||
| 52 | return "white"; | ||
| 53 | if (textWidget.state.state?.class == "over") | ||
| 54 | return "#f28a21"; | ||
| 55 | return "#555"; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | WrapperMouseArea { | ||
| 63 | id: mouseArea | ||
| 64 | |||
| 65 | anchors.fill: parent | ||
| 66 | hoverEnabled: true | ||
| 67 | |||
| 68 | cursorShape: Qt.PointingHandCursor | ||
| 69 | onClicked: { | ||
| 70 | Worktime.time.running = true; | ||
| 71 | Worktime.today.running = true; | ||
| 72 | } | ||
| 73 | |||
| 74 | Rectangle { | ||
| 75 | anchors.fill: parent | ||
| 76 | color: { | ||
| 77 | if (mouseArea.containsMouse) | ||
| 78 | return "#33808080"; | ||
| 79 | return "transparent"; | ||
| 80 | } | ||
| 81 | |||
| 82 | Row { | ||
| 83 | height: parent.height | ||
| 84 | anchors.centerIn: parent | ||
| 85 | spacing: 0 | ||
| 86 | |||
| 87 | TextWidget { | ||
| 88 | id: timeWidget | ||
| 89 | state: Worktime.time | ||
| 90 | } | ||
| 91 | |||
| 92 | TextWidget { | ||
| 93 | id: todayWidget | ||
| 94 | state: Worktime.today | ||
| 95 | } | ||
| 96 | |||
| 97 | MaterialDesignIcon { | ||
| 98 | id: icon | ||
| 99 | |||
| 100 | anchors.verticalCenter: parent.verticalCenter | ||
| 101 | |||
| 102 | implicitSize: 14 | ||
| 103 | |||
| 104 | visible: !timeWidget.visible && !todayWidget.visible | ||
| 105 | |||
| 106 | icon: (Worktime.time.running || Worktime.today.running) ? "update" : "timer-off" | ||
| 107 | color: "#555" | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | component WorktimePopup : PopupWindow { | ||
| 114 | id: tooltip | ||
| 115 | |||
| 116 | required property var state | ||
| 117 | required property var mouseArea | ||
| 118 | |||
| 119 | property bool iconVisible: tooltip.state.running || !tooltip.state.updating | ||
| 120 | property bool tooltipVisible: tooltip.state.state?.tooltip ?? false | ||
| 121 | |||
| 122 | property bool nextVisible: (tooltip.tooltipVisible || tooltip.iconVisible) && (tooltip.mouseArea.containsMouse || tooltipMouseArea.containsMouse) | ||
| 123 | |||
| 124 | anchor { | ||
| 125 | item: tooltip.mouseArea | ||
| 126 | edges: Edges.Bottom | Edges.Left | ||
| 127 | } | ||
| 128 | visible: false | ||
| 129 | |||
| 130 | onNextVisibleChanged: hangTimer.restart() | ||
| 131 | |||
| 132 | Timer { | ||
| 133 | id: hangTimer | ||
| 134 | interval: 100 | ||
| 135 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 136 | } | ||
| 137 | |||
| 138 | implicitWidth: (tooltipIcon.visible ? tooltipIcon.implicitWidth : 0) + (tooltipIcon.visible && tooltipText.visible ? 8 : 0) + (tooltipText.visible ? tooltipText.implicitWidth : 0) + 16 | ||
| 139 | implicitHeight: tooltipText.implicitHeight + 16 | ||
| 140 | color: "black" | ||
| 141 | |||
| 142 | WrapperMouseArea { | ||
| 143 | id: tooltipMouseArea | ||
| 144 | |||
| 145 | enabled: true | ||
| 146 | hoverEnabled: true | ||
| 147 | |||
| 148 | anchors.fill: parent | ||
| 149 | |||
| 150 | Item { | ||
| 151 | anchors.fill: parent | ||
| 152 | |||
| 153 | Row { | ||
| 154 | id: tooltipLayout | ||
| 155 | |||
| 156 | anchors { | ||
| 157 | left: parent.left | ||
| 158 | top: parent.top | ||
| 159 | leftMargin: 8 | ||
| 160 | topMargin: 8 | ||
| 161 | verticalCenter: parent.verticalCenter | ||
| 162 | } | ||
| 163 | |||
| 164 | height: parent.height | ||
| 165 | width: childrenRect.width | ||
| 166 | |||
| 167 | spacing: 0 | ||
| 168 | |||
| 169 | MaterialDesignIcon { | ||
| 170 | id: tooltipIcon | ||
| 171 | |||
| 172 | implicitSize: 14 | ||
| 173 | anchors.verticalCenter: parent.verticalCenter | ||
| 174 | |||
| 175 | visible: tooltip.iconVisible | ||
| 176 | |||
| 177 | icon: tooltip.state.running ? "update" : "timer-off" | ||
| 178 | } | ||
| 179 | |||
| 180 | Item { | ||
| 181 | visible: tooltipIcon.visible && tooltipText.visible | ||
| 182 | height: parent.height | ||
| 183 | width: 8 | ||
| 184 | } | ||
| 185 | |||
| 186 | Text { | ||
| 187 | id: tooltipText | ||
| 188 | |||
| 189 | visible: tooltip.tooltipVisible | ||
| 190 | |||
| 191 | anchors.verticalCenter: parent.verticalCenter | ||
| 192 | |||
| 193 | font.pointSize: 10 | ||
| 194 | font.family: "Fira Sans" | ||
| 195 | color: "white" | ||
| 196 | |||
| 197 | text: tooltip.state.state?.tooltip ?? "" | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | WorktimePopup { | ||
| 205 | state: Worktime.time | ||
| 206 | mouseArea: timeWidget.mouseArea | ||
| 207 | } | ||
| 208 | WorktimePopup { | ||
| 209 | state: Worktime.today | ||
| 210 | mouseArea: todayWidget.mouseArea | ||
| 211 | } | ||
| 212 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/YtDlpWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/YtDlpWidget.qml new file mode 100644 index 00000000..ff338d49 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/YtDlpWidget.qml | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | import QtQml.Models | ||
| 2 | import QtQuick | ||
| 3 | import QtQuick.Layouts | ||
| 4 | import QtQuick.Controls.Material | ||
| 5 | import Quickshell | ||
| 6 | import Quickshell.Io | ||
| 7 | import Quickshell.Widgets | ||
| 8 | import Custom as Custom | ||
| 9 | |||
| 10 | Item { | ||
| 11 | id: root | ||
| 12 | |||
| 13 | height: parent.height | ||
| 14 | width: icon.width | ||
| 15 | anchors.verticalCenter: parent.verticalCenter | ||
| 16 | |||
| 17 | visible: Boolean(unitsModel.values.length) | ||
| 18 | |||
| 19 | WrapperMouseArea { | ||
| 20 | id: widgetMouseArea | ||
| 21 | |||
| 22 | anchors.fill: parent | ||
| 23 | hoverEnabled: true | ||
| 24 | |||
| 25 | Item { | ||
| 26 | anchors.fill: parent | ||
| 27 | |||
| 28 | MaterialDesignIcon { | ||
| 29 | id: icon | ||
| 30 | |||
| 31 | implicitSize: 14 | ||
| 32 | anchors.centerIn: parent | ||
| 33 | |||
| 34 | icon: "tray-arrow-down" | ||
| 35 | color: "white" | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | PopupWindow { | ||
| 41 | id: tooltip | ||
| 42 | |||
| 43 | property bool openPopup: false | ||
| 44 | property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse || openPopup | ||
| 45 | |||
| 46 | anchor { | ||
| 47 | item: widgetMouseArea | ||
| 48 | edges: Edges.Bottom | Edges.Left | ||
| 49 | } | ||
| 50 | visible: false | ||
| 51 | |||
| 52 | onNextVisibleChanged: hangTimer.restart() | ||
| 53 | |||
| 54 | Timer { | ||
| 55 | id: hangTimer | ||
| 56 | interval: 100 | ||
| 57 | onTriggered: tooltip.visible = tooltip.nextVisible | ||
| 58 | } | ||
| 59 | |||
| 60 | implicitWidth: tooltipContent.width | ||
| 61 | implicitHeight: tooltipContent.height | ||
| 62 | color: "transparent" | ||
| 63 | |||
| 64 | Rectangle { | ||
| 65 | width: tooltip.width | ||
| 66 | height: tooltipLayout.childrenRect.height + 16 | ||
| 67 | color: "black" | ||
| 68 | } | ||
| 69 | |||
| 70 | WrapperItem { | ||
| 71 | id: tooltipContent | ||
| 72 | |||
| 73 | WrapperMouseArea { | ||
| 74 | id: tooltipMouseArea | ||
| 75 | |||
| 76 | hoverEnabled: true | ||
| 77 | enabled: true | ||
| 78 | |||
| 79 | WrapperItem { | ||
| 80 | margin: 8 | ||
| 81 | |||
| 82 | child: GridLayout { | ||
| 83 | id: tooltipLayout | ||
| 84 | |||
| 85 | columns: 2 | ||
| 86 | } | ||
| 87 | |||
| 88 | Repeater { | ||
| 89 | model: ScriptModel { | ||
| 90 | id: unitsModel | ||
| 91 | |||
| 92 | values: [...Custom.Systemd.userUnits.values].filter(unit => unit.id.match(/^yt-dlp@.+\.service$/) && unit.activeState === "active" && unit.runtimeDirectory) | ||
| 93 | } | ||
| 94 | |||
| 95 | Item { | ||
| 96 | id: unitDelegate | ||
| 97 | |||
| 98 | Component.onCompleted: { | ||
| 99 | while (children.length) { children[0].parent = tooltipLayout; } | ||
| 100 | } | ||
| 101 | |||
| 102 | required property var modelData | ||
| 103 | required property int index | ||
| 104 | |||
| 105 | property var state: null | ||
| 106 | |||
| 107 | Socket { | ||
| 108 | id: socket | ||
| 109 | |||
| 110 | path: Quickshell.env("XDG_RUNTIME_DIR") + "/" + unitDelegate.modelData.runtimeDirectory[0] + "/status.sock" | ||
| 111 | connected: true | ||
| 112 | onError: e => { | ||
| 113 | console.warn("YtDlpWidget: Error in Socket:", socket.path, e); | ||
| 114 | } | ||
| 115 | parser: SplitParser { | ||
| 116 | onRead: line => { | ||
| 117 | try { | ||
| 118 | unitDelegate.state = JSON.parse(line) | ||
| 119 | } catch (e) { | ||
| 120 | console.warn("YtDlpWidget: Failed to parse state:", line, e) | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | WrapperItem { | ||
| 127 | Layout.column: 0 | ||
| 128 | Layout.row: unitDelegate.index | ||
| 129 | |||
| 130 | implicitWidth: descText.contentWidth | ||
| 131 | implicitHeight: descText.contentHeight | ||
| 132 | |||
| 133 | Text { | ||
| 134 | id: descText | ||
| 135 | |||
| 136 | color: "white" | ||
| 137 | font.pointSize: 10 | ||
| 138 | font.family: "Fira Sans" | ||
| 139 | |||
| 140 | text: unitDelegate.state?.title || unitDelegate.modelData.id | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | /* | ||
| 145 | WrapperItem { | ||
| 146 | Layout.column: 1 | ||
| 147 | Layout.row: unitDelegate.index | ||
| 148 | |||
| 149 | implicitWidth: fragText.contentWidth | ||
| 150 | implicitHeight: fragText.contentHeight | ||
| 151 | |||
| 152 | visible: Boolean(unitDelegate.state) | ||
| 153 | |||
| 154 | Text { | ||
| 155 | id: fragText | ||
| 156 | |||
| 157 | color: "white" | ||
| 158 | font.pointSize: 10 | ||
| 159 | font.family: "Fira Sans" | ||
| 160 | |||
| 161 | text: `${unitDelegate.state?.fragment_index}/${unitDelegate.state?.fragment_count}` | ||
| 162 | } | ||
| 163 | } | ||
| 164 | */ | ||
| 165 | |||
| 166 | WrapperItem { | ||
| 167 | Layout.column: 1 | ||
| 168 | Layout.row: unitDelegate.index | ||
| 169 | |||
| 170 | visible: Boolean(unitDelegate.state) | ||
| 171 | |||
| 172 | ProgressBar { | ||
| 173 | id: progress | ||
| 174 | |||
| 175 | Material.background: "black" | ||
| 176 | Material.accent: "white" | ||
| 177 | |||
| 178 | from: 0 | ||
| 179 | to: unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate || 0 | ||
| 180 | value: unitDelegate.state?.downloaded_bytes || 0 | ||
| 181 | indeterminate: !Boolean(unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate) || unitDelegate.state?.status !== "downloading" | ||
| 182 | } | ||
| 183 | } | ||
| 184 | } | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/displaymanager.qml b/accounts/gkleen@skadhi/shell/quickshell/displaymanager.qml new file mode 100644 index 00000000..b452c03d --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/displaymanager.qml | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | //@ pragma UseQApplication | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Wayland | ||
| 5 | import Quickshell.Io | ||
| 6 | import Quickshell.Services.Greetd | ||
| 7 | import QtQml | ||
| 8 | |||
| 9 | |||
| 10 | ShellRoot { | ||
| 11 | id: displaymanager | ||
| 12 | |||
| 13 | settings.watchFiles: false | ||
| 14 | |||
| 15 | property string currentText: "" | ||
| 16 | property string username: @username@ | ||
| 17 | property list<string> command: @niri_session@ | ||
| 18 | property list<var> messages: [] | ||
| 19 | property bool responseRequired: false | ||
| 20 | property bool responseVisible: false | ||
| 21 | |||
| 22 | signal startAuth() | ||
| 23 | |||
| 24 | onStartAuth: { | ||
| 25 | if (Greetd.state !== GreetdState.Inactive) | ||
| 26 | Greetd.cancelSession(); | ||
| 27 | displaymanager.messages = []; | ||
| 28 | Greetd.createSession(displaymanager.username); | ||
| 29 | } | ||
| 30 | |||
| 31 | Connections { | ||
| 32 | target: Greetd | ||
| 33 | function onStateChanged() { | ||
| 34 | console.log("greetd state: ", GreetdState.toString(Greetd.state)); | ||
| 35 | if (Greetd.state === GreetdState.ReadyToLaunch) | ||
| 36 | Greetd.launch(displaymanager.command); | ||
| 37 | } | ||
| 38 | function onAuthMessage(message: string, error: bool, responseRequired: bool, echoResponse: bool) { | ||
| 39 | displaymanager.responseVisible = echoResponse; | ||
| 40 | displaymanager.responseRequired = responseRequired; | ||
| 41 | displaymanager.messages = Array.from(displaymanager.messages).concat([{ "text": message, "error": error }]); | ||
| 42 | } | ||
| 43 | function onAuthFailure(message: string) { | ||
| 44 | displaymanager.responseRequired = false; | ||
| 45 | displaymanager.messages = Array.from(displaymanager.messages).concat([{ "text": message, "error": true }]); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | Component.onCompleted: { | ||
| 50 | if (Greetd.state !== GreetdState.Inactive) | ||
| 51 | Greetd.cancelSession(); | ||
| 52 | } | ||
| 53 | |||
| 54 | Variants { | ||
| 55 | model: Quickshell.screens | ||
| 56 | |||
| 57 | delegate: Scope { | ||
| 58 | id: screenScope | ||
| 59 | |||
| 60 | required property var modelData | ||
| 61 | |||
| 62 | PanelWindow { | ||
| 63 | color: "black" | ||
| 64 | |||
| 65 | screen: screenScope.modelData | ||
| 66 | |||
| 67 | WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive | ||
| 68 | |||
| 69 | anchors.top: true | ||
| 70 | anchors.bottom: true | ||
| 71 | anchors.left: true | ||
| 72 | anchors.right: true | ||
| 73 | |||
| 74 | LockSurface { | ||
| 75 | id: surfaceContent | ||
| 76 | |||
| 77 | screen: screenScope.modelData | ||
| 78 | |||
| 79 | onCurrentTextChanged: displaymanager.currentText = currentText | ||
| 80 | Connections { | ||
| 81 | target: displaymanager | ||
| 82 | function onCurrentTextChanged() { surfaceContent.currentText = displaymanager.currentText; } | ||
| 83 | function onMessagesChanged() { surfaceContent.messages = Array.from(displaymanager.messages); } | ||
| 84 | function onResponseRequiredChanged() { surfaceContent.responseRequired = displaymanager.responseRequired; } | ||
| 85 | function onResponseVisibleChanged() { surfaceContent.responseVisible = displaymanager.responseVisible; } | ||
| 86 | } | ||
| 87 | |||
| 88 | onResponse: responseText => Greetd.respond(responseText); | ||
| 89 | Connections { | ||
| 90 | target: Greetd | ||
| 91 | function onStateChanged() { | ||
| 92 | if (Greetd.state === GreetdState.Authenticating) { | ||
| 93 | surfaceContent.authRunning = true; | ||
| 94 | } else { | ||
| 95 | surfaceContent.authRunning = false; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | onAuthRunningChanged: { | ||
| 101 | if (surfaceContent.authRunning && Greetd.state !== GreetdState.Authenticating) | ||
| 102 | displaymanager.startAuth(); | ||
| 103 | } | ||
| 104 | Component.onCompleted: { | ||
| 105 | surfaceContent.authRunning = Greetd.state === GreetdState.Authenticating | ||
| 106 | surfaceContent.messages = Array.from(displaymanager.messages); | ||
| 107 | surfaceContent.responseVisible = displaymanager.responseVisible; | ||
| 108 | surfaceContent.responseRequired = displaymanager.responseRequired; | ||
| 109 | surfaceContent.currentText = displaymanager.currentText; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
diff --git a/accounts/gkleen@skadhi/shell/quickshell/shell.qml b/accounts/gkleen@skadhi/shell/quickshell/shell.qml new file mode 100644 index 00000000..1a5875f0 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/shell.qml | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | //@ pragma UseQApplication | ||
| 2 | |||
| 3 | import Quickshell | ||
| 4 | import Quickshell.Wayland | ||
| 5 | |||
| 6 | ShellRoot { | ||
| 7 | settings.watchFiles: false | ||
| 8 | |||
| 9 | Variants { | ||
| 10 | model: Quickshell.screens | ||
| 11 | |||
| 12 | delegate: Scope { | ||
| 13 | id: screenScope | ||
| 14 | |||
| 15 | required property var modelData | ||
| 16 | |||
| 17 | PanelWindow { | ||
| 18 | id: bgWindow | ||
| 19 | |||
| 20 | screen: screenScope.modelData | ||
| 21 | |||
| 22 | WlrLayershell.layer: WlrLayer.Background | ||
| 23 | WlrLayershell.namespace: "background" | ||
| 24 | exclusionMode: ExclusionMode.Ignore | ||
| 25 | |||
| 26 | anchors.top: true | ||
| 27 | anchors.bottom: true | ||
| 28 | anchors.left: true | ||
| 29 | anchors.right: true | ||
| 30 | |||
| 31 | color: "black" | ||
| 32 | |||
| 33 | WallpaperBackground { | ||
| 34 | screen: bgWindow.screen.name | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | Bar { | ||
| 39 | screen: screenScope.modelData | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | Lockscreen {} | ||
| 45 | NiriIdle {} | ||
| 46 | |||
| 47 | VolumeOSD {} | ||
| 48 | BrightnessOSD {} | ||
| 49 | |||
| 50 | NotificationDisplay {} | ||
| 51 | |||
| 52 | UnixIPC {} | ||
| 53 | } | ||
diff --git a/accounts/gkleen@skadhi/zsh/default.nix b/accounts/gkleen@skadhi/zsh/default.nix new file mode 100644 index 00000000..ddc69f0d --- /dev/null +++ b/accounts/gkleen@skadhi/zsh/default.nix | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | { pkgs, lib, config, sysConfig, flakeInputs, ... }: | ||
| 2 | let | ||
| 3 | zshrc = pkgs.resholve.mkDerivation { | ||
| 4 | pname = "zshrc"; | ||
| 5 | version = "0.0.0"; | ||
| 6 | |||
| 7 | src = ./zshrc; | ||
| 8 | |||
| 9 | dontUnpack = true; | ||
| 10 | dontConfigure = true; | ||
| 11 | dontBuild = true; | ||
| 12 | |||
| 13 | installPhase = '' | ||
| 14 | mkdir -p $out/share | ||
| 15 | install "$src" $out/share/zshrc | ||
| 16 | ''; | ||
| 17 | |||
| 18 | solutions = { | ||
| 19 | default = { | ||
| 20 | scripts = [ "share/zshrc" ]; | ||
| 21 | interpreter = "none"; | ||
| 22 | inputs = with pkgs; [ | ||
| 23 | coreutils | ||
| 24 | rpm | ||
| 25 | binutils | ||
| 26 | squashfsTools | ||
| 27 | unzip | ||
| 28 | config.programs.git.package | ||
| 29 | magickWrapped | ||
| 30 | curl | ||
| 31 | file | ||
| 32 | gnutar | ||
| 33 | cpio | ||
| 34 | magic-wormhole | ||
| 35 | config.programs.zsh.package | ||
| 36 | util-linux | ||
| 37 | findutils | ||
| 38 | qrencode | ||
| 39 | tty-clock | ||
| 40 | config.programs.jq.package | ||
| 41 | eza | ||
| 42 | less | ||
| 43 | sysConfig.systemd.package | ||
| 44 | sysConfig.programs.ssh.package | ||
| 45 | gnused | ||
| 46 | miniserve | ||
| 47 | p7zip | ||
| 48 | ]; | ||
| 49 | execer = with pkgs; [ | ||
| 50 | "cannot:${lib.getExe' rpm "rpm2cpio"}" | ||
| 51 | "cannot:${lib.getExe' squashfsTools "unsquashfs"}" | ||
| 52 | "cannot:${lib.getExe' unzip "unzip"}" | ||
| 53 | "cannot:${lib.getExe config.programs.git.package}" | ||
| 54 | "cannot:${lib.getExe cpio}" | ||
| 55 | "cannot:${lib.getExe' magic-wormhole "wormhole"}" | ||
| 56 | "cannot:${lib.getExe' fuse "fusermount"}" | ||
| 57 | "cannot:${lib.getExe less}" | ||
| 58 | "cannot:${lib.getExe' sysConfig.systemd.package "systemctl"}" | ||
| 59 | "cannot:${lib.getExe sysConfig.programs.ssh.package}" | ||
| 60 | "cannot:${lib.getExe' p7zip "7z"}" | ||
| 61 | ]; | ||
| 62 | wrapper = with pkgs; [ | ||
| 63 | "${lib.getExe' magickWrapped "magick"}:${lib.getExe' imagemagick "magick"}" | ||
| 64 | ]; | ||
| 65 | fake = { | ||
| 66 | builtin = ["print"]; | ||
| 67 | external = lib.mapAttrsToList (_: cfg: cfg.program) sysConfig.security.wrappers; | ||
| 68 | }; | ||
| 69 | }; | ||
| 70 | }; | ||
| 71 | }; | ||
| 72 | magickWrapped = pkgs.symlinkJoin { | ||
| 73 | inherit (pkgs.imagemagick) name; | ||
| 74 | paths = [ pkgs.imagemagick ]; | ||
| 75 | |||
| 76 | buildInputs = with pkgs; [ makeWrapper ]; | ||
| 77 | postBuild = '' | ||
| 78 | wrapProgram $out/bin/magick \ | ||
| 79 | --prefix PATH : ${lib.makeBinPath (with pkgs; [ ghostscript ])} | ||
| 80 | ''; | ||
| 81 | }; | ||
| 82 | in { | ||
| 83 | config = { | ||
| 84 | programs.zsh.initContent = '' | ||
| 85 | source ${zshrc}/share/zshrc | ||
| 86 | ''; | ||
| 87 | programs.zsh.dirHashes = let | ||
| 88 | flakeHashes = lib.mapAttrs' (n: v: lib.nameValuePair (inputNames.${n} or n) (toString v)) flakeInputs; | ||
| 89 | inputNames = { | ||
| 90 | self = "nixos"; | ||
| 91 | }; | ||
| 92 | in flakeHashes // { | ||
| 93 | docs = "$HOME/documents"; | ||
| 94 | dl = "$HOME/Downloads"; | ||
| 95 | scrot = "$HOME/screenshots"; | ||
| 96 | media = "$HOME/media"; | ||
| 97 | }; | ||
| 98 | programs.starship.settings = { | ||
| 99 | directory.substitutions = lib.mapAttrs' (name: value: let | ||
| 100 | value' = builtins.unsafeDiscardStringContext value; | ||
| 101 | value'' = if lib.hasPrefix "$HOME/" value' then "~" + lib.removePrefix "$HOME" value' else value'; | ||
| 102 | in lib.nameValuePair value'' "~${name}" | ||
| 103 | ) config.programs.zsh.dirHashes; | ||
| 104 | }; | ||
| 105 | }; | ||
| 106 | } | ||
diff --git a/accounts/gkleen@skadhi/zsh/zshrc b/accounts/gkleen@skadhi/zsh/zshrc new file mode 100644 index 00000000..c532b308 --- /dev/null +++ b/accounts/gkleen@skadhi/zsh/zshrc | |||
| @@ -0,0 +1,298 @@ | |||
| 1 | dir() { | ||
| 2 | curlArchive=false | ||
| 3 | templateArchive="" | ||
| 4 | repoUrl="" | ||
| 5 | dir="" | ||
| 6 | forceShell=false | ||
| 7 | wormhole=false | ||
| 8 | gitWorktree="" | ||
| 9 | modifyPDF="" | ||
| 10 | miniserve=false | ||
| 11 | |||
| 12 | while getopts ':t:a:d:ir:wg:p:m' arg; do | ||
| 13 | case $arg in | ||
| 14 | "t") ;; | ||
| 15 | "a") | ||
| 16 | if [[ ${OPTARG} =~ "://" ]]; then | ||
| 17 | templateArchive=${OPTARG} | ||
| 18 | curlArchive=true | ||
| 19 | else | ||
| 20 | templateArchive=${OPTARG:a} | ||
| 21 | fi | ||
| 22 | ;; | ||
| 23 | "d") dir=${OPTARG} ;; | ||
| 24 | "i") forceShell=true ;; | ||
| 25 | "r") repoUrl=${OPTARG} ;; | ||
| 26 | "w") wormhole=true ;; | ||
| 27 | "g") gitWorktree=${OPTARG} ;; | ||
| 28 | "p") modifyPDF=${OPTARG:a} ;; | ||
| 29 | "m") miniserve=true ;; | ||
| 30 | *) printf "Invalid option: %s\n" $arg >&2; exit 2 ;; | ||
| 31 | esac | ||
| 32 | done | ||
| 33 | |||
| 34 | shift $((OPTIND - 1)) | ||
| 35 | |||
| 36 | if [[ -z ${dir} && ${#@} -ge 1 ]]; then | ||
| 37 | dir=${1} | ||
| 38 | shift | ||
| 39 | fi | ||
| 40 | |||
| 41 | [[ -n ${dir} ]] || return 2; | ||
| 42 | |||
| 43 | if [[ ! -e ${dir} ]]; then | ||
| 44 | if [[ -z "${gitWorktree}" ]]; then | ||
| 45 | mkdir -vp ${dir} | ||
| 46 | else | ||
| 47 | git -C ${gitWorktree} worktree add ${dir} | ||
| 48 | fi | ||
| 49 | else | ||
| 50 | gitWorktree="" | ||
| 51 | fi | ||
| 52 | |||
| 53 | miniservePIDFile="" | ||
| 54 | if [[ ${miniserve} = "true" ]]; then | ||
| 55 | miniservePIDFile=$(mktemp --tmpdir --suffix=.pid) | ||
| 56 | fi | ||
| 57 | |||
| 58 | cleanup() | ||
| 59 | { | ||
| 60 | if [[ -n ${modifyPDF} ]]; then | ||
| 61 | cd ${modifyPDF:h} | ||
| 62 | typeset -a pages | ||
| 63 | eval 'pages=(${dir}/${modifyPDF:t:r}_*.png(on))' | ||
| 64 | magick -verbose "${pages[@]}" $(mktemp --tmpdir=${modifyPDF:h} ${modifyPDF:t:r}_XXXXXXXXXX.${modifyPDF:e}) | ||
| 65 | modifyPDF="" | ||
| 66 | fi | ||
| 67 | if [[ -n ${miniservePIDFile} ]]; then | ||
| 68 | command kill --verbose -- $(cat ${miniservePIDFile}) && wait $(cat ${miniservePIDFile}) | ||
| 69 | miniservePIDFile="" | ||
| 70 | fi | ||
| 71 | } | ||
| 72 | |||
| 73 | ( | ||
| 74 | set -o localoptions -o localtraps | ||
| 75 | trap 'return 1' INT TERM | ||
| 76 | trap cleanup EXIT | ||
| 77 | |||
| 78 | cd ${dir} | ||
| 79 | export dir; | ||
| 80 | |||
| 81 | [[ -n ${repoUrl} ]] && git clone -- ${repoUrl} . | ||
| 82 | |||
| 83 | [[ -n ${modifyPDF} ]] && templateArchive=${modifyPDF} | ||
| 84 | |||
| 85 | if [[ -n ${templateArchive} ]]; then | ||
| 86 | ( | ||
| 87 | archiveFile="" | ||
| 88 | cleanup() { | ||
| 89 | [[ -n "${archiveFile}" ]] && rm -fv ${archiveFile} | ||
| 90 | } | ||
| 91 | trap cleanup EXIT | ||
| 92 | |||
| 93 | if [[ $curlArchive = "true" ]]; then | ||
| 94 | archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") | ||
| 95 | |||
| 96 | curl -SfL -o ${archiveFile} ${templateArchive} | ||
| 97 | |||
| 98 | templateArchive=${archiveFile} | ||
| 99 | fi | ||
| 100 | |||
| 101 | unpack=true | ||
| 102 | while [[ $unpack = "true" ]]; do | ||
| 103 | case $(file --brief --mime-type --dereference ${templateArchive}) in | ||
| 104 | application/zip) | ||
| 105 | unzip ${templateArchive} | ||
| 106 | unpack=false | ||
| 107 | ;; | ||
| 108 | application/vnd.debian.binary-package) | ||
| 109 | ar x ${templateArchive} | ||
| 110 | mkdir control data | ||
| 111 | tar -C control -xvaf control.* | ||
| 112 | tar -C data -xvaf data.* | ||
| 113 | unpack=false | ||
| 114 | ;; | ||
| 115 | application/x-rpm) | ||
| 116 | cpioArchive=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t:r}.cpio") | ||
| 117 | rpm2cpio ${templateArchive} > ${cpioArchive} | ||
| 118 | templateArchive=${cpioArchive} | ||
| 119 | unpack=true | ||
| 120 | ;; | ||
| 121 | application/x-cpio) | ||
| 122 | cpio --extract --make-directories --no-absolute-filenames -F ${templateArchive} | ||
| 123 | unpack=false | ||
| 124 | ;; | ||
| 125 | application/pdf) | ||
| 126 | magick -verbose -density 400 ${templateArchive} ${modifyPDF:t:r}_%0d.png | ||
| 127 | unpack=false | ||
| 128 | ;; | ||
| 129 | application/octet-stream) | ||
| 130 | if [[ $(file --brief --dereference ${templateArchive}) =~ Squashfs ]]; then | ||
| 131 | unsquashfs -d . ${templateArchive} | ||
| 132 | unpack=false | ||
| 133 | fi | ||
| 134 | ;; | ||
| 135 | application/x-iso9660-image) | ||
| 136 | 7z x ${templateArchive} | ||
| 137 | unpack=false | ||
| 138 | ;; | ||
| 139 | *) | ||
| 140 | tar -xvaf ${templateArchive} | ||
| 141 | unpack=false | ||
| 142 | ;; | ||
| 143 | esac | ||
| 144 | done | ||
| 145 | ) | ||
| 146 | fi | ||
| 147 | |||
| 148 | |||
| 149 | [[ $wormhole = "true" ]] && wormhole receive --accept-file | ||
| 150 | |||
| 151 | |||
| 152 | if [[ ${#@} -gt 0 ]]; then | ||
| 153 | ${@} | ||
| 154 | fi | ||
| 155 | |||
| 156 | cd $(pwd) # Needed for mounting to work | ||
| 157 | |||
| 158 | if [[ ${miniserve} = "true" ]]; then | ||
| 159 | miniserve --random-route --hidden --enable-tar-gz --enable-zip . & | ||
| 160 | echo $! > "${miniservePIDFile}" | ||
| 161 | fi | ||
| 162 | |||
| 163 | if [[ ${#@} -eq 0 ]] && [[ ${miniserve} != "true" ]] || [[ $forceShell = "true" ]]; then | ||
| 164 | isSingleDir() { | ||
| 165 | typeset -a contents | ||
| 166 | contents=(*(N) .*(N)) | ||
| 167 | |||
| 168 | if [[ ${#contents} -eq 1 && -d ${contents[1]} ]]; then | ||
| 169 | print ${contents[1]} | ||
| 170 | return 0 | ||
| 171 | else | ||
| 172 | return 1 | ||
| 173 | fi | ||
| 174 | } | ||
| 175 | while d=$(isSingleDir); do cd ${d}; done | ||
| 176 | |||
| 177 | zsh | ||
| 178 | elif [[ ${miniserve} == "true" ]]; then | ||
| 179 | wait $(cat "${miniservePIDFile}") | ||
| 180 | fi | ||
| 181 | ) | ||
| 182 | } | ||
| 183 | |||
| 184 | tmpdir() { | ||
| 185 | cleanup() | ||
| 186 | { | ||
| 187 | cd / | ||
| 188 | unmount() { | ||
| 189 | printf "Unmounting %s\n" ${1} >&2 | ||
| 190 | fusermount3 -u ${1} || umount ${1} || sudo umount ${1} | ||
| 191 | } | ||
| 192 | |||
| 193 | if [[ -n ${dir} ]]; then | ||
| 194 | if mountpoint -q -- ${dir}; then | ||
| 195 | unmount ${dir} || return $? | ||
| 196 | else | ||
| 197 | while read -d $'\0' subDir; do | ||
| 198 | mountpoint -q -- ${subDir} || continue | ||
| 199 | unmount ${subDir} || return $? | ||
| 200 | done <<<$(find ${dir} -xdev -type d -print0 | sort -zr) | ||
| 201 | fi | ||
| 202 | |||
| 203 | rm -rfv --one-file-system -- ${dir} | ||
| 204 | dir="" | ||
| 205 | fi | ||
| 206 | } | ||
| 207 | |||
| 208 | local tmpdir="" | ||
| 209 | |||
| 210 | while getopts ':t:a:d:ir:wg:p:m' arg; do | ||
| 211 | case $arg in | ||
| 212 | "t") tmpdir="=${OPTARG}" ;; | ||
| 213 | "?"|":") printf "Invalid option: %s\n" $arg >&2; exit 2 ;; | ||
| 214 | esac | ||
| 215 | done | ||
| 216 | |||
| 217 | ( | ||
| 218 | set -o localoptions -o localtraps | ||
| 219 | trap 'return 1' INT TERM | ||
| 220 | trap cleanup EXIT | ||
| 221 | |||
| 222 | |||
| 223 | local dir=$(mktemp -ud --tmpdir${tmpdir} ${0}.XXXXXXXXXX || return $?) | ||
| 224 | |||
| 225 | ( dir -d ${dir} ${@} ) | ||
| 226 | ) | ||
| 227 | } | ||
| 228 | |||
| 229 | qr() { | ||
| 230 | qrencode -l M -o - -t ANSIUTF8 $@ | ||
| 231 | } | ||
| 232 | |||
| 233 | clock() { | ||
| 234 | tty-clock -sSbc -C 7 -d 0 -a 100000000 | ||
| 235 | } | ||
| 236 | |||
| 237 | public-ip() { | ||
| 238 | curl -sSf -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' | ||
| 239 | } | ||
| 240 | |||
| 241 | swap() { | ||
| 242 | f1=${1} | ||
| 243 | f2=${2} | ||
| 244 | |||
| 245 | if [[ -z "${f1}" || ! -e "${f1}" ]]; then | ||
| 246 | printf "‘%s’ does not exist\n" "${f1}" >&2 | ||
| 247 | return 2 | ||
| 248 | fi | ||
| 249 | if [[ -z "${f2}" || ! -e "${f2}" ]]; then | ||
| 250 | printf "‘%s’ does not exist\n" "${f2}" >&2 | ||
| 251 | return 2 | ||
| 252 | fi | ||
| 253 | |||
| 254 | tmpfile=$(mktemp --dry-run --tmpdir=${f1:h} .swap.XXXXXXXXXX) | ||
| 255 | mv -v ${f1} ${tmpfile} | ||
| 256 | mv -v ${f2} ${f1} | ||
| 257 | mv -v ${tmpfile} ${f2} | ||
| 258 | } | ||
| 259 | |||
| 260 | ls() { | ||
| 261 | eza --all --group-directories-first --colour=always --sort=modified --smart-group $@ | less --mouse -FR | ||
| 262 | } | ||
| 263 | |||
| 264 | l() { | ||
| 265 | ls --long --binary --git --time-style=iso --header $@ | ||
| 266 | } | ||
| 267 | |||
| 268 | ssh-installer() { | ||
| 269 | ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentityFile=~/.ssh/gkleen@sif.midgard.yggdrasil $@ | ||
| 270 | } | ||
| 271 | |||
| 272 | dichotomic_search() { | ||
| 273 | min=$1; shift | ||
| 274 | max=$1; shift | ||
| 275 | |||
| 276 | while [[ $min -lt $max ]]; do | ||
| 277 | # Compute the mean between min and max, rounded up to the superior unit | ||
| 278 | current=$(( (min + max + 1 ) / 2 )) | ||
| 279 | if $@ $current; then | ||
| 280 | min=$current | ||
| 281 | else | ||
| 282 | max=$((current - 1)) | ||
| 283 | fi | ||
| 284 | done | ||
| 285 | |||
| 286 | echo $min | ||
| 287 | } | ||
| 288 | |||
| 289 | while read -r -d $'\0' d _ s; do | ||
| 290 | hash -d ${s}=${d} | ||
| 291 | done < <(find ~/projects ~/uni -regextype posix-extended -maxdepth 2 -type d -regex '\S+/[0-9]{2}[ws]/\S+' -print0 2>/dev/null | \ | ||
| 292 | sed -zr 's|(.*/([0-9]{2}[ws])/(.+))|\1 \2 \3|' | \ | ||
| 293 | sort -z -r -k2 | sort -z -s -k3 | uniq -z -f 2) | ||
| 294 | |||
| 295 | alias rzadm=$'tmpdir -i sh -c \'mkdir adm; sshfs gkleen@mgmt01:/adm adm\'' | ||
| 296 | alias mathcloud=$'tmpdir -i rclone mount --daemon mathcloud:// .' | ||
| 297 | |||
| 298 | export DEFAULT_USER=gkleen | ||
diff --git a/hosts/skadhi/default.nix b/hosts/skadhi/default.nix index 96be2e5b..1f3f5306 100644 --- a/hosts/skadhi/default.nix +++ b/hosts/skadhi/default.nix | |||
| @@ -1,9 +1,8 @@ | |||
| 1 | { flake, flakeInputs, pkgs, config, lib, ... }: | 1 | { flake, flakeInputs, pkgs, config, lib, ... }: |
| 2 | { | 2 | { |
| 3 | imports = with flake.nixosModules.systemProfiles; [ | 3 | imports = with flake.nixosModules.systemProfiles; [ |
| 4 | ./hw.nix ./fs.nix | 4 | ./hw.nix ./fs.nix ./networking |
| 5 | tmpfs-root default-locale openssh niri-unstable networkmanager lanzaboote zswap initrd-all-crypto-modules | 5 | tmpfs-root default-locale openssh lanzaboote zswap initrd-all-crypto-modules |
| 6 | flakeInputs.nixVirt.nixosModules.default | ||
| 7 | ]; | 6 | ]; |
| 8 | 7 | ||
| 9 | config = { | 8 | config = { |
| @@ -77,5 +76,11 @@ | |||
| 77 | enable = true; | 76 | enable = true; |
| 78 | config.hwaccel = true; | 77 | config.hwaccel = true; |
| 79 | }; | 78 | }; |
| 79 | |||
| 80 | environment.persistence."/persistent".timezone = true; | ||
| 81 | time.timeZone = null; | ||
| 82 | systemd.tmpfiles.settings = { | ||
| 83 | "10-localtime"."/etc/localtime".L.argument = "/persistent/etc/localtime"; | ||
| 84 | }; | ||
| 80 | }; | 85 | }; |
| 81 | } | 86 | } |
diff --git a/hosts/skadhi/fs.nix b/hosts/skadhi/fs.nix index 055769f3..64d49f7d 100644 --- a/hosts/skadhi/fs.nix +++ b/hosts/skadhi/fs.nix | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | "/var/lib/systemd" | 17 | "/var/lib/systemd" |
| 18 | config.boot.lanzaboote.pkiBundle | 18 | config.boot.lanzaboote.pkiBundle |
| 19 | ]; | 19 | ]; |
| 20 | timezone = true; | ||
| 21 | }; | 20 | }; |
| 22 | 21 | ||
| 23 | disko.devices = { | 22 | disko.devices = { |
diff --git a/hosts/skadhi/networking/default.nix b/hosts/skadhi/networking/default.nix new file mode 100644 index 00000000..ea5a62e2 --- /dev/null +++ b/hosts/skadhi/networking/default.nix | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | { flake, config, ... }: | ||
| 2 | { | ||
| 3 | imports = with flake.nixosModules.systemProfiles; [ | ||
| 4 | networkmanager | ||
| 5 | ]; | ||
| 6 | |||
| 7 | config = { | ||
| 8 | environment.persistence."/persistent".directories = [ | ||
| 9 | "/etc/NetworkManager/system-connections" | ||
| 10 | ]; | ||
| 11 | |||
| 12 | networking = { | ||
| 13 | domain = "yggdrasil"; | ||
| 14 | search = [ "yggdrasil" ]; | ||
| 15 | hosts = { | ||
| 16 | "127.0.0.1" = [ "${config.networking.hostName}.yggdrasil" config.networking.hostName ]; | ||
| 17 | "::1" = [ "${config.networking.hostName}.yggdrasil" config.networking.hostName ]; | ||
| 18 | }; | ||
| 19 | |||
| 20 | firewall.enable = false; | ||
| 21 | nftables = { | ||
| 22 | enable = true; | ||
| 23 | rulesetFile = ./ruleset.nft; | ||
| 24 | }; | ||
| 25 | |||
| 26 | useDHCP = false; | ||
| 27 | useNetworkd = true; | ||
| 28 | }; | ||
| 29 | }; | ||
| 30 | } | ||
diff --git a/hosts/skadhi/networking/ruleset.nft b/hosts/skadhi/networking/ruleset.nft new file mode 100644 index 00000000..62339f69 --- /dev/null +++ b/hosts/skadhi/networking/ruleset.nft | |||
| @@ -0,0 +1,223 @@ | |||
| 1 | define icmp_protos = { ipv6-icmp, icmp, igmp } | ||
| 2 | |||
| 3 | table arp filter { | ||
| 4 | limit lim_arp { | ||
| 5 | rate over 50 mbytes/second burst 50 mbytes | ||
| 6 | } | ||
| 7 | |||
| 8 | counter arp-rx {} | ||
| 9 | counter arp-tx {} | ||
| 10 | |||
| 11 | counter arp-ratelimit-rx {} | ||
| 12 | counter arp-ratelimit-tx {} | ||
| 13 | |||
| 14 | chain input { | ||
| 15 | type filter hook input priority filter | ||
| 16 | policy accept | ||
| 17 | |||
| 18 | limit name lim_arp counter name arp-ratelimit-rx drop | ||
| 19 | |||
| 20 | counter name arp-rx | ||
| 21 | } | ||
| 22 | |||
| 23 | chain output { | ||
| 24 | type filter hook output priority filter | ||
| 25 | policy accept | ||
| 26 | |||
| 27 | limit name lim_arp counter name arp-ratelimit-tx drop | ||
| 28 | |||
| 29 | counter name arp-tx | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | table inet filter { | ||
| 34 | limit lim_reject { | ||
| 35 | rate over 1000/second burst 1000 packets | ||
| 36 | } | ||
| 37 | |||
| 38 | limit lim_icmp { | ||
| 39 | rate over 50 mbytes/second burst 50 mbytes | ||
| 40 | } | ||
| 41 | |||
| 42 | counter invalid-fw {} | ||
| 43 | |||
| 44 | counter fw-lo {} | ||
| 45 | |||
| 46 | counter reject-ratelimit-fw {} | ||
| 47 | counter reject-fw {} | ||
| 48 | counter reject-tcp-fw {} | ||
| 49 | counter reject-icmp-fw {} | ||
| 50 | |||
| 51 | |||
| 52 | counter invalid-rx {} | ||
| 53 | counter rx-lo {} | ||
| 54 | counter invalid-local4-rx {} | ||
| 55 | counter invalid-local6-rx {} | ||
| 56 | |||
| 57 | counter icmp-ratelimit-rx {} | ||
| 58 | counter icmp-rx {} | ||
| 59 | |||
| 60 | counter ssh-rx {} | ||
| 61 | counter mosh-rx {} | ||
| 62 | counter wg-rx {} | ||
| 63 | counter yggdrasil-gre-rx {} | ||
| 64 | counter miniserve-rx {} | ||
| 65 | counter ausweisapp2-rx {} | ||
| 66 | |||
| 67 | counter established-rx {} | ||
| 68 | |||
| 69 | counter reject-ratelimit-rx {} | ||
| 70 | counter reject-rx {} | ||
| 71 | counter reject-tcp-rx {} | ||
| 72 | counter reject-icmp-rx {} | ||
| 73 | |||
| 74 | |||
| 75 | counter tx-lo {} | ||
| 76 | |||
| 77 | counter icmp-ratelimit-tx {} | ||
| 78 | counter icmp-tx {} | ||
| 79 | |||
| 80 | counter ssh-tx {} | ||
| 81 | counter mosh-tx {} | ||
| 82 | counter wg-tx {} | ||
| 83 | counter yggdrasil-gre-tx {} | ||
| 84 | counter miniserve-tx {} | ||
| 85 | |||
| 86 | counter tx {} | ||
| 87 | |||
| 88 | counter fw-libvirt {} | ||
| 89 | counter libvirt-dhcp {} | ||
| 90 | counter libvirt-dns {} | ||
| 91 | |||
| 92 | |||
| 93 | chain forward_tmp {} | ||
| 94 | chain forward { | ||
| 95 | type filter hook forward priority filter | ||
| 96 | policy drop | ||
| 97 | |||
| 98 | |||
| 99 | ct state invalid log level debug prefix "drop invalid forward: " counter name invalid-fw drop | ||
| 100 | |||
| 101 | |||
| 102 | iifname lo counter name fw-lo accept | ||
| 103 | |||
| 104 | jump forward_tmp | ||
| 105 | |||
| 106 | iifname virbr0 oifname != {lo, wgrz, yggdrasil-wg-4, yggdrasil-wg-6, yggdrasil, ip6tnl, ip6gre, yggre-surtr-6, yggre-surtr-4, yggre-vidhar-4} counter name fw-libvirt accept | ||
| 107 | oifname virbr0 ct state {established, related} counter name fw-libvirt accept | ||
| 108 | |||
| 109 | |||
| 110 | limit name lim_reject log level debug prefix "drop forward: " counter name reject-ratelimit-fw drop | ||
| 111 | log level debug prefix "reject forward: " counter name reject-fw | ||
| 112 | meta l4proto tcp ct state new counter name reject-tcp-fw reject with tcp reset | ||
| 113 | ct state new counter name reject-icmp-fw reject | ||
| 114 | } | ||
| 115 | |||
| 116 | chain input_tmp {} | ||
| 117 | chain input { | ||
| 118 | type filter hook input priority filter | ||
| 119 | policy drop | ||
| 120 | |||
| 121 | |||
| 122 | ct state invalid log level debug prefix "drop invalid input: " counter name invalid-rx drop | ||
| 123 | |||
| 124 | |||
| 125 | iifname lo counter name rx-lo accept | ||
| 126 | iif != lo ip daddr 127.0.0.1/8 counter name invalid-local4-rx reject | ||
| 127 | iif != lo ip6 daddr ::1/128 counter name invalid-local6-rx reject | ||
| 128 | |||
| 129 | meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-rx drop | ||
| 130 | meta l4proto $icmp_protos counter name icmp-rx accept | ||
| 131 | |||
| 132 | jump input_tmp | ||
| 133 | |||
| 134 | tcp dport 22 counter name ssh-rx accept | ||
| 135 | udp dport 60000-61000 counter name mosh-rx accept | ||
| 136 | |||
| 137 | tcp dport 8080 counter name miniserve-rx accept | ||
| 138 | udp dport 24727 counter name ausweisapp2-rx accept | ||
| 139 | |||
| 140 | udp dport 51820-51822 counter name wg-rx accept | ||
| 141 | iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-rx accept | ||
| 142 | |||
| 143 | iifname virbr0 udp dport 67 counter name libvirt-dhcp accept | ||
| 144 | iifname virbr0 udp dport 547 counter name libvirt-dhcp accept | ||
| 145 | iifname virbr0 udp dport 53 counter name libvirt-dns accept | ||
| 146 | iifname virbr0 tcp dport 53 counter name libvirt-dns accept | ||
| 147 | |||
| 148 | iifname wgrz ip saddr 10.200.116.1 meta l4proto gre counter accept | ||
| 149 | |||
| 150 | ct state {established, related} counter name established-rx accept | ||
| 151 | |||
| 152 | |||
| 153 | limit name lim_reject log level debug prefix "drop input: " counter name reject-ratelimit-rx drop | ||
| 154 | log level debug prefix "reject input: " counter name reject-rx | ||
| 155 | meta l4proto tcp ct state new counter name reject-tcp-rx reject with tcp reset | ||
| 156 | ct state new counter name reject-icmp-rx reject | ||
| 157 | } | ||
| 158 | |||
| 159 | chain output { | ||
| 160 | type filter hook output priority filter | ||
| 161 | policy accept | ||
| 162 | |||
| 163 | |||
| 164 | oifname lo counter name tx-lo accept | ||
| 165 | |||
| 166 | meta l4proto $icmp_protos limit name lim_icmp counter name icmp-ratelimit-tx drop | ||
| 167 | meta l4proto $icmp_protos counter name icmp-tx accept | ||
| 168 | |||
| 169 | |||
| 170 | tcp sport 22 counter name ssh-tx | ||
| 171 | udp sport 60000-61000 counter name mosh-tx | ||
| 172 | |||
| 173 | udp sport 51820-51822 counter name wg-tx | ||
| 174 | iifname "yggdrasil-wg-*" meta l4proto gre counter name yggdrasil-gre-tx | ||
| 175 | |||
| 176 | tcp sport 8080 counter name miniserve-tx accept | ||
| 177 | |||
| 178 | oifname virbr0 udp sport 67 counter name libvirt-dhcp accept | ||
| 179 | oifname virbr0 udp sport 547 counter name libvirt-dhcp accept | ||
| 180 | oifname virbr0 udp sport 53 counter name libvirt-dns accept | ||
| 181 | oifname virbr0 tcp sport 53 counter name libvirt-dns accept | ||
| 182 | |||
| 183 | |||
| 184 | counter name tx | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | table ip nat { | ||
| 189 | counter libvirt-nat {} | ||
| 190 | |||
| 191 | chain postrouting_tmp {} | ||
| 192 | chain postrouting { | ||
| 193 | type nat hook postrouting priority srcnat | ||
| 194 | policy accept | ||
| 195 | |||
| 196 | iifname virbr0 oifname != virbr0 counter name libvirt-nat masquerade | ||
| 197 | jump postrouting_tmp | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | table ip6 nat { | ||
| 202 | counter libvirt-nat {} | ||
| 203 | |||
| 204 | chain postrouting { | ||
| 205 | type nat hook postrouting priority srcnat | ||
| 206 | policy accept | ||
| 207 | |||
| 208 | iifname virbr0 oifname != virbr0 counter name libvirt-nat masquerade | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | table ip mss_clamp { | ||
| 213 | counter libvirt-mss-clamp {} | ||
| 214 | |||
| 215 | chain postrouting_tmp {} | ||
| 216 | chain postrouting { | ||
| 217 | type filter hook postrouting priority mangle | ||
| 218 | policy accept | ||
| 219 | |||
| 220 | iifname virbr0 oifname != virbr0 tcp flags & (syn|rst) == syn counter name libvirt-mss-clamp tcp option maxseg size set rt mtu | ||
| 221 | jump postrouting_tmp | ||
| 222 | } | ||
| 223 | } | ||
diff --git a/overlays/quickshell/default.nix b/overlays/quickshell/default.nix index 9aefeeb4..7b719231 100644 --- a/overlays/quickshell/default.nix +++ b/overlays/quickshell/default.nix | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | ]; | 16 | ]; |
| 17 | 17 | ||
| 18 | patches = (oldAttrs.patches or []) ++ [ | 18 | patches = (oldAttrs.patches or []) ++ [ |
| 19 | ./lock-state-changed.patch | 19 | # ./lock-state-changed.patch |
| 20 | ./pipewire.patch | 20 | ./pipewire.patch |
| 21 | ./io.patch | 21 | ./io.patch |
| 22 | ./close-stdin.patch | 22 | ./close-stdin.patch |
diff --git a/user-profiles/core.nix b/user-profiles/core.nix index 57fb7628..7034f17e 100644 --- a/user-profiles/core.nix +++ b/user-profiles/core.nix | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | { flake, flakeInputs, path, userName, config, lib, utils, ... }: | 1 | { flake, flakeInputs, sources, path, userName, config, lib, utils, ... }: |
| 2 | 2 | ||
| 3 | with lib; | 3 | with lib; |
| 4 | 4 | ||
| @@ -6,6 +6,9 @@ with lib; | |||
| 6 | config = { | 6 | config = { |
| 7 | users.users.${userName} = {}; # Just make sure the user is created | 7 | users.users.${userName} = {}; # Just make sure the user is created |
| 8 | home-manager.users.${userName} = let sysConfig = config; in { config, ... }: { | 8 | home-manager.users.${userName} = let sysConfig = config; in { config, ... }: { |
| 9 | config._module.args = { | ||
| 10 | inherit sysConfig flake flakeInputs sources; | ||
| 11 | }; | ||
| 9 | config.nix.settings = { | 12 | config.nix.settings = { |
| 10 | inherit (sysConfig.nix.settings) use-xdg-base-directories; | 13 | inherit (sysConfig.nix.settings) use-xdg-base-directories; |
| 11 | }; | 14 | }; |
diff --git a/user-profiles/zsh/default.nix b/user-profiles/zsh/default.nix index 7821d99a..a89da267 100644 --- a/user-profiles/zsh/default.nix +++ b/user-profiles/zsh/default.nix | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | { userName, pkgs, customUtils, lib, config, ... }: | 1 | { userName, pkgs, customUtils, lib, ... }: |
| 2 | { | 2 | { |
| 3 | config = { | 3 | config = { |
| 4 | nixpkgs.externalConfig.allowUnfreePackages = [ | 4 | nixpkgs.externalConfig.allowUnfreePackages = [ |
| 5 | "zsh-abbr" | 5 | "zsh-abbr" |
| 6 | ]; | 6 | ]; |
| 7 | 7 | ||
| 8 | home-manager.users.${userName} = let sysConfig = config; in { config, ... }: { | 8 | home-manager.users.${userName} = { sysConfig, config, ... }: { |
| 9 | config = { | 9 | config = { |
| 10 | programs.zsh = { | 10 | programs.zsh = { |
| 11 | dotDir = "${config.xdg.configHome}/zsh"; | 11 | dotDir = "${config.xdg.configHome}/zsh"; |
