From 540db27873563b2e53eb873536f6f09159393375 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Mon, 5 Feb 2024 06:25:43 -0500 Subject: [PATCH] feat(hypr): replace ags overview with hycov --- devices/wim/config/hypr/main.conf | 27 --- flake.lock | 111 ++++++---- flake.nix | 8 + home/dconf.nix | 20 -- modules/ags/config/binto.ts | 2 +- .../ags/config/scss/wim-widgets/overview.scss | 53 ----- modules/ags/config/scss/wim.scss | 1 - modules/ags/config/ts/overview/clients.ts | 197 ----------------- .../config/ts/overview/current-workspace.ts | 51 ----- modules/ags/config/ts/overview/dragndrop.ts | 122 ----------- modules/ags/config/ts/overview/main.ts | 151 ------------- modules/ags/config/ts/overview/variables.ts | 14 -- modules/ags/config/ts/overview/workspaces.ts | 202 ------------------ modules/ags/config/wim.ts | 3 - modules/dconf.nix | 28 +++ modules/hyprland/default.nix | 90 +------- modules/hyprland/hycov.nix | 29 +++ modules/hyprland/hyprgrass.nix | 41 ++++ modules/hyprland/packages.nix | 83 +++++++ modules/hyprland/security.nix | 52 +++++ 20 files changed, 316 insertions(+), 969 deletions(-) delete mode 100644 home/dconf.nix delete mode 100644 modules/ags/config/scss/wim-widgets/overview.scss delete mode 100644 modules/ags/config/ts/overview/clients.ts delete mode 100644 modules/ags/config/ts/overview/current-workspace.ts delete mode 100644 modules/ags/config/ts/overview/dragndrop.ts delete mode 100644 modules/ags/config/ts/overview/main.ts delete mode 100644 modules/ags/config/ts/overview/variables.ts delete mode 100644 modules/ags/config/ts/overview/workspaces.ts create mode 100644 modules/dconf.nix create mode 100644 modules/hyprland/hycov.nix create mode 100644 modules/hyprland/hyprgrass.nix create mode 100644 modules/hyprland/packages.nix create mode 100644 modules/hyprland/security.nix diff --git a/devices/wim/config/hypr/main.conf b/devices/wim/config/hypr/main.conf index df82cfb..2b81247 100644 --- a/devices/wim/config/hypr/main.conf +++ b/devices/wim/config/hypr/main.conf @@ -1,29 +1,9 @@ -plugin { - touch_gestures { - # The default sensitivity is probably too low on tablet screens, - # I recommend turning it up to 4.0 - sensitivity = 4.0 - - # must be >= 3 - workspace_swipe_fingers = 3 - - experimental { - # send proper cancel events to windows instead of hacky touch_up events, - # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default - send_cancel = 0 - } - } -} - # Autostart programs exec-once = sleep 3; nextcloud --background exec-once = squeekboard exec-once = ags exec-once = sleep 3; ags -t applauncher -## Change HandleLidSwitch to lock in logind.conf -exec-once = swayidle -w lock lock - ## Special window apps exec-once = [workspace special:thunder silent] thunderbird windowrule = workspace special:thunder silent,^(thunderbird)$ @@ -40,12 +20,6 @@ device:razer-razer-naga-pro-1 { accel_profile = "flat" } -gestures { - workspace_swipe = yes - workspace_swipe_fingers = 3 - workspace_swipe_cancel_ratio = 0.15 -} - # Binds @@ -58,7 +32,6 @@ bindr = CAPS, Caps_Lock, exec, ags -r 'Brightness.fetchCapsState()' bindn = , Escape, exec, ags run-js 'closeAll()' bind = $mainMod SHIFT, E , exec, ags -t powermenu bind = $mainMod , D , exec, ags -t applauncher -bind = ALT , Tab , exec, ags -t overview # Cosmetic diff --git a/flake.lock b/flake.lock index 86df615..d6ead99 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1706913502, - "narHash": "sha256-7LrQ5HH4enwk0nc6/vx7uHqGtraUkHv2OoxBu4qGOg4=", + "lastModified": 1707101684, + "narHash": "sha256-p/CZjHBjrCQp0WIW1OwxdpD4seW3qROlUDMmE5ICE1k=", "owner": "Aylur", "repo": "ags", - "rev": "fa590751134d713de5527cbbd42fdb50454444b1", + "rev": "58e1b14fe9abff805d70f685b15f86893437563f", "type": "github" }, "original": { @@ -194,11 +194,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1704982712, - "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "lastModified": 1706830856, + "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", "type": "github" }, "original": { @@ -373,11 +373,11 @@ ] }, "locked": { - "lastModified": 1706970615, - "narHash": "sha256-uJI9cwn4EYnw5CO97/Wwdh0mj+Q8F9pVmUj+IyxEV0g=", + "lastModified": 1707126335, + "narHash": "sha256-jCQkvM53r3sWKQTtV7A7ZCaJpkLhYdE90FxaFvbtcD8=", "owner": "juanfont", "repo": "headscale", - "rev": "4ea12f472a3c4a632b5a05b96d061368ca5f2604", + "rev": "cbf57e27a78922c88edd8de8f02c99810a653786", "type": "github" }, "original": { @@ -415,11 +415,11 @@ ] }, "locked": { - "lastModified": 1706985585, - "narHash": "sha256-ptshv4qXiC6V0GCfpABz88UGGPNwqs5tAxaRUKbk1Qo=", + "lastModified": 1707114923, + "narHash": "sha256-LDYPWa+BgxHSNEye93SyIPgz5u3RAfh78P9KyO+rQzI=", "owner": "nix-community", "repo": "home-manager", - "rev": "1ca210648a6ca9b957efde5da957f3de6b1f0c45", + "rev": "afcedcf2c8e424d0465e823cf833eb3adebe1db7", "type": "github" }, "original": { @@ -428,6 +428,26 @@ "type": "github" } }, + "hycov": { + "inputs": { + "hyprland": [ + "hyprland" + ] + }, + "locked": { + "lastModified": 1707093208, + "narHash": "sha256-IYsoBwEhWxmMfJdxqSLj9hrtBnIhSmaSXtxZutY9BpE=", + "owner": "DreamMaoMao", + "repo": "hycov", + "rev": "27e8b2679d32c72b1ecf7501c994ff809161c828", + "type": "github" + }, + "original": { + "owner": "DreamMaoMao", + "repo": "hycov", + "type": "github" + } + }, "hyprgrass": { "inputs": { "hyprland": [ @@ -459,11 +479,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1706985179, - "narHash": "sha256-4XX9Hb1lE5YzpCkcQ21+BwBsZ4fvSfJSgAMxiLELuo8=", + "lastModified": 1707098342, + "narHash": "sha256-dU5m6Cd4+WQZal2ICDVf1kww/dNzo1YUWRxWeCctEig=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "5d4ff60f535b65dc3db4cd0fb20e44c1f4360769", + "rev": "84ab8d11e8951a6551d1e1bf87796a8589da6d47", "type": "github" }, "original": { @@ -525,11 +545,11 @@ "nixpkgs-lib": "nixpkgs-lib_2" }, "locked": { - "lastModified": 1706443704, - "narHash": "sha256-ipRgFuoSFFRUJ/9NL9r0hTwtNpaAvKxDmAUCoyF6kU0=", + "lastModified": 1707048513, + "narHash": "sha256-gZh1mHkjtOmXrlgWWdl6G27NlKuNuruz1lOnhgmg1Nk=", "owner": "nix-community", "repo": "lib-aggregate", - "rev": "9842effaf0eb61c8bca645a5da7230392d76fe1d", + "rev": "83a014ca34f5cf6ef441b760e12d503856f20b35", "type": "github" }, "original": { @@ -622,11 +642,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1706750085, - "narHash": "sha256-y/+t2ctdeUD/b0DLWS96UgGUs/srj7vbWef709DPxW4=", + "lastModified": 1707095568, + "narHash": "sha256-6zZifK7cs9eWiC+3MQvlMsq2JeyH7hPSP0qZ6sTny68=", "owner": "fufexan", "repo": "nix-gaming", - "rev": "63fa64659760172fef0e4d674c6661b7ad53b16b", + "rev": "9bde4efca9e4750ed691520d68c4c6eb308015e7", "type": "github" }, "original": { @@ -664,11 +684,11 @@ ] }, "locked": { - "lastModified": 1706411424, - "narHash": "sha256-BzziJYucEZvdCE985vjPoo3ztWcmUiSQ1wJ2CoT6jCc=", + "lastModified": 1707016097, + "narHash": "sha256-V4lHr6hFQ3rK650dh64Xffxsf4kse9vUYWsM+ldjkco=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "c782f2a4f6fc94311ab5ef31df2f1149a1856181", + "rev": "3e3dad2808379c522138e2e8b0eb73500721a237", "type": "github" }, "original": { @@ -756,11 +776,11 @@ "nixpkgs-lib": { "locked": { "dir": "lib", - "lastModified": 1703961334, - "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", + "lastModified": 1706550542, + "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", + "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", "type": "github" }, "original": { @@ -773,11 +793,11 @@ }, "nixpkgs-lib_2": { "locked": { - "lastModified": 1706402708, - "narHash": "sha256-v6z1V+BwolqR9w0sbRkZ9DnnviMcZdZzPJe+4K4h+d4=", + "lastModified": 1707007541, + "narHash": "sha256-fuFppCuZO4wJAfodUkiWhtSxTb+pkBW+lJP2S51jRNU=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "4833b4eb30dfe3abad5a21775bc5460322c8d337", + "rev": "948ff77600f9fff8c904d1e1ffb87a60773991af", "type": "github" }, "original": { @@ -826,11 +846,11 @@ "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1706965675, - "narHash": "sha256-kTTBhL2qdpx3Qw8bWlWzCL2o0uWQpVNg5RSHOvmCGhM=", + "lastModified": 1707121157, + "narHash": "sha256-YYn/jO2VKcEx31vSQwCM2cBlkI/th4DCgFTTEjzKqLk=", "owner": "nix-community", "repo": "nixpkgs-wayland", - "rev": "9deb012acc895b182e2479a6d2d7a72852aa047b", + "rev": "ce2098dcdb085f2a8194f04d7f4d2d22f60d1950", "type": "github" }, "original": { @@ -841,11 +861,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1706367331, - "narHash": "sha256-AqgkGHRrI6h/8FWuVbnkfFmXr4Bqsr4fV23aISqj/xg=", + "lastModified": 1706925685, + "narHash": "sha256-hVInjWMmgH4yZgA4ZtbgJM1qEAel72SYhP5nOWX4UIM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "160b762eda6d139ac10ae081f8f78d640dd523eb", + "rev": "79a13f1437e149dc7be2d1290c74d378dad60814", "type": "github" }, "original": { @@ -873,11 +893,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1706732774, - "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", + "lastModified": 1706913249, + "narHash": "sha256-x3M7iV++CsvRXI1fpyFPduGELUckZEhSv0XWnUopAG8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", + "rev": "e92b6015881907e698782c77641aa49298330223", "type": "github" }, "original": { @@ -905,11 +925,11 @@ }, "nixpkgs_6": { "locked": { - "lastModified": 1706732774, - "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", + "lastModified": 1706913249, + "narHash": "sha256-x3M7iV++CsvRXI1fpyFPduGELUckZEhSv0XWnUopAG8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", + "rev": "e92b6015881907e698782c77641aa49298330223", "type": "github" }, "original": { @@ -1022,11 +1042,11 @@ }, "nur": { "locked": { - "lastModified": 1706985870, - "narHash": "sha256-L8rL33B0mueAJ6lkT6XU+QmHpsbGJQgfFNxhtWyfV0I=", + "lastModified": 1707126301, + "narHash": "sha256-fzYJfTdd3I6YsWIY2FTya+asDoSWTVwxmVgIJjmvn8Y=", "owner": "nix-community", "repo": "NUR", - "rev": "1932c50322b1c6e191a88da3436c6da6b18eca88", + "rev": "4f131f190ff362b8cadca9d063ac8e16207c7af7", "type": "github" }, "original": { @@ -1200,6 +1220,7 @@ "gtk-theme-src": "gtk-theme-src", "headscale": "headscale", "home-manager": "home-manager", + "hycov": "hycov", "hyprgrass": "hyprgrass", "hyprland": "hyprland", "modernx-src": "modernx-src", diff --git a/flake.nix b/flake.nix index 8e22597..4fa2219 100644 --- a/flake.nix +++ b/flake.nix @@ -202,6 +202,14 @@ inputs.hyprland.follows = "hyprland"; }; + hycov = { + type = "github"; + owner = "DreamMaoMao"; + repo = "hycov"; + + inputs.hyprland.follows = "hyprland"; + }; + ags = { type = "github"; owner = "Aylur"; diff --git a/home/dconf.nix b/home/dconf.nix deleted file mode 100644 index 86f22c4..0000000 --- a/home/dconf.nix +++ /dev/null @@ -1,20 +0,0 @@ -{...}: { - dconf.settings = { - "org/virt-manager/virt-manager/connections" = { - autoconnect = ["qemu:///system"]; - uris = ["qemu:///system"]; - }; - - "apps/seahorse/listing" = { - keyrings-selected = ["gnupg://"]; - }; - - "org/gtk/settings/file-chooser" = { - show-hidden = true; - }; - - "org/gnome/desktop/interface" = { - color-scheme = "prefer-dark"; - }; - }; -} diff --git a/modules/ags/config/binto.ts b/modules/ags/config/binto.ts index b940b5b..edaba99 100644 --- a/modules/ags/config/binto.ts +++ b/modules/ags/config/binto.ts @@ -8,7 +8,7 @@ import Powermenu from './ts/powermenu.ts'; const closeWinDelay = 800; -// TODO: add OSD, workspace indicator / overview and current window indicator +// TODO: add OSD, workspace indicator and current window indicator export default { onConfigParsed: () => { globalThis.Pointers = Pointers; diff --git a/modules/ags/config/scss/wim-widgets/overview.scss b/modules/ags/config/scss/wim-widgets/overview.scss deleted file mode 100644 index a8dd298..0000000 --- a/modules/ags/config/scss/wim-widgets/overview.scss +++ /dev/null @@ -1,53 +0,0 @@ -.overview { - background-color: rgba($bgfull, 0.4); - border: 2px solid $contrast-bg; - border-radius: 10px; - - .workspace { - padding: 4px 15px 4px 0; - border: 2px solid transparent; - border-radius: 10px; - - &.active { - background-color: rgba(lighten($color: black, $amount: 15), 0.8); - border: 2px solid black; - } - } - - .workspace .window { - background-color: $bgfull; - border-radius: 10px; - margin: 0 10px; - transition: min-width 0.2s ease-in-out, - min-height 0.2s ease-in-out, - border-color 0.2s ease-in-out, - font-size 0.2s ease-in-out; - } - - .normal { - margin-bottom: 5px; - - .workspace { - .window { - border: 2px solid #411C6C; - - &.active { - border: 2px solid purple; - } - } - } - } - - .special { - .workspace { - .window { - border: 2px solid lighten($color: black, $amount: 20); - - &.active { - border: 2px solid purple; - } - - } - } - } -} diff --git a/modules/ags/config/scss/wim.scss b/modules/ags/config/scss/wim.scss index bf2bd69..fdc0460 100644 --- a/modules/ags/config/scss/wim.scss +++ b/modules/ags/config/scss/wim.scss @@ -18,7 +18,6 @@ undershoot { @import "./wim-widgets/date"; @import "./wim-widgets/quick-settings"; @import "./wim-widgets/player"; -@import "./wim-widgets/overview"; @import "./wim-widgets/applauncher"; @import "./wim-widgets/osd"; @import "./wim-widgets/osk"; diff --git a/modules/ags/config/ts/overview/clients.ts b/modules/ags/config/ts/overview/clients.ts deleted file mode 100644 index 3840108..0000000 --- a/modules/ags/config/ts/overview/clients.ts +++ /dev/null @@ -1,197 +0,0 @@ -const Hyprland = await Service.import('hyprland'); - -const { Icon, Revealer } = Widget; -const { timeout } = Utils; - -import { WindowButton } from './dragndrop.ts'; -import * as VARS from './variables.ts'; - -// Types -import { Client as HyprClient } from 'types/service/hyprland.ts'; -import AgsRevealer from 'types/widgets/revealer.ts'; -import AgsBox from 'types/widgets/box.ts'; -import AgsButton from 'types/widgets/button.ts'; -import AgsIcon from 'types/widgets/icon.ts'; - -const scale = (size: number) => (size * VARS.SCALE) - VARS.MARGIN; - -const getFontSize = (client: HyprClient) => { - const valX = scale(client.size[0]) * VARS.ICON_SCALE; - const valY = scale(client.size[1]) * VARS.ICON_SCALE; - - const size = Math.min(valX, valY); - - return size <= 0 ? 0.1 : size; -}; - -const IconStyle = (client: HyprClient) => ` - min-width: ${scale(client.size[0])}px; - min-height: ${scale(client.size[1])}px; - font-size: ${getFontSize(client)}px; -`; - - -const Client = ( - client: HyprClient, - active: boolean, - clients: Array, - box: AgsBox, -) => { - const wsName = String(client.workspace.name).replace('special:', ''); - const wsId = client.workspace.id; - const addr = `address:${client.address}`; - - return Revealer({ - transition: 'crossfade', - reveal_child: true, - - attribute: { - address: client.address, - to_destroy: false, - }, - - child: WindowButton({ - mainBox: box, - address: client.address, - - on_secondary_click_release: () => { - Hyprland.sendMessage(`dispatch closewindow ${addr}`); - }, - - on_primary_click_release: () => { - if (wsId < 0) { - if (client.workspace.name === 'special') { - Hyprland.sendMessage('dispatch ' + - `movetoworkspacesilent special:${wsId},${addr}`) - .then(() => { - Hyprland.sendMessage('dispatch ' + - `togglespecialworkspace ${wsId}`) - .then(() => { - App.closeWindow('overview'); - }).catch(print); - }).catch(print); - } - else { - Hyprland.sendMessage('dispatch ' + - `togglespecialworkspace ${wsName}`) - .then(() => { - App.closeWindow('overview'); - }).catch(print); - } - } - else { - // Close special workspace if one is opened - const activeAddress = Hyprland.active.client.address; - - const currentActive = clients.find((c) => { - return c.address === activeAddress; - }); - - if (currentActive && currentActive.workspace.id < 0) { - const currentSpecial = `${currentActive.workspace.name}` - .replace('special:', ''); - - Hyprland.sendMessage('dispatch ' + - `togglespecialworkspace ${currentSpecial}`) - .catch(print); - } - - Hyprland.sendMessage(`dispatch focuswindow ${addr}`) - .then(() => { - App.closeWindow('overview'); - }).catch(print); - } - }, - - child: Icon({ - class_name: `window ${active ? 'active' : ''}`, - css: `${IconStyle(client)} font-size: 10px;`, - icon: client.class, - }), - }), - }); -}; - -export const updateClients = (box: AgsBox) => { - Hyprland.sendMessage('j/clients').then((out) => { - let clients = JSON.parse(out) as Array; - - clients = clients.filter((client) => client.class); - - box.attribute.workspaces.forEach( - (workspace: AgsRevealer) => { - const fixed = workspace.attribute.get_fixed(); - const toRemove = fixed.get_children() as Array; - - clients.filter((client) => - client.workspace.id === workspace.attribute.id) - .forEach((client) => { - const active = - client.address === Hyprland.active.client.address; - - // TODO: see if this works on multi monitor setup - const alloc = box.get_allocation(); - let monitor = box.get_display() - .get_monitor_at_point(alloc.x, alloc.y); - - monitor = Hyprland.monitors.find((mon) => { - return mon.make === monitor.manufacturer && - mon.model === monitor.model; - }); - - client.at[0] -= monitor.x; - client.at[1] -= monitor.y; - - // Special workspaces that haven't been opened yet - // return a size of 0. We need to set them to default - // values to show the workspace properly - if (client.size[0] === 0) { - client.size[0] = VARS.DEFAULT_SPECIAL.SIZE_X; - client.size[1] = VARS.DEFAULT_SPECIAL.SIZE_Y; - client.at[0] = VARS.DEFAULT_SPECIAL.POS_X; - client.at[1] = VARS.DEFAULT_SPECIAL.POS_Y; - } - - const newClient = [ - (fixed.get_children() as Array) - .find((ch) => - ch.attribute.address === client.address), - client.at[0] * VARS.SCALE, - client.at[1] * VARS.SCALE, - ] as [AgsRevealer, number, number]; - - // If it exists already - if (newClient[0]) { - toRemove.splice(toRemove.indexOf(newClient[0]), 1); - fixed.move(...newClient); - } - else { - newClient[0] = Client(client, active, clients, box); - fixed.put(...newClient); - } - - // Set a timeout here to have an animation when the icon first appears - timeout(1, () => { - ((newClient[0].child as AgsButton) - .child as AgsIcon) - .class_name = `window ${active}`; - - ((newClient[0].child as AgsButton) - .child as AgsIcon).setCss(IconStyle(client)); - }); - }); - - fixed.show_all(); - toRemove.forEach((ch) => { - if (ch.attribute.to_destroy) { - ch.destroy(); - } - else { - ch.reveal_child = false; - ch.attribute.to_destroy = true; - } - }); - }, - ); - }).catch(print); -}; diff --git a/modules/ags/config/ts/overview/current-workspace.ts b/modules/ags/config/ts/overview/current-workspace.ts deleted file mode 100644 index c83575e..0000000 --- a/modules/ags/config/ts/overview/current-workspace.ts +++ /dev/null @@ -1,51 +0,0 @@ -const Hyprland = await Service.import('hyprland'); - -const { Box } = Widget; - -import * as VARS from './variables.ts'; - -const PADDING = 34; -const MARGIN = 9; -const DEFAULT_STYLE = ` - min-width: ${VARS.SCREEN.X * VARS.SCALE}px; - min-height: ${(VARS.SCREEN.Y * VARS.SCALE) - (VARS.MARGIN / 2)}px; - border-radius: 10px; -`; - -// Types -import AgsBox from 'types/widgets/box.ts'; -import AgsRevealer from 'types/widgets/revealer.ts'; -import AgsCenterBox from 'types/widgets/centerbox.ts'; -import AgsEventBox from 'types/widgets/eventbox.ts'; - - -export const Highlighter = () => Box({ - vpack: 'start', - hpack: 'start', - class_name: 'workspace active', - css: DEFAULT_STYLE, -}); - -export const updateCurrentWorkspace = (main: AgsBox, highlighter: AgsBox) => { - const currentId = Hyprland.active.workspace.id; - const row = Math.floor((currentId - 1) / VARS.WORKSPACE_PER_ROW); - - const rowObject = (main.children[0] as AgsBox).children[row] as AgsRevealer; - const workspaces = ((((rowObject.child as AgsCenterBox) - .center_widget as AgsEventBox) - .child as AgsBox) - .get_children() as Array) - .filter((w) => w.reveal_child); - - const currentIndex = workspaces.findIndex( - (w) => w.attribute.id === currentId, - ); - const left = currentIndex * ((VARS.SCREEN.X * VARS.SCALE) + 2 + PADDING); - const height = row * ((VARS.SCREEN.Y * VARS.SCALE) + (PADDING / 2)); - - highlighter.setCss(` - ${DEFAULT_STYLE} - margin-left: ${MARGIN + left}px; - margin-top: ${MARGIN + height}px; - `); -}; diff --git a/modules/ags/config/ts/overview/dragndrop.ts b/modules/ags/config/ts/overview/dragndrop.ts deleted file mode 100644 index 2c5cfed..0000000 --- a/modules/ags/config/ts/overview/dragndrop.ts +++ /dev/null @@ -1,122 +0,0 @@ -const Hyprland = await Service.import('hyprland'); - -const { Button, EventBox } = Widget; - -import Cairo from 'cairo'; -const { Gtk, Gdk } = imports.gi; - -import { updateClients } from './clients.ts'; - -const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)]; -const display = Gdk.Display.get_default(); - -// Types -import AgsBox from 'types/widgets/box.ts'; -import AgsButton from 'types/widgets/button.ts'; -import AgsRevealer from 'types/widgets/revealer.ts'; -import { ButtonProps } from 'types/widgets/button.ts'; -import { EventBoxProps } from 'types/widgets/eventbox.ts'; -type WindowButtonType = ButtonProps & { - address: string - mainBox: AgsBox -}; - - -const createSurfaceFromWidget = (widget: AgsButton) => { - const alloc = widget.get_allocation(); - const surface = new Cairo.ImageSurface( - Cairo.Format.ARGB32, - alloc.width, - alloc.height, - ); - const cr = new Cairo.Context(surface); - - cr.setSourceRGBA(255, 255, 255, 0); - cr.rectangle(0, 0, alloc.width, alloc.height); - cr.fill(); - widget.draw(cr); - - return surface; -}; - -let hidden = 0; - -export const WorkspaceDrop = ({ ...props }: EventBoxProps) => EventBox({ - ...props, - setup: (self) => { - self.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY); - - self.on('drag-data-received', (_, _c, _x, _y, data) => { - let id = (self.get_parent() as AgsRevealer)?.attribute.id; - - if (id < -1) { - id = (self.get_parent() as AgsRevealer)?.attribute.name; - } - - else if (id === -1) { - id = `special:${++hidden}`; - } - - else if (id === 1000) { - id = 'empty'; - } - - Hyprland.sendMessage('dispatch ' + - `movetoworkspacesilent ${id},address:${data.get_text()}`) - .catch(print); - }); - }, -}); - -export const WindowButton = ({ - address, - mainBox, - ...props -}: WindowButtonType) => Button({ - ...props, - - setup: (self) => { - self.drag_source_set( - Gdk.ModifierType.BUTTON1_MASK, - TARGET, - Gdk.DragAction.COPY, - ); - - self - .on('drag-data-get', (_w, _c, data) => { - data.set_text(address, address.length); - }) - - .on('drag-begin', (_, context) => { - Gtk.drag_set_icon_surface( - context, - createSurfaceFromWidget(self), - ); - (self.get_parent() as AgsRevealer)?.set_reveal_child(false); - }) - - .on('drag-end', () => { - self.get_parent()?.destroy(); - - updateClients(mainBox); - }) - - // OnHover - .on('enter-notify-event', () => { - if (!display) { - return; - } - self.window.set_cursor(Gdk.Cursor.new_from_name( - display, - 'pointer', - )); - self.toggleClassName('hover', true); - }) - - // OnHoverLost - .on('leave-notify-event', () => { - self.window.set_cursor(null); - self.toggleClassName('hover', false); - }); - }, -}); diff --git a/modules/ags/config/ts/overview/main.ts b/modules/ags/config/ts/overview/main.ts deleted file mode 100644 index 2acbcbc..0000000 --- a/modules/ags/config/ts/overview/main.ts +++ /dev/null @@ -1,151 +0,0 @@ -const Hyprland = await Service.import('hyprland'); - -const { Box, Overlay, Window } = Widget; - -import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.ts'; -import { Highlighter, updateCurrentWorkspace } from './current-workspace.ts'; -import { updateClients } from './clients.ts'; - -// Types -import AgsBox from 'types/widgets/box.ts'; -import AgsOverlay from 'types/widgets/overlay.ts'; - - -// TODO: have a 'page' for each monitor, arrows on both sides to loop through -export const Overview = () => { - const highlighter = Highlighter(); - - const mainBox = Box({ - // Do this for scss hierarchy - class_name: 'overview', - css: 'all: unset', - - vertical: true, - vpack: 'center', - hpack: 'center', - - attribute: { - workspaces: [], - - update: () => { - getWorkspaces(mainBox); - updateWorkspaces(mainBox); - updateClients(mainBox); - updateCurrentWorkspace(mainBox, highlighter); - }, - }, - - children: [ - Box({ - vertical: true, - children: [ - WorkspaceRow('normal', 0), - ], - }), - - Box({ - vertical: true, - children: [ - WorkspaceRow('special', 0), - ], - }), - ], - - setup: (self) => { - self.hook(Hyprland, () => { - if (!App.getWindow('overview')?.visible) { - return; - } - - self.attribute.update(); - }); - }, - }); - - const widget = Overlay({ - overlays: [highlighter, mainBox], - - attribute: { - get_child: () => mainBox, - closing: false, - }, - - // Make size of overlay big enough for content - child: Box({ - class_name: 'overview', - css: ` - min-height: ${mainBox.get_allocated_height()}px; - min-width: ${mainBox.get_allocated_width()}px; - `, - }), - - // TODO: throttle this? - setup: (self) => { - self.on('get-child-position', (_, ch) => { - if (ch === mainBox && !self.attribute.closing) { - (self.child as AgsBox).setCss(` - transition: min-height 0.2s ease, min-width 0.2s ease; - min-height: ${mainBox.get_allocated_height()}px; - min-width: ${mainBox.get_allocated_width()}px; - `); - } - }); - }, - }); - - return widget; -}; - -// FIXME: can't use PopupWindow because this is an overlay already -export default () => { - const transition_duration = 800; - const win = Window({ - name: 'overview', - visible: false, - - // Needs this to have space - // allocated at the start - child: Box({ - css: ` - min-height: 1px; - min-width: 1px; - padding: 1px; - `, - }), - - attribute: { close_on_unfocus: 'none' }, - - setup: (self) => { - const name = 'overview'; - - Hyprland.sendMessage('[[BATCH]] ' + - `keyword layerrule ignorealpha[0.97],${name}; ` + - `keyword layerrule blur,${name}`); - - self.hook(App, (_, currentName, isOpen) => { - if (currentName === self.name) { - if (isOpen) { - self.child = Overview(); - self.show_all(); - - (self.child as AgsOverlay) - .attribute.get_child().attribute.update(); - } - else { - (self.child as AgsOverlay).attribute.closing = true; - - ((self.child as AgsOverlay) - .child as AgsBox).css = ` - min-height: 1px; - min-width: 1px; - transition: all - ${transition_duration - 10}ms ease; - `; - } - } - }); - }, - }); - - return win; -}; diff --git a/modules/ags/config/ts/overview/variables.ts b/modules/ags/config/ts/overview/variables.ts deleted file mode 100644 index 372ff37..0000000 --- a/modules/ags/config/ts/overview/variables.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const SCALE = 0.11; -export const ICON_SCALE = 0.8; -export const MARGIN = 8; -export const DEFAULT_SPECIAL = { - SIZE_X: 1524, - SIZE_Y: 908, - POS_X: 197, - POS_Y: 170, -}; -export const WORKSPACE_PER_ROW = 6; -export const SCREEN = { - X: 1920, - Y: 1200, -}; diff --git a/modules/ags/config/ts/overview/workspaces.ts b/modules/ags/config/ts/overview/workspaces.ts deleted file mode 100644 index dc28ff6..0000000 --- a/modules/ags/config/ts/overview/workspaces.ts +++ /dev/null @@ -1,202 +0,0 @@ -const Hyprland = await Service.import('hyprland'); - -const { Revealer, CenterBox, Box, EventBox, Fixed, Label } = Widget; - -import { WorkspaceDrop } from './dragndrop.ts'; -import * as VARS from './variables.ts'; - -const EMPTY_OFFSET = 16; -const DEFAULT_STYLE = ` - min-width: ${(VARS.SCREEN.X * VARS.SCALE) + EMPTY_OFFSET}px; - min-height: ${VARS.SCREEN.Y * VARS.SCALE}px; -`; - -// Types -import AgsBox from 'types/widgets/box.ts'; -import AgsRevealer from 'types/widgets/revealer.ts'; -import AgsCenterBox from 'types/widgets/centerbox.ts'; -import AgsEventBox from 'types/widgets/eventbox.ts'; - - -export const getWorkspaces = (box: AgsBox) => { - const children = [] as Array; - - (box.children as Array).forEach((type) => { - (type.children as Array).forEach( - (row) => { - ((((row.child as AgsCenterBox) - .center_widget as AgsEventBox) - .child as AgsBox) - .children as Array) - .forEach((workspace) => { - children.push(workspace); - }); - }, - ); - }); - box.attribute.workspaces = children.sort((a, b) => { - return a.attribute.id - b.attribute.id; - }); -}; - -const Workspace = (id: number, name: string, normal = true) => { - // @ts-expect-error - const fixed = Fixed(); - - const workspace = Revealer({ - transition: 'slide_right', - transition_duration: 500, - - attribute: { - id, - name, - get_fixed: () => fixed, - }, - - setup: (self) => { - if (normal) { - self.hook(Hyprland, () => { - const activeId = Hyprland.active.workspace.id; - const active = activeId === self.attribute.id; - const ws = Hyprland.getWorkspace(self.attribute.id); - - self.reveal_child = - (ws?.windows && ws.windows > 0) || active; - }); - } - }, - - child: WorkspaceDrop({ - child: Box({ - class_name: 'workspace', - css: normal ? - - DEFAULT_STYLE : - - ` - min-width: ${(VARS.SCREEN.X * VARS.SCALE / 2) + - EMPTY_OFFSET}px; - min-height: ${VARS.SCREEN.Y * VARS.SCALE}px; - `, - - children: normal ? - - [fixed] : - - [ - fixed, - Label({ - label: ' +', - css: 'font-size: 40px;', - }), - ], - }), - }), - }); - - return workspace; -}; - -export const WorkspaceRow = (class_name: string, i: number) => { - const addWorkspace = Workspace( - class_name === 'special' ? -1 : 1000, - class_name === 'special' ? 'special' : '', - false, - ); - - return Revealer({ - transition: 'slide_down', - hpack: class_name === 'special' ? 'fill' : 'start', - - setup: (self) => { - self.hook(Hyprland, (rev) => { - const minId = i * VARS.WORKSPACE_PER_ROW; - const activeId = Hyprland.active.workspace.id; - - const rowExists = Hyprland.workspaces.some((ws) => { - const isInRow = ws.id > minId; - const hasClients = ws.windows > 0; - const isActive = ws.id === activeId; - - return isInRow && (hasClients || isActive); - }); - - rev.reveal_child = rowExists; - }); - }, - - child: CenterBox({ - center_widget: EventBox({ - setup: (self) => { - self.hook(Hyprland, () => { - const maxId = (i + 1) * VARS.WORKSPACE_PER_ROW; - const activeId = Hyprland.active.workspace.id; - - const isSpecial = class_name === 'special'; - const nextRowExists = Hyprland.workspaces.some((ws) => { - const isInNextRow = ws.id > maxId; - const hasClients = ws.windows > 0; - const isActive = ws.id === activeId; - - return isInNextRow && (hasClients || isActive); - }); - - addWorkspace.reveal_child = isSpecial || !nextRowExists; - }); - }, - - child: Box({ - class_name, - children: [addWorkspace], - }), - }), - }), - }); -}; - -export const updateWorkspaces = (box: AgsBox) => { - Hyprland.workspaces.forEach((ws) => { - const currentWs = (box.attribute.workspaces as Array).find( - (ch) => ch.attribute.id === ws.id, - ); - - if (!currentWs) { - let type = 0; - let rowNo = 0; - - if (ws.id < 0) { - // This means it's a special workspace - type = 1; - } - else { - rowNo = Math.floor((ws.id - 1) / VARS.WORKSPACE_PER_ROW); - const wsRow = box.children[type] as AgsBox; - const wsQty = wsRow.children.length; - - if (rowNo >= wsQty) { - for (let i = wsQty; i <= rowNo; ++i) { - wsRow.add(WorkspaceRow( - type ? 'special' : 'normal', i, - )); - } - } - } - const row = ((((box.children[type] as AgsBox) - .children[rowNo] as AgsRevealer) - .child as AgsCenterBox) - .center_widget as AgsEventBox) - .child as AgsBox; - - row.add(Workspace(ws.id, type ? ws.name : '')); - } - }); - - // Make sure the order is correct - box.attribute.workspaces.forEach( - (workspace: AgsRevealer, i: number) => { - (workspace?.get_parent() as AgsBox) - ?.reorder_child(workspace, i); - }, - ); - box.show_all(); -}; diff --git a/modules/ags/config/wim.ts b/modules/ags/config/wim.ts index b0a17d7..03b43e0 100644 --- a/modules/ags/config/wim.ts +++ b/modules/ags/config/wim.ts @@ -7,7 +7,6 @@ import Corners from './ts/corners/main.ts'; import { NotifPopups, NotifCenter } from './ts/notifications/wim.ts'; import OSD from './ts/osd/main.ts'; import OSK from './ts/on-screen-keyboard/main.ts'; -import Overview from './ts/overview/main.ts'; import Powermenu from './ts/powermenu.ts'; import QSettings from './ts/quick-settings/main.ts'; @@ -23,7 +22,6 @@ export default { 'notification-center': closeWinDelay, 'osd': 300, 'osk': closeWinDelay, - 'overview': closeWinDelay, 'powermenu': closeWinDelay, 'quick-settings': closeWinDelay, }, @@ -35,7 +33,6 @@ export default { NotifCenter(), OSD(), OSK(), - Overview(), Powermenu(), QSettings(), diff --git a/modules/dconf.nix b/modules/dconf.nix new file mode 100644 index 0000000..7752b59 --- /dev/null +++ b/modules/dconf.nix @@ -0,0 +1,28 @@ +{config, ...}: let + inherit (config.vars) mainUser; +in { + programs = { + dconf.enable = true; + }; + + home-manager.users.${mainUser} = { + dconf.settings = { + "org/virt-manager/virt-manager/connections" = { + autoconnect = ["qemu:///system"]; + uris = ["qemu:///system"]; + }; + + "apps/seahorse/listing" = { + keyrings-selected = ["gnupg://"]; + }; + + "org/gtk/settings/file-chooser" = { + show-hidden = true; + }; + + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + }; + }; + }; +} diff --git a/modules/hyprland/default.nix b/modules/hyprland/default.nix index 8ea85c8..edce4c4 100644 --- a/modules/hyprland/default.nix +++ b/modules/hyprland/default.nix @@ -1,7 +1,6 @@ { config, hyprland, - hyprgrass, pkgs, lib, ... @@ -10,23 +9,16 @@ inherit (config.vars) configDir mainUser mainMonitor; isNvidia = config.hardware.nvidia.modesetting.enable; - isTouchscreen = config.hardware.sensor.iio.enable; in { # SYSTEM CONFIG imports = [ - ../greetd - ../dolphin.nix + ../dconf.nix + + ./packages.nix + ./security.nix ]; - security.pam.services.swaylock = {}; - - programs = { - kdeconnect.enable = true; - dconf.enable = true; - }; - services = { - gnome.gnome-keyring.enable = true; dbus.enable = true; gvfs.enable = true; }; @@ -42,25 +34,16 @@ in { # HOME-MANAGER CONFIG home-manager.users.${mainUser} = { imports = [ - ../../home/foot.nix - ../../home/dconf.nix - ../../home/mpv - ../../home/obs.nix - ../../home/swaylock.nix ../../home/theme.nix - ../../home/wofi + + ./hycov.nix + ./hyprgrass.nix ]; wayland.windowManager.hyprland = { enable = true; package = hyprland.packages.${pkgs.system}.default; - plugins = - [] - ++ (optionals isTouchscreen [ - hyprgrass.packages.${pkgs.system}.default - ]); - settings = { env = let gset = pkgs.gsettings-desktop-schemas; @@ -121,31 +104,15 @@ in { exec-once = [ "hyprctl setcursor Dracula-cursors 24" - "${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1" "swww init --no-cache && swww img -t none ${pkgs.dracula-theme}/wallpapers/waves.png" - "wl-paste --watch cliphist store" - "${config.programs.kdeconnect.package}/libexec/kdeconnectd" - "kdeconnect-indicator" - "gnome-keyring-daemon --start --components=secrets" ] ++ optionals (! isNull mainMonitor) ["hyprctl dispatch focusmonitor ${mainMonitor}"]; - windowrule = [ - "noborder,^(wofi)$" - - # Polkit - "float,^(org.kde.polkit-kde-authentication-agent-1)$" - "size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$" - "center,^(org.kde.polkit-kde-authentication-agent-1)$" - ]; - "$mainMod" = "SUPER"; bind = [ # Defaults - "$mainMod, L, exec, lock" - "$mainMod, Q, exec, foot" "$mainMod, F, fullscreen" "$mainMod, C, killactive, " "$mainMod SHIFT, SPACE, togglefloating, " @@ -181,12 +148,6 @@ in { "$mainMod SHIFT, 9, movetoworkspace, 9" "$mainMod SHIFT, 0, movetoworkspace, 10" - # Clipboard History - "$mainMod, V, exec, killall -r wofi || cliphist list | wofi --dmenu | cliphist decode | wl-copy" - - ",Print, exec, grim -g \"$(slurp)\" - | swappy -f -" - "$mainMod SHIFT, C, exec, wl-color-picker" - ",XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle & ags -r 'showSpeaker()' &" ",XF86AudioMicMute, exec, pactl set-source-mute @DEFAULT_SOURCE@ toggle" ]; @@ -217,52 +178,17 @@ in { }; }; + # libs home.packages = with pkgs; [ - # School - xournalpp - virt-manager - jetbrains.idea-ultimate - libreoffice-fresh # TODO: declarative conf? - hunspell - hunspellDicts.en_CA - config.customPkgs.rars-flatlaf - - # Apps - thunderbird # TODO: use programs.thunderbird - spotifywm - photoqt - nextcloud-client - jellyfin-media-player - prismlauncher-qt5 - - /* - Discord themes for Vencord - https://markchan0225.github.io/RoundedDiscord/RoundedDiscord.theme.css - https://raw.githubusercontent.com/dracula/BetterDiscord/master/Dracula_Official.theme.css - */ - (pkgs.discord.override { - withOpenASAR = true; - withVencord = true; - }) - # tools - wl-color-picker - wl-clipboard - cliphist - grim - slurp - swappy - swayidle bluez-tools brightnessctl pulseaudio alsa-utils - gnome.seahorse p7zip # for reshade swww - ## libs qt5.qtwayland qt6.qtwayland libayatana-appindicator diff --git a/modules/hyprland/hycov.nix b/modules/hyprland/hycov.nix new file mode 100644 index 0000000..7163c31 --- /dev/null +++ b/modules/hyprland/hycov.nix @@ -0,0 +1,29 @@ +{ + hycov, + pkgs, + ... +}: { + wayland.windowManager.hyprland = { + plugins = [hycov.packages.${pkgs.system}.hycov]; + + settings = { + plugin = { + hycov = { + enable_alt_release_exit = 1; + overview_gappo = 60; #gaps width from screen + overview_gappi = 24; #gaps width from clients + hotarea_size = 10; #hotarea size in bottom left,10x10 + enable_hotarea = 1; # enable mouse cursor hotarea + }; + }; + + bind = [ + "ALT, tab, hycov:toggleoverview" + "ALT, left, hycov:movefocus, l" + "ALT, right, hycov:movefocus, r" + "ALT, up, hycov:movefocus, u" + "ALT, down, hycov:movefocus, d" + ]; + }; + }; +} diff --git a/modules/hyprland/hyprgrass.nix b/modules/hyprland/hyprgrass.nix new file mode 100644 index 0000000..cada6e1 --- /dev/null +++ b/modules/hyprland/hyprgrass.nix @@ -0,0 +1,41 @@ +{ + osConfig, + hyprgrass, + lib, + pkgs, + ... +}: let + inherit (lib) optionalAttrs; + + isTouchscreen = osConfig.hardware.sensor.iio.enable; +in + optionalAttrs isTouchscreen { + wayland.windowManager.hyprland = { + plugins = [hyprgrass.packages.${pkgs.system}.default]; + + settings = { + plugin = { + touch_gestures = { + # The default sensitivity is probably too low on tablet screens, + # I recommend turning it up to 4.0 + sensitivity = 4.0; + + # must be >= 3 + workspace_swipe_fingers = 3; + + experimental = { + # send proper cancel events to windows instead of hacky touch_up events, + # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default + send_cancel = 0; + }; + }; + }; + + gestures = { + workspace_swipe = true; + workspace_swipe_fingers = 3; + workspace_swipe_cancel_ratio = 0.15; + }; + }; + }; + } diff --git a/modules/hyprland/packages.nix b/modules/hyprland/packages.nix new file mode 100644 index 0000000..d5e1f8a --- /dev/null +++ b/modules/hyprland/packages.nix @@ -0,0 +1,83 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.vars) mainUser; +in { + imports = [../dolphin.nix]; + + programs = { + kdeconnect.enable = true; + }; + + home-manager.users.${mainUser} = { + imports = [ + ../../home/foot.nix + ../../home/mpv + ../../home/obs.nix + ../../home/wofi + ]; + + home.packages = with pkgs; [ + # School + xournalpp + virt-manager + libreoffice-fresh # TODO: declarative conf? + hunspell + hunspellDicts.en_CA + config.customPkgs.rars-flatlaf + + # Apps + thunderbird # TODO: use programs.thunderbird + spotifywm + photoqt + nextcloud-client + jellyfin-media-player + prismlauncher-qt5 + + /* + Discord themes for Vencord + https://markchan0225.github.io/RoundedDiscord/RoundedDiscord.theme.css + https://raw.githubusercontent.com/dracula/BetterDiscord/master/Dracula_Official.theme.css + */ + (pkgs.discord.override { + withOpenASAR = true; + withVencord = true; + }) + + # tools + wl-color-picker + wl-clipboard + cliphist + grim + slurp + swappy + ]; + + wayland.windowManager.hyprland = { + settings = { + exec-once = [ + "${config.programs.kdeconnect.package}/libexec/kdeconnectd" + "kdeconnect-indicator" + + "wl-paste --watch cliphist store" + ]; + + windowrule = [ + "noborder,^(wofi)$" + ]; + + bind = [ + "$mainMod, Q, exec, foot" + + # Clipboard History + "$mainMod, V, exec, killall -r wofi || cliphist list | wofi --dmenu | cliphist decode | wl-copy" + + ",Print, exec, grim -g \"$(slurp)\" - | swappy -f -" + "$mainMod SHIFT, C, exec, wl-color-picker" + ]; + }; + }; + }; +} diff --git a/modules/hyprland/security.nix b/modules/hyprland/security.nix new file mode 100644 index 0000000..50d743f --- /dev/null +++ b/modules/hyprland/security.nix @@ -0,0 +1,52 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) optionals; + inherit (config.vars) mainUser; + + isLaptop = config.services.logind.lidSwitch == "lock"; +in { + imports = [ + ../greetd + ]; + + security.pam.services.swaylock = {}; + services.gnome.gnome-keyring.enable = true; + + home-manager.users.${mainUser} = { + imports = [ + ../../home/swaylock.nix + ]; + + home.packages = with pkgs; ([ + gnome.seahorse + ] + ++ optionals isLaptop [ + swayidle + ]); + + wayland.windowManager.hyprland = { + settings = { + exec-once = + [ + "gnome-keyring-daemon --start --components=secrets" + "${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1" + ] + ++ optionals isLaptop ["swayidle -w lock lock"]; + + windowrule = [ + "float,^(org.kde.polkit-kde-authentication-agent-1)$" + "size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$" + "center,^(org.kde.polkit-kde-authentication-agent-1)$" + ]; + + bind = [ + "$mainMod, L, exec, lock" + ]; + }; + }; + }; +}