mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 23:09:26 -05:00
Compare commits
344 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45c6d8a837 | |||
| 6eb590b1a2 | |||
| 14376cec94 | |||
| 397fb8d8c4 | |||
| aa044b4563 | |||
| ad7a7fe566 | |||
| a15f2a8a39 | |||
| 9b149e6fef | |||
| eb3613d3ed | |||
| 091da11da5 | |||
| a56cee16f1 | |||
| 54a1d172d7 | |||
| c58bb07a6b | |||
| 9c115f7a8f | |||
| b9e05599bc | |||
| ce80951210 | |||
| 6eaa869fac | |||
| 8f9cf67be7 | |||
| 20d1ff065b | |||
| 25fe0ab01e | |||
| c1b37bc467 | |||
| b470bf3fe8 | |||
| d4e777911e | |||
| d4d78a5e62 | |||
| c0706258b1 | |||
| 68c67aced4 | |||
| 215ac747d8 | |||
| 21689e1d51 | |||
| 9eda50178b | |||
| d5f9afe7c0 | |||
| 5c66902900 | |||
| 74e4e698d9 | |||
| 28ba8a4f43 | |||
| 798d35a538 | |||
| 7d5ce9a793 | |||
| c53265754c | |||
| 239b532ec6 | |||
| d1daedc6d2 | |||
| 20d9f80336 | |||
| 4420a6c22d | |||
| 2ade168a20 | |||
| 08201f2ac0 | |||
| bac0b388ad | |||
| ad12fe6ddf | |||
| 9e1568fcdc | |||
| b7b2e6e10d | |||
| 00a4235a81 | |||
| c504cdf22b | |||
| e6d2a7d88c | |||
| b50a4a7faa | |||
| 737eb7c356 | |||
| 5ce6280d98 | |||
| f7773acab4 | |||
| e8721b4b01 | |||
| 4c590874e0 | |||
| b85ed8691a | |||
| ac8d0e9a42 | |||
| 412b2222c2 | |||
| d6b27cf9dd | |||
| c53e9891cb | |||
| 1e442f1af0 | |||
| 20dde15900 | |||
| da47151345 | |||
| ba0e76da1b | |||
| 1c117e0880 | |||
| 7aad60eb2c | |||
| a9f87c06ca | |||
| 281b3e5627 | |||
| 388783e992 | |||
| ae7f6bd165 | |||
| 9279a5a181 | |||
| 403f7aa685 | |||
| 807c761ed0 | |||
| 7dcbabcd8c | |||
| a9dcaf0d4b | |||
| 2e161911bc | |||
| a23d050df5 | |||
| 7aa9e603d5 | |||
| e11d084be8 | |||
| 760c7034aa | |||
| b9f668e106 | |||
| 6c041b953a | |||
| 9f4afde0c5 | |||
| 010f070eef | |||
| f6b97c4649 | |||
| 0da83ba460 | |||
| 74c10b915d | |||
| 0ae900515e | |||
| c3147dc7ff | |||
| fb3ec1fdfc | |||
| b9acc518e9 | |||
| d1cd892c0f | |||
| 63495d0b28 | |||
| 36a4a19bca | |||
| c693a3f539 | |||
| c0888cbb98 | |||
| 2cfb0c2757 | |||
| b034a712a9 | |||
| aff6206930 | |||
| 0e1f6a97fc | |||
| 7834f22243 | |||
| cec16c8720 | |||
| 54e19afa81 | |||
| ffabb85693 | |||
| 72d950ed51 | |||
| 4eef9ea18e | |||
| 464cddad00 | |||
| 283995ca99 | |||
| 329fa31262 | |||
| 14f8b84635 | |||
| 36e0c3fddc | |||
| d24cbff7ac | |||
| ef9042838e | |||
| 87939110bf | |||
| a62e64e2ef | |||
| 493fb9b686 | |||
| 0db4f8bd5d | |||
| 15002949ee | |||
| 74b869c30b | |||
| a4d45f04f2 | |||
| d87fbf5523 | |||
| c582ecf8af | |||
| 6050148835 | |||
| cc582fd113 | |||
| c8eb9d2830 | |||
| 35c272c807 | |||
| e552776670 | |||
| fdcdc7f1a3 | |||
| 566e100623 | |||
| 2674382b5f | |||
| 01e2eb433b | |||
| 2c30b28fb6 | |||
| 7c27da5336 | |||
| 32934200e4 | |||
| 906d7adf3e | |||
| 37c3fface4 | |||
| ce52695746 | |||
| e597928a9e | |||
| e5def85946 | |||
| f5ae1d360f | |||
| 7f64e5c756 | |||
| 013e81f2ac | |||
| 0b2dfb1910 | |||
| 2eb5885b56 | |||
| beac11dc18 | |||
| 698692a500 | |||
| ef38057830 | |||
| c854d88ee9 | |||
| e1b79693e3 | |||
| 30583abf36 | |||
| 12d510e9eb | |||
| 61a2881ac1 | |||
| 96c8a63b21 | |||
| 950356e47d | |||
| 8cc6087744 | |||
| d52fbe0b40 | |||
| 193d82847a | |||
| 725b0ef5cf | |||
| b1b96904a9 | |||
| 82ed7498c8 | |||
| 1e0ed08909 | |||
| 350f48a74b | |||
| 36f01b78fe | |||
| 3f77086b93 | |||
| 87f61b9331 | |||
| 725c873ab9 | |||
| f02bcdcce7 | |||
| 6b7a12fc9f | |||
| 6878368d71 | |||
| 467f19b40e | |||
| 90c3b642b2 | |||
| 6e433e4a39 | |||
| 05eb696ead | |||
| 0818a6ad9c | |||
| 8ca3ef773a | |||
| e2aa71b59e | |||
| e4ad01c20f | |||
| 522bb5dc0a | |||
| 80752b7812 | |||
| 247da26c7b | |||
| 09d92aff7b | |||
| 3bb9127e32 | |||
| a316f91e86 | |||
| b4c8a63d1a | |||
| 68a51b79ff | |||
| 8d1b9a2ea0 | |||
| ace263cd45 | |||
| 134bf4d986 | |||
| 481e848a65 | |||
| 17c2702d2b | |||
| 84d7928518 | |||
| a81f52fcd7 | |||
| 6eda3c674d | |||
| 54f4709d5f | |||
| 7a46a5c4e5 | |||
| 25dba608ae | |||
| 6eb547bb18 | |||
| cd1a0b3d69 | |||
| 842b09c548 | |||
| f7998dd7c4 | |||
| 43177b9cf3 | |||
| ef86c64933 | |||
| bd767f140f | |||
| 7215d465ea | |||
| 67a19bedaf | |||
| e3dbaf4242 | |||
| 1fe219e215 | |||
| e012eb646c | |||
| 485372ee56 | |||
| b14e0c494c | |||
| 1ad259ff9b | |||
| 2109cf5e09 | |||
| a33122cd3c | |||
| 7a4468258b | |||
| ae0c9f4731 | |||
| 521f3cab6d | |||
| 455252dff1 | |||
| 60ba555de6 | |||
| 485c40406d | |||
| 98a766608d | |||
| 026a660aa7 | |||
| 9e76e89b94 | |||
| da5b8e8912 | |||
| bdf91e1d16 | |||
| 139e64c28e | |||
| 2d94bace7b | |||
| e7368bdc25 | |||
| 09cdad1554 | |||
| 8b84537579 | |||
| ea35ca1582 | |||
| 8fccfef9f1 | |||
| 9e6c1d7c08 | |||
| aaff9d5273 | |||
| 6f633122ed | |||
| 24392e3791 | |||
| 0e049db304 | |||
| 680d8e85c8 | |||
| 6ac1861e1e | |||
| 7f59246c6d | |||
| f3e26d8f22 | |||
| 0a185efcc5 | |||
| 124ea7b245 | |||
| 4fcc12444f | |||
| aefc88755a | |||
| 216a44274e | |||
| db7caae4b5 | |||
| c4f9b20b23 | |||
| 17a99ec068 | |||
| 1225c014e8 | |||
| 5ac40d5445 | |||
| 08b7b393cb | |||
| 0c69a344d5 | |||
| 3ca94d1e70 | |||
| c538505f94 | |||
| 3cac4206f9 | |||
| b3d15cbae1 | |||
| 495e205934 | |||
| ad922ac368 | |||
| 6393092e63 | |||
| e0f2875141 | |||
| 83dcb349da | |||
| 675e14e338 | |||
| 79fe2651cc | |||
| da7bddf1d1 | |||
| a66d0f3146 | |||
| cb5966de0f | |||
| d0e51ffe19 | |||
| 32e8f90b14 | |||
| b59c3f5c30 | |||
| f9bd67699c | |||
| e3eeff8d5d | |||
| 0b0693b1fd | |||
| 227d822655 | |||
| 5e16f2bc10 | |||
| be87a1ae79 | |||
| 653dc9c95f | |||
| e2805ef1a1 | |||
| 6111956c4a | |||
| ff1dfedc72 | |||
| 4e162bd8a6 | |||
| 6bd6f30a5e | |||
| 6952d89a7f | |||
| d1dc89b9f2 | |||
| 1113b6162c | |||
| d41cda858c | |||
| 38dbc8769b | |||
| 7a9b080616 | |||
| a174ed1a84 | |||
| 245aae965f | |||
| 3d5c43135a | |||
| 96b8af05cc | |||
| 422db1ee91 | |||
| 8e21d8c8e3 | |||
| 3b13d0c938 | |||
| f8840e8389 | |||
| 3a4804653d | |||
| dd0b8a5114 | |||
| 6b08e16222 | |||
| 233a06a4c0 | |||
| 2a714378c9 | |||
| e480477db2 | |||
| 83baff7894 | |||
| 3da23ce176 | |||
| 635d49cad0 | |||
| 9ffe4dfb11 | |||
| c155bde816 | |||
| 6cd2d31c99 | |||
| 7a74897b47 | |||
| 28936dd226 | |||
| aa4c18b86a | |||
| 0235e56af3 | |||
| 6b29e73ab7 | |||
| 2bb001a62b | |||
| 15afa07b14 | |||
| bb10002976 | |||
| 368df5b717 | |||
| 6f5ab232a6 | |||
| 3447198e13 | |||
| 1c295ddaac | |||
| 7ba30cee4a | |||
| 6fd2bd51ad | |||
| aec849c820 | |||
| be4eb16b60 | |||
| 314b0ab3d0 | |||
| 10491f2362 | |||
| c2f65e79bc | |||
| 6bb0c251a9 | |||
| e1913d0e95 | |||
| 74c012c930 | |||
| 74368ad25a | |||
| 4718922c55 | |||
| d8eb55fea9 | |||
| 5f9fe2d250 | |||
| 4a44994168 | |||
| 879111fe01 | |||
| ed8c8ae8d7 | |||
| ead98b98b8 | |||
| 5bb1aa06af | |||
| 58184f5be8 | |||
| 28e580c2b1 | |||
| 819fa81fc6 | |||
| fb13cc1a21 | |||
| d1988bef02 | |||
| 7872fba6fe |
+5
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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`
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
hl.bind("CTRL+SUPER+ALT+Slash", hl.dsp.exec_cmd("xdg-open ~/.config/hypr/custom/keybinds.lua"), {description = "Edit user keybinds"} )
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# hyprlang noerror false
|
||||
# For all available variables, see ~/.config/hypr/hyprland/variables.conf
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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)",
|
||||
})
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
@@ -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]
|
||||
|
||||
@@ -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" }))
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 =
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)",
|
||||
})
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -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
Reference in New Issue
Block a user