344 Commits

Author SHA1 Message Date
end-4 45c6d8a837 Merge branch 'main' into hefty-hype 2026-05-25 00:27:46 +02:00
end-4 6eb590b1a2 add light/dark wallpaper variant switching based on suffix 2026-05-25 00:27:31 +02:00
Minh 14376cec94 fix(ii): send configured User-Agent to Konachan requests (#3232) 2026-05-24 23:51:29 +02:00
Minh 397fb8d8c4 Fix broken waifu.im image and tag search (#3239) 2026-05-24 23:45:50 +02:00
Minh aa044b4563 fix source url safe access 2026-05-24 23:45:15 +02:00
end-4 ad7a7fe566 Merge branch 'main' into hefty-hype 2026-05-24 23:37:13 +02:00
end-4 a15f2a8a39 add a weak anti flashbang variant 2026-05-24 23:37:01 +02:00
end-4 9b149e6fef qs: sidebar: quick toggle: friendlier/shorter default state text 2026-05-24 23:34:21 +02:00
Minh eb3613d3ed fix: show escaped text for selected entry in clipboard (#3303) 2026-05-24 23:28:35 +02:00
Minh 091da11da5 Fix monitor scale type (#3312) 2026-05-24 23:26:05 +02:00
Minh a56cee16f1 Restore nwg-displays entry (#3381) 2026-05-24 22:55:37 +02:00
Minh 54a1d172d7 add file existence check for nwg displays include 2026-05-24 22:55:17 +02:00
Minh c58bb07a6b fix(qs): NotificationItem polish() loop on Qt 6.11 — freezes sidebar (#3388) 2026-05-24 22:52:56 +02:00
Minh 9c115f7a8f fix: hypridle Lua-dispatch compatibility for lock and DPMS (#3393) 2026-05-24 22:34:45 +02:00
Minh b9e05599bc Fix screen corners only appearing on integrated monitor (#3386) 2026-05-24 11:28:01 +02:00
Love, Trevor S ce80951210 fix: hypridle dispatch commands for Lua-based Hyprland 2026-05-22 11:41:16 -07:00
RamonBritoDev 6eaa869fac fix(qs): NotificationItem polish() loop on Qt 6.11
summaryText.Layout.fillWidth depended on summaryRow.implicitWidth,
its own parent RowLayout, creating a circular dependency:

  summaryText.Layout.fillWidth
    -> changes summaryText.width
    -> changes summaryRow.implicitWidth
    -> re-evaluates summaryText.Layout.fillWidth (loop)

Qt 6.10 tolerated this through layout settling heuristics, but
Qt 6.11.1 detects the loop and emits "ColumnLayout called polish()
inside updatePolish() of ColumnLayout" warnings repeatedly, pinning
CPU at 100% and freezing the sidebar/notification UI when opened.

Use root.width (the stable width inherited from the parent ListView)
as the reference for the elision threshold instead of the recursive
summaryRow.implicitWidth.
2026-05-21 16:23:40 +00:00
Jihed Kdiss 8f9cf67be7 fix(screenCorners): remove shadowing screen property to fix multi-monitor corner rendering 2026-05-21 14:16:22 +01:00
Zhengjie Min 20d1ff065b style: space indent 2026-05-20 11:38:00 -04:00
Zhengjie Min 25fe0ab01e fix(hyprland): restore nwg-display entry 2026-05-20 11:32:13 -04:00
Minh c1b37bc467 fix(hyprsunset): remove vestigial Hyprland.dispatch broken under .lua schema (#3356) 2026-05-18 23:40:22 +02:00
Minh b470bf3fe8 Fix: XDG_DATA_DIRS now expands correctly (fixes 3354) (#3358) 2026-05-18 23:06:27 +02:00
GregorVal d4e777911e Fix: XDG_DATA_DIRS now expands correctly
Previously the environmental variable would become literally 
*:$XDG_DATA_DIRS
Now the variable is expanded correctly
2026-05-17 14:46:26 +02:00
zzalli d4d78a5e62 fix(hyprsunset): remove vestigial Hyprland.dispatch broken under .lua schema 2026-05-17 15:36:14 +03:00
end-4 c0706258b1 add back some repetitive keybinds to cheatsheet 2026-05-16 23:27:26 +02:00
Minh 68c67aced4 Update keybinds.lua to allow hl.unbind() (#3336) 2026-05-14 19:43:29 +02:00
VietNguyenx 215ac747d8 Update keybinds.lua 2026-05-15 00:31:29 +07:00
end-4 21689e1d51 Merge branch 'main' into hefty-hype 2026-05-14 14:37:23 +02:00
end-4 9eda50178b remove redundant scripts 2026-05-14 14:37:06 +02:00
end-4 d5f9afe7c0 qs: remove no longer necessary unlock refocus hack 2026-05-14 14:34:45 +02:00
end-4 5c66902900 qs: fix wrong capitalization in cheatsheet 2026-05-14 14:34:07 +02:00
end-4 74e4e698d9 Merge branch 'main' into hefty-hype 2026-05-14 14:32:52 +02:00
end-4 28ba8a4f43 hl: make custom stuff optional 2026-05-14 12:35:29 +02:00
end-4 798d35a538 hl: remove that whatever jetbrains windowrule (fixes #3324) 2026-05-14 12:28:05 +02:00
end-4 7d5ce9a793 hl: fix #3327 send to scratchpad desc at wrong scope 2026-05-14 12:25:28 +02:00
end-4 c53265754c hl: create custom config files automatically 2026-05-14 12:21:00 +02:00
end-4 239b532ec6 ctrl+super+shift+d for dark/light toggle (like powertoys) 2026-05-14 10:43:23 +02:00
end-4 d1daedc6d2 qs: cheatsheet: display categories nicely 2026-05-14 09:37:45 +02:00
end-4 20d9f80336 fix wrong merge 2026-05-14 09:34:19 +02:00
end-4 4420a6c22d Merge branch 'main' into hefty-hype 2026-05-14 09:33:48 +02:00
end-4 2ade168a20 hl config: remove unused bash scripts 2026-05-14 08:17:29 +02:00
end-4 08201f2ac0 hl: keybinds: fix workspace groups, categorize descriptions 2026-05-14 08:16:47 +02:00
end-4 bac0b388ad Merge branch 'main' into hefty-hype 2026-05-13 20:37:34 +02:00
Minh ad12fe6ddf feat: notification on specific monitor (#3292) 2026-05-13 20:01:56 +02:00
end-4 9e1568fcdc qs: rename config option notifications.monitor to notifications.forceMonitor 2026-05-13 20:01:21 +02:00
Minh b7b2e6e10d fix Hyprsunset default color temperature (#3254) 2026-05-13 19:49:51 +02:00
Minh 00a4235a81 Update emoji list to emoji 17.0 (#3268) 2026-05-13 19:48:48 +02:00
Minh c504cdf22b Fix kitty config (#3284) 2026-05-13 19:47:06 +02:00
Minh e6d2a7d88c Fix HOME env in lua (#3316) 2026-05-13 19:46:22 +02:00
Minh b50a4a7faa Merge branch 'main' into fix-home-env 2026-05-13 19:46:12 +02:00
Minh 737eb7c356 Do not override XDG_DATA_DIRS (fixes #2583) (#3321) 2026-05-13 19:42:50 +02:00
Minh 5ce6280d98 fix(keybinds): correct fullscreen and maximize bind syntax (#3306) 2026-05-13 19:39:43 +02:00
GregorVal f7773acab4 Do not override XDG_DATA_DIRS (fixes #2583) 2026-05-13 17:51:41 +02:00
imitoy e8721b4b01 Fix HOME env in lua 2026-05-13 16:03:09 +08:00
end-4 4c590874e0 fix dupe y 2026-05-13 00:07:46 +02:00
PetLucy b85ed8691a Fix monitor scale type
Changes the default monitor scale value from `"1"` to `1`.

This fixes the typo in the default monitor configuration.
2026-05-12 15:23:17 -05:00
Rasmion ac8d0e9a42 fix: specify toggle action explicitly 2026-05-12 22:00:36 +02:00
Minh 412b2222c2 readme: move warning content to wiki 2026-05-12 15:37:00 +02:00
Rasmion d6b27cf9dd fix(keybinds): correct fullscreen and maximize bind syntax 2026-05-12 14:45:53 +02:00
end-4 c53e9891cb qs: fix super key hold state properly 2026-05-12 12:07:33 +02:00
end-4 1e442f1af0 qs: temp fix super key always thought to be held down 2026-05-12 11:13:26 +02:00
Minh 20dde15900 readme: add hyprland 0.55 warning 2026-05-12 11:04:30 +02:00
end-4 da47151345 Merge branch 'main' into hefty-hype 2026-05-12 10:47:55 +02:00
end-4 ba0e76da1b fix hyprland theming 2026-05-12 10:47:44 +02:00
end-4 1c117e0880 add example keybind for editing user keybinds 2026-05-12 10:34:59 +02:00
end-4 7aad60eb2c install script: add check for hyprland.conf rename 2026-05-12 10:31:40 +02:00
end-4 a9f87c06ca install script: rename hyprland.conf to not use it 2026-05-12 10:06:10 +02:00
end-4 281b3e5627 previous commit but in the "legacy" script 2026-05-12 09:59:17 +02:00
end-4 388783e992 hyprland: exclude monitors and workspaces conf 2026-05-12 09:55:24 +02:00
end-4 ae7f6bd165 fix keybind cheatsheet 2026-05-12 09:28:07 +02:00
end-4 9279a5a181 Merge branch 'main' into hefty-hype 2026-05-12 09:27:19 +02:00
lnb 403f7aa685 fix: show escaped text for selected entry in clipboard 2026-05-12 12:04:28 +05:30
end-4 807c761ed0 qs: fix some manual hyprland dispatches 2026-05-12 08:28:10 +02:00
end-4 7dcbabcd8c fix screen locking 2026-05-12 08:11:47 +02:00
end-4 a9dcaf0d4b Merge branch 'main' into hefty-hype 2026-05-12 07:55:05 +02:00
end-4 2e161911bc qs: fix hyprland overrides (game mode, anti flashbang) 2026-05-12 07:54:56 +02:00
end-4 a23d050df5 qs: hyprland dispatcher fixes 2026-05-12 07:24:29 +02:00
end-4 7aa9e603d5 Merge branch 'main' into hefty-hype 2026-05-12 07:23:24 +02:00
end-4 e11d084be8 remove redundant wallpaper switching stuff 2026-05-11 23:46:23 +02:00
end-4 760c7034aa qs: fix hyprland dispatchers 2026-05-11 23:45:44 +02:00
end-4 b9f668e106 Merge branch 'main' into hefty-hype 2026-05-11 23:40:19 +02:00
Minh 6c041b953a migrate hyprland config to lua (#3269) 2026-05-11 23:02:05 +02:00
end-4 9f4afde0c5 use globalshortcut for 4finger up touchpad gesture 2026-05-11 23:00:50 +02:00
end-4 010f070eef fix stuff 2026-05-11 22:52:48 +02:00
Linuxius f6b97c4649 Update general.lua 2026-05-09 21:57:36 +02:00
electricsteve 0da83ba460 feat: notification on specific monitor 2026-05-09 19:10:43 +02:00
fb24m 74c10b915d fix kitty config 2026-05-07 21:45:11 +04:00
Linuxius 0ae900515e Add files via upload 2026-05-07 19:20:37 +02:00
Linuxius c3147dc7ff Add files via upload 2026-05-07 11:19:53 +02:00
Linuxius fb3ec1fdfc Add files via upload 2026-05-06 19:15:03 +02:00
end-4 b9acc518e9 Merge branch 'main' into hefty-hype 2026-05-04 10:18:09 +02:00
Linuxius d1cd892c0f Add files via upload 2026-05-03 13:16:49 +02:00
Linuxius 63495d0b28 Add files via upload 2026-05-03 11:13:26 +02:00
Linuxius 36a4a19bca Add files via upload 2026-05-03 11:12:54 +02:00
ThomasNoorlander c693a3f539 Create variables.lua 2026-05-02 17:50:36 +02:00
ThomasNoorlander c0888cbb98 Create rules.lua 2026-05-02 17:50:24 +02:00
ThomasNoorlander 2cfb0c2757 Create keybinds.lua 2026-05-02 17:50:11 +02:00
ThomasNoorlander b034a712a9 Create general.lua 2026-05-02 17:49:57 +02:00
ThomasNoorlander aff6206930 Create execs.lua 2026-05-02 17:49:42 +02:00
ThomasNoorlander 0e1f6a97fc Create env.lua 2026-05-02 17:49:28 +02:00
ThomasNoorlander 7834f22243 Add files via upload 2026-05-02 17:48:52 +02:00
ThomasNoorlander cec16c8720 Create main.lua 2026-05-02 17:48:26 +02:00
ThomasNoorlander 54e19afa81 Add files via upload 2026-05-02 17:47:55 +02:00
Hanz Montano ffabb85693 feat: update emoji list to emoji 17.0 2026-05-02 12:09:57 +08:00
Reluckycf 72d950ed51 change hyprsunset default color temp to 6000 2026-04-25 18:58:48 -05:00
Kashi754 4eef9ea18e Fix still tags not being applied to search request. 2026-04-21 19:23:21 +09:00
end-4 464cddad00 Merge branch 'main' into hefty-hype 2026-04-16 22:33:02 +02:00
end-4 283995ca99 fix notif drag getting stuck 2026-04-16 22:32:54 +02:00
Kashi754 329fa31262 Fix broken waifu.im image and tag search 2026-04-15 18:16:56 +09:00
Hugo Hsi 14f8b84635 fix(ii): add Konachan support in sidebar 2026-04-14 01:58:37 -04:00
Hugo Hsi 36e0c3fddc fix(ii): remove Konachan wallpaper UA fallback 2026-04-14 01:58:30 -04:00
Hugo Hsi d24cbff7ac fix(ii): send user agent for Konachan wallpaper 2026-04-14 01:51:08 -04:00
end-4 ef9042838e Merge branch 'main' into hefty-hype 2026-04-13 16:45:05 +02:00
end-4 87939110bf Merge branch 'main' into hefty-hype 2026-04-10 22:12:48 +02:00
end-4 a62e64e2ef Merge branch 'main' into hefty-hype 2026-04-08 10:23:53 +02:00
end-4 493fb9b686 fix more member overrides base object member warning 2026-04-08 10:19:03 +02:00
end-4 0db4f8bd5d Merge branch 'main' into hefty-hype 2026-04-08 10:18:18 +02:00
end-4 15002949ee hefty: bar: adjust hresources spacing 2026-04-07 22:58:40 +02:00
end-4 74b869c30b Merge branch 'main' into hefty-hype 2026-04-07 16:01:49 +02:00
end-4 a4d45f04f2 removed duped print 2026-04-07 15:59:59 +02:00
end-4 d87fbf5523 merge main 2026-04-05 23:20:10 +02:00
end-4 c582ecf8af merge recognize-music.sh 2026-04-05 21:55:32 +02:00
end-4 6050148835 GoogleCloud: re fetch token on expiry 2026-04-05 21:52:50 +02:00
end-4 cc582fd113 Merge branch 'main' into hefty-hype 2026-04-05 20:22:48 +02:00
end-4 c8eb9d2830 hefty: bar: fix stacked exclusivity when theres multiple monitors 2026-04-05 00:45:10 +02:00
end-4 35c272c807 Merge branch 'main' into hefty-hype 2026-04-04 23:33:46 +02:00
end-4 e552776670 add screentranslator to hefty family 2026-04-04 23:30:34 +02:00
end-4 fdcdc7f1a3 Merge branch 'main' into hefty-hype 2026-04-03 20:50:58 +02:00
end-4 566e100623 Merge branch 'main' into hefty-hype 2026-04-03 19:34:59 +02:00
end-4 2674382b5f refactor toolbar fab 2026-04-03 19:27:28 +02:00
end-4 01e2eb433b add MultiTurnProcess 2026-04-03 19:26:47 +02:00
end-4 2c30b28fb6 revealer: more correct reveal condition 2026-04-03 19:26:36 +02:00
end-4 7c27da5336 lock: refactor error shake 2026-04-03 19:26:23 +02:00
end-4 32934200e4 Merge branch 'main' into hefty-hype 2026-03-31 15:06:52 +02:00
end-4 906d7adf3e Merge branch 'main' into hefty-hype 2026-03-29 23:59:28 +02:00
end-4 37c3fface4 hefty: bar: fix weird window info popup cutoff; spacing adjustments 2026-03-29 23:52:01 +02:00
end-4 ce52695746 actually fixing popup content spacing this time 2026-03-29 19:22:18 +02:00
end-4 e597928a9e hefty: bar: workspaces: less disgusting workspace number showing logic 2026-03-29 19:21:07 +02:00
end-4 e5def85946 hefty: toplayer: fade out on locking 2026-03-29 19:20:39 +02:00
end-4 f5ae1d360f Merge branch 'main' into hefty-hype 2026-03-29 18:29:59 +02:00
end-4 7f64e5c756 hefty: bar: fix popup content spacing 2026-03-29 18:29:11 +02:00
end-4 013e81f2ac hefty: bar: adjust module spacings 2026-03-29 18:28:52 +02:00
end-4 0b2dfb1910 Merge branch 'main' into hefty-hype 2026-03-27 23:20:08 +01:00
end-4 2eb5885b56 hyprland: add windowrule for chromium screensharing popup positioning 2026-03-26 21:19:53 +01:00
end-4 beac11dc18 Merge branch 'main' into hefty-hype 2026-03-24 17:22:59 +01:00
end-4 698692a500 use tabular numbers for sidebar timers 2026-03-24 17:22:44 +01:00
end-4 ef38057830 fish: update prompt; don't be fancy in tty 2026-03-24 14:46:53 +01:00
end-4 c854d88ee9 reload kitty properly on theme change 2026-03-24 14:45:09 +01:00
end-4 e1b79693e3 hefty: bar: tray: adjust spacing & allow rmb to open unpinneds 2026-03-24 14:44:58 +01:00
end-4 30583abf36 hefty: bar: add system tray 2026-03-22 20:54:44 +01:00
end-4 12d510e9eb globalfocusgrab: try to close dismissed stuff to prevent focusgrab crash 2026-03-22 20:53:50 +01:00
end-4 61a2881ac1 hefty: bar: fix ws indocator hover when in special ws 2026-03-22 17:56:55 +01:00
end-4 96c8a63b21 hefty: fix bar covering whole screen when changing position 2026-03-22 17:56:33 +01:00
end-4 950356e47d anti-flashbang: adjust brightness curve 2026-03-22 10:09:11 +01:00
end-4 8cc6087744 region selector: breathing for region recording 2026-03-22 10:08:48 +01:00
end-4 d52fbe0b40 hefty: bar: fix some alignment issues for floating 2026-03-22 09:58:22 +01:00
end-4 193d82847a Merge branch 'main' into hefty-hype 2026-03-22 08:25:27 +01:00
end-4 725b0ef5cf hefty: bar: windowinfo: fix icon randomly not showing 2026-03-21 12:28:02 +01:00
end-4 b1b96904a9 merge from main 2026-03-21 12:05:22 +01:00
end-4 82ed7498c8 Revert "hefty: bar: fix popup bg getting clipped"
nvm that sloppy calculation made it worse
2026-03-21 11:59:41 +01:00
end-4 1e0ed08909 hefty: bar: fix popup bg getting clipped 2026-03-21 11:59:41 +01:00
end-4 350f48a74b hefty: bar: window info 2026-03-21 11:59:41 +01:00
end-4 36f01b78fe hefty: bar: make left sidebar button circular (when alone) 2026-03-21 11:59:41 +01:00
end-4 3f77086b93 change choreographergridlayout back to gridlayout 2026-03-21 11:59:41 +01:00
end-4 87f61b9331 hefty: bar: adjust battery text spacing 2026-03-21 11:59:41 +01:00
end-4 725c873ab9 hefty: bar: ws: rmb for overview 2026-03-21 11:59:41 +01:00
end-4 f02bcdcce7 hefty: bar: resources: dont keep settings open 2026-03-21 11:57:48 +01:00
end-4 6b7a12fc9f hefty: more subtle focus grab darkening 2026-03-21 11:57:48 +01:00
end-4 6878368d71 music recognition script fix from main 2026-03-21 11:57:48 +01:00
end-4 467f19b40e hefty: bar: resources: make battery bolt icon not weird 2026-03-21 11:57:21 +01:00
end-4 90c3b642b2 hefty: bar: make popups not move while open 2026-03-21 11:57:21 +01:00
end-4 6e433e4a39 hefty: bar: resources indicator: add more stats 2026-03-21 11:57:21 +01:00
end-4 05eb696ead ii: ActiveWindow: remove unused props 2026-03-21 11:56:33 +01:00
end-4 0818a6ad9c wicons: wifi: also check for connected status 2026-03-21 11:56:33 +01:00
end-4 8ca3ef773a network: fix strength prop 2026-03-21 11:55:58 +01:00
end-4 e2aa71b59e hefty: bar: add "left sidebar" button
for now...
i'll probably replace the left sidebar later
2026-03-21 11:55:24 +01:00
end-4 e4ad01c20f hefty: bar: resources popup: show mem & cpu 2026-03-21 11:55:24 +01:00
end-4 522bb5dc0a ii bar resources popup: use formatting func from ResourceUsage 2026-03-21 11:55:24 +01:00
end-4 80752b7812 hefty: bar: add wifi bt sound indicator 2026-03-21 11:55:24 +01:00
end-4 247da26c7b make battery icons adapt to battery percentage 2026-03-21 11:55:24 +01:00
end-4 09d92aff7b hefty: bar: battery: checkmark when full, more natural order for vertical 2026-03-21 11:55:24 +01:00
end-4 3bb9127e32 replace 9999 radius with pill 2026-03-21 11:55:24 +01:00
end-4 a316f91e86 tiny reload popup design tweaks 2026-03-21 11:55:24 +01:00
end-4 b4c8a63d1a move material symbol in Network service to Icon 2026-03-21 11:55:24 +01:00
end-4 68a51b79ff directories: add user ai prompts dir creation 2026-03-21 11:55:24 +01:00
end-4 8d1b9a2ea0 hefty: bar: add power button widget 2026-03-21 11:55:24 +01:00
end-4 ace263cd45 hefty: bar: fix widget backgrounds flash when changing size 2026-03-21 11:55:24 +01:00
end-4 134bf4d986 rename HSystemInfo to HResources 2026-03-21 11:55:24 +01:00
end-4 481e848a65 hefty: bar: fix weird popup shape when smaller than container 2026-03-21 11:55:24 +01:00
end-4 17c2702d2b boxes: add spacing prop 2026-03-21 11:55:24 +01:00
end-4 84d7928518 refactor flexible grids into Box 2026-03-21 11:55:24 +01:00
end-4 a81f52fcd7 hefty: bar: make battery vertical-compatible 2026-03-21 11:55:24 +01:00
end-4 6eda3c674d hefty: use ii overview for now; add global focus scrim 2026-03-21 11:54:47 +01:00
end-4 54f4709d5f hefty: bar: put popups in loaders 2026-03-21 11:54:47 +01:00
end-4 7a46a5c4e5 faster text anim 2026-03-21 11:54:47 +01:00
end-4 25dba608ae hefty: bar: systeminfo: add to default bar config, add ppd btns 2026-03-21 11:54:47 +01:00
end-4 6eb547bb18 make focus rings not go behind 2026-03-21 11:54:47 +01:00
end-4 cd1a0b3d69 set default calendar locale to C instead of bri'ish 2026-03-21 11:54:47 +01:00
end-4 842b09c548 hefty: bar: adjust calendar spacing 2026-03-21 11:54:47 +01:00
end-4 f7998dd7c4 add focus ring to group and ripple buttons 2026-03-21 11:54:47 +01:00
end-4 43177b9cf3 hefty: bar: fix popup displaying wrong value 2026-03-21 11:54:47 +01:00
end-4 ef86c64933 hefty: bar: make day of week row reliable 2026-03-21 11:54:47 +01:00
end-4 bd767f140f hefty: bar: add system info indicator (only battery for now) 2026-03-21 11:54:47 +01:00
end-4 7215d465ea ClippedProgressBar: switch from opacitymask to multieffect 2026-03-21 11:54:47 +01:00
end-4 67a19bedaf battery service: add energy rate known-or-not status 2026-03-21 11:54:47 +01:00
end-4 e3dbaf4242 MaterialSymbol: allow customization of fill anim 2026-03-21 11:54:47 +01:00
end-4 1fe219e215 hefty: bar: fix wrong placement of center-right group 2026-03-21 11:54:47 +01:00
end-4 e012eb646c refactor fixed width text 2026-03-21 11:54:47 +01:00
end-4 485372ee56 hefty: bar: fix ws icons sometimes not showing 2026-03-21 11:54:47 +01:00
end-4 b14e0c494c refactor time duration formatting 2026-03-21 11:54:47 +01:00
end-4 1ad259ff9b change spring anims to expressive default spatial 2026-03-21 11:54:47 +01:00
end-4 2109cf5e09 notifications: dont print on discard 2026-03-21 11:54:47 +01:00
end-4 a33122cd3c hefty: bar: time: calendar 2026-03-21 11:54:47 +01:00
end-4 7a4468258b hefty: bar: make popups work for vertical 2026-03-21 11:54:47 +01:00
end-4 ae0c9f4731 hefty: bar: popup choreography 2026-03-21 11:54:47 +01:00
end-4 521f3cab6d hefty: bar: refactor content hover effect 2026-03-21 11:54:47 +01:00
end-4 455252dff1 hefty: bar: click to close popups 2026-03-21 11:54:47 +01:00
end-4 60ba555de6 refactor bar widget shape background and make it work at the right edge 2026-03-21 11:54:47 +01:00
end-4 485c40406d changes from main 2026-03-21 11:54:47 +01:00
end-4 98a766608d hefty: bar: time: popout 2026-03-21 11:54:47 +01:00
end-4 026a660aa7 hefty: bar: ws: nicer ws icon anim on populate 2026-03-21 11:54:47 +01:00
end-4 9e76e89b94 hefty: bar: ws: proper occupied ws detection for numbers/dots 2026-03-21 11:54:47 +01:00
end-4 da5b8e8912 hefty: bar: cleaner hover anim when in special ws 2026-03-21 11:54:47 +01:00
end-4 bdf91e1d16 hefty: bar: center time 2026-03-21 11:54:47 +01:00
end-4 139e64c28e hefty: bar: ws: consistent icons & bouncy icon dodge anim 2026-03-21 11:54:47 +01:00
end-4 2d94bace7b thicker text weight 2026-03-21 11:54:47 +01:00
end-4 e7368bdc25 hefty: bar: ws: improve hover indicator readability 2026-03-21 11:54:47 +01:00
end-4 09cdad1554 hefty: bar: time widget 2026-03-21 11:54:47 +01:00
end-4 8b84537579 hefty: bar: ws: bouncy special ws 2026-03-21 11:54:47 +01:00
end-4 ea35ca1582 hefty: bar: proper vertical layouting 2026-03-21 11:54:47 +01:00
end-4 8fccfef9f1 hefty: bar: ws: make number map work 2026-03-21 11:54:47 +01:00
end-4 9e6c1d7c08 revert weird launcher entries with terminal apps 2026-03-21 11:54:47 +01:00
end-4 aaff9d5273 hefty: bar: special ws indication 2026-03-21 11:54:47 +01:00
end-4 6f633122ed hefty: bar: workspace widget 2026-03-21 11:54:47 +01:00
end-4 24392e3791 hefty: bar: allow vertical 2026-03-21 11:52:41 +01:00
end-4 0e049db304 bar: component loader 2026-03-21 11:52:41 +01:00
end-4 680d8e85c8 changes from main n stuff 2026-03-21 11:52:41 +01:00
end-4 6ac1861e1e hefty: make overview bg work with bottom position 2026-03-21 11:50:59 +01:00
end-4 7f59246c6d make bar work with bottom position 2026-03-21 11:50:59 +01:00
end-4 f3e26d8f22 hefty: morphing thingy 2026-03-21 11:50:59 +01:00
end-4 0a185efcc5 Revert "hefty: bar: fix popup bg getting clipped"
nvm that sloppy calculation made it worse
2026-03-20 23:49:33 +01:00
end-4 124ea7b245 hefty: bar: fix popup bg getting clipped 2026-03-20 23:42:48 +01:00
end-4 4fcc12444f hefty: bar: window info 2026-03-20 23:38:14 +01:00
end-4 aefc88755a hefty: bar: make left sidebar button circular (when alone) 2026-03-20 23:36:26 +01:00
end-4 216a44274e change choreographergridlayout back to gridlayout 2026-03-20 23:35:51 +01:00
end-4 db7caae4b5 hefty: bar: adjust battery text spacing 2026-03-19 22:58:38 +01:00
end-4 c4f9b20b23 hefty: bar: ws: rmb for overview 2026-03-19 22:56:25 +01:00
end-4 17a99ec068 update quickshell 2026-03-19 16:46:30 +01:00
end-4 1225c014e8 add anti-flashbang using shader 2026-03-19 12:34:32 +01:00
end-4 5ac40d5445 refactor gamemodetoggle's config option fetching 2026-03-19 12:31:30 +01:00
end-4 08b7b393cb changes from main 2026-03-19 12:30:07 +01:00
end-4 0c69a344d5 sessionwarnings: pacman: only check critical operations 2026-03-19 08:47:41 +01:00
end-4 3ca94d1e70 make game mode persistent 2026-03-18 08:23:44 +01:00
end-4 c538505f94 hefty: bar: resources: dont keep settings open 2026-03-15 17:31:28 +01:00
end-4 3cac4206f9 hefty: more subtle focus grab darkening 2026-03-15 17:30:56 +01:00
end-4 b3d15cbae1 music recognition script fix from main 2026-03-15 17:01:07 +01:00
end-4 495e205934 hefty: bar: resources: make battery bolt icon not weird 2026-03-15 17:00:49 +01:00
end-4 ad922ac368 hefty: bar: make popups not move while open 2026-03-15 17:00:25 +01:00
end-4 6393092e63 hefty: bar: resources indicator: add more stats 2026-03-15 13:17:40 +01:00
end-4 e0f2875141 changes from main 2026-03-14 22:04:57 +01:00
end-4 83dcb349da ii: ActiveWindow: remove unused props 2026-03-14 22:02:20 +01:00
end-4 675e14e338 wicons: wifi: also check for connected status 2026-03-14 22:01:59 +01:00
end-4 79fe2651cc ai: extra user models fix from main 2026-03-14 21:57:04 +01:00
end-4 da7bddf1d1 network: fix strength prop 2026-03-14 21:56:40 +01:00
end-4 a66d0f3146 matugen 4.0 fix 2026-03-13 14:31:25 +01:00
end-4 cb5966de0f hefty: bar: add "left sidebar" button
for now...
i'll probably replace the left sidebar later
2026-03-12 13:11:04 +01:00
end-4 d0e51ffe19 add fluent ethernet filled icon 2026-03-12 13:10:05 +01:00
end-4 32e8f90b14 hefty: bar: resources popup: show mem & cpu 2026-03-12 11:23:48 +01:00
end-4 b59c3f5c30 ii bar resources popup: use formatting func from ResourceUsage 2026-03-12 11:22:26 +01:00
end-4 f9bd67699c hefty: bar: add wifi bt sound indicator 2026-03-12 11:21:58 +01:00
end-4 e3eeff8d5d make battery icons adapt to battery percentage 2026-03-11 23:33:45 +01:00
end-4 0b0693b1fd hefty: bar: battery: checkmark when full, more natural order for vertical 2026-03-11 22:11:33 +01:00
end-4 227d822655 replace 9999 radius with pill 2026-03-11 22:10:23 +01:00
end-4 5e16f2bc10 tiny reload popup design tweaks 2026-03-11 22:09:54 +01:00
end-4 be87a1ae79 move material symbol in Network service to Icon 2026-03-11 21:55:56 +01:00
end-4 653dc9c95f directories: add user ai prompts dir creation 2026-03-10 08:22:46 +01:00
end-4 e2805ef1a1 hefty: bar: add power button widget 2026-03-10 08:13:31 +01:00
end-4 6111956c4a hefty: bar: fix widget backgrounds flash when changing size 2026-03-10 08:13:21 +01:00
end-4 ff1dfedc72 rename HSystemInfo to HResources 2026-03-09 23:28:14 +01:00
end-4 4e162bd8a6 hefty: bar: fix weird popup shape when smaller than container 2026-03-09 23:27:52 +01:00
end-4 6bd6f30a5e boxes: add spacing prop 2026-03-09 23:27:11 +01:00
end-4 6952d89a7f refactor flexible grids into Box 2026-03-09 11:03:56 +01:00
end-4 d1dc89b9f2 hefty: bar: make battery vertical-compatible 2026-03-08 21:51:54 +01:00
end-4 1113b6162c fix sidebar detach crash (from main) 2026-03-08 21:50:31 +01:00
end-4 d41cda858c hefty: use ii overview for now; add global focus scrim 2026-03-08 21:02:47 +01:00
end-4 38dbc8769b hefty: bar: put popups in loaders 2026-03-08 21:02:16 +01:00
end-4 7a9b080616 faster text anim 2026-03-08 21:01:21 +01:00
end-4 a174ed1a84 hefty: bar: systeminfo: add to default bar config, add ppd btns 2026-03-08 19:58:37 +01:00
end-4 245aae965f make focus rings not go behind 2026-03-08 19:57:57 +01:00
end-4 3d5c43135a set default calendar locale to C instead of bri'ish 2026-03-08 19:31:35 +01:00
end-4 96b8af05cc hefty: bar: adjust calendar spacing 2026-03-08 19:19:28 +01:00
end-4 422db1ee91 add focus ring to group and ripple buttons 2026-03-08 19:19:10 +01:00
end-4 8e21d8c8e3 hefty: bar: fix popup displaying wrong value 2026-03-08 18:45:35 +01:00
end-4 3b13d0c938 hefty: bar: make day of week row reliable 2026-03-08 18:41:41 +01:00
end-4 f8840e8389 hefty: bar: add system info indicator (only battery for now) 2026-03-08 18:17:44 +01:00
end-4 3a4804653d ClippedProgressBar: switch from opacitymask to multieffect 2026-03-08 18:17:01 +01:00
end-4 dd0b8a5114 battery service: add energy rate known-or-not status 2026-03-08 18:16:31 +01:00
end-4 6b08e16222 MaterialSymbol: allow customization of fill anim 2026-03-08 18:15:50 +01:00
end-4 233a06a4c0 hefty: bar: fix wrong placement of center-right group 2026-03-08 18:15:25 +01:00
end-4 2a714378c9 refactor fixed width text 2026-03-08 18:15:00 +01:00
end-4 e480477db2 hefty: bar: fix ws icons sometimes not showing 2026-03-08 18:14:38 +01:00
end-4 83baff7894 refactor time duration formatting 2026-03-08 18:09:34 +01:00
end-4 3da23ce176 change spring anims to expressive default spatial 2026-03-07 21:49:38 +01:00
end-4 635d49cad0 notifications: dont print on discard 2026-03-07 21:47:12 +01:00
end-4 9ffe4dfb11 hefty: bar: time: calendar 2026-03-07 21:47:00 +01:00
end-4 c155bde816 changes from main 2026-03-05 16:21:30 +01:00
end-4 6cd2d31c99 hefty: bar: make popups work for vertical 2026-03-05 16:20:06 +01:00
end-4 7a74897b47 update quickshell 2026-03-03 10:35:24 +01:00
end-4 28936dd226 hefty: bar: popup choreography 2026-03-02 21:55:18 +01:00
end-4 aa4c18b86a waffles: more readable months when scrolling 2026-03-02 21:54:06 +01:00
end-4 0235e56af3 update hyprland config 2026-02-27 22:50:19 +01:00
end-4 6b29e73ab7 hefty: bar: refactor content hover effect 2026-02-22 00:12:26 +01:00
end-4 2bb001a62b hefty: bar: click to close popups 2026-02-21 23:10:57 +01:00
end-4 15afa07b14 gtk theme changes from main 2026-02-21 21:56:41 +01:00
end-4 bb10002976 refactor bar widget shape background and make it work at the right edge 2026-02-20 22:58:52 +01:00
end-4 368df5b717 changes from main 2026-02-20 22:56:59 +01:00
end-4 6f5ab232a6 hefty: bar: time: popout 2026-02-15 17:40:23 +01:00
end-4 3447198e13 Update shapes 2026-02-15 17:39:48 +01:00
end-4 1c295ddaac accent color preventing wall switch fix from main 2026-02-11 20:42:03 +01:00
end-4 7ba30cee4a hefty: bar: ws: nicer ws icon anim on populate 2026-02-11 20:41:33 +01:00
end-4 6fd2bd51ad hefty: bar: ws: proper occupied ws detection for numbers/dots 2026-02-08 23:54:04 +01:00
end-4 aec849c820 hefty: bar: cleaner hover anim when in special ws 2026-02-08 20:31:14 +01:00
end-4 be4eb16b60 clearer session screen download warning, update check config option 2026-02-08 20:29:49 +01:00
end-4 314b0ab3d0 hefty: bar: center time 2026-02-07 10:00:35 +01:00
end-4 10491f2362 kb focus fix from main 2026-02-07 09:46:31 +01:00
end-4 c2f65e79bc hefty: bar: ws: consistent icons & bouncy icon dodge anim 2026-02-07 09:46:21 +01:00
end-4 6bb0c251a9 thicker text weight 2026-02-07 09:45:54 +01:00
end-4 e1913d0e95 hefty: bar: ws: improve hover indicator readability 2026-02-06 23:52:31 +01:00
end-4 74c012c930 hefty: bar: time widget 2026-02-06 23:38:05 +01:00
end-4 74368ad25a hefty: bar: ws: bouncy special ws 2026-02-06 22:38:58 +01:00
end-4 4718922c55 hefty: bar: proper vertical layouting 2026-02-06 22:38:45 +01:00
end-4 d8eb55fea9 fish: more typo aliases 2026-02-06 21:49:53 +01:00
end-4 5f9fe2d250 hefty: bar: ws: make number map work 2026-02-06 21:38:00 +01:00
end-4 4a44994168 revert weird launcher entries with terminal apps 2026-02-06 21:37:27 +01:00
end-4 879111fe01 ai: remove openrouter deepseek 2026-02-06 21:10:36 +01:00
end-4 ed8c8ae8d7 hefty: bar: special ws indication 2026-02-06 20:49:03 +01:00
end-4 ead98b98b8 hefty: bar: workspace widget 2026-02-05 12:49:36 +01:00
end-4 5bb1aa06af hefty: bar: allow vertical 2026-02-03 22:43:09 +01:00
end-4 58184f5be8 bar: component loader 2026-02-03 18:17:02 +01:00
end-4 28e580c2b1 changes from main n stuff 2026-02-03 14:47:08 +01:00
end-4 819fa81fc6 make lock push hack work for multimonitor 2026-01-10 10:42:53 +01:00
end-4 fb13cc1a21 hefty: make overview bg work with bottom position 2026-01-05 23:23:10 +01:00
end-4 d1988bef02 make bar work with bottom position 2026-01-05 20:27:39 +01:00
end-4 7872fba6fe hefty: morphing thingy 2026-01-04 22:08:53 +01:00
196 changed files with 6602 additions and 2281 deletions
+5 -1
View File
@@ -17,6 +17,10 @@
<h3></h3>
</div>
> [!WARNING]
> Hyprland 0.55 update:
> If your distro has not shipped Hyprland 0.55 and/or you're not ready for it, you should switch to the Pre-Hyprland Luaification release (or not update yet, if you're going to do that). See the wiki for more info: [Install](https://ii.clsty.link/en/ii-qs/01setup/#automated-installation) | [Update](https://ii.clsty.link/en/ii-qs/01setup/#updating)
<details>
<summary>What this is/isn't</summary>
@@ -39,7 +43,7 @@
<details>
<summary>Installation</summary>
- _If you're new to Linux and decide to use Hyprland, you're in for a tough ride._
- **IMPORTANT: Hyprland 0.55 Update**: If your distro has not shipped Hyprland 0.55 and/or you're not ready for it, you should switch to the Pre-Hyprland Luaification release. See [the wiki](https://ii.clsty.link/en/ii-qs/01setup/) for more info
- Just run `bash <(curl -s https://ii.clsty.link/get)`
- Or, clone this repo and run `./setup install`
- See [the wiki](https://ii.clsty.link/en/ii-qs/01setup/) for more details
-23
View File
@@ -1,23 +0,0 @@
# hyprlang noerror false
# You can put extra environment variables here
# https://wiki.hyprland.org/Configuring/Environment-variables/
# ######### Input method ##########
# See https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland
#env = QT_IM_MODULE, fcitx
#env = XMODIFIERS, @im=fcitx
#env = SDL_IM_MODULE, fcitx
#env = GLFW_IM_MODULE, ibus
#env = INPUT_METHOD, fcitx
# ######## Wayland #########
# Tearing
# env = WLR_DRM_NO_ATOMIC, 1
# ?
# env = WLR_NO_HARDWARE_CURSORS, 1
# ######## EDITOR #########
#https://wiki.archlinux.org/title/Category:Text_editors
# for example: vi nano nvim ...
#env = EDITOR, vim
+1
View File
@@ -0,0 +1 @@
-7
View File
@@ -1,7 +0,0 @@
# hyprlang noerror false
# You can make apps auto-start here
# Relevant Hyprland wiki section: https://wiki.hyprland.org/Configuring/Keywords/#executing
# Input method
# exec-once = fcitx5
+1
View File
@@ -0,0 +1 @@
-7
View File
@@ -1,7 +0,0 @@
# hyprlang noerror false
# Put general config stuff here
# Here's a list of every variable: https://wiki.hyprland.org/Configuring/Variables/
# monitor=,addreserved, 0, 0, 0, 0 # Custom reserved area
# HDMI port: mirror display. To see device name, use `hyprctl monitors`
+1
View File
@@ -0,0 +1 @@
-25
View File
@@ -1,25 +0,0 @@
# hyprlang noerror false
# See https://wiki.hyprland.org/Configuring/Binds/
#!
##! User
bind = Ctrl+Super, Slash, exec, xdg-open ~/.config/illogical-impulse/config.json # Edit shell config
bind = Ctrl+Super+Alt, Slash, exec, xdg-open ~/.config/hypr/custom/keybinds.conf # Edit extra keybinds
##! Apps
# bind = Super, Return, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "${TERMINAL}" "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # Terminal
# bind = Super, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "${TERMINAL}" "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] (terminal) (alt)
# bind = Ctrl+Alt, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "${TERMINAL}" "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] (terminal) (for Ubuntu people)
# bind = Super, E, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "${TERMINAL}" "kitty -1 fish -c yazi" # File manager
# bind = Super, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "google-chrome-stable" "zen-browser" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" "librewolf" # Browser
# bind = Super, C, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "code" "codium" "cursor" "zed" "zedit" "zeditor" "kate" "gnome-text-editor" "emacs" "command -v nvim && kitty -1 nvim" "command -v micro && kitty -1 micro" # Code editor
# bind = Ctrl+Super+Shift+Alt, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "wps" "onlyoffice-desktopeditors" "libreoffice" # Office software
# bind = Super, X, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kate" "gnome-text-editor" "emacs" # Text editor
# bind = Ctrl+Super, V, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "pavucontrol-qt" "pavucontrol" # Volume mixer
# bind = Super, I, exec, XDG_CURRENT_DESKTOP=gnome ~/.config/hypr/hyprland/scripts/launch_first_available.sh "qs -p ~/.config/quickshell/$qsConfig/settings.qml" "systemsettings" "gnome-control-center" "better-control" # Settings app
# bind = Ctrl+Shift, Escape, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "gnome-system-monitor" "plasma-systemmonitor --page-name Processes" "command -v btop && kitty -1 fish -c btop" # Task manager
# Add stuff here
# Use #! to add an extra column on the cheatsheet
# Use ##! to add a section in that column
# Add a comment after a bind to add a description, like above
+1
View File
@@ -0,0 +1 @@
hl.bind("CTRL+SUPER+ALT+Slash", hl.dsp.exec_cmd("xdg-open ~/.config/hypr/custom/keybinds.lua"), {description = "Edit user keybinds"} )
-12
View File
@@ -1,12 +0,0 @@
# hyprlang noerror false
# You can put custom rules here
# Window/layer rules: https://wiki.hyprland.org/Configuring/Window-Rules/
# Workspace rules: https://wiki.hyprland.org/Configuring/Workspace-Rules/
# ######## Window rules ########
# Uncomment to apply global transparency to all windows:
# windowrule = opacity 0.89 override 0.89 override, match:class .*
# Disable blur for all xwayland apps
# windowrule = no_blur on, match:xwayland 1
+1
View File
@@ -0,0 +1 @@
-2
View File
@@ -1,2 +0,0 @@
# hyprlang noerror false
# For all available variables, see ~/.config/hypr/hyprland/variables.conf
+1
View File
@@ -0,0 +1 @@
+4 -4
View File
@@ -1,11 +1,11 @@
$lock_cmd = hyprctl dispatch global quickshell:lock & pidof qs quickshell hyprlock || hyprlock
$lock_cmd = hyprctl dispatch 'hl.dsp.global("quickshell:lock")' & pidof qs quickshell hyprlock || hyprlock
# $lock_cmd = pidof hyprlock || hyprlock
$suspend_cmd = systemctl suspend || loginctl suspend
general {
lock_cmd = $lock_cmd
before_sleep_cmd = loginctl lock-session
after_sleep_cmd = hyprctl dispatch global quickshell:lockFocus
after_sleep_cmd = hyprctl dispatch 'hl.dsp.global("quickshell:lockFocus")'
inhibit_sleep = 3
}
@@ -16,8 +16,8 @@ listener {
listener {
timeout = 600 # 10mins
on-timeout = hyprctl dispatch dpms off
on-resume = hyprctl dispatch dpms on
on-timeout = hyprctl dispatch 'hl.dsp.dpms(false)'
on-resume = hyprctl dispatch 'hl.dsp.dpms(true)'
}
listener {
-49
View File
@@ -1,49 +0,0 @@
# This file sources other files in `hyprland` and `custom` folders
# You wanna add your stuff in files in `custom`
# --- Environment variables ---
source=hyprland/env.conf
# hyprlang noerror true
source=custom/env.conf
# hyprlang noerror false
# --- Other vars ---
source=hyprland/variables.conf
# hyprlang noerror true
source=custom/variables.conf
# hyprlang noerror false
# --- Defaults ---
# hyprlang if !dontLoadDefaultExecs
source=hyprland/execs.conf
# hyprlang endif
# hyprlang if !dontLoadDefaultGeneral
source=hyprland/general.conf
# hyprlang endif
# hyprlang if !dontLoadDefaultRules
source=hyprland/rules.conf
# hyprlang endif
# hyprlang if !dontLoadDefaultColors
source=hyprland/colors.conf
# hyprlang endif
# hyprlang if !dontLoadDefaultKeybinds
source=hyprland/keybinds.conf
# hyprlang endif
# --- Custom ---
# hyprlang noerror true
source=custom/execs.conf
# hyprlang noerror true
source=custom/general.conf
# hyprlang noerror true
source=custom/rules.conf
# hyprlang noerror true
source=custom/keybinds.conf
# hyprlang noerror false
# --- nwg-displays support ---
source=workspaces.conf
source=monitors.conf
# --- Shell overrides ---
source=hyprland/shellOverrides/main.conf
+44
View File
@@ -0,0 +1,44 @@
-- This file sources other files in `hyprland` and `custom` folders
-- You wanna add your stuff in files in `custom`
-- Internal stuff --
require("hyprland.lib")
require("hyprland.services")
-- Environment variables --
require("hyprland.env")
if is_file_exists(HOME .. "/.config/hypr/custom/env.lua") then
require("custom.env")
end
-- Default configurations --
require("hyprland.execs")
require("hyprland.general")
require("hyprland.rules")
require("hyprland.colors")
require("hyprland.keybinds")
-- Custom configurations --
if is_file_exists(HOME .. "/.config/hypr/custom/execs.lua") then
require("custom.execs")
end
if is_file_exists(HOME .. "/.config/hypr/custom/general.lua") then
require("custom.general")
end
if is_file_exists(HOME .. "/.config/hypr/custom/rules.lua") then
require("custom.rules")
end
if is_file_exists(HOME .. "/.config/hypr/custom/keybinds.lua") then
require("custom.keybinds")
end
-- nwg-displays support --
if is_file_exists(HOME .. "/.config/hypr/workspaces.lua") then
require("workspaces")
end
if is_file_exists(HOME .. "/.config/hypr/monitors.lua") then
require("monitors")
end
-- Shell overrides --
require("hyprland.shellOverrides.main")
-34
View File
@@ -1,34 +0,0 @@
# exec = export SLURP_ARGS='-d -c FFDAD4BB -b 673B3444 -s 00000000'
general {
col.active_border = rgba(F7DCDE39)
col.inactive_border = rgba(A58A8D30)
}
misc {
background_color = rgba(1D1011FF)
}
plugin {
hyprbars {
# Honestly idk if it works like css, but well, why not
bar_text_font = Google Sans Flex Medium, Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif
bar_height = 30
bar_padding = 10
bar_button_padding = 5
bar_precedence_over_border = true
bar_part_of_window = true
bar_color = rgba(1D1011FF)
col.text = rgba(F7DCDEFF)
# example buttons (R -> L)
# hyprbars-button = color, size, on-click
hyprbars-button = rgb(F7DCDE), 13, 󰖭, hyprctl dispatch killactive
hyprbars-button = rgb(F7DCDE), 13, 󰖯, hyprctl dispatch fullscreen 1
hyprbars-button = rgb(F7DCDE), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special
}
}
windowrule = border_color rgba(FFB2BCAA) rgba(FFB2BC77), match:pin 1
+16
View File
@@ -0,0 +1,16 @@
hl.config({
general = {
col = {
active_border = "rgba(44464f77)",
inactive_border = "rgba(1a1b2033)",
},
},
misc = {
background_color = "rgba(121318FF)",
},
})
hl.window_rule({ -- not sure how to syntax "pin 1"
match = { pin = 1 },
border_color = "rgba(afc6ffAA) rgba(afc6ff77)",
})
-13
View File
@@ -1,13 +0,0 @@
# ############ Wayland #############
env = ELECTRON_OZONE_PLATFORM_HINT,auto
######### Applications #########
env = XDG_DATA_DIRS,$HOME/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
# ############ Themes #############
env = QT_QPA_PLATFORM, wayland;xcb
env = QT_QPA_PLATFORMTHEME, kde
env = XDG_MENU_PREFIX, plasma-
# ######## Virtual envrionment #########
env = ILLOGICAL_IMPULSE_VIRTUAL_ENV, ~/.local/state/quickshell/.venv
+16
View File
@@ -0,0 +1,16 @@
local home_dir = os.getenv("HOME")
-- Wayland
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "auto")
-- Applications
local xdg_data_dirs_old = os.getenv("XDG_DATA_DIRS") or ""
hl.env("XDG_DATA_DIRS", home_dir .. "/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share:" .. xdg_data_dirs_old)
-- Themes
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
hl.env("QT_QPA_PLATFORMTHEME", "kde")
hl.env("XDG_MENU_PREFIX", "plasma-")
-- Virtual environment
hl.env("ILLOGICAL_IMPULSE_VIRTUAL_ENV", home_dir .. "/.local/state/quickshell/.venv")
-25
View File
@@ -1,25 +0,0 @@
# Bar, wallpaper
exec-once = ~/.config/hypr/hyprland/scripts/start_geoclue_agent.sh
exec-once = qs -c $qsConfig &
exec-once = ~/.config/hypr/custom/scripts/__restore_video_wallpaper.sh
# Core components (authentication, lock screen, notification daemon)
exec-once = gnome-keyring-daemon --start --components=secrets
exec-once = hypridle
exec-once = dbus-update-activation-environment --all
exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # Some fix idk
# Audio
exec-once = easyeffects --hide-window --service-mode
# Clipboard: history
# exec-once = wl-paste --watch cliphist store &
exec-once = wl-paste --type text --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'
exec-once = wl-paste --type image --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'
# Cursor
exec-once = hyprctl setcursor Bibata-Modern-Classic 24
# Fix dock pinned apps not launching properly (https://github.com/end-4/dots-hyprland/issues/2200)
# This causes https://github.com/end-4/dots-hyprland/issues/2427
# exec-once = sleep 3.5 && hyprctl reload && sleep 0.5 && touch ~/.config/quickshell/ii/shell.qml
+25
View File
@@ -0,0 +1,25 @@
-- put former exec-once commands inside the func and former exec commands outside
hl.on("hyprland.start", function ()
-- Bar, wallpaper
hl.exec_cmd("$HOME/.config/hypr/hyprland/scripts/start_geoclue_agent.sh")
hl.exec_cmd("qs -c $qsConfig")
hl.exec_cmd("$HOME/.config/hypr/custom/scripts/__restore_video_wallpaper.sh")
-- Core components (authentication, lock screen, notification daemon)
hl.exec_cmd("gnome-keyring-daemon --start --components=secrets")
hl.exec_cmd("hypridle")
hl.exec_cmd("dbus-update-activation-environment --all")
hl.exec_cmd("sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP") -- Some fix idk
-- Audio
hl.exec_cmd("easyeffects --hide-window --service-mode")
-- Clipboard: history
--hl.exec_cmd("wl-paste --watch cliphist store")
hl.exec_cmd("wl-paste --type text --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'")
hl.exec_cmd("wl-paste --type image --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'")
-- Cursor
hl.exec_cmd("hyprctl setcursor Bibata-Modern-Classic 24")
end)
-171
View File
@@ -1,171 +0,0 @@
# MONITOR CONFIG
monitor=,preferred,auto,1
gesture = 3, swipe, move,
gesture = 3, pinch, float
gesture = 4, horizontal, workspace
gesture = 4, up, dispatcher, global, quickshell:overviewWorkspacesToggle
gesture = 4, down, dispatcher, global, quickshell:overviewWorkspacesClose
gestures {
workspace_swipe_distance = 700
workspace_swipe_cancel_ratio = 0.2
workspace_swipe_min_speed_to_force = 5
workspace_swipe_direction_lock = true
workspace_swipe_direction_lock_threshold = 10
workspace_swipe_create_new = true
}
general {
# Gaps and border
gaps_in = 4
gaps_out = 5
gaps_workspaces = 50
border_size = 1
col.active_border = rgba(0DB7D455)
col.inactive_border = rgba(31313600)
resize_on_border = true
no_focus_fallback = true
allow_tearing = true # This just allows the `immediate` window rule to work
snap {
enabled = true
window_gap = 4
monitor_gap = 5
respect_gaps = true
}
}
dwindle {
preserve_split = true
smart_split = false
smart_resizing = false
# precise_mouse_move = true
}
decoration {
# 2 = circle, higher = squircle, 4 = very obvious squircle
# Clear squircles look really off; we use only extra .4 here to make the rounding feel more continuous
rounding_power = 2
rounding = 18
blur {
enabled = true
xray = true
special = false
new_optimizations = true
size = 10
passes = 3
brightness = 1
noise = 0.05
contrast = 0.89
vibrancy = 0.5
vibrancy_darkness = 0.5
popups = false
popups_ignorealpha = 0.6
input_methods = true
input_methods_ignorealpha = 0.8
}
shadow {
enabled = true
ignore_window = true
range = 20
offset = 0 2
render_power = 10
color = rgba(00000020)
}
# Dim
dim_inactive = true
dim_strength = 0.05
dim_special = 0.2
}
animations {
enabled = true
# Curves
bezier = expressiveFastSpatial, 0.42, 1.67, 0.21, 0.90
bezier = expressiveSlowSpatial, 0.39, 1.29, 0.35, 0.98
bezier = expressiveDefaultSpatial, 0.38, 1.21, 0.22, 1.00
bezier = emphasizedDecel, 0.05, 0.7, 0.1, 1
bezier = emphasizedAccel, 0.3, 0, 0.8, 0.15
bezier = standardDecel, 0, 0, 0, 1
bezier = menu_decel, 0.1, 1, 0, 1
bezier = menu_accel, 0.52, 0.03, 0.72, 0.08
bezier = stall, 1, -0.1, 0.7, 0.85
# Configs
# windows
animation = windowsIn, 1, 3, emphasizedDecel, popin 80%
animation = fadeIn, 1, 3, emphasizedDecel
animation = windowsOut, 1, 2, emphasizedDecel, popin 90%
animation = fadeOut, 1, 2, emphasizedDecel
animation = windowsMove, 1, 3, emphasizedDecel, slide
animation = border, 1, 10, emphasizedDecel
# layers
animation = layersIn, 1, 2.7, emphasizedDecel, popin 93%
animation = layersOut, 1, 2.4, menu_accel, popin 94%
# fade
animation = fadeLayersIn, 1, 0.5, menu_decel
animation = fadeLayersOut, 1, 2.7, stall
# workspaces
animation = workspaces, 1, 7, menu_decel, slide
## specialWorkspace
animation = specialWorkspaceIn, 1, 2.8, emphasizedDecel, slidevert
animation = specialWorkspaceOut, 1, 1.2, emphasizedAccel, slidevert
# zoom
animation = zoomFactor, 1, 3, standardDecel
}
input {
kb_layout = us
numlock_by_default = true
repeat_delay = 250
repeat_rate = 35
follow_mouse = 1
off_window_axis_events = 2
touchpad {
natural_scroll = yes
disable_while_typing = true
clickfinger_behavior = true
scroll_factor = 0.7
}
}
misc {
disable_hyprland_logo = true
disable_splash_rendering = true
vfr = 1
vrr = 0
mouse_move_enables_dpms = true
key_press_enables_dpms = true
animate_manual_resizes = false
animate_mouse_windowdragging = false
enable_swallow = false
swallow_regex = (foot|kitty|allacritty|Alacritty)
on_focus_under_fullscreen = 2
allow_session_lock_restore = true
session_lock_xray = true
initial_workspace_tracking = false
focus_on_activate = true
}
binds {
scroll_event_delay = 0
hide_special_on_workspace_change = true
}
cursor {
zoom_factor = 1
zoom_rigid = false
zoom_disable_aa = true
hotspot_padding = 1
}
xwayland {
force_zero_scaling = true
}
+305
View File
@@ -0,0 +1,305 @@
-- MONITOR CONFIG
hl.monitor({
output = "",
mode = "preferred",
position = "auto",
scale = 1
})
hl.gesture({
fingers = 3,
direction = "swipe",
action = "move"
})
hl.gesture({
fingers = 3,
direction = "pinch",
action = "fullscreen"
})
hl.gesture({
fingers = 4,
direction = "horizontal",
action = "workspace"
})
hl.gesture({
fingers = 4,
direction = "up",
action = function()
hl.dispatch(hl.dsp.global("quickshell:overviewWorkspacesToggle"))
end
})
hl.gesture({
fingers = 4,
direction = "down",
action = function()
hl.dispatch(hl.dsp.global("quickshell:overviewWorkspacesToggle"))
end
})
hl.config({
gestures = {
workspace_swipe_distance = 700,
workspace_swipe_cancel_ratio = 0.2,
workspace_swipe_min_speed_to_force = 5,
workspace_swipe_direction_lock = true,
workspace_swipe_direction_lock_threshold = 10,
workspace_swipe_create_new = true
},
general = {
-- Gaps and border
gaps_in = 4,
gaps_out = 5,
gaps_workspaces = 50,
border_size = 1,
col = {
active_border = "rgba(0DB7D455)",
inactive_border = "rgba(31313600)"
},
resize_on_border = true,
no_focus_fallback = true,
allow_tearing = true, -- This just allows the `immediate` window rule to work
snap = {
enabled = true,
window_gap = 4,
monitor_gap = 5,
respect_gaps = true
}
},
decoration = {
-- 2 = circle, higher = squircle, 4 = very obvious squircle
-- Fuck clearly visible squircles. 100% Apple brainrot.
rounding_power = 2.5,
rounding = 18,
blur = {
enabled = true,
xray = true,
special = false,
new_optimizations = true,
size = 10,
passes = 3,
brightness = 1,
noise = 0.05,
contrast = 0.89,
vibrancy = 0.5,
vibrancy_darkness = 0.5,
popups = false,
popups_ignorealpha = 0.6,
input_methods = true,
input_methods_ignorealpha = 0.8
},
shadow = {
enabled = true,
range = 20,
offset = {0, 2},
render_power = 10,
color = "rgba(00000020)"
},
-- Dim
dim_inactive = true,
dim_strength = 0.05,
dim_special = 0.2
},
animations = {
enabled = true
},
dwindle = {
preserve_split = true,
smart_split = false,
smart_resizing = false
-- precise_mouse_move = true,
},
})
-- Curves
hl.curve("expressiveFastSpatial", {
type = "bezier",
points = {{0.42, 1.67}, {0.21, 0.90}}
})
hl.curve("expressiveSlowSpatial", {
type = "bezier",
points = {{0.39, 1.29}, {0.35, 0.98}}
})
hl.curve("expressiveDefaultSpatial", {
type = "bezier",
points = {{0.38, 1.21}, {0.22, 1.00}}
})
hl.curve("emphasizedDecel", {
type = "bezier",
points = {{0.05, 0.7}, {0.1, 1}}
})
hl.curve("emphasizedAccel", {
type = "bezier",
points = {{0.3, 0}, {0.8, 0.15}}
})
hl.curve("standardDecel", {
type = "bezier",
points = {{0, 0}, {0, 1}}
})
hl.curve("menu_decel", {
type = "bezier",
points = {{0.1, 1}, {0, 1}}
})
hl.curve("menu_accel", {
type = "bezier",
points = {{0.52, 0.03}, {0.72, 0.08}}
})
hl.curve("stall", {
type = "bezier",
points = {{1, -0.1}, {0.7, 0.85}}
})
-- Configs
-- windows
hl.animation({
leaf = "windowsIn",
enabled = true,
speed = 3,
bezier = "emphasizedDecel",
style = "popin 80%"
})
hl.animation({
leaf = "fadeIn",
enabled = true,
speed = 3,
bezier = "emphasizedDecel"
})
hl.animation({
leaf = "windowsOut",
enabled = true,
speed = 2,
bezier = "emphasizedDecel",
style = "popin 90%"
})
hl.animation({
leaf = "fadeOut",
enabled = true,
speed = 2,
bezier = "emphasizedDecel"
})
hl.animation({
leaf = "windowsMove",
enabled = true,
speed = 3,
bezier = "emphasizedDecel",
style = "slide"
})
hl.animation({
leaf = "border",
enabled = true,
speed = 10,
bezier = "emphasizedDecel"
})
-- layers
hl.animation({
leaf = "layersIn",
enabled = true,
speed = 2.7,
bezier = "emphasizedDecel",
style = "popin 93%"
})
hl.animation({
leaf = "layersOut",
enabled = true,
speed = 2.4,
bezier = "menu_accel",
style = "popin 94%"
})
-- fade
hl.animation({
leaf = "fadeLayersIn",
enabled = true,
speed = 0.5,
bezier = "menu_decel"
})
hl.animation({
leaf = "fadeLayersOut",
enabled = true,
speed = 2.7,
bezier = "stall"
})
-- workspaces
hl.animation({
leaf = "workspaces",
enabled = true,
speed = 7,
bezier = "menu_decel",
style = "slide"
})
-- specialWorkspace
hl.animation({
leaf = "specialWorkspaceIn",
enabled = true,
speed = 2.8,
bezier = "emphasizedDecel",
style = "slidevert"
})
hl.animation({
leaf = "specialWorkspaceOut",
enabled = true,
speed = 1.2,
bezier = "emphasizedAccel",
style = "slidevert"
})
-- zoom
hl.animation({
leaf = "zoomFactor",
enabled = true,
speed = 3,
bezier = "standardDecel"
})
hl.config({
input = {
kb_layout = "us",
numlock_by_default = true,
repeat_delay = 250,
repeat_rate = 35,
follow_mouse = 1,
off_window_axis_events = 2,
touchpad = {
natural_scroll = true,
disable_while_typing = true,
clickfinger_behavior = true,
scroll_factor = 0.7
}
},
misc = {
disable_hyprland_logo = true,
disable_splash_rendering = true,
vrr = 0,
mouse_move_enables_dpms = true,
key_press_enables_dpms = true,
animate_manual_resizes = false,
animate_mouse_windowdragging = false,
enable_swallow = false,
swallow_regex = "(foot|kitty|allacritty|Alacritty)",
on_focus_under_fullscreen = 2,
allow_session_lock_restore = true,
session_lock_xray = true,
initial_workspace_tracking = false,
focus_on_activate = true
},
binds = {
scroll_event_delay = 0,
hide_special_on_workspace_change = true
},
cursor = {
zoom_factor = 1,
zoom_rigid = false,
zoom_disable_aa = true,
hotspot_padding = 1
},
xwayland = {
force_zero_scaling = true
}
})
-272
View File
@@ -1,272 +0,0 @@
# Lines ending with `# [hidden]` won't be shown on cheatsheet
# Lines starting with #! are section headings
# DO NOT REMOVE THIS EXEC OR YOU WON'T BE ABLE TO USE ANY KEYBIND
exec = hyprctl dispatch submap global
# This is required for catchall to work
submap = global
#!
##! Shell
# These absolutely need to be on top, or they won't work consistently
bindid = Super, Super_L, Toggle search, global, quickshell:searchToggleRelease # Toggle search
bindid = Super, Super_R, Toggle search, global, quickshell:searchToggleRelease # [hidden] Toggle search
bind = Super, Super_L, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill fuzzel || fuzzel # [hidden] Launcher (fallback)
bind = Super, Super_R, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill fuzzel || fuzzel # [hidden] Launcher (fallback)
binditn = Super, catchall, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Ctrl, Super_L, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Ctrl, Super_R, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:272, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:273, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:274, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:275, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:276, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse:277, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse_up, global, quickshell:searchToggleReleaseInterrupt # [hidden]
bind = Super, mouse_down,global, quickshell:searchToggleReleaseInterrupt # [hidden]
bindit = ,Super_L, global, quickshell:workspaceNumber # [hidden]
bindit = ,Super_R, global, quickshell:workspaceNumber # [hidden]
bind = Super, Tab, global, quickshell:overviewWorkspacesToggle # Toggle overview
bindd = Super, V, Clipboard history >> clipboard, global, quickshell:overviewClipboardToggle # Clipboard history >> clipboard
bindd = Super, Period, Emoji >> clipboard, global, quickshell:overviewEmojiToggle # Emoji >> clipboard
bind = Super, A, global, quickshell:sidebarLeftToggle # Toggle left sidebar
bind = Super+Alt, A, global, quickshell:sidebarLeftToggleDetach # [hidden]
bind = Super, B, global, quickshell:sidebarLeftToggle # [hidden]
bind = Super, O, global, quickshell:sidebarLeftToggle # [hidden]
bindd = Super, N, Toggle right sidebar, global, quickshell:sidebarRightToggle # Toggle right sidebar
bindd = Super, Slash, Toggle cheatsheet, global, quickshell:cheatsheetToggle # Toggle cheatsheet
bindd = Super, K, Toggle on-screen keyboard, global, quickshell:oskToggle # Toggle on-screen keyboard
bindd = Super, M, Toggle media controls, global, quickshell:mediaControlsToggle # Toggle media controls
bind = Super, G, global, quickshell:overlayToggle # Toggle overlay
bindd = Ctrl+Alt, Delete, Toggle session menu, global, quickshell:sessionToggle # Toggle session menu
bindd = Super, J, Toggle bar, global, quickshell:barToggle # Toggle bar
bind = Ctrl+Alt, Delete, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill wlogout || wlogout -p layer-shell # [hidden] Session menu (fallback)
bind = Shift+Super+Alt, Slash, exec, qs -p ~/.config/quickshell/$qsConfig/welcome.qml # [hidden] Launch welcome app
bindle=, XF86MonBrightnessUp, exec, qs -c $qsConfig ipc call brightness increment || brightnessctl s 5%+ # [hidden]
bindle=, XF86MonBrightnessDown, exec, qs -c $qsConfig ipc call brightness decrement || brightnessctl s 5%- # [hidden]
bindle=, XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%+ -l 1.5# [hidden]
bindle=, XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%- # [hidden]
bindl = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SINK@ toggle # [hidden]
bindld = Super+Shift,M, Toggle mute, exec, wpctl set-mute @DEFAULT_SINK@ toggle # [hidden]
bindl = Alt ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
bindl = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
bindld = Super+Alt,M, Toggle mic, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
bindd = Ctrl+Super, T, Toggle wallpaper selector, global, quickshell:wallpaperSelectorToggle # Wallpaper selector
bindd = Ctrl+Super+Alt, T, Select random wallpaper, global, quickshell:wallpaperSelectorRandom # Random wallpaper
bindd = Ctrl+Super, T, Change wallpaper, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/quickshell/$qsConfig/scripts/colors/switchwall.sh # [hidden] Change wallpaper (fallback)
bind = Ctrl+Super, R, exec, killall ydotool qs quickshell; qs -c $qsConfig & # Restart widgets
bind = Ctrl+Super, P, global, quickshell:panelFamilyCycle # Cycle panel family
##! Utilities
# Screenshot, Record, OCR, Color picker, Clipboard history
bindd = Super, V, Copy clipboard history entry, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy # [hidden] Clipboard history >> clipboard (fallback)
bindd = Super, Period, Copy an emoji, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill fuzzel || ~/.config/hypr/hyprland/scripts/fuzzel-emoji.sh copy # [hidden] Emoji >> clipboard (fallback)
bind = Super+Shift, S, global, quickshell:regionScreenshot # Screen snip
bind = Super+Shift, S, exec, qs -c $qsConfig ipc call TEST_ALIVE || pidof slurp || hyprshot --freeze --clipboard-only --mode region --silent # [hidden] Screen snip (fallback)
bind = Super+Shift, A, global, quickshell:regionSearch # Google Lens
bind = Super+Shift, A, exec, qs -c $qsConfig ipc call TEST_ALIVE || pidof slurp || ~/.config/hypr/hyprland/scripts/snip_to_search.sh # [hidden] Google Lens (fallback)
# OCR
bind = Super+Shift, X, global, quickshell:regionOcr # Character recognition >> clipboard
bind = Super+Shift, T, global, quickshell:screenTranslate # Translate screen content
bind = Super+Shift, X,exec, qs -c $qsConfig ipc call TEST_ALIVE || pidof slurp || grim -g "$(slurp $SLURP_ARGS)" "/tmp/ocr_image.png" && tesseract "/tmp/ocr_image.png" stdout -l $(tesseract --list-langs | awk 'NR>1{print $1}' | tr '\\n' '+' | sed 's/\\+$/\\n/') | wl-copy && rm "/tmp/ocr_image.png" # [hidden]
# Color picker
bindd = Super+Shift, C, Color picker, exec, hyprpicker -a # Pick color (Hex) >> clipboard
# Recording stuff
bindl = Super+Shift, R, global, quickshell:regionRecord # Record region (no sound)
bindl = Super+Shift, R, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/quickshell/$qsConfig/scripts/videos/record.sh # [hidden] Record region (no sound) (fallback)
bindl = Super+Alt, R, global, quickshell:regionRecord # [hidden] Record region (no sound)
bindl = Super+Alt, R, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/quickshell/$qsConfig/scripts/videos/record.sh # [hidden] Record region (no sound) (fallback)
bindl = Ctrl+Alt, R, exec, ~/.config/quickshell/$qsConfig/scripts/videos/record.sh --fullscreen # [hidden] Record screen (no sound)
bindl = Super+Shift+Alt, R, exec, ~/.config/quickshell/$qsConfig/scripts/videos/record.sh --fullscreen --sound # Record screen (with sound)
# Fullscreen screenshot
bindl = ,Print,exec,grim -o "$(hyprctl activeworkspace -j | jq -r '.monitor')" - | wl-copy # Screenshot >> clipboard
bindln = Ctrl,Print, exec, mkdir -p $(xdg-user-dir PICTURES)/Screenshots && grim -o "$(hyprctl activeworkspace -j | jq -r '.monitor')" $(xdg-user-dir PICTURES)/Screenshots/Screenshot_"$(date '+%Y-%m-%d_%H.%M.%S')".png # Screenshot >> clipboard & file
bindln = Ctrl,Print,exec,grim -o "$(hyprctl activeworkspace -j | jq -r '.monitor')" - | wl-copy # [hidden] Screenshot >> clipboard & file (clipboard)
# AI
bindd = Super+Shift+Alt, mouse:273, Generate AI summary for selected text, exec, ~/.config/hypr/hyprland/scripts/ai/primary-buffer-query.sh # [hidden] AI summary for selected text (requires a running ollama model)
#!
##! Window
# Focusing
bindm = Super, mouse:272, movewindow # Move
bindm = Super, mouse:274, movewindow # [hidden]
bindm = Super, mouse:273, resizewindow # Resize
#/# bind = Super, ←/↑/→/↓,, # Focus in direction
bind = Super, Left, movefocus, l # [hidden]
bind = Super, Right, movefocus, r # [hidden]
bind = Super, Up, movefocus, u # [hidden]
bind = Super, Down, movefocus, d # [hidden]
bind = Super, BracketLeft, movefocus, l # [hidden]
bind = Super, BracketRight, movefocus, r # [hidden]
#/# bind = Super+Shift, ←/↑/→/↓,, # Move in direction
bind = Super+Shift, Left, movewindow, l # [hidden]
bind = Super+Shift, Right, movewindow, r # [hidden]
bind = Super+Shift, Up, movewindow, u # [hidden]
bind = Super+Shift, Down, movewindow, d # [hidden]
bind = Alt, F4, killactive, # [hidden] Close (Windows)
bind = Super, Q, killactive, # Close
bind = Super+Shift+Alt, Q, exec, hyprctl kill # Forcefully zap a window
# Window split ratio
#/# binde = Super, ;/',, # Adjust split ratio
binde = Super, Semicolon, layoutmsg, splitratio -0.1 # [hidden]
binde = Super, Apostrophe, layoutmsg, splitratio +0.1 # [hidden]
# Positioning mode
bind = Super+Alt, Space, togglefloating, # Float/Tile
bind = Super, D, fullscreen, 1 # Maximize
bind = Super, F, fullscreen, 0 # Fullscreen
bind = Super+Alt, F, fullscreenstate, 0 3 # Fullscreen spoof
bind = Super, P, pin # Pin
#/# bind = Super+Alt, Hash,, # Send to workspace # (1, 2, 3,...)
# We use raw keycodes because some keyboard layouts register number keys as different chars. The codes can be verified with `wev`
bind = Super+Alt, code:10, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 1 # [hidden]
bind = Super+Alt, code:11, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 2 # [hidden]
bind = Super+Alt, code:12, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 3 # [hidden]
bind = Super+Alt, code:13, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 4 # [hidden]
bind = Super+Alt, code:14, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 5 # [hidden]
bind = Super+Alt, code:15, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 6 # [hidden]
bind = Super+Alt, code:16, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 7 # [hidden]
bind = Super+Alt, code:17, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 8 # [hidden]
bind = Super+Alt, code:18, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 9 # [hidden]
bind = Super+Alt, code:19, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 10 # [hidden]
# keypad numbers
bind = Super+Alt, code:87, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 1 # [hidden]
bind = Super+Alt, code:88, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 2 # [hidden]
bind = Super+Alt, code:89, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 3 # [hidden]
bind = Super+Alt, code:83, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 4 # [hidden]
bind = Super+Alt, code:84, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 5 # [hidden]
bind = Super+Alt, code:85, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 6 # [hidden]
bind = Super+Alt, code:79, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 7 # [hidden]
bind = Super+Alt, code:80, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 8 # [hidden]
bind = Super+Alt, code:81, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 9 # [hidden]
bind = Super+Alt, code:90, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 10 # [hidden]
# #/# bind = Super+Shift, Scroll ↑/↓,, # Send to workspace left/right
bind = Super+Shift, mouse_down, movetoworkspace, r-1 # [hidden]
bind = Super+Shift, mouse_up, movetoworkspace, r+1 # [hidden]
bind = Super+Alt, mouse_down, movetoworkspace, -1 # [hidden]
bind = Super+Alt, mouse_up, movetoworkspace, +1 # [hidden]
#/# bind = Super+Shift, Page_↑/↓,, # Send to workspace left/right
bind = Super+Alt, Page_Down, movetoworkspace, +1 # [hidden]
bind = Super+Alt, Page_Up, movetoworkspace, -1 # [hidden]
bind = Super+Shift, Page_Down, movetoworkspace, r+1 # [hidden]
bind = Super+Shift, Page_Up, movetoworkspace, r-1 # [hidden]
bind = Ctrl+Super+Shift, Right, movetoworkspace, r+1 # [hidden]
bind = Ctrl+Super+Shift, Left, movetoworkspace, r-1 # [hidden]
bind = Super+Alt, S, movetoworkspacesilent, special # Send to scratchpad
bind = Ctrl+Super, S, togglespecialworkspace, # [hidden]
##! Workspace
# Switching
#/# bind = Super, Hash,, # Focus workspace # (1, 2, 3,...)
# We use raw keycodes because some keyboard layouts register number keys as different chars. The codes can be verified with `wev`
bind = Super, code:10, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 1 # [hidden]
bind = Super, code:11, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 2 # [hidden]
bind = Super, code:12, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 3 # [hidden]
bind = Super, code:13, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 4 # [hidden]
bind = Super, code:14, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 5 # [hidden]
bind = Super, code:15, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 6 # [hidden]
bind = Super, code:16, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 7 # [hidden]
bind = Super, code:17, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 8 # [hidden]
bind = Super, code:18, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 9 # [hidden]
bind = Super, code:19, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 10 # [hidden]
# keypad numbers
bindp = Super, code:87, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 1 # [hidden]
bindp = Super, code:88, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 2 # [hidden]
bindp = Super, code:89, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 3 # [hidden]
bindp = Super, code:83, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 4 # [hidden]
bindp = Super, code:84, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 5 # [hidden]
bindp = Super, code:85, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 6 # [hidden]
bindp = Super, code:79, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 7 # [hidden]
bindp = Super, code:80, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 8 # [hidden]
bindp = Super, code:81, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 9 # [hidden]
bindp = Super, code:90, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 10 # [hidden]
#/# bind = Ctrl+Super, ←/→,, # Focus left/right
bind = Ctrl+Super, Right, workspace, r+1 # [hidden]
bind = Ctrl+Super, Left, workspace, r-1 # [hidden]
#/# bind = Ctrl+Super+Alt, ←/→,, # [hidden] Focus busy left/right
bind = Ctrl+Super+Alt, Right, workspace, m+1 # [hidden]
bind = Ctrl+Super+Alt, Left, workspace, m-1 # [hidden]
#/# bind = Super, Page_↑/↓,, # Focus left/right
bind = Super, Page_Down, workspace, +1 # [hidden]
bind = Super, Page_Up, workspace, -1 # [hidden]
bind = Ctrl+Super, Page_Down, workspace, r+1 # [hidden]
bind = Ctrl+Super, Page_Up, workspace, r-1 # [hidden]
#/# bind = Super, Scroll ↑/↓,, # Focus left/right
bind = Super, mouse_up, workspace, +1 # [hidden]
bind = Super, mouse_down, workspace, -1 # [hidden]
bind = Ctrl+Super, mouse_up, workspace, r+1 # [hidden]
bind = Ctrl+Super, mouse_down, workspace, r-1 # [hidden]
## Special
bind = Super, S, togglespecialworkspace, # Toggle scratchpad
bind = Super, mouse:275, togglespecialworkspace, # [hidden]
bind = Ctrl+Super, BracketLeft, workspace, -1 # [hidden]
bind = Ctrl+Super, BracketRight, workspace, +1 # [hidden]
bind = Ctrl+Super, Up, workspace, r-5 # [hidden]
bind = Ctrl+Super, Down, workspace, r+5 # [hidden]
##! Virtual machines
bind = Super+Alt, F1, exec, notify-send 'Entered Virtual Machine submap' 'Keybinds disabled. Hit Super+Alt+F1 to escape' -a 'Hyprland' && hyprctl dispatch submap virtual-machine # Disable keybinds
submap = virtual-machine
bind = Super+Alt, F1, exec, notify-send 'Exited Virtual Machine submap' 'Keybinds re-enabled' -a 'Hyprland' && hyprctl dispatch submap global # [hidden]
submap = global
#!
# Testing
bind = Super+Alt, f11, exec, bash -c 'RANDOM_IMAGE=$(find ~/Pictures -type f | grep -v -i "nipple" | grep -v -i "pussy" | shuf -n 1); ACTION=$(notify-send "Test notification with body image" "This notification should contain your user account <b>image</b> and <a href=\"https://discord.com/app\">Discord</a> <b>icon</b>. Oh and here is a random image in your Pictures folder: <img src=\"$RANDOM_IMAGE\" alt=\"Testing image\"/>" -a "Hyprland keybind" -p -h "string:image-path:/var/lib/AccountsService/icons/$USER" -t 6000 -i "discord" -A "openImage=Profile image" -A "action2=Open the random image" -A "action3=Useless button"); [[ $ACTION == *openImage ]] && xdg-open "/var/lib/AccountsService/icons/$USER"; [[ $ACTION == *action2 ]] && xdg-open \"$RANDOM_IMAGE\"' # [hidden]
bind = Super+Alt, f12, exec, bash -c 'RANDOM_IMAGE=$(find ~/Pictures -type f | grep -v -i "nipple" | grep -v -i "pussy" | shuf -n 1); ACTION=$(notify-send "Test notification" "This notification should contain a random image in your <b>Pictures</b> folder and <a href=\"https://discord.com/app\">Discord</a> <b>icon</b>.\n<i>Flick right to dismiss!</i>" -a "Discord (fake)" -p -h "string:image-path:$RANDOM_IMAGE" -t 6000 -i "discord" -A "openImage=Profile image" -A "action2=Useless button"); [[ $ACTION == *openImage ]] && xdg-open "/var/lib/AccountsService/icons/$USER"' # [hidden]
bind = Super+Alt, Equal, exec, notify-send "Urgent notification" "Ah hell no" -u critical -a 'Hyprland keybind' # [hidden]
##! Session
bindd = Super, L, Lock, exec, loginctl lock-session # Lock
bindld = Super+Shift, L, Suspend system, exec, systemctl suspend || loginctl suspend # Sleep
# bindl=,switch:on:Lid Switch, exec, systemctl suspend || loginctl suspend # [hidden] Suspend when laptop lid is closed, uncomment if for whatever reason it's not the default behavior
bindd = Ctrl+Shift+Alt+Super, Delete, Shutdown, exec, systemctl poweroff || loginctl poweroff # [hidden] Power off
##! Screen
# Zoom
binde = Super, Minus, exec, ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.3 # Zoom out
binde = Super, Equal, exec, ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.3 # Zoom in
# Zoom with keypad
binde = Super, code:82, exec, qs -c $qsConfig ipc call zoom zoomOut # [hidden] Zoom out
binde = Super, code:86, exec, qs -c $qsConfig ipc call zoom zoomIn # [hidden] Zoom in
binde = Super, code:82, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.1 # [hidden] Zoom out
binde = Super, code:86, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.1 # [hidden] Zoom in
##! Media
bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # Next track
bindl= ,XF86AudioNext, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # [hidden]
bindl= ,XF86AudioPrev, exec, playerctl previous # [hidden]
bind = Super+Shift+Alt, mouse:275, exec, playerctl previous # [hidden]
bind = Super+Shift+Alt, mouse:276, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # [hidden]
bindl= Super+Shift, B, exec, playerctl previous # Previous track
bindl= Super+Shift, P, exec, playerctl play-pause # Play/pause media
bindl= ,XF86AudioPlay, exec, playerctl play-pause # [hidden]
bindl= ,XF86AudioPause, exec, playerctl play-pause # [hidden]
##! Apps
bind = Super, Return, exec, $terminal # Terminal
bind = Super, T, exec, $terminal # [hidden] (terminal) (alt)
bind = Ctrl+Alt, T, exec, $terminal # [hidden] (terminal) (for Ubuntu people)
bind = Super, E, exec, $fileManager # File manager
bind = Super, W, exec, $browser # Browser
bind = Super, C, exec, $codeEditor # Code editor
bind = Ctrl+Super+Shift+Alt, W, exec, $officeSoftware # Office software
bind = Super, X, exec, $textEditor # Text editor
bind = Ctrl+Super, V, exec, $volumeMixer # Volume mixer
bind = Super, I, exec, $settingsApp # Settings app
bind = Ctrl+Shift, Escape, exec, $taskManager # Task manager
# Cursed stuff
## Make window not amogus large
bind = Ctrl+Super, Backslash, resizeactive, exact 640 480 # [hidden]
+359
View File
@@ -0,0 +1,359 @@
require("hyprland.lib")
require("hyprland.variables")
if is_file_exists(HOME .. "/.config/hypr/custom/variables.lua") then
require("custom.variables")
end
local qsScripts = "$HOME/.config/quickshell/$qsConfig/scripts"
local hyprScripts = "$HOME/.config/hypr/hyprland/scripts"
local qsIpcCall = "qs -c $qsConfig ipc call"
local qsIsAlive = qsIpcCall .. " TEST_ALIVE"
hl.bind("SUPER + SUPER_L", hl.dsp.global("quickshell:searchToggleRelease"), { description = "Shell: Toggle search" })
hl.bind("SUPER + SUPER_R", hl.dsp.global("quickshell:searchToggleRelease"))
hl.bind("SUPER + SUPER_L", hl.dsp.exec_cmd(qsIsAlive .. " || pkill fuzzel || fuzzel"))
hl.bind("SUPER + SUPER_R", hl.dsp.exec_cmd(qsIsAlive .. " || pkill fuzzel || fuzzel"))
hl.bind("SUPER_L", hl.dsp.global("quickshell:workspaceNumber"), { ignore_mods = true, transparent = true })
hl.bind("SUPER_R", hl.dsp.global("quickshell:workspaceNumber"), { ignore_mods = true, transparent = true })
hl.bind("SUPER_L", hl.dsp.global("quickshell:workspaceNumber"),
{ ignore_mods = true, transparent = true, release = true })
hl.bind("SUPER_R", hl.dsp.global("quickshell:workspaceNumber"),
{ ignore_mods = true, transparent = true, release = true })
hl.bind("SUPER + Tab", hl.dsp.global("quickshell:overviewWorkspacesToggle"), { description = "Shell: Toggle overview" })
hl.bind("SUPER + V", hl.dsp.global("quickshell:overviewClipboardToggle"))
hl.bind("SUPER + Period", hl.dsp.global("quickshell:overviewEmojiToggle"))
hl.bind("SUPER + A", hl.dsp.global("quickshell:sidebarLeftToggle"), { description = "Shell: Toggle left sidebar" })
hl.bind("SUPER + ALT + A", hl.dsp.global("quickshell:sidebarLeftToggleDetach"))
hl.bind("SUPER + B", hl.dsp.global("quickshell:sidebarLeftToggle"))
hl.bind("SUPER + O", hl.dsp.global("quickshell:sidebarLeftToggle"))
hl.bind("SUPER + N", hl.dsp.global("quickshell:sidebarRightToggle"), { description = "Shell: Toggle right sidebar" })
hl.bind("SUPER + Slash", hl.dsp.global("quickshell:cheatsheetToggle"), { description = "Shell: Toggle cheatsheet" })
hl.bind("SUPER + K", hl.dsp.global("quickshell:oskToggle"), { description = "Shell: Toggle on-screen keyboard" })
hl.bind("SUPER + M", hl.dsp.global("quickshell:mediaControlsToggle"), { description = "Shell: Toggle media controls" })
hl.bind("SUPER + G", hl.dsp.global("quickshell:overlayToggle"), { description = "Shell: Toggle widget overlay" })
hl.bind("CTRL + ALT + Delete", hl.dsp.global("quickshell:sessionToggle"), { description = "Shell: Toggle session menu" })
hl.bind("SUPER + J", hl.dsp.global("quickshell:barToggle"), { description = "Shell: Toggle bar" })
hl.bind("CTRL + ALT + Delete", hl.dsp.exec_cmd(qsIsAlive .. " || pkill wlogout || wlogout -p layer-shell"))
hl.bind("SHIFT + SUPER + ALT + Slash", hl.dsp.exec_cmd("qs -p $HOME/.config/quickshell/$qsConfig/welcome.qml"))
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd(qsIpcCall .. " brightness increment || brightnessctl s 5%+"),
{ locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd(qsIpcCall .. " brightness decrement || brightnessctl s 5%-"),
{ locked = true, repeating = true })
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%+ -l 1.5"),
{ locked = true, repeating = true })
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%-"),
{ locked = true, repeating = true })
hl.bind("CTRL + SUPER + T", hl.dsp.global("quickshell:wallpaperSelectorToggle"),
{ description = "Shell: Change wallpaper" })
hl.bind("CTRL + SUPER + ALT + T", hl.dsp.global("quickshell:wallpaperSelectorRandom"),
{ description = "Shell: Random wallpaper" })
hl.bind("CTRL + SUPER + SHIFT + D", hl.dsp.global("quickshell:toggleLightDark"),
{ description = "Shell: Toggle light/dark mode" })
hl.bind("CTRL + SUPER + T", hl.dsp.exec_cmd(qsIsAlive .. " || " .. qsScripts .. "/colors/switchwall.sh"))
hl.bind("CTRL + SUPER + R", hl.dsp.exec_cmd("killall ydotool qs quickshell; qs -c $qsConfig &"),
{ description = "Shell: Restart widgets" })
hl.bind("CTRL + SUPER + P", hl.dsp.global("quickshell:panelFamilyCycle"), { description = "Shell: Cycle panel family" })
--##! Utilities
--# Screenshot, Record, OCR, Color picker, Clipboard history
hl.bind("SUPER + V", hl.dsp.exec_cmd(
qsIsAlive .. " || pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy"),
{ description = "Utilities: Clipboard history >> clipboard" })
hl.bind("SUPER + Period", hl.dsp.exec_cmd(
qsIsAlive .. " || pkill fuzzel || " .. hyprScripts .. "/fuzzel-emoji.sh copy"),
{ description = "Utilities: Emoji >> clipboard" })
hl.bind("SUPER + SHIFT + S", hl.dsp.global("quickshell:regionScreenshot"), { description = "Utilities: Screen snip" })
hl.bind("SUPER + SHIFT + S",
hl.dsp.exec_cmd(qsIsAlive .. " || pidof slurp || hyprshot --freeze --clipboard-only --mode region --silent"))
hl.bind("SUPER + SHIFT + A", hl.dsp.global("quickshell:regionSearch"), { description = "Utilities: Google Lens" })
hl.bind("SUPER + SHIFT + A", hl.dsp.exec_cmd(qsIsAlive .. " || pidof slurp || " .. hyprScripts .. "/snip_to_search.sh"))
--# OCR
hl.bind("SUPER + SHIFT + X", hl.dsp.global("quickshell:regionOcr"),
{ description = "Utilities: Character recognition >> clipboard" })
hl.bind("SUPER + SHIFT + T", hl.dsp.global("quickshell:screenTranslate"),
{ description = "Utilities: Translate screen content" })
hl.bind("SUPER + SHIFT + X", hl.dsp.exec_cmd(
qsIsAlive ..
" || pidof slurp || grim -g \"$(slurp $SLURP_ARGS)\" \"/tmp/ocr_image.png\" && tesseract \"/tmp/ocr_image.png\" stdout -l $(tesseract --list-langs | awk 'NR>1{print $1}' | tr '\\\\n' '+' | sed 's/\\\\+$/\\\\n/') | wl-copy && rm \"/tmp/ocr_image.png\""
))
--# Color picker
hl.bind("SUPER + SHIFT + C", hl.dsp.exec_cmd("hyprpicker -a"),
{ description = "Utilities: Pick color #RRGGBB >> clipboard" })
--# Recording stuff
hl.bind("SUPER + SHIFT + R", hl.dsp.global("quickshell:regionRecord"),
{ locked = true, description = "Utilities: Record region (no sound)" })
hl.bind("SUPER + SHIFT + R", hl.dsp.exec_cmd(qsIsAlive .. " || " .. qsScripts .. "/videos/record.sh"), { locked = true })
hl.bind("SUPER + ALT + R", hl.dsp.global("quickshell:regionRecord"), { locked = true })
hl.bind("SUPER + ALT + R", hl.dsp.exec_cmd(qsIsAlive .. " || " .. qsScripts .. "/videos/record.sh"), { locked = true })
hl.bind("CTRL + ALT + R", hl.dsp.exec_cmd(qsScripts .. "/videos/record.sh --fullscreen"), { locked = true })
hl.bind("SUPER + SHIFT + ALT + R", hl.dsp.exec_cmd(qsScripts .. "/videos/record.sh --fullscreen --sound"),
{ locked = true, description = "Utilities: Record screen (with sound)" })
--# Fullscreen screenshot
local grimhyprctl = "grim -o \"$(hyprctl activeworkspace -j | jq -r '.monitor')\""
hl.bind("Print", hl.dsp.exec_cmd(grimhyprctl .. " - | wl-copy"),
{ locked = true, description = "Utilities: Screenshot >> clipboard" })
hl.bind("CTRL + Print", hl.dsp.exec_cmd(
"mkdir -p $(xdg-user-dir PICTURES)/Screenshots && " ..
grimhyprctl .. " $(xdg-user-dir PICTURES)/Screenshots/Screenshot_\"$(date '+%Y-%m-%d_%H.%M.%S')\".png"
), { locked = true, non_consuming = true, description = "Utilities: Screenshot >> clipboard & file" })
hl.bind("CTRL + Print", hl.dsp.exec_cmd(grimhyprctl .. " - | wl-copy"), { locked = true, non_consuming = true })
--# AI
hl.bind("SUPER + SHIFT + ALT + mouse:273", hl.dsp.exec_cmd(hyprScripts .. "/ai/primary-buffer-query.sh"),
{ description = "Utilities: Generate AI summary for selected text" })
-- (requires a running ollama model)
--##! Screen
--# Zoom
local function zoomfunction(value)
local zoomvalue = hl.get_config("cursor:zoom_factor")
if (zoomvalue + value) > 3.0 then
hl.config({ cursor = { zoom_factor = 3.0 } })
elseif (zoomvalue + value) < 1.0 then
hl.config({ cursor = { zoom_factor = 1.0 } })
else
hl.config({ cursor = { zoom_factor = zoomvalue + value } })
end
end
hl.bind("SUPER + Minus", function() zoomfunction(-0.3) end, { repeating = true, description = "Screen: Zoom out" })
hl.bind("SUPER + Equal", function() zoomfunction(0.3) end, { repeating = true, description = "Screen: Zoom in" })
--# Zoom with keypad
hl.bind("SUPER + code:82", function() zoomfunction(-0.3) end, { repeating = true })
hl.bind("SUPER + code:86", function() zoomfunction(0.3) end, { repeating = true })
--##! Media
local mediaNextCommand =
"playerctl next || playerctl position `bc <<< \"100 * $(playerctl metadata mpris:length) / 1000000 / 100\"`"
hl.bind("SUPER + SHIFT + N", hl.dsp.exec_cmd(mediaNextCommand), { locked = true, description = "Media: Next track" })
hl.bind("XF86AudioNext", hl.dsp.exec_cmd(mediaNextCommand), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
hl.bind("SUPER + SHIFT + ALT + mouse:275", hl.dsp.exec_cmd("playerctl previous"))
hl.bind("SUPER + SHIFT + ALT + mouse:276", hl.dsp.exec_cmd(mediaNextCommand))
hl.bind("SUPER + SHIFT + B", hl.dsp.exec_cmd("playerctl previous"),
{ locked = true, description = "Media: Previous track" })
hl.bind("SUPER + SHIFT + P", hl.dsp.exec_cmd("playerctl play-pause"),
{ locked = true, description = "Media: Play/pause media" })
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SINK@ toggle"), { locked = true })
hl.bind("SUPER + SHIFT + M", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SINK@ toggle"),
{ locked = true, description = "Media: Toggle mute" })
hl.bind("ALT + XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SOURCE@ toggle"), { locked = true })
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SOURCE@ toggle"), { locked = true })
hl.bind("SUPER + ALT + M", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SOURCE@ toggle"),
{ locked = true, description = "Media: Toggle mic" })
--#!
--##! Window
--# Focusing
hl.bind("SUPER + mouse:272", hl.dsp.window.drag(), { mouse = true, description = "Window: Move" })
hl.bind("SUPER + mouse:274", hl.dsp.window.drag(), { mouse = true })
hl.bind("SUPER + mouse:273", hl.dsp.window.resize(), { mouse = true, description = "Window: Resize" })
--#/# bind = SUPER + ←/↑/→/↓,, -- Focus in direction
for i = 1, 4 do
local arrowkey = { "Left", "Right", "Up", "Down" }
local focusdir = { "l", "r", "u", "d" }
hl.bind("SUPER + " .. arrowkey[i], hl.dsp.focus({ direction = focusdir[i] }),
{ description = "Window: Focus " .. arrowkey[i] })
end
for i = 1, 2 do
local arrowkey = { "BracketLeft", "BracketRight" }
local focusdir = { "l", "r" }
hl.bind("SUPER + " .. arrowkey[i], hl.dsp.focus({ direction = focusdir[i] }))
end
--#/# bind = SUPER + SHIFT, ←/↑/→/↓,, -- Move in direction
for i = 1, 4 do
local arrowkey = { "Left", "Right", "Up", "Down" }
local focusdir = { "l", "r", "u", "d" }
hl.bind("SUPER + SHIFT + " .. arrowkey[i], hl.dsp.window.move({ direction = focusdir[i] }),
{ description = "Window: Move " .. arrowkey[i] })
end
hl.bind("ALT + F4",
function()
hl.exec_cmd(
"notify-send \"Wrong close keybind\" \"Super+Q to close. Use Alt+F4 for Windows VMs\" -a Hyprland")
end,
{ non_consuming = true })
hl.bind("SUPER + Q", hl.dsp.window.close(), { description = "Window: Close" })
hl.bind("SUPER + SHIFT + ALT + Q", hl.dsp.exec_cmd("hyprctl kill"), { description = "Window: Forcefully zap a window" })
--# Window split ratio
--#/# binde = SUPER, ;/',, -- Adjust split ratio
hl.bind("SUPER + Semicolon", hl.dsp.layout("splitratio -0.1"), { repeating = true })
hl.bind("SUPER + Apostrophe", hl.dsp.layout("splitratio +0.1"), { repeating = true })
--# Positioning mode
hl.bind("SUPER + ALT + Space", hl.dsp.window.float({ action = "toggle" }), { description = "Window: Float/Tile" })
hl.bind("SUPER + D", hl.dsp.window.fullscreen({ mode = "maximized", action = "toggle" }),
{ description = "Window: Maximize" })
hl.bind("SUPER + F", hl.dsp.window.fullscreen({ mode = "fullscreen", action = "toggle" }),
{ description = "Window: Fullscreen" })
hl.bind("SUPER + ALT + F", hl.dsp.window.fullscreen_state({ internal = 0, client = 3, action = "toggle" }),
{ description = "Window: Fullscreen spoof" })
hl.bind("SUPER + P", hl.dsp.window.pin(), { description = "Window: Pin" })
--#/# bind = SUPER+ALT, Hash,, -- Send to workspace -- (1, 2, 3,...)
for i = 1, 10 do
hl.bind("SUPER + ALT + " .. (i % 10), function()
hl.dispatch(hl.dsp.window.move({ workspace = workspace_in_group(i), follow = false }))
end, { description = "Window: Send to workspace " .. i })
end
--# We also use raw keycodes because some keyboard layouts register number keys as different chars. The codes can be verified with `wev`
for i = 1, 10 do
local numberkey = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }
hl.bind("SUPER + ALT + code:" .. numberkey[i], function()
hl.dispatch(hl.dsp.window.move({ workspace = workspace_in_group(i), follow = false }))
end)
end
--# keypad numbers
for i = 1, 10 do
local numpadkey = { 87, 88, 89, 83, 84, 85, 79, 80, 81, 90 }
hl.bind("SUPER + ALT + code:" .. numpadkey[i], function()
hl.dispatch(hl.dsp.window.move({ workspace = workspace_in_group(i), follow = false }))
end)
end
--# #/# bind = SUPER+SHIFT, Scroll ↑/↓,, -- Send to workspace left/right
for i = 1, 4 do
local key = { "SUPER + SHIFT + mouse_", "SUPER + ALT + mouse_" }
local keycombos = { key[1] .. "down", key[1] .. "up", key[2] .. "down", key[2] .. "up" }
local prefix = { "r-", "r+", "r-", "r+" }
hl.bind(keycombos[i], hl.dsp.window.move({ workspace = prefix[i] .. "1" }))
end
--#/# bind = SUPER+SHIFT, Page_↑/↓,, -- Send to workspace left/right
for i = 1, 2 do
local keydirs = { "Up", "Down" }
local prefix = { "r-", "r+" }
local descdir = { "left", "right" }
hl.bind("SUPER + SHIFT + Page_" .. keydirs[i], hl.dsp.window.move({ workspace = prefix[i] .. "1" }), {description = "Window: Send to workspace " .. descdir[i]})
end
for i = 1, 4 do
local key = { "SUPER + ALT + Page_", "CTRL + SUPER + SHIFT + " }
local keycombos = { key[1] .. "down", key[1] .. "up", key[2] .. "Right", key[2] .. "Left" }
local prefix = { "r+", "r-", "r+", "r-" }
hl.bind(keycombos[i], hl.dsp.window.move({ workspace = prefix[i] .. "1" })) -- # [hidden]
end
hl.bind("SUPER + ALT + S",
hl.dsp.window.move({ workspace = "special:special", follow = false }), { description = "Window: Send to scratchpad" })
hl.bind("CTRL + SUPER + S", hl.dsp.workspace.toggle_special("special"))
--##! Workspace
--# Switching
--#/# bind = SUPER, Hash,, -- Focus workspace -- (1, 2, 3,...)
for i = 1, 10 do
hl.bind("SUPER + " .. (i % 10), function()
hl.dispatch(hl.dsp.focus({ workspace = workspace_in_group(i) }))
end, { description = "Workspace: Focus " .. i })
end
--# We also use raw keycodes because some keyboard layouts register number keys as different chars. The codes can be verified with `wev`
for i = 1, 10 do
local numberkey = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }
hl.bind("SUPER + code:" .. numberkey[i], function()
hl.dispatch(hl.dsp.focus({ workspace = workspace_in_group(i) }))
end)
end
--# keypad numbers
for i = 1, 10 do
local numpadkey = { 87, 88, 89, 83, 84, 85, 79, 80, 81, 90 }
hl.bind("SUPER + code:" .. numpadkey[i], function()
hl.dispatch(hl.dsp.focus({ workspace = workspace_in_group(i) }))
end)
end
--#/# bind = CTRL+SUPER, ←/→,, -- Focus left/right
--#/# bind = CTRL+SUPER+ALT, ←/→,, -- # [hidden] Focus busy left/right
for i = 1, 2 do
local keys = { "Left", "Right" }
local prefix = { "r-", "r+" }
local descdir = { "left", "right" }
hl.bind("CTRL + SUPER + " .. keys[i], hl.dsp.focus({ workspace = prefix[i] .. "1" }), {description = "Workspace: Focus " .. descdir[i]})
end
for i = 1, 2 do
local keys = { "Left", "Right" }
local prefix = { "m-", "m+" }
hl.bind("CTRL + SUPER + ALT + " .. keys[i], hl.dsp.focus({ workspace = prefix[i] .. "1" }))
end
--#/# bind = SUPER, Page_↑/↓,, -- Focus left/right
for i = 1, 4 do
local key = { "SUPER + Page_Down", "SUPER + Page_Up" }
local keycombos = { key[1], key[2], "CTRL + " .. key[1], "CTRL + " .. key[2] }
local prefix = { "r+", "r-", "r+", "r-" }
hl.bind(keycombos[i], hl.dsp.focus({ workspace = prefix[i] .. "1" }))
end
--#/# bind = SUPER, Scroll ↑/↓,, -- Focus left/right
for i = 1, 4 do
local key = { "SUPER + mouse_up", "SUPER + mouse_down" }
local keycombos = { key[1], key[2], "CTRL + " .. key[1], "CTRL + " .. key[2] }
local prefix = { "+", "-", "r+", "r-" }
hl.bind(keycombos[i], hl.dsp.focus({ workspace = prefix[i] .. "1" }))
end
--## Special
hl.bind("SUPER + S", hl.dsp.workspace.toggle_special("special"), { description = "Workspace: Toggle scratchpad" })
hl.bind("SUPER + mouse:275", hl.dsp.workspace.toggle_special("special"))
for i = 1, 4 do
local key = { "BracketLeft", "BracketRight", "Up", "Down" }
local prefix = { "-1", "+1", "r-5", "r+5" }
hl.bind("CTRL + SUPER + " .. key[i], hl.dsp.focus({ workspace = prefix[i] }))
end
--##! Virtual machines
hl.define_submap("virtual-machine", function()
hl.bind("SUPER + ALT + F1", function()
local currentsubmap = hl.get_current_submap()
if currentsubmap == "virtual-machine" then
hl.dispatch(hl.dsp.exec_cmd(
"notify-send 'Exited Virtual Machine submap' 'Keybinds re-enabled' -a 'Hyprland'"))
hl.dispatch(hl.dsp.submap("reset"))
elseif currentsubmap == "" then
hl.dispatch(hl.dsp.exec_cmd(
"notify-send 'Entered Virtual Machine submap' 'Keybinds disabled. hit SUPER+ALT+F1 to escape' -a 'Hyprland'"))
hl.dispatch(hl.dsp.submap("virtual-machine"))
end
end, { submap_universal = true })
end)
--#!
--# Testing
hl.bind("SUPER + ALT + F11",
hl.dsp.exec_cmd(
"bash -c 'RANDOM_IMAGE=$(find ~/Pictures -type f | shuf -n 1); ACTION=$(notify-send \"Test notification with body image\" \"This notification should contain your user account <b>image</b> and <a href=\\\"https://discord.com/app\\\">Discord</a> <b>icon</b>. Oh and here is a random image in your Pictures folder: <img src=\\\"$RANDOM_IMAGE\\\" alt=\\\"Testing image\\\"/>\" -a \"Hyprland\" -p -h \"string:image-path:/var/lib/AccountsService/icons/$USER\" -t 6000 -i \"discord\" -A \"openImage=Profile image\" -A \"action2=Open the random image\" -A \"action3=Useless button\"); [[ $ACTION == *openImage ]] && xdg-open \"/var/lib/AccountsService/icons/$USER\"; [[ $ACTION == *action2 ]] && xdg-open \"$RANDOM_IMAGE\"'")
) -- # [hidden]
hl.bind("SUPER + ALT + F12",
hl.dsp.exec_cmd(
"bash -c 'RANDOM_IMAGE=$(find ~/Pictures -type f | shuf -n 1); ACTION=$(notify-send \"Test notification\" \"This notification should contain a random image in your <b>Pictures</b> folder and <a href=\\\"https://discord.com/app\\\">Discord</a> <b>icon</b>.\n<i>Flick right to dismiss!</i>\" -a \"Discord (fake)\" -p -h \"string:image-path:$RANDOM_IMAGE\" -t 6000 -i \"discord\" -A \"openImage=Profile image\" -A \"action2=Useless button\"); [[ $ACTION == *openImage ]] && xdg-open \"/var/lib/AccountsService/icons/$USER\"'")
) -- # [hidden]
hl.bind("SUPER + ALT + Equal",
hl.dsp.exec_cmd("notify-send 'Urgent notification' 'Ah hell no' -u critical -a 'Hyprland keybind'")) -- # [hidden]
--##! Session
hl.bind("SUPER + L", hl.dsp.exec_cmd("loginctl lock-session"), { description = "Session: Lock" })
hl.bind("SUPER + SHIFT + L", hl.dsp.exec_cmd("systemctl suspend || loginctl suspend"),
{ locked = true, description = "Session: Sleep" }) -- Sleep
-- hl.bind("switch:on:Lid Switch", hl.dsp.exec_cmd("systemctl suspend || loginctl suspend"), {locked = true} ) -- # [hidden] Suspend when laptop lid is closed, uncomment if for whatever reason it's not the default behavior
hl.bind("CTRL + SHIFT + ALT + SUPER + Delete", hl.dsp.exec_cmd("systemctl poweroff || loginctl poweroff"),
{ description = "Session: Shut down" }) -- # [hidden] Power off
--##! Apps
hl.bind("SUPER + Return", hl.dsp.exec_cmd(terminal), { description = "App: Terminal" })
hl.bind("SUPER + T", hl.dsp.exec_cmd(terminal))
hl.bind("CTRL + ALT + T", hl.dsp.exec_cmd(terminal))
hl.bind("SUPER + E", hl.dsp.exec_cmd(fileManager), { description = "App: File manager" })
hl.bind("SUPER + W", hl.dsp.exec_cmd(browser), { description = "App: Browser" })
hl.bind("SUPER + C", hl.dsp.exec_cmd(codeEditor), { description = "App: Code editor" })
hl.bind("CTRL + SUPER + SHIFT + ALT + W", hl.dsp.exec_cmd(officeSoftware), { description = "App: Office software" })
hl.bind("SUPER + X", hl.dsp.exec_cmd(textEditor), { description = "App: Text editor" })
hl.bind("CTRL + SUPER + V", hl.dsp.exec_cmd(volumeMixer), { description = "App: Volume mixer" })
hl.bind("SUPER + I", hl.dsp.exec_cmd(settingsApp), { description = "App: Settings app" })
hl.bind("CTRL + SHIFT + Escape", hl.dsp.exec_cmd(taskManager), { description = "App: Task manager" })
--# Cursed stuff
--## Make window not amogus large
hl.bind("CTRL + SUPER + Backslash", hl.dsp.window.resize({ x = 640, y = 480, "exact" }))
+27
View File
@@ -0,0 +1,27 @@
HOME = os.getenv("HOME")
function is_file_exists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
function create_if_not_exists(path)
if not is_file_exists(path) then
os.execute("mkdir -p \"$(dirname \"" .. path .. "\")\"")
os.execute("echo '-- This file will not be overwritten across dots-hyprland updates.\n-- The file name is for the sake of organization and does not matter\n-- See the corresponding files in ~/.config/hypr/hyprland for examples' > \"" .. path .. "\"")
return true
end
return false
end
function workspace_in_group(i)
local curr = hl.get_active_workspace().id
local newVal = math.floor((curr - 1) / workspaceGroupSize) * workspaceGroupSize + i
-- hl.notification.create({ text = "curr " .. curr .. " floor " .. math.floor(curr / 10) .. " new " .. newVal, duration = 5000 })
return newVal
end
-173
View File
@@ -1,173 +0,0 @@
# ######## Window rules ########
# Disable blur for xwayland context menus
windowrule = match:class ^()$, match:title ^()$, no_blur on
# Disable blur for every window
windowrule = match:class .*, no_blur on
# Floating
windowrule = match:title ^(Open File)(.*)$, center on
windowrule = match:title ^(Open File)(.*)$, float on
windowrule = match:title ^(Select a File)(.*)$, center on
windowrule = match:title ^(Select a File)(.*)$, float on
windowrule = match:title ^(Choose wallpaper)(.*)$, center on
windowrule = match:title ^(Choose wallpaper)(.*)$, float on
windowrule = match:title ^(Choose wallpaper)(.*)$, size (monitor_w*.60) (monitor_h*.65)
windowrule = match:title ^(Open Folder)(.*)$, center on
windowrule = match:title ^(Open Folder)(.*)$, float on
windowrule = match:title ^(Save As)(.*)$, center on
windowrule = match:title ^(Save As)(.*)$, float on
windowrule = match:title ^(Library)(.*)$, center on
windowrule = match:title ^(Library)(.*)$, float on
windowrule = match:title ^(File Upload)(.*)$, center on
windowrule = match:title ^(File Upload)(.*)$, float on
windowrule = match:title ^(.*)(wants to save)$, center on
windowrule = match:title ^(.*)(wants to save)$, float on
windowrule = match:title ^(.*)(wants to open)$, center on
windowrule = match:title ^(.*)(wants to open)$, float on
windowrule = match:class ^(blueberry\.py)$, float on
windowrule = match:class ^(guifetch)$ , float on # FlafyDev/guifetch
windowrule = match:class ^(pavucontrol)$, float on
windowrule = match:class ^(pavucontrol)$, size (monitor_w*.45) (monitor_h*.45)
windowrule = match:class ^(pavucontrol)$, center on
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, float on
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, size (monitor_w*.45) (monitor_h*.45)
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, center on
windowrule = match:class ^(nm-connection-editor)$, float on
windowrule = match:class ^(nm-connection-editor)$, size (monitor_w*.45) (monitor_h*.45)
windowrule = match:class ^(nm-connection-editor)$, center on
windowrule = match:class .*plasmawindowed.*, float on
windowrule = match:class kcm_.*, float on
windowrule = match:class .*bluedevilwizard, float on
windowrule = match:title .*Welcome, float on
windowrule = match:title ^(illogical-impulse Settings)$, float on
windowrule = match:title .*Shell conflicts.*, float on
windowrule = match:class org.freedesktop.impl.portal.desktop.kde, float on
windowrule = match:class org.freedesktop.impl.portal.desktop.kde, size (monitor_w*.60) (monitor_h*.65)
windowrule = match:class ^(Zotero)$, float on
windowrule = match:class ^(Zotero)$, size (monitor_w*.45) (monitor_h*.45)
# Move
# kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
windowrule = match:class ^(plasma-changeicons)$, float on
windowrule = match:class ^(plasma-changeicons)$, no_initial_focus on
windowrule = match:class ^(plasma-changeicons)$, move 999999 999999
# stupid dolphin copy
windowrule = match:title ^(Copying — Dolphin)$, move 40 80
# Tiling
windowrule = match:class ^dev\.warp\.Warp$, tile on
# Picture-in-Picture
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, float on
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, keep_aspect_ratio on
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, move (monitor_w*.73) (monitor_h*.72)
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, size (monitor_w*.25) (monitor_h*.25)
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, float on
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, pin on
# Screen sharing
windowrule = match:title .*is sharing (a window|your screen).*, float on
windowrule = match:title .*is sharing (a window|your screen).*, pin on
windowrule = match:title .*is sharing (a window|your screen).*, move (monitor_w*.5-window_w*.5) (monitor_h-window_h-12)
# --- Tearing ---
windowrule = match:title .*\.exe, immediate on
windowrule = match:title .*minecraft.*, immediate on
windowrule = match:class ^(steam_app).*, immediate on
# Fix Jetbrain IDEs focus/rerendering problem
windowrule = match:class ^jetbrains-.*$, match:float 1, match:title ^$|^\s$|^win\d+$, no_initial_focus on
# No shadow for tiled windows (matches windows that are not floating).
windowrule = match:float 0, no_shadow on
# ######## Workspace rules ########
workspace = special:special, gapsout:30
# ######## Layer rules ########
layerrule = match:namespace .*, xray on
# layerrule = match:namespace .*, no_anim on
layerrule = match:namespace walker, no_anim on
layerrule = match:namespace selection, no_anim on
layerrule = match:namespace overview, no_anim on
layerrule = match:namespace anyrun, no_anim on
layerrule = match:namespace indicator.*, no_anim on
layerrule = match:namespace osk, no_anim on
layerrule = match:namespace hyprpicker, no_anim on
layerrule = match:namespace noanim, no_anim on
layerrule = match:namespace gtk-layer-shell, blur on
layerrule = match:namespace gtk-layer-shell, ignore_alpha 0
layerrule = match:namespace launcher, blur on
layerrule = match:namespace launcher, ignore_alpha 0.5
layerrule = match:namespace notifications, blur on
layerrule = match:namespace notifications, ignore_alpha 0.69
layerrule = match:namespace logout_dialog # wlogout, blur on
# ags
layerrule = match:namespace sideleft.*, animation slide left
layerrule = match:namespace sideright.*, animation slide right
layerrule = match:namespace session[0-9]*, blur on
layerrule = match:namespace bar[0-9]*, blur on
layerrule = match:namespace bar[0-9]*, ignore_alpha 0.6
layerrule = match:namespace barcorner.*, blur on
layerrule = match:namespace barcorner.*, ignore_alpha 0.6
layerrule = match:namespace dock[0-9]*, blur on
layerrule = match:namespace dock[0-9]*, ignore_alpha 0.6
layerrule = match:namespace indicator.*, blur on
layerrule = match:namespace indicator.*, ignore_alpha 0.6
layerrule = match:namespace overview[0-9]*, blur on
layerrule = match:namespace overview[0-9]*, ignore_alpha 0.6
layerrule = match:namespace cheatsheet[0-9]*, blur on
layerrule = match:namespace cheatsheet[0-9]*, ignore_alpha 0.6
layerrule = match:namespace sideright[0-9]*, blur on
layerrule = match:namespace sideright[0-9]*, ignore_alpha 0.6
layerrule = match:namespace sideleft[0-9]*, blur on
layerrule = match:namespace sideleft[0-9]*, ignore_alpha 0.6
layerrule = match:namespace indicator.*, blur on
layerrule = match:namespace indicator.*, ignore_alpha 0.6
layerrule = match:namespace osk[0-9]*, blur on
layerrule = match:namespace osk[0-9]*, ignore_alpha 0.6
# Quickshell
# Quickshell: illogical-impulse
layerrule = match:namespace quickshell:.*, blur_popups on
layerrule = match:namespace quickshell:.*, blur on
layerrule = match:namespace quickshell:.*, ignore_alpha 0.79
layerrule = match:namespace quickshell:bar, animation slide
layerrule = match:namespace quickshell:actionCenter, no_anim on
layerrule = match:namespace quickshell:cheatsheet, animation slide bottom
layerrule = match:namespace quickshell:dock, animation slide bottom
layerrule = match:namespace quickshell:screenCorners, animation popin 120%
layerrule = match:namespace quickshell:lockWindowPusher, no_anim on
layerrule = match:namespace quickshell:notificationPopup, animation fade
layerrule = match:namespace quickshell:overlay, no_anim on
layerrule = match:namespace quickshell:overlay, ignore_alpha 1
layerrule = match:namespace quickshell:overview, no_anim on
layerrule = match:namespace quickshell:osk, animation slide bottom
layerrule = match:namespace quickshell:polkit, no_anim on
layerrule = match:namespace quickshell:popup, xray off # No weird color for bar tooltips (this in theory should suffice)
layerrule = match:namespace quickshell:popup, ignore_alpha 1 # No weird color for bar tooltips (but somehow this is necessary)
layerrule = match:namespace quickshell:mediaControls, ignore_alpha 1 # Same as above
layerrule = match:namespace quickshell:reloadPopup, animation slide
layerrule = match:namespace quickshell:regionSelector, no_anim on
layerrule = match:namespace quickshell:screenshot, no_anim on
layerrule = match:namespace quickshell:session, blur on
layerrule = match:namespace quickshell:session, no_anim on
layerrule = match:namespace quickshell:session, ignore_alpha 0
layerrule = match:namespace quickshell:sidebarRight, animation slide right
layerrule = match:namespace quickshell:sidebarLeft, animation slide left
layerrule = match:namespace quickshell:verticalBar, animation slide
layerrule = match:namespace quickshell:osk, order -1
# Quickshell: waffles
layerrule = match:namespace quickshell:wallpaperSelector, animation slide top
layerrule = match:namespace quickshell:wNotificationCenter, no_anim on
layerrule = match:namespace quickshell:wOnScreenDisplay, no_anim on
layerrule = match:namespace quickshell:wStartMenu, no_anim on
layerrule = match:namespace quickshell:wTaskView, ignore_alpha 0
layerrule = match:namespace quickshell:wTaskView, no_anim on
# Launchers need to be FAST
layerrule = match:namespace gtk4-layer-shell, no_anim on
+169
View File
@@ -0,0 +1,169 @@
-- ######## Window rules ########
-- Disable blur for xwayland context menus
hl.window_rule({match = {class = "^()$", title = "^()$" }, no_blur = true })
-- Disable blur for every window
hl.window_rule({match = {class = ".*" }, no_blur = true })
-- Floating
hl.window_rule({match = {title = "^(Open File)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Open File)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(Select a File)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Select a File)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(Choose wallpaper)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Choose wallpaper)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(Choose wallpaper)(.*)$" }, size = {"(monitor_w*0.60)", "(monitor_h*0.65)"} })
hl.window_rule({match = {title = "^(Open Folder)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Open Folder)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(Save As)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Save As)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(Library)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(Library)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(File Upload)(.*)$" }, center = true})
hl.window_rule({match = {title = "^(File Upload)(.*)$" }, float = true})
hl.window_rule({match = {title = "^(.*)(wants to save)$" }, center = true})
hl.window_rule({match = {title = "^(.*)(wants to save)$" }, float = true})
hl.window_rule({match = {title = "^(.*)(wants to open)$" }, center = true})
hl.window_rule({match = {title = "^(.*)(wants to open)$" }, float = true})
hl.window_rule({match = {class = "^(blueberry\\.py)$" }, float = true})
hl.window_rule({match = {class = "^(guifetch)$" }, float = true}) -- FlafyDev/guifetch
hl.window_rule({match = {class = "^(pavucontrol)$" }, float = true})
hl.window_rule({match = {class = "^(pavucontrol)$" }, size = {"(monitor_w*0.45)", "(monitor_h*0.45)"} })
hl.window_rule({match = {class = "^(pavucontrol)$" }, center = true})
hl.window_rule({match = {class = "^(org.pulseaudio.pavucontrol)$" }, float = true})
hl.window_rule({match = {class = "^(org.pulseaudio.pavucontrol)$" }, size = {"(monitor_w*0.45)", "(monitor_h*0.45)"} })
hl.window_rule({match = {class = "^(org.pulseaudio.pavucontrol)$" }, center = true})
hl.window_rule({match = {class = "^(nm-connection-editor)$" }, float = true})
hl.window_rule({match = {class = "^(nm-connection-editor)$" }, size = {"(monitor_w*0.45)", "(monitor_h*0.45)"} })
hl.window_rule({match = {class = "^(nm-connection-editor)$" }, center = true})
hl.window_rule({match = {class = ".*plasmawindowed.*" }, float = true})
hl.window_rule({match = {class = "kcm_.*" }, float = true})
hl.window_rule({match = {class = ".*bluedevilwizard" }, float = true})
hl.window_rule({match = {title = ".*Welcome" }, float = true})
hl.window_rule({match = {title = "^(illogical-impulse Settings)$" }, float = true})
hl.window_rule({match = {title = ".*Shell conflicts.*" }, float = true})
hl.window_rule({match = {class = "org.freedesktop.impl.portal.desktop.kde" }, float = true})
hl.window_rule({match = {class = "org.freedesktop.impl.portal.desktop.kde" }, size = {"(monitor_w*0.60)", "(monitor_h*0.65)"} })
hl.window_rule({match = {class = "^(Zotero)$" }, float = true})
hl.window_rule({match = {class = "^(Zotero)$" }, size = {"(monitor_w*0.45)", "(monitor_h*0.45)"} })
-- Move
-- kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
hl.window_rule({match = {class = "^(plasma-changeicons)$" }, float = true})
hl.window_rule({match = {class = "^(plasma-changeicons)$" }, no_initial_focus = true})
hl.window_rule({match = {class = "^(plasma-changeicons)$" }, move = {999999, 999999}})
-- stupid dolphin copy
hl.window_rule({match = {title = "^(Copying — Dolphin)$" }, move = {40, 80}})
-- Tiling
hl.window_rule({match = {class = "^dev\\.warp\\.Warp$" }, tile = true})
-- Picture-in-Picture
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, float = true})
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, keep_aspect_ratio = true})
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, move = {"(monitor_w*0.73)", "(monitor_h*0.72)"} })
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, size = {"(monitor_w*0.25)", "(monitor_h*0.25)"} })
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, float = true})
hl.window_rule({match = {title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, pin = true})
-- Screen sharing
hl.window_rule({match = {title = ".*is sharing (a window|your screen).*" }, float = true})
hl.window_rule({match = {title = ".*is sharing (a window|your screen).*" }, pin = true})
hl.window_rule({match = {title = ".*is sharing (a window|your screen).*" }, move = {"(monitor_w*.5-window_w*.5)", "(monitor_h-window_h-12)"} })
-- --- Tearing ---
hl.window_rule({match = {title = ".*\\.exe" }, immediate = true})
hl.window_rule({match = {title = ".*minecraft.*" }, immediate = true})
hl.window_rule({match = {class = "^(steam_app).*" }, immediate = true})
-- No shadow for tiled windows
hl.window_rule({match = {float = 0 }, no_shadow = true})
-- ######## Workspace rules ########
hl.workspace_rule({ workspace = "special:special", gaps_out = 30 })
-- ######## Layer rules ########
hl.layer_rule({ match = { namespace = ".*" }, xray = true})
hl.layer_rule({ match = { namespace = "walker" }, no_anim = true})
hl.layer_rule({ match = { namespace = "selection" }, no_anim = true})
hl.layer_rule({ match = { namespace = "overview" }, no_anim = true})
hl.layer_rule({ match = { namespace = "anyrun" }, no_anim = true})
hl.layer_rule({ match = { namespace = "indicator.*" }, no_anim = true})
hl.layer_rule({ match = { namespace = "osk" }, no_anim = true})
hl.layer_rule({ match = { namespace = "hyprpicker" }, no_anim = true})
hl.layer_rule({ match = { namespace = "noanim" }, no_anim = true})
hl.layer_rule({ match = { namespace = "gtk-layer-shell" }, blur = true})
hl.layer_rule({ match = { namespace = "gtk-layer-shell" }, ignore_alpha = 0})
hl.layer_rule({ match = { namespace = "launcher" }, blur = true})
hl.layer_rule({ match = { namespace = "launcher" }, ignore_alpha = 0.5})
hl.layer_rule({ match = { namespace = "notifications" }, blur = true})
hl.layer_rule({ match = { namespace = "notifications" }, ignore_alpha = 0.69})
hl.layer_rule({ match = { namespace = "logout_dialog" }, blur = true}) -- wlogout
-- ags
hl.layer_rule({ match = { namespace = "sideleft.*" }, animation = "slide left"})
hl.layer_rule({ match = { namespace = "sideright.*" }, animation = "slide right"})
hl.layer_rule({ match = { namespace = "session[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "bar[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "bar[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "barcorner.*" }, blur = true})
hl.layer_rule({ match = { namespace = "barcorner.*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "dock[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "dock[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "indicator.*" }, blur = true})
hl.layer_rule({ match = { namespace = "indicator.*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "overview[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "overview[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "cheatsheet[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "cheatsheet[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "sideright[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "sideright[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "sideleft[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "sideleft[0-9]*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "indicator.*" }, blur = true})
hl.layer_rule({ match = { namespace = "indicator.*" }, ignore_alpha = 0.6})
hl.layer_rule({ match = { namespace = "osk[0-9]*" }, blur = true})
hl.layer_rule({ match = { namespace = "osk[0-9]*" }, ignore_alpha = 0.6})
-- Quickshell
-- Quickshell: illogical-impulse
hl.layer_rule({ match = { namespace = "quickshell:.*" }, blur_popups = true})
hl.layer_rule({ match = { namespace = "quickshell:.*" }, blur = true})
hl.layer_rule({ match = { namespace = "quickshell:.*" }, ignore_alpha = 0.79})
hl.layer_rule({ match = { namespace = "quickshell:bar" }, animation = "slide"})
hl.layer_rule({ match = { namespace = "quickshell:actionCenter" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:cheatsheet" }, animation = "slide bottom"})
hl.layer_rule({ match = { namespace = "quickshell:dock" }, animation = "slide bottom"})
hl.layer_rule({ match = { namespace = "quickshell:screenCorners" }, animation = "popin 120%"})
hl.layer_rule({ match = { namespace = "quickshell:lockWindowPusher" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:notificationPopup" }, animation = "fade"})
hl.layer_rule({ match = { namespace = "quickshell:overlay" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:overlay" }, ignore_alpha = 1})
hl.layer_rule({ match = { namespace = "quickshell:overview" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:osk" }, animation = "slide bottom"})
hl.layer_rule({ match = { namespace = "quickshell:polkit" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:popup" }, xray = false}) -- No weird color for bar tooltips (this in theory should suffice)
hl.layer_rule({ match = { namespace = "quickshell:popup" }, ignore_alpha = 1}) -- No weird color for bar tooltips (but somehow this is necessary)
hl.layer_rule({ match = { namespace = "quickshell:mediaControls" }, ignore_alpha = 1}) -- Same as above
hl.layer_rule({ match = { namespace = "quickshell:reloadPopup" }, animation = "slide"})
hl.layer_rule({ match = { namespace = "quickshell:regionSelector" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:screenshot" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:session" }, blur = true})
hl.layer_rule({ match = { namespace = "quickshell:session" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:session" }, ignore_alpha = 0})
hl.layer_rule({ match = { namespace = "quickshell:sidebarRight" }, animation = "slide right"})
hl.layer_rule({ match = { namespace = "quickshell:sidebarLeft" }, animation = "slide left"})
hl.layer_rule({ match = { namespace = "quickshell:verticalBar" }, animation = "slide"})
hl.layer_rule({ match = { namespace = "quickshell:osk" }, order = -1})
-- Quickshell: waffles
hl.layer_rule({ match = { namespace = "quickshell:wallpaperSelector" }, animation = "slide top"})
hl.layer_rule({ match = { namespace = "quickshell:wNotificationCenter" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:wOnScreenDisplay" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:wStartMenu" }, no_anim = true})
hl.layer_rule({ match = { namespace = "quickshell:wTaskView" }, ignore_alpha = 0})
hl.layer_rule({ match = { namespace = "quickshell:wTaskView" }, no_anim = true})
-- Launchers need to be FAST
hl.layer_rule({ match = { namespace = "gtk4-layer-shell" }, no_anim = true})
@@ -1885,4 +1885,69 @@ AH↗️HA↘️HA↗️HA↘️ pekora arrows hahaha rabbit
↵ enter key return
𝕏 twitter x logo
👉👈 etou ughhhhhhh shy
👉👌 put it in imagination perv
👉👌 put it in imagination perv
🫨 shaking face tremble shake shocked
🩷 pink heart love
🩵 light blue heart love cyan
🩶 grey heart gray love
🫷 leftwards pushing hand stop halt left
🫸 rightwards pushing hand stop halt right
🫎 moose animal antlers
🫏 donkey animal mule ass
🪽 wing bird feather fly
🐦‍⬛ black bird crow raven rook
🪿 goose bird honk
🪼 jellyfish sea ocean sting
🪻 hyacinth flower spring
🫚 ginger root spice food
🫛 pea pod peas vegetable food
🪭 folding hand fan fan cool
🪮 hair pick afro comb
🪇 maracas instrument music shake
🪈 flute instrument music
🪯 khanda sikh religion symbol
🛜 wireless wifi wi-fi internet network
🙂‍↔️ head shaking horizontally no shake
🙂‍↕️ head shaking vertically yes nod
🚶‍➡️ person walking facing right walk
🚶‍♀️‍➡️ woman walking facing right walk
🚶‍♂️‍➡️ man walking facing right walk
🧎‍➡️ person kneeling facing right kneel
🧎‍♀️‍➡️ woman kneeling facing right kneel
🧎‍♂️‍➡️ man kneeling facing right kneel
🧑‍🦯‍➡️ person with white cane facing right accessibility blind
👨‍🦯‍➡️ man with white cane facing right accessibility blind
👩‍🦯‍➡️ woman with white cane facing right accessibility blind
🧑‍🦼‍➡️ person in motorized wheelchair facing right accessibility
👨‍🦼‍➡️ man in motorized wheelchair facing right accessibility
👩‍🦼‍➡️ woman in motorized wheelchair facing right accessibility
🧑‍🦽‍➡️ person in manual wheelchair facing right accessibility
👨‍🦽‍➡️ man in manual wheelchair facing right accessibility
👩‍🦽‍➡️ woman in manual wheelchair facing right accessibility
🏃‍➡️ person running facing right run
🏃‍♀️‍➡️ woman running facing right run
🏃‍♂️‍➡️ man running facing right run
🧑‍🧑‍🧒 family adult adult child parents
🧑‍🧑‍🧒‍🧒 family adult adult child child parents
🧑‍🧒 family adult child parent
🧑‍🧒‍🧒 family adult child child parent
🐦‍🔥 phoenix fire bird rebirth
🍋‍🟩 lime fruit citrus green
🍄‍🟫 brown mushroom fungi
⛓️‍💥 broken chain snap shatter
🫩 face with bags under eyes tired sleepy exhausted
🫆 fingerprint id biometric
🪾 leafless tree barren dead winter
🫜 root vegetable food turnip radish
🪉 harp instrument music
🪏 shovel dig tool
🫟 splatter splash stain mess
🇨🇶 flag sark
🫪 distorted face anxiety shocked panic
🫯 fight cloud comic brawl dust
🫈 hairy creature sasquatch bigfoot
🧑‍🩰 ballet dancer dance ballerina
🫍 orca killer whale
🛘 landslide rockfall disaster
🪊 trombone instrument music
🪎 treasure chest gold loot pirate
@@ -1,18 +0,0 @@
#!/usr/bin/env bash
curr_workspace="$(hyprctl activeworkspace -j | jq -r ".id")"
dispatcher="$1"
shift ## The target is now in $1, not $2
if [[ -z "${dispatcher}" || "${dispatcher}" == "--help" || "${dispatcher}" == "-h" || -z "$1" ]]; then
echo "Usage: $0 <dispatcher> <target>"
exit 1
fi
if [[ "$1" == *"+"* || "$1" == *"-"* ]]; then ## Is this something like r+1 or -1?
hyprctl dispatch "${dispatcher}" "$1" ## $1 = workspace id since we shifted earlier.
elif [[ "$1" =~ ^[0-9]+$ ]]; then ## Is this just a number?
target_workspace=$((((curr_workspace - 1) / 10 ) * 10 + $1))
hyprctl dispatch "${dispatcher}" "${target_workspace}"
else
hyprctl dispatch "${dispatcher}" "$1" ## In case the target in a string, required for special workspaces.
exit 1
fi
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
# Controls Hyprland's cursor zoom_factor, clamped between 1.0 and 3.0
# Get current zoom level
get_zoom() {
hyprctl getoption -j cursor:zoom_factor | jq '.float'
}
# Clamp a value between 1.0 and 3.0
clamp() {
local val="$1"
awk "BEGIN {
v = $val;
if (v < 1.0) v = 1.0;
if (v > 3.0) v = 3.0;
print v;
}"
}
# Set zoom level
set_zoom() {
local value="$1"
clamped=$(clamp "$value")
hyprctl keyword cursor:zoom_factor "$clamped"
}
case "$1" in
reset)
set_zoom 1.0
;;
increase)
if [[ -z "$2" ]]; then
echo "Usage: $0 increase STEP"
exit 1
fi
current=$(get_zoom)
new=$(awk "BEGIN { print $current + $2 }")
set_zoom "$new"
;;
decrease)
if [[ -z "$2" ]]; then
echo "Usage: $0 decrease STEP"
exit 1
fi
current=$(get_zoom)
new=$(awk "BEGIN { print $current - $2 }")
set_zoom "$new"
;;
*)
echo "Usage: $0 {reset|increase STEP|decrease STEP}"
exit 1
;;
esac
@@ -0,0 +1,29 @@
require("hyprland/lib")
hl.on("hyprland.start", function()
local homeDir = os.getenv("HOME")
if string.len(homeDir) == 0 then
return
end
local baseCustomDir = homeDir .. "/.config/hypr/custom"
local files = {
baseCustomDir .. "/env.lua",
baseCustomDir .. "/execs.lua",
baseCustomDir .. "/general.lua",
baseCustomDir .. "/keybinds.lua",
baseCustomDir .. "/rules.lua",
baseCustomDir .. "/variables.lua"
}
local createdFiles = 0
for _, file in ipairs(files) do
if not is_file_exists(file) then
create_if_not_exists(file)
createdFiles = createdFiles + 1
end
end
if createdFiles > 0 then
-- hl.exec_cmd("notify-send 'Hyprland config' 'Created " .. createdFiles .. " custom Hyprland config files in " .. baseCustomDir .. "' -a 'Hyprland'")
-- hl.exec_cmd("hyprctl reload")
end
end)
@@ -0,0 +1 @@
require("hyprland/services/create_custom_config")
@@ -0,0 +1,2 @@
-- DO NOT EDIT THIS FILE. IT IS MANAGED BY THE SHELL AND FOLLOWS STRICT RULES
-- In other words, I ain't writing a lua parser for this, so please be a good boi/girl/whatever
-23
View File
@@ -1,23 +0,0 @@
# Default variables
# Copy these to ~/.config/hypr/custom/variables.conf to make changes in a dotfiles-update-friendly manner
# Apps
# PULL REQUESTS ADDING MORE WILL NOT BE ACCEPTED, CONFIG FOR YOURSELF
$terminal = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm"
$fileManager = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "kitty -1 fish -c yazi"
$browser = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "google-chrome-stable" "zen-browser" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" "librewolf"
$codeEditor = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "antigravity" "code" "codium" "cursor" "zed" "zedit" "zeditor" "kate" "gnome-text-editor" "emacs" "command -v nvim && kitty -1 nvim" "command -v micro && kitty -1 micro"
$officeSoftware = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "wps" "onlyoffice-desktopeditors" "libreoffice"
$textEditor = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kate" "gnome-text-editor" "emacs"
$volumeMixer = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "pavucontrol-qt" "pavucontrol"
$settingsApp = XDG_CURRENT_DESKTOP=gnome ~/.config/hypr/hyprland/scripts/launch_first_available.sh "qs -p ~/.config/quickshell/$qsConfig/settings.qml" "systemsettings" "gnome-control-center" "better-control"
$taskManager = ~/.config/hypr/hyprland/scripts/launch_first_available.sh "gnome-system-monitor" "plasma-systemmonitor --page-name Processes" "command -v btop && kitty -1 fish -c btop"
# The folder within ~/.config/quickshell containing the config
$qsConfig = ii
# Leave blank like this to load default config. Set to anything to not.
$dontLoadDefaultExecs =
$dontLoadDefaultGeneral =
$dontLoadDefaultRules =
$dontLoadDefaultKeybinds =
+19
View File
@@ -0,0 +1,19 @@
-- Default variables
-- Copy these to ~/.config/hypr/custom/variables.lua to make changes in a dotfiles-update-friendly manner
-- The folder within ~/.config/quickshell containing the config
hl.env("qsConfig", "ii")
-- Apps
-- PULL REQUESTS ADDING MORE WILL NOT BE ACCEPTED, CONFIG FOR YOURSELF
terminal = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'foot' 'kitty -1' 'alacritty' 'wezterm' 'konsole' 'kgx' 'uxterm' 'xterm'"
fileManager = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'dolphin' 'nautilus' 'nemo' 'thunar' 'kitty -1 fish -c yazi'"
browser = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'google-chrome-stable' 'zen-browser' 'firefox' 'brave' 'chromium' 'microsoft-edge-stable' 'opera' 'librewolf'"
codeEditor = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'windsurf' 'antigravity' 'code' 'codium' 'cursor' 'zed' 'zedit' 'zeditor' 'kate' 'gnome-text-editor' 'emacs' 'command -v nvim && kitty -1 nvim' 'command -v micro && kitty -1 micro'"
officeSoftware = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'wps' 'onlyoffice-desktopeditors' 'libreoffice'"
textEditor = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'kate' 'gnome-text-editor' 'emacs'"
volumeMixer = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'pavucontrol-qt' 'pavucontrol'"
settingsApp = "XDG_CURRENT_DESKTOP=gnome ~/.config/hypr/hyprland/scripts/launch_first_available.sh 'qs -p ~/.config/quickshell/$qsConfig/settings.qml' 'systemsettings' 'gnome-control-center' 'better-control'"
taskManager = "~/.config/hypr/hyprland/scripts/launch_first_available.sh 'gnome-system-monitor' 'plasma-systemmonitor --page-name Processes' 'command -v btop && kitty -1 fish -c btop'"
workspaceGroupSize = 10
-4
View File
@@ -1,4 +0,0 @@
# This file is to be overwritten by nwg-displays if you choose to use it.
# nwg-displays is a graphical tool for managing monitors.
# - Installation for Arch Linux: sudo pacman -S nwg-displays
# - Repo: https://github.com/nwg-piotr/nwg-displays
-4
View File
@@ -1,4 +0,0 @@
# This file is to be overwritten by nwg-displays if you choose to use it.
# nwg-displays is a graphical tool for managing monitors.
# - Installation for Arch Linux: sudo pacman -S nwg-displays
# - Repo: https://github.com/nwg-piotr/nwg-displays
+2 -2
View File
@@ -6,8 +6,8 @@ input_path = '~/.config/matugen/templates/colors.json'
output_path = '~/.local/state/quickshell/user/generated/colors.json'
[templates.hyprland]
input_path = '~/.config/matugen/templates/hyprland/colors.conf'
output_path = '~/.config/hypr/hyprland/colors.conf'
input_path = '~/.config/matugen/templates/hyprland/colors.lua'
output_path = '~/.config/hypr/hyprland/colors.lua'
[templates.hyprlock]
input_path = '~/.config/matugen/templates/hyprland/hyprlock-colors.conf'
@@ -1,32 +0,0 @@
general {
col.active_border = rgba({{colors.outline_variant.default.hex_stripped}}77)
col.inactive_border = rgba({{colors.surface_container_low.default.hex_stripped}}33)
}
misc {
background_color = rgba({{colors.surface.dark.hex_stripped}}FF)
}
plugin {
hyprbars {
# Honestly idk if it works like css, but well, why not
bar_text_font = Google Sans Flex Medium, Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif
bar_height = 30
bar_padding = 10
bar_button_padding = 5
bar_precedence_over_border = true
bar_part_of_window = true
bar_color = rgba({{colors.background.default.hex_stripped}}FF)
col.text = rgba({{colors.on_background.default.hex_stripped}}FF)
# example buttons (R -> L)
# hyprbars-button = color, size, on-click
hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖭, hyprctl dispatch killactive
hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖯, hyprctl dispatch fullscreen 1
hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special
}
}
windowrule = border_color rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77), match:pin 1
@@ -0,0 +1,16 @@
hl.config({
general = {
col = {
active_border = "rgba({{colors.outline_variant.default.hex_stripped}}77)",
inactive_border = "rgba({{colors.surface_container_low.default.hex_stripped}}33)",
},
},
misc = {
background_color = "rgba({{colors.surface.dark.hex_stripped}}FF)",
},
})
hl.window_rule({
match = { pin = 1 },
border_color = "rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77)",
})
+152 -140
View File
@@ -1,160 +1,172 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import Quickshell
import Quickshell.Wayland
Scope {
id: root
property bool failed;
property string errorString;
id: root
property bool failed
property string errorString
property real progressHeight: 3
// Connect to the Quickshell global to listen for the reload signals.
Connections {
target: Quickshell
// Connect to the Quickshell global to listen for the reload signals.
Connections {
target: Quickshell
function onReloadCompleted() {
root.failed = false;
popupLoader.loading = true;
}
function onReloadCompleted() {
root.failed = false;
popupLoader.loading = true;
}
function onReloadFailed(error: string) {
// Close any existing popup before making a new one.
popupLoader.active = false;
function onReloadFailed(error: string) {
// Close any existing popup before making a new one.
popupLoader.active = false;
root.failed = true;
root.errorString = error;
popupLoader.loading = true;
}
}
root.failed = true;
root.errorString = error;
popupLoader.loading = true;
}
}
// Keep the popup in a loader because it isn't needed most of the time
LazyLoader {
id: popupLoader
// Keep the popup in a loader because it isn't needed most of the time
LazyLoader {
id: popupLoader
PanelWindow {
id: popup
PanelWindow {
id: popup
exclusiveZone: 0
anchors.top: true
margins.top: 0
exclusiveZone: 0
anchors.top: true
margins.top: 0
implicitWidth: rect.width + shadow.radius * 2
implicitHeight: rect.height + shadow.radius * 2
implicitWidth: rect.width + 8 * 2
implicitHeight: rect.height + 8 * 2
WlrLayershell.namespace: "quickshell:reloadPopup"
WlrLayershell.namespace: "quickshell:reloadPopup"
// color blending is a bit odd as detailed in the type reference.
color: "transparent"
// color blending is a bit odd as detailed in the type reference.
color: "transparent"
Rectangle {
id: rect
anchors.centerIn: parent
color: failed ? "#ffe99195" : "#ffD1E8D5"
implicitHeight: layout.implicitHeight + 30
implicitWidth: layout.implicitWidth + 30
radius: 12
// Fills the whole area of the rectangle, making any clicks go to it,
// which dismiss the popup.
MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: {
popupLoader.active = false
}
// makes the mouse area track mouse hovering, so the hide animation
// can be paused when hovering.
hoverEnabled: true
}
ColumnLayout {
id: layout
spacing: 10
anchors {
top: parent.top
topMargin: 10
horizontalCenter: parent.horizontalCenter
}
Text {
renderType: Text.NativeRendering
font.family: "Google Sans Flex"
font.pointSize: 14
text: root.failed ? "Quickshell: Reload failed" : "Quickshell reloaded"
color: failed ? "#ff93000A" : "#ff0C1F13"
}
Text {
renderType: Text.NativeRendering
font.family: "JetBrains Mono NF"
font.pointSize: 11
text: root.errorString
color: failed ? "#ff93000A" : "#ff0C1F13"
// When visible is false, it also takes up no space.
visible: root.errorString != ""
}
}
// A progress bar on the bottom of the screen, showing how long until the
// popup is removed.
Rectangle {
z: 2
id: bar
color: failed ? "#ff93000A" : "#ff0C1F13"
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 10
height: 5
radius: 9999
PropertyAnimation {
id: anim
target: bar
property: "width"
from: rect.width - bar.anchors.margins * 2
to: 0
duration: failed ? 10000 : 1000
onFinished: popupLoader.active = false
// Pause the animation when the mouse is hovering over the popup,
// so it stays onscreen while reading. This updates reactively
// when the mouse moves on and off the popup.
paused: mouseArea.containsMouse
}
}
// Its bg
Rectangle {
z: 1
id: bar_bg
color: failed ? "#30af1b25" : "#4027643e"
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 10
height: 5
radius: 9999
width: rect.width - bar.anchors.margins * 2
}
// We could set `running: true` inside the animation, but the width of the
// rectangle might not be calculated yet, due to the layout.
// In the `Component.onCompleted` event handler, all of the component's
// properties and children have been initialized.
Component.onCompleted: anim.start()
}
DropShadow {
id: shadow
RectangularShadow {
anchors.fill: rect
horizontalOffset: 0
verticalOffset: 2
radius: 6
samples: radius * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs
color: "#44000000"
source: rect
radius: rect.radius
blur: 6.3
offset: Qt.vector2d(0.0, 1.0)
spread: 1
color: "#55000000"
}
}
}
Rectangle {
id: rect
anchors.centerIn: parent
color: root.failed ? "#ffe99195" : "#ffD1E8D5"
implicitHeight: layout.implicitHeight + 30
implicitWidth: layout.implicitWidth + 30
radius: 8
// Fills the whole area of the rectangle, making any clicks go to it,
// which dismiss the popup.
MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: {
popupLoader.active = false;
}
// makes the mouse area track mouse hovering, so the hide animation
// can be paused when hovering.
hoverEnabled: true
}
ColumnLayout {
id: layout
spacing: 10
anchors {
top: parent.top
topMargin: 10
horizontalCenter: parent.horizontalCenter
}
Text {
id: title
renderType: Text.NativeRendering
font.family: "Google Sans Flex"
font.pointSize: 14
text: root.failed ? "Quickshell: Reload failed" : "Quickshell reloaded"
color: root.failed ? "#ff93000A" : "#ff0C1F13"
}
Text {
id: info
renderType: Text.NativeRendering
font.family: "JetBrains Mono NF"
font.pointSize: 11
text: root.errorString
color: root.failed ? "#ff93000A" : "#ff0C1F13"
// When visible is false, it also takes up no space.
visible: root.errorString != ""
}
}
// A progress bar on the bottom of the screen, showing how long until the
// popup is removed.
Rectangle {
id: bar
z: 2
color: root.failed ? "#ff93000A" : "#ff0C1F13"
property real maxWidth: Math.max(title.width, info.width)
anchors {
left: parent.left
leftMargin: (parent.width - maxWidth) / 2
bottom: parent.bottom
bottomMargin: 10
}
height: root.progressHeight
radius: 9999
PropertyAnimation {
id: anim
target: bar
property: "width"
from: Math.max(title.width, info.width)
to: 0
duration: root.failed ? 10000 : 1000
onFinished: popupLoader.active = false
// Pause the animation when the mouse is hovering over the popup,
// so it stays onscreen while reading. This updates reactively
// when the mouse moves on and off the popup.
paused: mouseArea.containsMouse
}
}
// Its bg
Rectangle {
id: bar_bg
z: 1
color: root.failed ? "#30af1b25" : "#4027643e"
property real maxWidth: Math.max(title.width, info.width)
anchors {
left: parent.left
right: parent.right
leftMargin: (parent.width - maxWidth) / 2
rightMargin: anchors.leftMargin
bottom: parent.bottom
bottomMargin: 10
}
height: root.progressHeight
radius: 9999
width: bar.width
}
// We could set `running: true` inside the animation, but the width of the
// rectangle might not be calculated yet, due to the layout.
// In the `Component.onCompleted` event handler, all of the component's
// properties and children have been initialized.
Component.onCompleted: anim.start()
}
}
}
}
@@ -224,7 +224,7 @@ Singleton {
}
property QtObject variableAxes: QtObject {
property var main: ({
"wght": 450,
"wght": 500,
"wdth": 100,
})
property var numbers: ({
@@ -3,7 +3,9 @@ pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import qs.modules.common.functions
import "functions"
import "config"
Singleton {
id: root
@@ -13,6 +15,8 @@ Singleton {
property int readWriteDelay: 50 // milliseconds
property bool blockWrites: false
signal reloaded()
function setNestedValue(nestedKey, value) {
let keys = nestedKey.split(".");
let obj = root.options;
@@ -48,7 +52,7 @@ Singleton {
interval: root.readWriteDelay
repeat: false
onTriggered: {
configFileView.reload()
configFileView.reload();
}
}
@@ -57,7 +61,7 @@ Singleton {
interval: root.readWriteDelay
repeat: false
onTriggered: {
configFileView.writeAdapter()
configFileView.writeAdapter();
}
}
@@ -68,7 +72,10 @@ Singleton {
blockWrites: root.blockWrites
onFileChanged: fileReloadTimer.restart()
onAdapterUpdated: fileWriteTimer.restart()
onLoaded: root.ready = true
onLoaded: {
if (!root.ready) root.reloaded()
root.ready = true
}
onLoadFailed: error => {
if (error == FileViewError.FileNotFound) {
writeAdapter();
@@ -152,8 +159,8 @@ Singleton {
property JsonObject apps: JsonObject {
property string bluetooth: "kcmshell6 kcm_bluetooth"
property string changePassword: "kitty -1 --hold=yes fish -i -c 'passwd'"
property string network: "kcmshell6 kcm_networkmanagement"
property string manageUser: "kcmshell6 kcm_users"
property string network: "kcmshell6 kcm_networkmanagement"
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
property string taskManager: "plasma-systemmonitor --page-name Processes"
property string terminal: "kitty -1" // This is only for shell actions
@@ -238,9 +245,15 @@ Singleton {
property bool floatStyleShadow: true // Show shadow behind bar when cornerStyle == 1 (Float)
property bool borderless: false // true for no grouping of items
property string topLeftIcon: "spark" // Options: "distro" or any icon name in ~/.config/quickshell/ii/assets/icons
property list<string> screenList: [] // List of names, like "eDP-1", find out with 'hyprctl monitors' command
property bool showBackground: true
property bool verbose: true
property bool vertical: false
property JsonObject indicators: JsonObject {
property JsonObject notifications: JsonObject {
property bool showUnreadCount: false
}
}
property JsonObject resources: JsonObject {
property bool alwaysShowSwap: true
property bool alwaysShowCpu: true
@@ -248,7 +261,9 @@ Singleton {
property int swapWarningThreshold: 85
property int cpuWarningThreshold: 90
}
property list<string> screenList: [] // List of names, like "eDP-1", find out with 'hyprctl monitors' command
property JsonObject tooltips: JsonObject {
property bool clickToShow: false
}
property JsonObject utilButtons: JsonObject {
property bool showScreenSnip: true
property bool showColorPicker: false
@@ -258,6 +273,13 @@ Singleton {
property bool showPerformanceProfileToggle: false
property bool showScreenRecord: false
}
property JsonObject weather: JsonObject {
property bool enable: false
property bool enableGPS: true // gps based location
property string city: "" // When 'enableGPS' is false
property bool useUSCS: false // Instead of metric (SI) units
property int fetchInterval: 10 // minutes
}
property JsonObject workspaces: JsonObject {
property bool monochromeIcons: true
property int shown: 10
@@ -267,21 +289,6 @@ Singleton {
property list<string> numberMap: ["1", "2"] // Characters to show instead of numbers on workspace indicator
property bool useNerdFont: false
}
property JsonObject weather: JsonObject {
property bool enable: false
property bool enableGPS: true // gps based location
property string city: "" // When 'enableGPS' is false
property bool useUSCS: false // Instead of metric (SI) units
property int fetchInterval: 10 // minutes
}
property JsonObject indicators: JsonObject {
property JsonObject notifications: JsonObject {
property bool showUnreadCount: false
}
}
property JsonObject tooltips: JsonObject {
property bool clickToShow: false
}
}
property JsonObject battery: JsonObject {
@@ -293,7 +300,10 @@ Singleton {
}
property JsonObject calendar: JsonObject {
property string locale: "en-GB"
property string locale: "C"
property bool force2CharDayOfWeek: true
property bool animate: false // Disabled by default cuz laggy
property bool weekScrollPrecision: false // One scroll advances 1 week instead of 1 month
}
property JsonObject cheatsheet: JsonObject {
@@ -341,7 +351,8 @@ Singleton {
property int mouseScrollFactor: 120
property int touchpadScrollFactor: 450
}
property JsonObject deadPixelWorkaround: JsonObject { // Hyprland leaves out 1 pixel on the right for interactions
property JsonObject deadPixelWorkaround: JsonObject {
// Hyprland leaves out 1 pixel on the right for interactions
property bool enable: false
}
}
@@ -356,7 +367,7 @@ Singleton {
}
property JsonObject launcher: JsonObject {
property list<string> pinnedApps: [ "org.kde.dolphin", "kitty", "cmake-gui"]
property list<string> pinnedApps: ["org.kde.dolphin", "kitty", "cmake-gui"]
}
property JsonObject light: JsonObject {
@@ -399,6 +410,10 @@ Singleton {
property JsonObject notifications: JsonObject {
property int timeout: 7000
property JsonObject forceMonitor: JsonObject {
property bool enable: false
property string name: "" // Name of the monitor to show notifications on, like "eDP-1". Find out with 'hyprctl monitors' command
}
}
property JsonObject osd: JsonObject {
@@ -461,7 +476,7 @@ Singleton {
property bool monochromeIcons: true
property bool showItemId: false
property bool invertPinnedItems: true // Makes the below a whitelist for the tray and blacklist for the pinned area
property list<var> pinnedItems: [ "Fcitx" ]
property list<var> pinnedItems: ["Fcitx"]
property bool filterPassive: true
}
@@ -525,12 +540,30 @@ Singleton {
property JsonObject android: JsonObject {
property int columns: 5
property list<var> toggles: [
{ "size": 2, "type": "network" },
{ "size": 2, "type": "bluetooth" },
{ "size": 1, "type": "idleInhibitor" },
{ "size": 1, "type": "mic" },
{ "size": 2, "type": "audio" },
{ "size": 2, "type": "nightLight" }
{
"size": 2,
"type": "network"
},
{
"size": 2,
"type": "bluetooth"
},
{
"size": 1,
"type": "idleInhibitor"
},
{
"size": 1,
"type": "mic"
},
{
"size": 2,
"type": "audio"
},
{
"size": 2,
"type": "nightLight"
}
]
}
}
@@ -544,7 +577,7 @@ Singleton {
}
property JsonObject screenRecord: JsonObject {
property string savePath: Directories.videos.replace("file://","") // strip "file://"
property string savePath: Directories.videos.replace("file://", "") // strip "file://"
}
property JsonObject screenSnip: JsonObject {
@@ -578,11 +611,11 @@ Singleton {
property int adviseUpdateThreshold: 75 // packages
property int stronglyAdviseUpdateThreshold: 200 // packages
}
property JsonObject wallpaperSelector: JsonObject {
property bool useSystemFileDialog: false
}
property JsonObject windows: JsonObject {
property bool showTitlebar: true // Client-side decoration for shell apps
property bool centerTitle: true
@@ -604,26 +637,8 @@ Singleton {
}
}
property JsonObject waffles: JsonObject {
// Some spots are kinda janky/awkward. Setting the following to
// false will make (some) stuff also be like that for accuracy.
// Example: the right-click menu of the Start button
property JsonObject tweaks: JsonObject {
property bool switchHandlePositionFix: true
property bool smootherMenuAnimations: true
property bool smootherSearchBar: true
}
property JsonObject bar: JsonObject {
property bool bottom: true
property bool leftAlignApps: false
}
property JsonObject actionCenter: JsonObject {
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "nightLight", "darkMode", "antiFlashbang", "cloudflareWarp", "mic", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
}
property JsonObject calendar: JsonObject {
property bool force2CharDayOfWeek: true
}
}
property JsonObject hefty: HeftyConfig {}
property JsonObject waffles: WaffleConfig {}
}
}
}
@@ -20,7 +20,8 @@ Singleton {
readonly property string music: StandardPaths.standardLocations(StandardPaths.MusicLocation)[0]
readonly property string videos: StandardPaths.standardLocations(StandardPaths.MoviesLocation)[0]
// Other dirs used by the shell, without "file://"
/////// Stuff below are without "file://" /////////
// General
property string assetsPath: Quickshell.shellPath("assets")
property string scriptPath: Quickshell.shellPath("scripts")
property string favicons: FileUtils.trimFileProtocol(`${Directories.cache}/media/favicons`)
@@ -30,9 +31,6 @@ Singleton {
property string booruDownloads: FileUtils.trimFileProtocol(Directories.pictures + "/homework")
property string booruDownloadsNsfw: FileUtils.trimFileProtocol(Directories.pictures + "/homework/🌶️")
property string latexOutput: FileUtils.trimFileProtocol(`${Directories.cache}/media/latex`)
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
property string shellConfigName: "config.json"
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
property string todoPath: FileUtils.trimFileProtocol(`${Directories.state}/user/todo.json`)
property string notesPath: FileUtils.trimFileProtocol(`${Directories.state}/user/notes.txt`)
property string conflictCachePath: FileUtils.trimFileProtocol(`${Directories.cache}/conflict-killer`)
@@ -43,24 +41,39 @@ Singleton {
property string screenshotTemp: "/tmp/quickshell/media/screenshot"
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
property string defaultAiPrompts: Quickshell.shellPath("defaults/ai/prompts")
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
property string userActions: FileUtils.trimFileProtocol(`${Directories.shellConfig}/actions`)
property string aiChats: FileUtils.trimFileProtocol(`${Directories.state}/user/ai/chats`)
property string aiTranslationScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/ai/gemini-translate.sh`)
property string recordScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/videos/record.sh`)
property string userAvatarPathAccountsService: FileUtils.trimFileProtocol(`/var/lib/AccountsService/icons/${SystemInfo.username}`)
property string userAvatarPathRicersAndWeirdSystems: FileUtils.trimFileProtocol(`${Directories.home}.face`)
property string userAvatarPathRicersAndWeirdSystems2: FileUtils.trimFileProtocol(`${Directories.home}.face.icon`)
// User
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
property string shellConfigName: "config.json"
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
property string userActions: FileUtils.trimFileProtocol(`${Directories.shellConfig}/actions`)
property string userComponents: FileUtils.trimFileProtocol(`${Directories.shellConfig}/components`)
// Cleanup on init
Component.onCompleted: {
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
Quickshell.execDetached(["mkdir", "-p", `${favicons}`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
Quickshell.execDetached(["mkdir", "-p", `${aiChats}`])
Quickshell.execDetached(["mkdir", "-p", `${userActions}`])
Quickshell.execDetached(["mkdir", "-p", `${favicons}`])
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
Quickshell.execDetached(["rm", "-rf", `${tempImages}`])
Quickshell.execDetached(["mkdir", "-p", `${userComponents}`])
Quickshell.execDetached(["mkdir", "-p", `${userAiPrompts}`])
Quickshell.execDetached(["mkdir", "-p", `${userActions}`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
}
Component.onDestruction: {
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
}
}
@@ -0,0 +1,21 @@
import QtQuick
import Quickshell
import Quickshell.Io
JsonObject {
property JsonObject bar: JsonObject {
property list<var> leftWidgets: ["HLeftSidebarButton", "HWindowInfo"]
property list<var> centerLeftWidgets: ["HTime"]
property list<var> centerWidgets: ["HWorkspaces"]
property list<var> centerRightWidgets: ["HResources"]
property list<var> rightWidgets: ["HSystemTray", "HSystemIndicators"]
property bool m3ExpressiveGrouping: true
property JsonObject resources: JsonObject {
property bool showMemory: false
property bool showRam: false
property bool showSwap: false
property bool showCpu: false
}
}
}
@@ -0,0 +1,21 @@
import QtQuick
import Quickshell
import Quickshell.Io
JsonObject {
// Some spots are kinda janky/awkward. Setting the following to
// false will make (some) stuff also be like that for accuracy.
// Example: the right-click menu of the Start button
property JsonObject tweaks: JsonObject {
property bool switchHandlePositionFix: true
property bool smootherMenuAnimations: true
property bool smootherSearchBar: true
}
property JsonObject bar: JsonObject {
property bool bottom: true
property bool leftAlignApps: false
}
property JsonObject actionCenter: JsonObject {
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "nightLight", "darkMode", "antiFlashbang", "cloudflareWarp", "mic", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
}
}
@@ -109,7 +109,8 @@ Singleton {
*/
function transparentize(color, percentage = 1) {
var c = Qt.color(color);
return Qt.rgba(c.r, c.g, c.b, c.a * (1 - percentage));
var a = c.a * (1 - clamp01(percentage));
return Qt.rgba(c.r, c.g, c.b, a);
}
/**
@@ -121,7 +122,7 @@ Singleton {
*/
function applyAlpha(color, alpha) {
var c = Qt.color(color);
var a = Math.max(0, Math.min(1, alpha));
var a = clamp01(alpha);
return Qt.rgba(c.r, c.g, c.b, a);
}
@@ -24,4 +24,19 @@ Singleton {
targetDate.setDate(firstDayDate.getDate() + i);
return targetDate;
}
function formatDuration(seconds) {
const d = Math.floor(seconds / 86400);
const h = Math.floor((seconds % 86400) / 3600);
const m = Math.floor((seconds % 3600) / 60);
let str = "";
if (d > 0)
str += `${d}d`;
if (h > 0)
str += `${str ? ", " : ""}${h}h`;
if (m > 0 || !str)
str += `${str ? ", " : ""}${m}m`;
return str;
}
}
@@ -0,0 +1,16 @@
pragma Singleton
import Quickshell
Singleton {
id: root
/**
* Rounds the given number to the nearest even integer.
*
* @param {number} num - The number to round.
* @returns {number} The nearest even integer.
*/
function roundToEven(num) {
return Math.round(num / 2) * 2;
}
}
@@ -95,4 +95,15 @@ Singleton {
}
}
}
function findParentWithProperty(obj, propertyName) {
let current = obj;
while (current) {
if (current.hasOwnProperty(propertyName)) {
return current;
}
current = current.parent;
}
return null;
}
}
@@ -4,7 +4,7 @@ import QtQuick
// The former animates faster than the latter, see the NumberAnimations below
QtObject {
id: root
required property int index
property int index
property real idx1: index
property real idx2: index
@@ -0,0 +1,63 @@
import QtQuick
import Quickshell.Wayland
import Quickshell.Hyprland
import qs.services
import qs.modules.common as C
NestableObject {
id: root
required property HyprlandMonitor monitor
readonly property var liveMonitorData: HyprlandData.monitors.find(m => m.id === monitor.id)
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
readonly property int activeWorkspace: monitor?.activeWorkspace?.id
readonly property bool currentWorkspaceNotFake: activeWindow?.activated ?? false // Active empty workspace = fake. At least, that's how I like to call it.
readonly property int fakeWorkspace: currentWorkspaceNotFake ? -9999 : activeWorkspace
readonly property int shownCount: C.Config.options.bar.workspaces.shown
readonly property int group: Math.floor((activeWorkspace - 1) / shownCount)
readonly property var specialWorkspace: liveMonitorData?.specialWorkspace
readonly property string specialWorkspaceName: specialWorkspace.name.replace("special:", "")
readonly property bool specialWorkspaceActive: specialWorkspaceName !== ""
property list<bool> occupied: []
property list<var> biggestWindow: occupied.map((_, index) => {
const wsId = getWorkspaceIdAt(index);
var biggestWindow = HyprlandData.biggestWindowForWorkspace(wsId);
return biggestWindow;
})
function getWorkspaceId(group, index) {
return group * root.shownCount + index + 1;
}
function getWorkspaceIdAt(index) {
return root.getWorkspaceId(root.group, index);
}
// Function to update workspaceOccupied
function updateWorkspaceOccupied() {
root.occupied = Array.from({
length: root.shownCount
}, (_, i) => {
const thisWorkspaceId = getWorkspaceId(root.group, i);
return Hyprland.workspaces.values.some(ws => ws.id === thisWorkspaceId);
});
}
// Occupied workspace updates
Component.onCompleted: updateWorkspaceOccupied()
Connections {
target: Hyprland.workspaces
function onValuesChanged() {
root.updateWorkspaceOccupied();
}
}
Connections {
target: Hyprland
function onFocusedWorkspaceChanged() {
root.updateWorkspaceOccupied();
}
}
onGroupChanged: {
updateWorkspaceOccupied();
}
}
@@ -5,13 +5,13 @@ import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Anti-flashbang")
tooltipText: Translation.tr("Anti-flashbang")
icon: "flash_off"
name: HyprlandAntiFlashbangShader.enabled ? (HyprlandAntiFlashbangShader.weak ? Translation.tr("Anti-flash: Weak") : Translation.tr("Anti-flash: Strong")) : Translation.tr("Anti-flashbang")
tooltipText: `${Translation.tr("Anti-flashbang")}: ${HyprlandAntiFlashbangShader.enabled ? (HyprlandAntiFlashbangShader.weak ? Translation.tr("Weak") : Translation.tr("Strong")) : Translation.tr("Off")}`
icon: HyprlandAntiFlashbangShader.enabled ? (!HyprlandAntiFlashbangShader.weak ? "flash_off" : "sunny_snowing") : "flash_on"
toggled: HyprlandAntiFlashbangShader.enabled
mainAction: () => {
HyprlandAntiFlashbangShader.toggle()
HyprlandAntiFlashbangShader.cycle()
}
hasMenu: true
}
@@ -8,7 +8,7 @@ QuickToggleModel {
name: Translation.tr("Internet")
statusText: Network.networkName
tooltipText: Translation.tr("%1 | Right-click to configure").arg(Network.networkName)
icon: Network.materialSymbol
icon: Icons.getNetworkMaterialSymbol()
toggled: Network.wifiStatus !== "disabled"
mainAction: () => Network.toggleWifi()
@@ -74,9 +74,6 @@ Scope {
// Unlock the screen before exiting, or the compositor will display a
// fallback lock you can't interact with.
GlobalStates.screenLocked = false;
// Refocus last focused window on unlock (hack)
Quickshell.execDetached(["bash", "-c", `sleep 0.2; hyprctl --batch "dispatch togglespecialworkspace; dispatch togglespecialworkspace"`])
// Reset
lockContext.reset();
@@ -16,9 +16,20 @@ Process {
return StringUtils.shellSingleQuoteEscape(FileUtils.trimFileProtocol(filePath));
}
function processSourceUrl() {
return StringUtils.shellSingleQuoteEscape(sourceUrl);
}
function curlUserAgentArg() {
if (!downloadUserAgent) {
return "";
}
return ` -H 'User-Agent: ${StringUtils.shellSingleQuoteEscape(downloadUserAgent)}'`;
}
running: true
command: ["bash", "-c",
`mkdir -p $(dirname '${processFilePath()}'); [ -f '${processFilePath()}' ] || curl -sSL '${sourceUrl}' -o '${processFilePath()}' && file '${processFilePath()}'`
`mkdir -p $(dirname '${processFilePath()}'); [ -f '${processFilePath()}' ] || curl -sSL '${processSourceUrl()}'${curlUserAgentArg()} -o '${processFilePath()}' && file '${processFilePath()}'`
]
stdout: StdioCollector {
id: imageSizeOutputCollector
@@ -0,0 +1,19 @@
pragma ComponentBehavior: Bound
import QtQuick
import ".."
Item {
id: root
property real progress: 0
default property Item child
implicitWidth: child.implicitWidth
implicitHeight: child.implicitHeight
children: [child]
property var animation: Appearance.animation.elementMoveSmall.numberAnimation.createObject(this)
Behavior on progress {
animation: root.animation
}
}
@@ -0,0 +1,62 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
Control {
id: root
property list<real> valueWeights: [1]
property list<real> values: [0.5]
property list<color> valueHighlights: ["white"]
property list<color> valueTroughs: []
readonly property list<real> normalizedValueWeights: {
const totalWeight = valueWeights.reduce((sum, weight) => sum + weight, 0)
return valueWeights.map(weight => weight / totalWeight)
}
readonly property list<real> visualEnds: {
let cumsum = 0;
let positions = [];
for (let i = 0; i < normalizedValueWeights.length; i++) {
cumsum += normalizedValueWeights[i];
positions.push(cumsum);
}
return positions;
}
readonly property list<real> visualPositions: {
let positions = [];
let lastEnd = 0;
for(let i = 0; i < visualEnds.length; i++) {
const thisEnd = visualEnds[i];
const width = thisEnd - lastEnd;
const thisPos = lastEnd + width * values[i];
positions.push(thisPos);
lastEnd = visualEnds[i];
}
return positions;
}
readonly property list<var> visualSegments: {
let segs = [];
let lastEnd = 0;
for(let i = 0; i < visualEnds.length; i++) {
const thisEnd = visualEnds[i];
const thisPos = visualPositions[i];
segs.push([lastEnd, thisPos]);
segs.push([thisPos, thisEnd]);
lastEnd = visualEnds[i];
}
return segs;
}
readonly property list<color> segmentColors: {
var cols = [];
for(let i = 0; i < valueHighlights.length; i++) {
cols.push(valueHighlights[i]);
cols.push(valueTroughs[i]);
}
return cols;
}
}
@@ -0,0 +1,15 @@
import QtQuick
import org.kde.kirigami as Kirigami
import qs.services
import qs.modules.common
Kirigami.Icon {
id: root
property real implicitSize: 26
implicitWidth: implicitSize
implicitHeight: implicitSize
roundToIconSize: false
animated: true // It's just fading from one icon to another
}
@@ -0,0 +1,13 @@
pragma ComponentBehavior: Bound
import QtQuick
StyledRectangle {
property bool vertical: false
property real startRadius
property real endRadius
topLeftRadius: startRadius
topRightRadius: vertical ? startRadius : endRadius
bottomLeftRadius: vertical ? endRadius : startRadius
bottomRightRadius: endRadius
}
@@ -0,0 +1,12 @@
import QtQuick
RectangularContainerShape {
property bool vertical: false
property real startRadius
property real endRadius
topLeftRadius: startRadius
topRightRadius: vertical ? startRadius : endRadius
bottomLeftRadius: vertical ? endRadius : startRadius
bottomRightRadius: endRadius
}
@@ -0,0 +1,16 @@
pragma ComponentBehavior: Bound
import QtQuick
// A type that's both capable of being rows and columns
// Qt Row is just a locked down Grid smh
// Calling it a Box because that's how row-or-column widget is called in Gtk
Grid {
id: root
property bool vertical: false
columns: vertical ? 1 : -1
rows: vertical ? -1 : 1
property alias spacing: root.rowSpacing
columnSpacing: rowSpacing
}
@@ -0,0 +1,18 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
// Box, Layout version
// A type that's both capable of being rows and columns
// Qt Row is just a locked down Grid smh
// Calling it a Box because that's how row-or-column widget is called in Gtk
GridLayout {
id: root
property bool vertical: false
columns: vertical ? 1 : -1
rows: vertical ? -1 : 1
property alias spacing: root.rowSpacing
columnSpacing: rowSpacing
}
@@ -0,0 +1,9 @@
pragma ComponentBehavior: Bound
import QtQuick
// MouseArea that contains good defaults for buttons
MouseArea {
id: root
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
}
@@ -0,0 +1,36 @@
pragma ComponentBehavior: Bound
import QtQuick
/**
* Replacement for QtQuick Controls DayOfWeek row.
* I have to do this because that one is somehow really unreliable in my dynamically loaded widget
*/
Row {
id: root
property Component delegate
property alias model: repeater.model
property var locale: Qt.locale()
readonly property var firstDayOfWeek: locale.firstDayOfWeek
Repeater {
id: repeater
model: Array.from({
length: 7
}, (_, i) => {
const day = (root.firstDayOfWeek + i + 7 - 1) % 7 + 1
return ({
// Convert Locale day of week enum values to that of Qt enum values for
// consistency with DayOfWeekRow. Note that Locale day of week enum values are 0-indexed,
// while Qt day of week enum values are 1-indexed.
// Refererences:
// Locale enum values: https://doc.qt.io/qt-6/qml-qtqml-locale.html#firstDayOfWeek-prop
// DayOfWeek model values: https://doc.qt.io/qt-6/qml-qtquick-controls-dayofweekrow.html#delegate-prop
// which mentions the enum values in the Qt namespace at: https://doc.qt.io/qt-6/qt.html#DayOfWeek-enum
day: day,
shortName: root.locale.toString(new Date(2024, 0, day), "ddd")
})
})
delegate: root.delegate
}
}
@@ -1,15 +1,10 @@
pragma ComponentBehavior: Bound
import QtQml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import qs.modules.waffle.looks
Item {
id: root
@@ -36,15 +31,23 @@ Item {
const diffWeeks = Math.round(diffMillis / root.millisPerWeek);
root.targetWeekDiff += diffWeeks;
}
function scrollToToday() {
root.targetWeekDiff = 0;
}
property int weeksPerScroll: 1
property real targetWeekDiff: 0
property real weekDiff: targetWeekDiff
property int contentWeekDiff: weekDiff // whole part of weekDiff
property bool scrolling: false
property Animation scrollAnimation: NumberAnimation {
duration: Config.options.calendar.animate ? Appearance.animation.scroll.duration : 0
easing.type: Appearance.animation.scroll.type
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
}
Behavior on weekDiff {
id: weekScrollBehavior
animation: Looks.transition.scroll.createObject(this)
animation: root.scrollAnimation
}
Timer {
id: scrollAnimationCheckTimer
@@ -56,12 +59,20 @@ Item {
scrollAnimationCheckTimer.restart();
}
MouseArea {
anchors.fill: parent
onWheel: wheel => {
root.targetWeekDiff += wheel.angleDelta.y / 120 * -root.weeksPerScroll; // Reverse cuz scrolling down should advance
property var wheelAction: (wheel) => {
// Reverse cuz scrolling down should advance
const sign = wheel.angleDelta.y / 120 * -1;
if (Config.options.calendar.weekScrollPrecision) {
root.targetWeekDiff += sign * root.weeksPerScroll;
} else {
scrollMonthsAndSnap(sign);
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
onWheel: (wheel) => root.wheelAction(wheel)
}
// Date calculations
readonly property int millisPerWeek: 7 * 24 * 60 * 60 * 1000
@@ -82,14 +93,16 @@ Item {
return DateUtils.getIthDayDateOfSameWeek(dateInTargetWeek, root.focusDayOfWeekIndex - root.locale.firstDayOfWeek, root.locale.firstdayOfWeek); // 4 = Thursday
}
property int focusedMonth: focusedDate.getMonth() + 1 // 0-indexed -> 1-indexed
property string title: locale.toString(focusedDate, "MMMM yyyy")
// Sizes
property real verticalPadding: 0
property real horizontalPadding: 0
property real buttonSize: 40
property real buttonSpacing: 2
property real buttonVerticalSpacing: buttonSpacing
implicitHeight: (6 * buttonSize) + (5 * buttonVerticalSpacing) + (2 * verticalPadding)
implicitWidth: weeksColumn.implicitWidth
implicitWidth: weeksColumn.implicitWidth + (2 * horizontalPadding)
clip: true
ColumnLayout {
@@ -97,6 +110,8 @@ Item {
anchors {
left: parent.left
right: parent.right
leftMargin: root.horizontalPadding
rightMargin: root.horizontalPadding
}
y: {
const spacePerExtraRow = root.buttonSize + root.buttonVerticalSpacing;
@@ -0,0 +1,41 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
GridLayout {
id: root
columns: 1
property real totalDuration: 250
property real interval: totalDuration / count
property list<QtObject> choreographableChildren: children.filter(c => {
return c.hasOwnProperty("progress")
})
readonly property int count: choreographableChildren.length
property bool shown: false
onShownChanged: {
// When hiding, hide all at once
if (!shown) {
for (var i = 0; i < count; i++) {
choreographableChildren[i].progress = 0;
}
}
// When showing, choreograph
root.choreographIndex = 0;
}
property int choreographIndex: count
Timer {
id: choreographTimer
interval: root.interval
property bool step: root.shown && root.choreographIndex < root.count
running: step
repeat: step
onTriggered: {
const index = root.choreographIndex;
root.choreographableChildren[index].progress = 1;
root.choreographIndex++;
}
}
}
@@ -0,0 +1,7 @@
pragma ComponentBehavior: Bound
import QtQuick
FadeLoader {
id: root
onActiveChanged: if (active) item.shown = true
}
@@ -1,7 +1,7 @@
import QtQuick
Rectangle {
property double diameter
property real diameter
implicitWidth: diameter
implicitHeight: diameter
@@ -42,8 +42,7 @@ Item {
active: root.fill
anchors.fill: parent
sourceComponent: Rectangle {
radius: 9999
sourceComponent: Circle {
color: root.colSecondary
}
}
@@ -3,7 +3,7 @@ import qs.modules.common.functions
import qs.modules.common.widgets
import QtQuick
import QtQuick.Controls
import Qt5Compat.GraphicalEffects
import QtQuick.Effects
/**
* A progress bar with both ends rounded and text acts as clipping like OneUI 7's battery indicator.
@@ -16,15 +16,17 @@ ProgressBar {
property color highlightColor: Appearance?.colors.colOnSecondaryContainer ?? "#685496"
property color trackColor: ColorUtils.transparentize(highlightColor, 0.5) ?? "#F1D3F9"
property alias radius: contentItem.radius
property alias progressRadius: progressFill.radius
property string text
default property Item textMask: Item {
width: valueBarWidth
height: valueBarHeight
StyledText {
anchors.centerIn: parent
width: root.valueBarWidth
height: root.valueBarHeight
VisuallyCenteredStyledText {
anchors.fill: parent
font: root.font
text: root.text
}
layer.enabled: true
}
text: Math.round(value * 100)
@@ -38,10 +40,9 @@ ProgressBar {
implicitWidth: valueBarWidth
}
contentItem: Rectangle {
contentItem: Pill {
id: contentItem
anchors.fill: parent
radius: 9999
color: root.trackColor
visible: false
@@ -80,22 +81,40 @@ ProgressBar {
}
}
OpacityMask {
id: roundingMask
Rectangle {
id: contentMaskRect
anchors.fill: contentItem
width: contentItem.width
height: contentItem.height
radius: contentItem.radius
layer.enabled: true
visible: false
anchors.fill: parent
source: contentItem
maskSource: Rectangle {
width: contentItem.width
height: contentItem.height
radius: contentItem.radius
}
}
OpacityMask {
anchors.fill: parent
source: roundingMask
invert: true
maskSource: root.textMask
Item {
// textMask has to be rendered somewhere so we put it in a practically invisible item
anchors.centerIn: parent
opacity: 0
Component.onCompleted: root.textMask.layer.enabled = true // for multieffect masking
children: [root.textMask]
}
MaskMultiEffect {
id: boxClip
anchors.fill: parent
source: contentItem
maskSource: contentMaskRect
visible: false
}
MaskMultiEffect {
id: textClip
anchors.fill: parent
implicitWidth: contentItem.implicitWidth
implicitHeight: contentItem.implicitHeight
source: boxClip
maskSource: root.textMask
maskInverted: true
}
}
@@ -0,0 +1,14 @@
import QtQuick
import QtQuick.Effects
import qs.modules.common
MultiEffect {
property color sourceColor: "black"
colorization: 1
brightness: 1 - sourceColor.hslLightness
Behavior on colorizationColor {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
@@ -0,0 +1,75 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Shapes
import qs.modules.common
AbstractCombinedProgressBar {
id: root
property int implicitSize: 30
property int lineWidth: 2
property real gapAngle: 360 / 18
valueHighlights: [Appearance.colors.colPrimary, Appearance.colors.colTertiary]
valueTroughs: [Appearance.colors.colSecondaryContainer, Appearance.colors.colTertiaryContainer]
property bool enableAnimation: true
property int animationDuration: 800
property var easingType: Easing.OutCubic
implicitWidth: implicitSize
implicitHeight: implicitSize
readonly property real centerX: root.width / 2
readonly property real centerY: root.height / 2
readonly property real arcRadius: root.implicitSize / 2 - root.lineWidth
readonly property real startAngle: -90
background: Item {
implicitWidth: root.implicitSize
implicitHeight: root.implicitSize
}
function isNegligibleSegment(seg: var): bool {
const range = seg[1] - seg[0];
return range < 1 / 360; // TODO make this less arbitrary
}
Repeater {
model: root.visualSegments
delegate: Shape {
id: segShape
required property int index
required property var modelData
property bool negligible: root.isNegligibleSegment(modelData)
property bool atStart: index == 0
property bool atEnd: index == root.visualSegments.length - 1
property real displaySegStart: {
var i = index;
while ((i > 0 && root.isNegligibleSegment(root.visualSegments[i - 1])))
i--;
return root.visualSegments[i][0];
}
anchors.fill: parent
layer.enabled: true
layer.smooth: true
preferredRendererType: Shape.CurveRenderer
ShapePath {
strokeColor: segShape.negligible ? "transparent" : root.segmentColors[segShape.index % root.segmentColors.length]
strokeWidth: segShape.negligible ? 0 : root.lineWidth
capStyle: ShapePath.RoundCap
fillColor: "transparent"
PathAngleArc {
centerX: root.centerX
centerY: root.centerY
radiusX: root.arcRadius
radiusY: root.arcRadius
startAngle: root.startAngle + 360 * segShape.displaySegStart + root.gapAngle / 2
sweepAngle: 360 * (segShape.modelData[1] - segShape.displaySegStart) - root.gapAngle
}
}
}
}
}
@@ -23,6 +23,10 @@ Flow {
]
property var currentValue: null
function focusSelectedChild() {
children.find(c => c.value == currentValue).forceActiveFocus()
}
signal selected(var newValue)
Repeater {
@@ -31,6 +35,7 @@ Flow {
id: paletteButton
required property var modelData
required property int index
readonly property var value: modelData.value
onYChanged: {
if (index === 0) {
paletteButton.leftmost = true
@@ -33,6 +33,7 @@ RippleButton {
}
StyledSwitch {
id: switchWidget
focusPolicy: Qt.NoFocus
down: root.down
Layout.fillWidth: false
checked: root.checked
@@ -0,0 +1,25 @@
import QtQuick
import Quickshell
import qs.modules.common
Item {
id: root
property alias load: loader.activeAsync
property bool shown: true // By default show immediately when loaded
property alias component: loader.component
property alias fade: opacityBehavior.enabled
property alias animation: opacityBehavior.animation
opacity: loader.active && shown ? 1 : 0
visible: opacity > 0
Behavior on opacity {
id: opacityBehavior
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
LazyLoader {
id: loader
}
}
@@ -0,0 +1,25 @@
import QtQuick
Loader {
id: root
property int fallbackIndex: 0
property list<url> fallbacks: []
property list<Component> fallbackComponents: []
onStatusChanged: {
if (status === Loader.Error && fallbackIndex < fallbacks.length) {
if (fallbacks[fallbackIndex]) {
source = fallbacks[fallbackIndex];
if (fallbackComponents[fallbackIndex]) {
console.warn("[FallbackLoader] Both fallbacks urls and components are set, using url fallback");
}
} else if (fallbackComponents[fallbackIndex]) {
sourceComponent = fallbackComponents[fallbackIndex];
} else {
console.error("[FallbackLoader] Out of fallbacks, tried all", fallbackIndex);
}
fallbackIndex += 1;
}
}
}
@@ -0,0 +1,16 @@
import QtQuick
Item {
id: root
property alias longestText: longestTextMetrics.text
property alias font: longestTextMetrics.font
implicitWidth: longestTextMetrics.width
implicitHeight: longestTextMetrics.height
TextMetrics {
id: longestTextMetrics
text: root.longestText
}
}
@@ -0,0 +1,26 @@
pragma ComponentBehavior: Bound
import QtQuick
AbstractChoreographable {
id: root
progress: 0
property bool vertical: true
property bool reverseDirection: false
property real distance: 15
readonly property real directionMultiplier: reverseDirection ? -1 : 1
Component.onCompleted: syncProgress()
onProgressChanged: syncProgress()
function syncProgress() {
const progressDistance = distance * (1 - progress) * directionMultiplier;
root.child.opacity = progress
if (vertical) {
root.child.y = progressDistance
} else {
root.child.x = progressDistance
}
}
}
@@ -42,6 +42,7 @@ Button {
property color colBackgroundToggled: Appearance?.colors.colPrimary ?? "#65558F"
property color colBackgroundToggledHover: Appearance?.colors.colPrimaryHover ?? "#77699C"
property color colBackgroundToggledActive: Appearance?.colors.colPrimaryActive ?? "#D6CEE2"
property color colFocusRing: Appearance.colors.colOnSecondaryContainer
property real radius: root.down ? root.buttonRadiusPressed : root.buttonRadius
property real leftRadius: root.down ? root.buttonRadiusPressed : root.buttonRadius
@@ -117,7 +118,6 @@ Button {
};
}
property bool tabbedTo: root.focus && (focusReason === Qt.TabFocusReason || focusReason === Qt.BacktabFocusReason)
background: Rectangle {
id: buttonBackground
topLeftRadius: root.leftRadius
@@ -130,9 +130,25 @@ Button {
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
border.width: root.tabbedTo ? 2 : 0
border.color: Appearance.colors.colSecondary
z: visualFocus ? 1 : 0
Rectangle {
id: focusRing
topLeftRadius: root.leftRadius - anchors.margins
topRightRadius: root.rightRadius - anchors.margins
bottomLeftRadius: root.leftRadius - anchors.margins
bottomRightRadius: root.rightRadius - anchors.margins
visible: root.visualFocus
color: "transparent"
anchors {
fill: parent
margins: -4
}
border {
color: root.colFocusRing
width: 2
}
}
contentItem: StyledText {
@@ -20,11 +20,12 @@ StyledText {
}
}
property Animation fillAnimation: NumberAnimation {
duration: Appearance?.animation.elementMoveFast.duration ?? 200
easing.type: Appearance?.animation.elementMoveFast.type ?? Easing.BezierSpline
easing.bezierCurve: Appearance?.animation.elementMoveFast.bezierCurve ?? [0.34, 0.80, 0.34, 1.00, 1, 1]
}
Behavior on fill { // Leaky leaky, no good
NumberAnimation {
duration: Appearance?.animation.elementMoveFast.duration ?? 200
easing.type: Appearance?.animation.elementMoveFast.type ?? Easing.BezierSpline
easing.bezierCurve: Appearance?.animation.elementMoveFast.bezierCurve ?? [0.34, 0.80, 0.34, 1.00, 1, 1]
}
animation: root.fillAnimation
}
}
@@ -85,7 +85,7 @@ MouseArea { // Notification group area
automaticallyReset: false
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
onPressed: {
onPressed: (mouse) => {
if (mouse.button === Qt.RightButton)
root.toggleExpanded();
}
@@ -153,7 +153,7 @@ Item { // Notification item area
implicitHeight: summaryText.implicitHeight
StyledText {
id: summaryText
Layout.fillWidth: summaryTextMetrics.width >= summaryRow.implicitWidth * root.summaryElideRatio
Layout.fillWidth: summaryTextMetrics.width >= root.width * root.summaryElideRatio
visible: !root.onlyNotification
font.pixelSize: root.fontSize
color: Appearance.colors.colOnLayer3
@@ -0,0 +1,5 @@
import QtQuick
Rectangle {
radius: Math.min(width, height) / 2
}
@@ -0,0 +1,91 @@
import QtQuick
import qs.modules.common.models as M
import "shapes/material-shapes.js" as MaterialShapes
import "shapes/shapes/corner-rounding.js" as CornerRounding
import "shapes/geometry/offset.js" as Offset
// For returning the points
M.NestableObject {
id: root
required property real width
required property real height
property real radius: 0
property real topLeftRadius: radius
property real topRightRadius: radius
property real bottomLeftRadius: radius
property real bottomRightRadius: radius
property real xOffset: 0
property real yOffset: 0
readonly property real radiusLimit: Math.min(width, height) / 2
readonly property real effectiveTopLeftRadius: Math.min(topLeftRadius, radiusLimit)
readonly property real effectiveTopRightRadius: Math.min(topRightRadius, radiusLimit)
readonly property real effectiveBottomLeftRadius: Math.min(bottomLeftRadius, radiusLimit)
readonly property real effectiveBottomRightRadius: Math.min(bottomRightRadius, radiusLimit)
// Clockwise starting from bottom
property list<var> bottomPoints: [
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width - effectiveBottomRightRadius, yOffset + height), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width / 2, yOffset + height), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + effectiveBottomLeftRadius, yOffset + height), new CornerRounding.CornerRounding(0)),
]
property list<var> leftPoints: [
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + 0, yOffset + height - effectiveBottomLeftRadius), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + 0, yOffset + height / 2), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + 0, yOffset + effectiveTopLeftRadius), new CornerRounding.CornerRounding(0)),
]
property list<var> topPoints: [
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + effectiveTopLeftRadius, yOffset + 0), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width / 2, yOffset + 0), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width - effectiveTopRightRadius, yOffset + 0), new CornerRounding.CornerRounding(0)),
]
property list<var> rightPoints: [
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width, yOffset + effectiveTopRightRadius), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width, yOffset + height / 2), new CornerRounding.CornerRounding(0)),
new MaterialShapes.PointNRound(new Offset.Offset(xOffset + width, yOffset + height - effectiveBottomRightRadius), new CornerRounding.CornerRounding(0)),
]
function getFirstBottomPoints() {
return bottomPoints.slice(Math.floor(bottomPoints.length / 2))
}
function getLastBottomPoints() {
return bottomPoints.slice(0, Math.floor(bottomPoints.length / 2))
}
function getBottomLeftPoint(extraXOffset = 0, extraYOffset = 0, radius = undefined) {
if (radius === undefined) radius = effectiveBottomLeftRadius;
return new MaterialShapes.PointNRound(new Offset.Offset(xOffset + extraXOffset + 0, yOffset + extraYOffset + height), new CornerRounding.CornerRounding(radius))
}
function getTopLeftPoint(extraXOffset = 0, extraYOffset = 0, radius = undefined) {
if (radius === undefined) radius = effectiveTopLeftRadius;
return new MaterialShapes.PointNRound(new Offset.Offset(xOffset + extraXOffset + 0, yOffset + extraYOffset + 0), new CornerRounding.CornerRounding(radius))
}
function getTopRightPoint(extraXOffset = 0, extraYOffset = 0, radius = undefined) {
if (radius === undefined) radius = effectiveTopRightRadius;
return new MaterialShapes.PointNRound(new Offset.Offset(xOffset + extraXOffset + width, yOffset + extraYOffset + 0), new CornerRounding.CornerRounding(radius))
}
function getBottomRightPoint(extraXOffset = 0, extraYOffset = 0, radius = undefined) {
if (radius === undefined) radius = effectiveBottomRightRadius;
return new MaterialShapes.PointNRound(new Offset.Offset(xOffset + extraXOffset + width, yOffset + extraYOffset + height), new CornerRounding.CornerRounding(radius))
}
function getFullShape() {
const points = [
...getFirstBottomPoints(),
getBottomLeftPoint(),
...leftPoints,
getTopLeftPoint(),
...topPoints,
getTopRightPoint(),
...rightPoints,
getBottomRightPoint(),
...getLastBottomPoints(),
]
return MaterialShapes.customPolygon(points);
}
}
@@ -29,6 +29,7 @@ Button {
property color colBackgroundToggledHover: Appearance?.colors.colPrimaryHover ?? "#77699C"
property color colRipple: Appearance?.colors.colLayer1Active ?? "#D6CEE2"
property color colRippleToggled: Appearance?.colors.colPrimaryActive ?? "#D6CEE2"
property color colFocusRing: Appearance.colors.colOnSecondaryContainer
opacity: root.enabled ? 1 : 0.4
property color buttonColor: ColorUtils.transparentize(root.toggled ?
@@ -180,6 +181,22 @@ Button {
}
}
z: visualFocus ? 1 : 0
Rectangle {
id: focusRing
radius: buttonBackground.radius - anchors.margins
visible: root.visualFocus
color: "transparent"
anchors {
fill: parent
margins: -4
}
border {
color: root.colFocusRing
width: 2
}
}
contentItem: StyledText {
text: root.buttonText
}
@@ -0,0 +1,19 @@
import QtQuick
Rectangle {
id: root
// https://m3.material.io/foundations/interaction/states/state-layers
enum State {
Hover, Focus, Press, Drag
}
property var state: StateLayer.State.Hover
opacity: switch(state) {
case StateLayer.State.Hover: return 0.08;
case StateLayer.State.Focus: return 0.1;
case StateLayer.State.Press: return 0.1;
case StateLayer.State.Drag: return 0.16;
default: return 0;
}
}
@@ -0,0 +1,66 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs.modules.common as C
Rectangle {
id: root
property bool hover: false
property bool press: false
property bool drag: false
property color contentColor: C.Appearance.m3colors.m3onBackground
color: "transparent"
FadeLoader {
id: hoverLoader
anchors.fill: parent
shown: root.hover
sourceComponent: StateLayer {
state: StateLayer.State.Hover
color: root.contentColor
topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomLeftRadius: root.bottomLeftRadius
bottomRightRadius: root.bottomRightRadius
}
}
FadeLoader {
id: focusLoader
anchors.fill: parent
shown: root.focus
sourceComponent: StateLayer {
state: StateLayer.State.Focus
color: root.contentColor
topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomLeftRadius: root.bottomLeftRadius
bottomRightRadius: root.bottomRightRadius
}
}
FadeLoader {
id: pressLoader
anchors.fill: parent
shown: root.press
sourceComponent: StateLayer {
state: StateLayer.State.Press
color: root.contentColor
topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomLeftRadius: root.bottomLeftRadius
bottomRightRadius: root.bottomRightRadius
}
}
FadeLoader {
id: dragLoader
anchors.fill: parent
shown: root.drag
sourceComponent: StateLayer {
state: StateLayer.State.Drag
color: root.contentColor
topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomLeftRadius: root.bottomLeftRadius
bottomRightRadius: root.bottomRightRadius
}
}
}
@@ -0,0 +1,81 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import ".."
import "../functions"
Button {
id: root
property alias radius: bg.radius
property alias contentLayer: bg.contentLayer
property color colFocusRing: Appearance.colors.colOnSecondaryContainer
property color colBackground: checked ? colBackgroundChecked : colBackgroundUnchecked
property color colForeground: checked ? colForegroundChecked : colForegroundUnchecked
property color colBackgroundUnchecked: ColorUtils.transparentize(Appearance.colors.colLayer4Base, 1)
property color colBackgroundChecked: Appearance.colors.colPrimary
property color colForegroundUnchecked: Appearance.colors.colOnLayer4
property color colForegroundChecked: Appearance.colors.colOnPrimary
hoverEnabled: true
opacity: root.enabled ? 1 : 0.5
Behavior on colBackground {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
Behavior on colForeground {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
HoverHandler {
cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
}
background: StyledRectangle {
id: bg
implicitHeight: root.contentItem.implicitHeight
implicitWidth: root.contentItem.implicitWidth
radius: Math.min(width, height) / 2
color: root.colBackground
StateOverlay {
anchors.fill: parent
hover: root.hovered && root.enabled
press: root.pressed && root.enabled
focus: false // We use a ring instead
radius: bg.radius
}
Rectangle {
id: focusRing
radius: bg.radius - anchors.margins
visible: root.visualFocus
color: "transparent"
anchors {
fill: parent
margins: -4
}
border {
color: root.colFocusRing
width: 2
}
}
}
z: visualFocus ? 1 : 0
contentItem: Item {
implicitWidth: buttonText.implicitWidth
implicitHeight: buttonText.implicitHeight
VisuallyCenteredStyledText {
id: buttonText
anchors.centerIn: parent
text: root.text
color: root.colForeground
}
}
}
@@ -0,0 +1,73 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs.modules.common
AbstractCombinedProgressBar {
id: root
property real valueBarWidth: 120
property real valueBarHeight: 4
property real valueBarGap: 4
property real valueBarInnerRadius: Appearance.rounding.unsharpen
valueHighlights: [Appearance.colors.colPrimary, Appearance.colors.colTertiary]
valueTroughs: [Appearance.colors.colSecondaryContainer, Appearance.colors.colTertiaryContainer]
background: Item {
implicitWidth: root.valueBarWidth
implicitHeight: root.valueBarHeight
}
// "negligible" = too small that it'd look weird when shown
function isNegligibleSegment(seg: var): bool {
const wdth = seg[1] - seg[0];
const visualWidth = availableWidth * wdth;
return (visualWidth <= valueBarGap + valueBarHeight)
}
contentItem: Item {
Repeater {
model: root.visualSegments
delegate: Rectangle {
required property int index
required property var modelData
visible: !root.isNegligibleSegment(modelData)
property bool atStart: index == 0
property bool atEnd: index == root.visualSegments.length - 1
property real displaySegStart: { // swallow previous segments if they're "negligible"
var i = index;
while ((i > 0 && root.isNegligibleSegment(root.visualSegments[i-1])))
i--;
return root.visualSegments[i][0]
}
anchors {
top: parent.top
bottom: parent.bottom
}
x: {
var result = root.availableWidth * displaySegStart;
if (!atStart) result += root.valueBarGap / 2;
return result;
}
width: {
var result = root.availableWidth * (modelData[1] - displaySegStart)
if (atStart || atEnd) result -= root.valueBarGap / 2;
else result -= root.valueBarGap;
return result;
}
color: root.segmentColors[index % root.segmentColors.length]
property real startRadius: atStart ? height / 2 : root.valueBarInnerRadius
property real endRadius: atEnd ? height / 2 : root.valueBarInnerRadius
topLeftRadius: startRadius
bottomLeftRadius: startRadius
topRightRadius: endRadius
bottomRightRadius: endRadius
}
}
}
}
@@ -0,0 +1,19 @@
pragma ComponentBehavior: Bound
import QtQuick
StyledButton {
id: root
property alias implicitSize: root.implicitHeight
implicitWidth: implicitHeight
property alias iconSize: icon.iconSize
contentItem: Item {
MaterialSymbol {
id: icon
anchors.centerIn: parent
color: root.colForeground
text: root.text
}
}
}
@@ -0,0 +1,22 @@
import QtQuick
import qs.modules.common as C
// This is to enable future fancy styles for rectangles. Some ideas:
// - normal rounded rect
// - osk.sh
// - 3d
// i hope i actually get to this and not shrimply forget
// aaaaa i realized for this to work i would have to make this for shapes in general not just rects
Rectangle {
enum ContentLayer { Background, Pane, Group, Subgroup, Control }
property var contentLayer: StyledRectangle.ContentLayer.Pane // To appropriately add effects like shadows/3d-ization
color: switch(contentLayer) {
case StyledRectangle.ContentLayer.Background: C.Appearance.colors.colLayer0;
case StyledRectangle.ContentLayer.Pane: C.Appearance.colors.colLayer1;
case StyledRectangle.ContentLayer.Group: C.Appearance.colors.colLayer2;
case StyledRectangle.ContentLayer.Subgroup: C.Appearance.colors.colLayer3;
case StyledRectangle.ContentLayer.Control: C.Appearance.colors.colLayer4;
default: C.Appearance.colors.colLayer1;
}
}
@@ -23,7 +23,7 @@ Text {
component Anim: NumberAnimation {
target: root
duration: 300 / 2
duration: 130
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
@@ -55,7 +55,8 @@ Text {
Anim {
property: "opacity"
to: 0
easing.type: Easing.InSine
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
}
PropertyAction {} // Tie the text update to this point (we don't want it to happen during the first slide+fade)
@@ -83,7 +84,8 @@ Text {
Anim {
property: "opacity"
to: 1
easing.type: Easing.OutSine
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
}
}
@@ -0,0 +1,17 @@
import QtQuick
import qs.modules.common as C
FallbackLoader {
id: root
required property string componentName
property string context // Path for the builtin component
readonly property string componentNameWithExt: componentName.endsWith(".qml") ? componentName : `${componentName}.qml`
source: `${C.Directories.userComponents}/${componentNameWithExt}`
fallbacks: [
...(context ? [ `${context}/${componentNameWithExt}` ] : []),
componentNameWithExt
]
}
@@ -0,0 +1,45 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
Item {
id: root
property alias textWidget: textWidget
property alias text: textWidget.text
property alias horizontalAlignment: textWidget.horizontalAlignment
property alias verticalAlignment: textWidget.verticalAlignment
property alias font: textWidget.font
property alias color: textWidget.color
property alias elide: textWidget.elide
property alias wrapMode: textWidget.wrapMode
property alias animateChange: textWidget.animateChange
// In many cases the baseline is a bit high to accomodate the dangling parts of "g" and "y",
// making most text (especiall number-only text) not well-balanced.
// This adjusts the rounding to make sure the text gets lowered if not internally pixel-aligned
property bool lowerBias: true
implicitWidth: textMetrics.width
implicitHeight: textMetrics.height
TextMetrics {
id: textMetrics
font: root.font
text: root.text
}
StyledText {
id: textWidget
anchors {
left: parent.left
right: parent.right
}
y: {
const value = (parent.height - textMetrics.height) / 2;
return root.lowerBias ? Math.ceil(value) : Math.round(value);
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
@@ -0,0 +1,73 @@
import QtQuick
import Quickshell
import qs.services as S
/**
* Abstract morphed panel to be used in TopLayerPanel.
* Screen width and height are to be supplied when declared in the top layer panel
* Others are to be declared by panels deriving from this
*
* To make sure morph movements don't look weird:
* - Follow the convention of having points start from bottom-middle and go clockwise
* - Make sure the number of points is "balanced" in all directions
* - Tip: Sometimes symmetry is not enough. Try to have more intermediate points if ones you have are too spaced out and act funny.
*/
Item {
id: root
// To be fed
property int screenWidth: QsWindow.window.width
property int screenHeight: QsWindow.window.height
// Signals & loading
signal requestFocus()
signal dismissed()
signal focusGrabDismissed()
property bool load: true
property bool shown: true
// Some info
property int reservedTop: 0
property int reservedBottom: 0
property int reservedLeft: 0
property int reservedRight: 0
// Main stuff
property var backgroundPolygon
property list<Item> baseMaskItems: [root]
property list<Item> attachedMaskItems: []
property list<Item> maskItems: [...baseMaskItems, ...attachedMaskItems]
property Region maskRegion: Region {
regions: root.maskItems.map(item => regionComp.createObject(this, { "item": item }))
}
function addAttachedMaskItem(item) {
if (root.attachedMaskItems.includes(item)) return;
root.attachedMaskItems.push(item);
}
function removeAttachedMaskItem(item) {
root.attachedMaskItems = root.attachedMaskItems.filter(i => i !== item);
}
onAttachedMaskItemsChanged: {
if (attachedMaskItems.length > 0) {
S.GlobalFocusGrab.addDismissable(root.QsWindow.window);
} else {
S.GlobalFocusGrab.removeDismissable(root.QsWindow.window);
}
}
Connections {
target: S.GlobalFocusGrab
function onDismissed() {
root.attachedMaskItems = [];
root.focusGrabDismissed();
}
}
Component {
id: regionComp
Region {}
}
}
@@ -0,0 +1,94 @@
import QtQuick
import Quickshell.Hyprland
import qs
import qs.modules.common
import "../../common/widgets/shapes/material-shapes.js" as MaterialShapes
import "../../common/widgets/shapes/shapes/corner-rounding.js" as CornerRounding
import "../../common/widgets/shapes/geometry/offset.js" as Offset
HAbstractMorphedPanel {
id: root
// Own props
property int edgeGap: Appearance.sizes.hyprlandGapsOut
property real rounding: Appearance.rounding.windowRounding
property real contentHeight: 300 // For now
property real contentWidth: root.screenWidth * 0.9
property real horizontalGap: (root.screenWidth - contentWidth) / 2
// Background
backgroundPolygon: {
const bottom = Config.options.bar.bottom
const topY = bottom ? (root.screenHeight - edgeGap - contentHeight) : edgeGap
const bottomY = bottom ? (root.screenHeight - edgeGap) : (edgeGap + contentHeight)
const points = [
// bottom-middle
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth / 2, bottomY), new CornerRounding.CornerRounding(0)),
// bottom-left
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap + rounding, bottomY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap, bottomY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap, bottomY - rounding), new CornerRounding.CornerRounding(rounding)),
// top-left
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap, topY + rounding), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap, topY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(horizontalGap + rounding, topY), new CornerRounding.CornerRounding(rounding)),
// top-middle
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth / 2, topY), new CornerRounding.CornerRounding(0)),
// top-right
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap - rounding, topY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap, topY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap, topY + rounding), new CornerRounding.CornerRounding(rounding)),
// bottom-right
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap, bottomY - rounding), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap, bottomY), new CornerRounding.CornerRounding(rounding)),
new MaterialShapes.PointNRound(new Offset.Offset(root.screenWidth - horizontalGap - rounding, bottomY), new CornerRounding.CornerRounding(rounding)),
]
return MaterialShapes.customPolygon(points, 1, new Offset.Offset(root.screenWidth / 2, edgeGap + contentHeight / 2))
}
// // Keybinds
// GlobalShortcut {
// name: "searchToggle"
// description: "Toggles search on press"
// onPressed: {
// GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
// }
// }
// GlobalShortcut {
// name: "searchToggleRelease"
// description: "Toggles search on release"
// onPressed: {
// GlobalStates.superReleaseMightTrigger = true;
// }
// onReleased: {
// if (!GlobalStates.superReleaseMightTrigger) {
// GlobalStates.superReleaseMightTrigger = true;
// return;
// }
// GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
// }
// }
// GlobalShortcut {
// name: "searchToggleReleaseInterrupt"
// description: "Interrupts possibility of search being toggled on release. " + "This is necessary because GlobalShortcut.onReleased in quickshell triggers whether or not you press something else while holding the key. " + "To make sure this works consistently, use binditn = MODKEYS, catchall in an automatically triggered submap that includes everything."
// onPressed: {
// GlobalStates.superReleaseMightTrigger = false;
// }
// }
// Connections {
// target: GlobalStates
// function onOverviewOpenChanged() {
// if (GlobalStates.overviewOpen) {
// root.requestFocus();
// } else {
// root.dismissed();
// }
// }
// }
}

Some files were not shown because too many files have changed in this diff Show More