Merge remote-tracking branch 'origin/main' into addon-i18n
@@ -20,6 +20,7 @@ end
|
|||||||
alias pamcan pacman
|
alias pamcan pacman
|
||||||
alias ls 'eza --icons'
|
alias ls 'eza --icons'
|
||||||
alias clear "printf '\033[2J\033[3J\033[1;1H'"
|
alias clear "printf '\033[2J\033[3J\033[1;1H'"
|
||||||
|
alias q 'qs -c ii'
|
||||||
|
|
||||||
|
|
||||||
# function fish_prompt
|
# function fish_prompt
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# This file sources other files in `hyprland` and `custom` folders
|
# This file sources other files in `hyprland` and `custom` folders
|
||||||
# You wanna add your stuff in files in `custom`
|
# You wanna add your stuff in files in `custom`
|
||||||
|
|
||||||
|
$qsConfig = ii
|
||||||
exec = hyprctl dispatch submap global # DO NOT REMOVE THIS OR YOU WON'T BE ABLE TO USE ANY KEYBIND
|
exec = hyprctl dispatch submap global # DO NOT REMOVE THIS OR YOU WON'T BE ABLE TO USE ANY KEYBIND
|
||||||
submap = global # This is required for catchall to work
|
submap = global # This is required for catchall to work
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Bar, wallpaper
|
# Bar, wallpaper
|
||||||
exec-once = swww-daemon --format xrgb --no-cache
|
exec-once = ~/.config/hypr/hyprland/scripts/start_geoclue_agent.sh & gammastep
|
||||||
exec-once = sleep 0.5; swww img "$(cat ~/.local/state/quickshell/user/generated/wallpaper/path.txt)" --transition-step 100 --transition-fps 120 --transition-type grow --transition-angle 30 --transition-duration 1
|
exec-once = sleep 0.7; [ "$(hyprctl monitors -j | jq 'length')" -eq 1 ] && swww-daemon --format xrgb --no-cache || swww-daemon --format xrgb
|
||||||
exec-once = /usr/lib/geoclue-2.0/demos/agent & gammastep
|
exec-once = sleep 0.7; swww img "$(cat ~/.local/state/quickshell/user/generated/wallpaper/path.txt)" --transition-step 100 --transition-fps 120 --transition-type grow --transition-angle 30 --transition-duration 1
|
||||||
exec-once = qs &
|
exec-once = qs -c $qsConfig &
|
||||||
|
|
||||||
# Input method
|
# Input method
|
||||||
exec-once = fcitx5
|
exec-once = fcitx5
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
##! Shell
|
##! Shell
|
||||||
# These absolutely need to be on top, or they won't work consistently
|
# These absolutely need to be on top, or they won't work consistently
|
||||||
bindid = Super, Super_L, Toggle overview, global, quickshell:overviewToggleRelease # Toggle overview/launcher
|
bindid = Super, Super_L, Toggle overview, global, quickshell:overviewToggleRelease # Toggle overview/launcher
|
||||||
bind = Super, Super_L, exec, qs ipc call TEST_ALIVE || pkill fuzzel || fuzzel # [hidden] Launcher (fallback)
|
bind = Super, Super_L, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill fuzzel || fuzzel # [hidden] Launcher (fallback)
|
||||||
binditn = Super, catchall, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
binditn = Super, catchall, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
||||||
bind = Ctrl, Super_L, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
bind = Ctrl, Super_L, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
||||||
bind = Super, mouse:272, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
bind = Super, mouse:272, global, quickshell:overviewToggleReleaseInterrupt # [hidden]
|
||||||
@@ -30,11 +30,12 @@ bindd = Super, Slash, Toggle cheatsheet, global, quickshell:cheatsheetToggle # T
|
|||||||
bindd = Super, K, Toggle on-screen keyboard, global, quickshell:oskToggle # Toggle on-screen keyboard
|
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
|
bindd = Super, M, Toggle media controls, global, quickshell:mediaControlsToggle # Toggle media controls
|
||||||
bindd = Ctrl+Alt, Delete, Toggle session menu, global, quickshell:sessionToggle # Toggle session menu
|
bindd = Ctrl+Alt, Delete, Toggle session menu, global, quickshell:sessionToggle # Toggle session menu
|
||||||
bind = Ctrl+Alt, Delete, exec, qs ipc call TEST_ALIVE || pkill wlogout || wlogout -p layer-shell # [hidden] Session menu (fallback)
|
bindd = Super, J, Toggle bar, global, quickshell:barToggle # Toggle bar
|
||||||
bind = Shift+Super+Alt, Slash, exec, qs -p ~/.config/quickshell/welcome.qml # [hidden] Launch welcome app
|
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 ipc call brightness increment || brightnessctl s 5%+ # [hidden]
|
bindle=, XF86MonBrightnessUp, exec, qs -c $qsConfig ipc call brightness increment || brightnessctl s 5%+ # [hidden]
|
||||||
bindle=, XF86MonBrightnessDown, exec, qs ipc call brightness decrement || brightnessctl s 5%- # [hidden]
|
bindle=, XF86MonBrightnessDown, exec, qs -c $qsConfig ipc call brightness decrement || brightnessctl s 5%- # [hidden]
|
||||||
bindle=, XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 2%+ # [hidden]
|
bindle=, XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 2%+ # [hidden]
|
||||||
bindle=, XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%- # [hidden]
|
bindle=, XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%- # [hidden]
|
||||||
|
|
||||||
@@ -43,14 +44,14 @@ bindld = Super+Shift,M, Toggle mute, exec, wpctl set-mute @DEFAULT_SINK@ toggle
|
|||||||
bindl = Alt ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
|
bindl = Alt ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
|
||||||
bindl = ,XF86AudioMicMute, 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]
|
bindld = Super+Alt,M, Toggle mic, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle # [hidden]
|
||||||
bindd = Ctrl+Super, T, Change wallpaper, exec, ~/.config/quickshell/scripts/colors/switchwall.sh # Change wallpaper
|
bindd = Ctrl+Super, T, Change wallpaper, exec, ~/.config/quickshell/$qsConfig/scripts/colors/switchwall.sh # Change wallpaper
|
||||||
bind = Ctrl+Super, R, exec, killall ags agsv1 gjs ydotool qs quickshell; qs & # Restart widgets
|
bind = Ctrl+Super, R, exec, killall ags agsv1 gjs ydotool qs quickshell; qs -c $qsConfig & # Restart widgets
|
||||||
|
|
||||||
##! Utilities
|
##! Utilities
|
||||||
# Screenshot, Record, OCR, Color picker, Clipboard history
|
# Screenshot, Record, OCR, Color picker, Clipboard history
|
||||||
bindd = Super, V, Copy clipboard history entry, exec, qs ipc call TEST_ALIVE || pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy # [hidden] Clipboard history >> clipboard (fallback)
|
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 ipc call TEST_ALIVE || pkill fuzzel || ~/.config/hypr/hyprland/scripts/fuzzel-emoji.sh copy # [hidden] Emoji >> 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)
|
||||||
bindd = Super+Shift, S, Screen snip, exec, qs -p ~/.config/quickshell/screenshot.qml || pidof slurp || hyprshot --freeze --clipboard-only --mode region --silent # Screen snip
|
bindd = Super+Shift, S, Screen snip, exec, qs -p ~/.config/quickshell/$qsConfig/screenshot.qml || pidof slurp || hyprshot --freeze --clipboard-only --mode region --silent # Screen snip
|
||||||
# OCR
|
# OCR
|
||||||
bindd = Super+Shift, T, Character recognition,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract "tmp.png" - | wl-copy && rm "tmp.png" # [hidden]
|
bindd = Super+Shift, T, Character recognition,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract "tmp.png" - | wl-copy && rm "tmp.png" # [hidden]
|
||||||
# Color picker
|
# Color picker
|
||||||
@@ -183,8 +184,10 @@ bindd = Ctrl+Shift+Alt+Super, Delete, Shutdown, exec, systemctl poweroff || logi
|
|||||||
|
|
||||||
##! Screen
|
##! Screen
|
||||||
# Zoom
|
# Zoom
|
||||||
binde = Super, Minus, exec, ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.1 # Zoom out
|
binde = Super, Minus, exec, qs -c $qsConfig ipc call zoom zoomOut # Zoom out
|
||||||
binde = Super, Equal, exec, ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.1 # Zoom in
|
binde = Super, Equal, exec, qs -c $qsConfig ipc call zoom zoomIn # Zoom in
|
||||||
|
binde = Super, Minus, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.1 # [hidden] Zoom out
|
||||||
|
binde = Super, Equal, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.1 # [hidden] Zoom in
|
||||||
|
|
||||||
##! Media
|
##! Media
|
||||||
bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # Next track
|
bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # Next track
|
||||||
@@ -203,12 +206,12 @@ bind = Super, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh
|
|||||||
bind = Ctrl+Alt, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] Kitty (for Ubuntu people)
|
bind = Ctrl+Alt, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] Kitty (for Ubuntu people)
|
||||||
bind = Super, E, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "kitty -1 fish -c yazi" # File manager
|
bind = Super, E, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "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" # Browser
|
bind = Super, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "google-chrome-stable" "zen-browser" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" # Browser
|
||||||
bind = Super, C, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "code" "codium" "zed" "kate" "gnome-text-editor" "emacs" "command -v nvim && kitty -1 nvim" # Code editor
|
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" # Code editor
|
||||||
bind = Super+Shift, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "wps" "onlyoffice-desktopeditors" # Office software
|
bind = Super+Shift, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "wps" "onlyoffice-desktopeditors" # Office software
|
||||||
bind = Super, X, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kate" "gnome-text-editor" "emacs" # Text editor
|
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 = 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/settings.qml" "systemsettings" "gnome-control-center" "better-control" # Settings app
|
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-systemmonitzor --page-name Processes" "command -v btop && kitty -1 fish -c btop" # Task manager
|
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
|
||||||
|
|
||||||
# Cursed stuff
|
# Cursed stuff
|
||||||
## Make window not amogus large
|
## Make window not amogus large
|
||||||
|
|||||||
@@ -27,12 +27,17 @@ windowrulev2 = float, class:.*bluedevilwizard
|
|||||||
windowrulev2 = float, title:.*Welcome
|
windowrulev2 = float, title:.*Welcome
|
||||||
windowrulev2 = float, title:^(illogical-impulse Settings)$
|
windowrulev2 = float, title:^(illogical-impulse Settings)$
|
||||||
windowrulev2 = float, class:org.freedesktop.impl.portal.desktop.kde
|
windowrulev2 = float, class:org.freedesktop.impl.portal.desktop.kde
|
||||||
|
windowrulev2 = float, class:^(Zotero)$
|
||||||
|
windowrulev2 = size 45%, class:^(Zotero)$
|
||||||
|
|
||||||
# No appearance
|
|
||||||
|
# Move
|
||||||
# kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
|
# kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
|
||||||
windowrulev2 = float, class:^(plasma-changeicons)$
|
windowrulev2 = float, class:^(plasma-changeicons)$
|
||||||
windowrulev2 = noinitialfocus, class:^(plasma-changeicons)$
|
windowrulev2 = noinitialfocus, class:^(plasma-changeicons)$
|
||||||
windowrulev2 = move 999999 999999, class:^(plasma-changeicons)$
|
windowrulev2 = move 999999 999999, class:^(plasma-changeicons)$
|
||||||
|
# stupid dolphin copy
|
||||||
|
windowrulev2 = move 40 80, title:^(Copying — Dolphin)$
|
||||||
|
|
||||||
# Tiling
|
# Tiling
|
||||||
windowrulev2 = tile, class:^dev\.warp\.Warp$
|
windowrulev2 = tile, class:^dev\.warp\.Warp$
|
||||||
@@ -135,6 +140,7 @@ layerrule = animation fade, quickshell:notificationPopup
|
|||||||
layerrule = blur, quickshell:backgroundWidgets
|
layerrule = blur, quickshell:backgroundWidgets
|
||||||
layerrule = ignorealpha 0.05, quickshell:backgroundWidgets
|
layerrule = ignorealpha 0.05, quickshell:backgroundWidgets
|
||||||
layerrule = noanim, quickshell:screenshot
|
layerrule = noanim, quickshell:screenshot
|
||||||
|
layerrule = animation popin 120%, quickshell:screenCorners
|
||||||
|
|
||||||
|
|
||||||
# Launchers need to be FAST
|
# Launchers need to be FAST
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Check if GeoClue agent is already running
|
||||||
|
if pgrep -f 'geoclue-2.0/demos/agent' > /dev/null; then
|
||||||
|
echo "GeoClue agent is already running."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List of known possible GeoClue agent paths
|
||||||
|
AGENT_PATHS="
|
||||||
|
/usr/libexec/geoclue-2.0/demos/agent
|
||||||
|
/usr/lib/geoclue-2.0/demos/agent
|
||||||
|
"
|
||||||
|
|
||||||
|
# Find the first valid agent path
|
||||||
|
for path in $AGENT_PATHS; do
|
||||||
|
if [ -x "$path" ]; then
|
||||||
|
echo "Starting GeoClue agent from: $path"
|
||||||
|
"$path" & # starts in the background
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# If we got here, none of the paths worked
|
||||||
|
echo "GeoClue agent not found in known paths."
|
||||||
|
echo "Please install GeoClue or update the script with the correct path."
|
||||||
|
exit 1
|
||||||
@@ -10,7 +10,7 @@ monitor = 0
|
|||||||
|
|
||||||
# File containing absolute path of an image (Takes precedence over automatic wallpaper detection)
|
# File containing absolute path of an image (Takes precedence over automatic wallpaper detection)
|
||||||
# Commented by default
|
# Commented by default
|
||||||
file = /home/end/.local/state/quickshell/user/wallpaper.txt
|
file = ~/.local/state/quickshell/user/generated/wallpaper/path.txt
|
||||||
|
|
||||||
# List of 7 space separated colors (hex or rgb) to be used for text in pywal/konsole/KSyntaxHighlighting instead of wallpaper ones
|
# List of 7 space separated colors (hex or rgb) to be used for text in pywal/konsole/KSyntaxHighlighting instead of wallpaper ones
|
||||||
# Accepted values are hex e.g #ff0000 and rgb e.g 255,0,0 colors (rgb is converted to hex)
|
# Accepted values are hex e.g #ff0000 and rgb e.g 255,0,0 colors (rgb is converted to hex)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Appearance]
|
[Appearance]
|
||||||
color_scheme_path=/home/end/.config/qt6ct/style-colors.conf
|
color_scheme_path=~/.config/qt6ct/style-colors.conf
|
||||||
custom_palette=true
|
custom_palette=true
|
||||||
icon_theme=OneUI
|
icon_theme=OneUI
|
||||||
standard_dialogs=default
|
standard_dialogs=default
|
||||||
|
|||||||
@@ -9,12 +9,21 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
property bool barOpen: true
|
||||||
property bool sidebarLeftOpen: false
|
property bool sidebarLeftOpen: false
|
||||||
property bool sidebarRightOpen: false
|
property bool sidebarRightOpen: false
|
||||||
property bool overviewOpen: false
|
property bool overviewOpen: false
|
||||||
property bool workspaceShowNumbers: false
|
property bool workspaceShowNumbers: false
|
||||||
property bool superReleaseMightTrigger: true
|
property bool superReleaseMightTrigger: true
|
||||||
|
|
||||||
|
property real screenZoom: 1
|
||||||
|
onScreenZoomChanged: {
|
||||||
|
Quickshell.execDetached(["hyprctl", "keyword", "cursor:zoom_factor", root.screenZoom.toString()]);
|
||||||
|
}
|
||||||
|
Behavior on screenZoom {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
// When user is not reluctant while pressing super, they probably don't need to see workspace numbers
|
// When user is not reluctant while pressing super, they probably don't need to see workspace numbers
|
||||||
onSuperReleaseMightTriggerChanged: {
|
onSuperReleaseMightTriggerChanged: {
|
||||||
workspaceShowNumbersTimer.stop()
|
workspaceShowNumbersTimer.stop()
|
||||||
@@ -42,4 +51,16 @@ Singleton {
|
|||||||
workspaceShowNumbers = false
|
workspaceShowNumbers = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "zoom"
|
||||||
|
|
||||||
|
function zoomIn() {
|
||||||
|
screenZoom = Math.min(screenZoom + 0.4, 3.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoomOut() {
|
||||||
|
screenZoom = Math.max(screenZoom - 0.4, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 660 B After Width: | Height: | Size: 660 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 538 B After Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
@@ -80,9 +80,9 @@ Scope {
|
|||||||
right: true
|
right: true
|
||||||
}
|
}
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
HyprlandWindow.visibleMask: Region {
|
// HyprlandWindow.visibleMask: Region { // Buggy with scaled monitors
|
||||||
item: widgetBackground
|
// item: widgetBackground
|
||||||
}
|
// }
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: widgetBackground
|
id: widgetBackground
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import "root:/services"
|
||||||
import "root:/modules/common"
|
import "root:/modules/common"
|
||||||
import "root:/modules/common/widgets"
|
import "root:/modules/common/widgets"
|
||||||
import "root:/services/"
|
import "root:/services/"
|
||||||
@@ -12,6 +13,10 @@ Item {
|
|||||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
|
||||||
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||||
|
|
||||||
|
property string activeWindowAddress: `0x${activeWindow.HyprlandToplevel.address}`
|
||||||
|
property bool focusingThisMonitor: HyprlandData.activeWorkspace.monitor == monitor.name
|
||||||
|
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(HyprlandData.monitors[root.monitor.id].activeWorkspace.id)
|
||||||
|
|
||||||
implicitWidth: colLayout.implicitWidth
|
implicitWidth: colLayout.implicitWidth
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
@@ -27,7 +32,10 @@ Item {
|
|||||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||||
color: Appearance.colors.colSubtext
|
color: Appearance.colors.colSubtext
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: root.activeWindow?.activated ? root.activeWindow?.appId : Translation.tr("Desktop")
|
text: root.focusingThisMonitor && root.activeWindow?.activated && root.biggestWindow ?
|
||||||
|
root.activeWindow?.appId :
|
||||||
|
(root.biggestWindow?.class) ?? Translation.tr("Desktop")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -35,7 +43,9 @@ Item {
|
|||||||
font.pixelSize: Appearance.font.pixelSize.small
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
color: Appearance.colors.colOnLayer0
|
color: Appearance.colors.colOnLayer0
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: root.activeWindow?.activated ? root.activeWindow?.title : `${Translation.tr("Workspace")} ${monitor.activeWorkspace?.id}`
|
text: root.focusingThisMonitor && root.activeWindow?.activated && root.biggestWindow ?
|
||||||
|
root.activeWindow?.title :
|
||||||
|
(root.biggestWindow?.title) ?? `${Translation.tr("Workspace")} ${monitor.activeWorkspace?.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,615 @@
|
|||||||
|
import "root:/"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/modules/common/"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||||
|
import "root:/modules/bar/weather"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Services.UPower
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: bar
|
||||||
|
|
||||||
|
readonly property int osdHideMouseMoveThreshold: 20
|
||||||
|
property bool showBarBackground: Config.options.bar.showBackground
|
||||||
|
|
||||||
|
component VerticalBarSeparator: Rectangle {
|
||||||
|
Layout.topMargin: Appearance.sizes.baseBarHeight / 3
|
||||||
|
Layout.bottomMargin: Appearance.sizes.baseBarHeight / 3
|
||||||
|
Layout.fillHeight: true
|
||||||
|
implicitWidth: 1
|
||||||
|
color: Appearance.colors.colOutlineVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
// For each monitor
|
||||||
|
model: {
|
||||||
|
const screens = Quickshell.screens;
|
||||||
|
const list = Config.options.bar.screenList;
|
||||||
|
if (!list || list.length === 0)
|
||||||
|
return screens;
|
||||||
|
return screens.filter(screen => list.includes(screen.name));
|
||||||
|
}
|
||||||
|
LazyLoader {
|
||||||
|
id: barLoader
|
||||||
|
activeAsync: GlobalStates.barOpen
|
||||||
|
required property ShellScreen modelData
|
||||||
|
component: PanelWindow { // Bar window
|
||||||
|
id: barRoot
|
||||||
|
screen: barLoader.modelData
|
||||||
|
|
||||||
|
property var brightnessMonitor: Brightness.getMonitorForScreen(barLoader.modelData)
|
||||||
|
property real useShortenedForm: (Appearance.sizes.barHellaShortenScreenWidthThreshold >= screen.width) ? 2 : (Appearance.sizes.barShortenScreenWidthThreshold >= screen.width) ? 1 : 0
|
||||||
|
readonly property int centerSideModuleWidth: (useShortenedForm == 2) ? Appearance.sizes.barCenterSideModuleWidthHellaShortened : (useShortenedForm == 1) ? Appearance.sizes.barCenterSideModuleWidthShortened : Appearance.sizes.barCenterSideModuleWidth
|
||||||
|
|
||||||
|
WlrLayershell.namespace: "quickshell:bar"
|
||||||
|
implicitHeight: Appearance.sizes.barHeight + Appearance.rounding.screenRounding
|
||||||
|
exclusiveZone: Appearance.sizes.baseBarHeight + (Config.options.bar.cornerStyle === 1 ? Appearance.sizes.hyprlandGapsOut : 0)
|
||||||
|
mask: Region {
|
||||||
|
item: barContent
|
||||||
|
}
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: !Config.options.bar.bottom
|
||||||
|
bottom: Config.options.bar.bottom
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // Bar content region
|
||||||
|
id: barContent
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
bottom: undefined
|
||||||
|
}
|
||||||
|
implicitHeight: Appearance.sizes.barHeight
|
||||||
|
height: Appearance.sizes.barHeight
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
AnchorChanges {
|
||||||
|
target: barContent
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
left: parent.left
|
||||||
|
top: undefined
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background shadow
|
||||||
|
Loader {
|
||||||
|
active: showBarBackground && Config.options.bar.cornerStyle === 1
|
||||||
|
anchors.fill: barBackground
|
||||||
|
sourceComponent: StyledRectangularShadow {
|
||||||
|
anchors.fill: undefined // The loader's anchors act on this, and this should not have any anchor
|
||||||
|
target: barBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Background
|
||||||
|
Rectangle {
|
||||||
|
id: barBackground
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0 // idk why but +1 is needed
|
||||||
|
}
|
||||||
|
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
radius: Config.options.bar.cornerStyle === 1 ? Appearance.rounding.windowRounding : 0
|
||||||
|
border.width: Config.options.bar.cornerStyle === 1 ? 1 : 0
|
||||||
|
border.color: Appearance.m3colors.m3outlineVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea { // Left side | scroll to change brightness
|
||||||
|
id: barLeftSideMouseArea
|
||||||
|
anchors.left: parent.left
|
||||||
|
implicitHeight: Appearance.sizes.baseBarHeight
|
||||||
|
height: Appearance.sizes.barHeight
|
||||||
|
width: (barRoot.width - middleSection.width) / 2
|
||||||
|
property bool hovered: false
|
||||||
|
property real lastScrollX: 0
|
||||||
|
property real lastScrollY: 0
|
||||||
|
property bool trackingScroll: false
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onEntered: event => {
|
||||||
|
barLeftSideMouseArea.hovered = true;
|
||||||
|
}
|
||||||
|
onExited: event => {
|
||||||
|
barLeftSideMouseArea.hovered = false;
|
||||||
|
barLeftSideMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.LeftButton) {
|
||||||
|
Hyprland.dispatch('global quickshell:sidebarLeftOpen');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Scroll to change brightness
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: event => {
|
||||||
|
if (event.angleDelta.y < 0)
|
||||||
|
barRoot.brightnessMonitor.setBrightness(barRoot.brightnessMonitor.brightness - 0.05);
|
||||||
|
else if (event.angleDelta.y > 0)
|
||||||
|
barRoot.brightnessMonitor.setBrightness(barRoot.brightnessMonitor.brightness + 0.05);
|
||||||
|
// Store the mouse position and start tracking
|
||||||
|
barLeftSideMouseArea.lastScrollX = event.x;
|
||||||
|
barLeftSideMouseArea.lastScrollY = event.y;
|
||||||
|
barLeftSideMouseArea.trackingScroll = true;
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
if (barLeftSideMouseArea.trackingScroll) {
|
||||||
|
const dx = mouse.x - barLeftSideMouseArea.lastScrollX;
|
||||||
|
const dy = mouse.y - barLeftSideMouseArea.lastScrollY;
|
||||||
|
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
|
||||||
|
Hyprland.dispatch('global quickshell:osdBrightnessHide');
|
||||||
|
barLeftSideMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
// Left section
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitHeight: leftSectionRowLayout.implicitHeight
|
||||||
|
implicitWidth: leftSectionRowLayout.implicitWidth
|
||||||
|
|
||||||
|
ScrollHint {
|
||||||
|
reveal: barLeftSideMouseArea.hovered
|
||||||
|
icon: "light_mode"
|
||||||
|
tooltipText: qsTr("Scroll to change brightness")
|
||||||
|
side: "left"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout { // Content
|
||||||
|
id: leftSectionRowLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
RippleButton {
|
||||||
|
// Left sidebar button
|
||||||
|
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||||
|
Layout.leftMargin: Appearance.rounding.screenRounding
|
||||||
|
Layout.fillWidth: false
|
||||||
|
property real buttonPadding: 5
|
||||||
|
implicitWidth: distroIcon.width + buttonPadding * 2
|
||||||
|
implicitHeight: distroIcon.height + buttonPadding * 2
|
||||||
|
|
||||||
|
buttonRadius: Appearance.rounding.full
|
||||||
|
colBackground: barLeftSideMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||||
|
colBackgroundHover: Appearance.colors.colLayer1Hover
|
||||||
|
colRipple: Appearance.colors.colLayer1Active
|
||||||
|
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||||
|
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||||
|
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||||
|
toggled: GlobalStates.sidebarLeftOpen
|
||||||
|
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
Hyprland.dispatch('global quickshell:sidebarLeftToggle');
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomIcon {
|
||||||
|
id: distroIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: 19.5
|
||||||
|
height: 19.5
|
||||||
|
source: Config.options.bar.topLeftIcon == 'distro' ? SystemInfo.distroIcon : "spark-symbolic"
|
||||||
|
colorize: true
|
||||||
|
color: Appearance.colors.colOnLayer0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveWindow {
|
||||||
|
visible: barRoot.useShortenedForm === 0
|
||||||
|
Layout.rightMargin: Appearance.rounding.screenRounding
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
bar: barRoot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout { // Middle section
|
||||||
|
id: middleSection
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Config.options?.bar.borderless ? 4 : 8
|
||||||
|
|
||||||
|
BarGroup {
|
||||||
|
id: leftCenterGroup
|
||||||
|
Layout.preferredWidth: barRoot.centerSideModuleWidth
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
Resources {
|
||||||
|
alwaysShowAllResources: barRoot.useShortenedForm === 2
|
||||||
|
Layout.fillWidth: barRoot.useShortenedForm === 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Media {
|
||||||
|
visible: barRoot.useShortenedForm < 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarSeparator {
|
||||||
|
visible: Config.options?.bar.borderless
|
||||||
|
}
|
||||||
|
|
||||||
|
BarGroup {
|
||||||
|
id: middleCenterGroup
|
||||||
|
padding: workspacesWidget.widgetPadding
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
Workspaces {
|
||||||
|
id: workspacesWidget
|
||||||
|
bar: barRoot
|
||||||
|
Layout.fillHeight: true
|
||||||
|
MouseArea {
|
||||||
|
// Right-click to toggle overview
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.RightButton) {
|
||||||
|
Hyprland.dispatch('global quickshell:overviewToggle');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarSeparator {
|
||||||
|
visible: Config.options?.bar.borderless
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: rightCenterGroup
|
||||||
|
implicitWidth: rightCenterGroupContent.implicitWidth
|
||||||
|
implicitHeight: rightCenterGroupContent.implicitHeight
|
||||||
|
Layout.preferredWidth: barRoot.centerSideModuleWidth
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
Hyprland.dispatch('global quickshell:sidebarRightToggle');
|
||||||
|
}
|
||||||
|
|
||||||
|
BarGroup {
|
||||||
|
id: rightCenterGroupContent
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
ClockWidget {
|
||||||
|
showDate: (Config.options.bar.verbose && barRoot.useShortenedForm < 2)
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
UtilButtons {
|
||||||
|
visible: (Config.options.bar.verbose && barRoot.useShortenedForm === 0)
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryIndicator {
|
||||||
|
visible: (barRoot.useShortenedForm < 2 && UPower.displayDevice.isLaptopBattery)
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarSeparator {
|
||||||
|
visible: Config.options.bar.borderless && Config.options.bar.weather.enable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea { // Right side | scroll to change volume
|
||||||
|
id: barRightSideMouseArea
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
implicitHeight: Appearance.sizes.baseBarHeight
|
||||||
|
height: Appearance.sizes.barHeight
|
||||||
|
width: (barRoot.width - middleSection.width) / 2
|
||||||
|
|
||||||
|
property bool hovered: false
|
||||||
|
property real lastScrollX: 0
|
||||||
|
property real lastScrollY: 0
|
||||||
|
property bool trackingScroll: false
|
||||||
|
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onEntered: event => {
|
||||||
|
barRightSideMouseArea.hovered = true;
|
||||||
|
}
|
||||||
|
onExited: event => {
|
||||||
|
barRightSideMouseArea.hovered = false;
|
||||||
|
barRightSideMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.LeftButton) {
|
||||||
|
Hyprland.dispatch('global quickshell:sidebarRightOpen');
|
||||||
|
} else if (event.button === Qt.RightButton) {
|
||||||
|
MprisController.activePlayer.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Scroll to change volume
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: event => {
|
||||||
|
const currentVolume = Audio.value;
|
||||||
|
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||||
|
if (event.angleDelta.y < 0)
|
||||||
|
Audio.sink.audio.volume -= step;
|
||||||
|
else if (event.angleDelta.y > 0)
|
||||||
|
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
|
||||||
|
// Store the mouse position and start tracking
|
||||||
|
barRightSideMouseArea.lastScrollX = event.x;
|
||||||
|
barRightSideMouseArea.lastScrollY = event.y;
|
||||||
|
barRightSideMouseArea.trackingScroll = true;
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
if (barRightSideMouseArea.trackingScroll) {
|
||||||
|
const dx = mouse.x - barRightSideMouseArea.lastScrollX;
|
||||||
|
const dy = mouse.y - barRightSideMouseArea.lastScrollY;
|
||||||
|
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
|
||||||
|
Hyprland.dispatch('global quickshell:osdVolumeHide');
|
||||||
|
barRightSideMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitHeight: rightSectionRowLayout.implicitHeight
|
||||||
|
implicitWidth: rightSectionRowLayout.implicitWidth
|
||||||
|
|
||||||
|
ScrollHint {
|
||||||
|
reveal: barRightSideMouseArea.hovered
|
||||||
|
icon: "volume_up"
|
||||||
|
tooltipText: qsTr("Scroll to change volume")
|
||||||
|
side: "right"
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: rightSectionRowLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 5
|
||||||
|
layoutDirection: Qt.RightToLeft
|
||||||
|
|
||||||
|
RippleButton { // Right sidebar button
|
||||||
|
id: rightSidebarButton
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
Layout.rightMargin: Appearance.rounding.screenRounding
|
||||||
|
Layout.fillWidth: false
|
||||||
|
|
||||||
|
implicitWidth: indicatorsRowLayout.implicitWidth + 10 * 2
|
||||||
|
implicitHeight: indicatorsRowLayout.implicitHeight + 5 * 2
|
||||||
|
|
||||||
|
buttonRadius: Appearance.rounding.full
|
||||||
|
colBackground: barRightSideMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||||
|
colBackgroundHover: Appearance.colors.colLayer1Hover
|
||||||
|
colRipple: Appearance.colors.colLayer1Active
|
||||||
|
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||||
|
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||||
|
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||||
|
toggled: GlobalStates.sidebarRightOpen
|
||||||
|
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
|
||||||
|
|
||||||
|
Behavior on colText {
|
||||||
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
Hyprland.dispatch('global quickshell:sidebarRightToggle');
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: indicatorsRowLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property real realSpacing: 15
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Revealer {
|
||||||
|
reveal: Audio.sink?.audio?.muted ?? false
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.rightMargin: reveal ? indicatorsRowLayout.realSpacing : 0
|
||||||
|
Behavior on Layout.rightMargin {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementMoveFast.duration
|
||||||
|
easing.type: Appearance.animation.elementMoveFast.type
|
||||||
|
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: "volume_off"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Revealer {
|
||||||
|
reveal: Audio.source?.audio?.muted ?? false
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.rightMargin: reveal ? indicatorsRowLayout.realSpacing : 0
|
||||||
|
Behavior on Layout.rightMargin {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementMoveFast.duration
|
||||||
|
easing.type: Appearance.animation.elementMoveFast.type
|
||||||
|
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: "mic_off"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
Layout.rightMargin: indicatorsRowLayout.realSpacing
|
||||||
|
text: Network.materialSymbol
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: Bluetooth.bluetoothConnected ? "bluetooth_connected" : Bluetooth.bluetoothEnabled ? "bluetooth" : "bluetooth_disabled"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysTray {
|
||||||
|
bar: barRoot
|
||||||
|
visible: barRoot.useShortenedForm === 0
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
Loader {
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
Layout.fillHeight: true
|
||||||
|
active: Config.options.bar.weather.enable
|
||||||
|
sourceComponent: BarGroup {
|
||||||
|
implicitHeight: Appearance.sizes.baseBarHeight
|
||||||
|
WeatherBar {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round decorators
|
||||||
|
Loader {
|
||||||
|
id: roundDecorators
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
y: Appearance.sizes.barHeight
|
||||||
|
width: parent.width
|
||||||
|
height: Appearance.rounding.screenRounding
|
||||||
|
active: showBarBackground && Config.options.bar.cornerStyle === 0 // Hug
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
PropertyChanges {
|
||||||
|
roundDecorators.y: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
implicitHeight: Appearance.rounding.screenRounding
|
||||||
|
RoundCorner {
|
||||||
|
id: leftCorner
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
|
size: Appearance.rounding.screenRounding
|
||||||
|
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
opacity: 1.0 - Appearance.transparency
|
||||||
|
|
||||||
|
corner: RoundCorner.CornerEnum.TopLeft
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
PropertyChanges {
|
||||||
|
leftCorner.corner: RoundCorner.CornerEnum.BottomLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RoundCorner {
|
||||||
|
id: rightCorner
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
top: !Config.options.bar.bottom ? parent.top : undefined
|
||||||
|
bottom: Config.options.bar.bottom ? parent.bottom : undefined
|
||||||
|
}
|
||||||
|
size: Appearance.rounding.screenRounding
|
||||||
|
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
opacity: 1.0 - Appearance.transparency
|
||||||
|
|
||||||
|
corner: RoundCorner.CornerEnum.TopRight
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
PropertyChanges {
|
||||||
|
rightCorner.corner: RoundCorner.CornerEnum.BottomRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "bar"
|
||||||
|
|
||||||
|
function toggle(): void {
|
||||||
|
GlobalStates.barOpen = !GlobalStates.barOpen
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): void {
|
||||||
|
GlobalStates.barOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(): void {
|
||||||
|
GlobalStates.barOpen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barToggle"
|
||||||
|
description: qsTr("Toggles bar on press")
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = !GlobalStates.barOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barOpen"
|
||||||
|
description: qsTr("Opens bar on press")
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barClose"
|
||||||
|
description: qsTr("Closes bar on press")
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -173,14 +173,7 @@ Item {
|
|||||||
id: workspaceButtonBackground
|
id: workspaceButtonBackground
|
||||||
implicitWidth: workspaceButtonWidth
|
implicitWidth: workspaceButtonWidth
|
||||||
implicitHeight: workspaceButtonWidth
|
implicitHeight: workspaceButtonWidth
|
||||||
property var biggestWindow: {
|
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(button.workspaceValue)
|
||||||
const windowsInThisWorkspace = HyprlandData.windowList.filter(w => w.workspace.id == button.workspaceValue)
|
|
||||||
return windowsInThisWorkspace.reduce((maxWin, win) => {
|
|
||||||
const maxArea = (maxWin?.size?.[0] ?? 0) * (maxWin?.size?.[1] ?? 0)
|
|
||||||
const winArea = (win?.size?.[0] ?? 0) * (win?.size?.[1] ?? 0)
|
|
||||||
return winArea > maxArea ? win : maxWin
|
|
||||||
}, null)
|
|
||||||
}
|
|
||||||
property var mainAppIconSource: Quickshell.iconPath(AppSearch.guessIcon(biggestWindow?.class), "image-missing")
|
property var mainAppIconSource: Quickshell.iconPath(AppSearch.guessIcon(biggestWindow?.class), "image-missing")
|
||||||
|
|
||||||
StyledText { // Workspace number text
|
StyledText { // Workspace number text
|
||||||
@@ -206,6 +199,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle { // Dot instead of ws number
|
Rectangle { // Dot instead of ws number
|
||||||
|
id: wsDot
|
||||||
opacity: (Config.options?.bar.workspaces.alwaysShowNumbers
|
opacity: (Config.options?.bar.workspaces.alwaysShowNumbers
|
||||||
|| GlobalStates.workspaceShowNumbers
|
|| GlobalStates.workspaceShowNumbers
|
||||||
|| (Config.options?.bar.workspaces.showAppIcons && workspaceButtonBackground.biggestWindow)
|
|| (Config.options?.bar.workspaces.showAppIcons && workspaceButtonBackground.biggestWindow)
|
||||||
@@ -257,6 +251,25 @@ Item {
|
|||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: Config.options.bar.workspaces.monochromeIcons
|
||||||
|
anchors.fill: mainAppIcon
|
||||||
|
sourceComponent: Item {
|
||||||
|
Desaturate {
|
||||||
|
id: desaturatedIcon
|
||||||
|
visible: false // There's already color overlay
|
||||||
|
anchors.fill: parent
|
||||||
|
source: mainAppIcon
|
||||||
|
desaturation: 0.8
|
||||||
|
}
|
||||||
|
ColorOverlay {
|
||||||
|
anchors.fill: desaturatedIcon
|
||||||
|
source: desaturatedIcon
|
||||||
|
color: ColorUtils.transparentize(wsDot.color, 0.9)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import "root:/services"
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: root
|
||||||
|
property real margin: 10
|
||||||
|
property bool hovered: false
|
||||||
|
implicitWidth: rowLayout.implicitWidth + margin * 2
|
||||||
|
implicitHeight: rowLayout.implicitHeight
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: rowLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
MaterialSymbol {
|
||||||
|
fill: 0
|
||||||
|
text: WeatherIcons.codeToName[Weather.data.wCode]
|
||||||
|
iconSize: Appearance.font.pixelSize.large
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
visible: true
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
text: Weather.data.temp
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: popupLoader
|
||||||
|
active: root.containsMouse
|
||||||
|
|
||||||
|
component: PopupWindow {
|
||||||
|
id: popupWindow
|
||||||
|
visible: true
|
||||||
|
implicitWidth: weatherPopup.implicitWidth
|
||||||
|
implicitHeight: weatherPopup.implicitHeight
|
||||||
|
anchor.item: root
|
||||||
|
anchor.edges: Edges.Bottom
|
||||||
|
anchor.rect.x: (root.implicitWidth - popupWindow.implicitWidth) / 2
|
||||||
|
anchor.rect.y: root.implicitHeight + 10
|
||||||
|
color: "transparent"
|
||||||
|
WeatherPopup {
|
||||||
|
id: weatherPopup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
color: Appearance.colors.colLayer1
|
||||||
|
implicitWidth: columnLayout.implicitWidth * 2
|
||||||
|
implicitHeight: columnLayout.implicitHeight * 2
|
||||||
|
Layout.fillWidth: parent
|
||||||
|
|
||||||
|
property alias title: title.text
|
||||||
|
property alias value: value.text
|
||||||
|
property alias symbol: symbol.text
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: -10
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
MaterialSymbol {
|
||||||
|
id: symbol
|
||||||
|
fill: 0
|
||||||
|
iconSize: Appearance.font.pixelSize.normal
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
id: title
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
id: value
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.normal
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
// credits: calestia
|
||||||
|
// this snippet is taken from
|
||||||
|
// https://github.com/caelestia-dots/shell
|
||||||
|
readonly property var codeToName: ({
|
||||||
|
"113": "clear_day",
|
||||||
|
"116": "partly_cloudy_day",
|
||||||
|
"119": "cloud",
|
||||||
|
"122": "cloud",
|
||||||
|
"143": "foggy",
|
||||||
|
"176": "rainy",
|
||||||
|
"179": "rainy",
|
||||||
|
"182": "rainy",
|
||||||
|
"185": "rainy",
|
||||||
|
"200": "thunderstorm",
|
||||||
|
"227": "cloudy_snowing",
|
||||||
|
"230": "snowing_heavy",
|
||||||
|
"248": "foggy",
|
||||||
|
"260": "foggy",
|
||||||
|
"263": "rainy",
|
||||||
|
"266": "rainy",
|
||||||
|
"281": "rainy",
|
||||||
|
"284": "rainy",
|
||||||
|
"293": "rainy",
|
||||||
|
"296": "rainy",
|
||||||
|
"299": "rainy",
|
||||||
|
"302": "weather_hail",
|
||||||
|
"305": "rainy",
|
||||||
|
"308": "weather_hail",
|
||||||
|
"311": "rainy",
|
||||||
|
"314": "rainy",
|
||||||
|
"317": "rainy",
|
||||||
|
"320": "cloudy_snowing",
|
||||||
|
"323": "cloudy_snowing",
|
||||||
|
"326": "cloudy_snowing",
|
||||||
|
"329": "snowing_heavy",
|
||||||
|
"332": "snowing_heavy",
|
||||||
|
"335": "snowing",
|
||||||
|
"338": "snowing_heavy",
|
||||||
|
"350": "rainy",
|
||||||
|
"353": "rainy",
|
||||||
|
"356": "rainy",
|
||||||
|
"359": "weather_hail",
|
||||||
|
"362": "rainy",
|
||||||
|
"365": "rainy",
|
||||||
|
"368": "cloudy_snowing",
|
||||||
|
"371": "snowing",
|
||||||
|
"374": "rainy",
|
||||||
|
"377": "rainy",
|
||||||
|
"386": "thunderstorm",
|
||||||
|
"389": "thunderstorm",
|
||||||
|
"392": "thunderstorm",
|
||||||
|
"395": "snowing"
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import "root:/services"
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
readonly property real margin: 10
|
||||||
|
implicitWidth: columnLayout.implicitWidth + margin * 2
|
||||||
|
implicitHeight: columnLayout.implicitHeight + margin * 2
|
||||||
|
color: Appearance.colors.colLayer0
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
border.width: 1
|
||||||
|
border.color: Appearance.m3colors.m3outlineVariant
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
spacing: 5
|
||||||
|
anchors.centerIn: root
|
||||||
|
implicitWidth: Math.max(header.implicitWidth, gridLayout.implicitWidth)
|
||||||
|
implicitHeight: gridLayout.implicitHeight
|
||||||
|
|
||||||
|
// Header
|
||||||
|
RowLayout {
|
||||||
|
id: header
|
||||||
|
spacing: 5
|
||||||
|
Layout.fillWidth: parent
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
MaterialSymbol {
|
||||||
|
fill: 0
|
||||||
|
text: "location_on"
|
||||||
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Weather.data.city
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.title
|
||||||
|
font.family: Appearance.font.family.title
|
||||||
|
color: Appearance.colors.colOnLayer0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metrics grid
|
||||||
|
GridLayout {
|
||||||
|
id: gridLayout
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 5
|
||||||
|
columnSpacing: 5
|
||||||
|
uniformCellWidths: true
|
||||||
|
|
||||||
|
WeatherCard {
|
||||||
|
title: "UV Index"
|
||||||
|
symbol: "wb_sunny"
|
||||||
|
value: Weather.data.uv
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Wind"
|
||||||
|
symbol: "air"
|
||||||
|
value: `(${Weather.data.windDir}) ${Weather.data.wind}`
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Precipitation"
|
||||||
|
symbol: "rainy_light"
|
||||||
|
value: Weather.data.precip
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Humidity"
|
||||||
|
symbol: "humidity_low"
|
||||||
|
value: Weather.data.humidity
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Visibility"
|
||||||
|
symbol: "visibility"
|
||||||
|
value: Weather.data.visib
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Pressure"
|
||||||
|
symbol: "readiness_score"
|
||||||
|
value: Weather.data.press
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Sunrise"
|
||||||
|
symbol: "wb_twilight"
|
||||||
|
value: Weather.data.sunrise
|
||||||
|
}
|
||||||
|
WeatherCard {
|
||||||
|
title: "Sunset"
|
||||||
|
symbol: "bedtime"
|
||||||
|
value: Weather.data.sunset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
@@ -15,11 +16,22 @@ import Quickshell.Hyprland
|
|||||||
|
|
||||||
Scope { // Scope
|
Scope { // Scope
|
||||||
id: root
|
id: root
|
||||||
|
property var tabButtonList: [
|
||||||
|
{
|
||||||
|
"icon": "keyboard",
|
||||||
|
"name": qsTr("Keybinds")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "experiment",
|
||||||
|
"name": qsTr("Elements")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
property int selectedTab: 0
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: cheatsheetLoader
|
id: cheatsheetLoader
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
sourceComponent: PanelWindow { // Window
|
sourceComponent: PanelWindow { // Window
|
||||||
id: cheatsheetRoot
|
id: cheatsheetRoot
|
||||||
visible: cheatsheetLoader.active
|
visible: cheatsheetLoader.active
|
||||||
@@ -32,7 +44,7 @@ Scope { // Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
cheatsheetLoader.active = false
|
cheatsheetLoader.active = false;
|
||||||
}
|
}
|
||||||
exclusiveZone: 0
|
exclusiveZone: 0
|
||||||
implicitWidth: cheatsheetBackground.width + Appearance.sizes.elevationMargin * 2
|
implicitWidth: cheatsheetBackground.width + Appearance.sizes.elevationMargin * 2
|
||||||
@@ -48,14 +60,14 @@ Scope { // Scope
|
|||||||
|
|
||||||
HyprlandFocusGrab { // Click outside to close
|
HyprlandFocusGrab { // Click outside to close
|
||||||
id: grab
|
id: grab
|
||||||
windows: [ cheatsheetRoot ]
|
windows: [cheatsheetRoot]
|
||||||
active: cheatsheetRoot.visible
|
active: cheatsheetRoot.visible
|
||||||
onCleared: () => {
|
onCleared: () => {
|
||||||
if (!active) cheatsheetRoot.hide()
|
if (!active)
|
||||||
|
cheatsheetRoot.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Background
|
// Background
|
||||||
StyledRectangularShadow {
|
StyledRectangularShadow {
|
||||||
target: cheatsheetBackground
|
target: cheatsheetBackground
|
||||||
@@ -64,14 +76,31 @@ Scope { // Scope
|
|||||||
id: cheatsheetBackground
|
id: cheatsheetBackground
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: Appearance.colors.colLayer0
|
color: Appearance.colors.colLayer0
|
||||||
|
border.width: 1
|
||||||
|
border.color: Appearance.m3colors.m3outlineVariant
|
||||||
radius: Appearance.rounding.windowRounding
|
radius: Appearance.rounding.windowRounding
|
||||||
property real padding: 30
|
property real padding: 30
|
||||||
implicitWidth: cheatsheetColumnLayout.implicitWidth + padding * 2
|
implicitWidth: cheatsheetColumnLayout.implicitWidth + padding * 2
|
||||||
implicitHeight: cheatsheetColumnLayout.implicitHeight + padding * 2
|
implicitHeight: cheatsheetColumnLayout.implicitHeight + padding * 2
|
||||||
|
|
||||||
Keys.onPressed: (event) => { // Esc to close
|
Keys.onPressed: event => { // Esc to close
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
cheatsheetRoot.hide()
|
cheatsheetRoot.hide();
|
||||||
|
}
|
||||||
|
if (event.modifiers === Qt.ControlModifier) {
|
||||||
|
if (event.key === Qt.Key_PageDown) {
|
||||||
|
root.selectedTab = Math.min(root.selectedTab + 1, root.tabButtonList.length - 1);
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_PageUp) {
|
||||||
|
root.selectedTab = Math.max(root.selectedTab - 1, 0);
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
|
root.selectedTab = (root.selectedTab + 1) % root.tabButtonList.length;
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
|
root.selectedTab = (root.selectedTab - 1 + root.tabButtonList.length) % root.tabButtonList.length;
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +118,7 @@ Scope { // Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
cheatsheetRoot.hide()
|
cheatsheetRoot.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: MaterialSymbol {
|
contentItem: MaterialSymbol {
|
||||||
@@ -112,10 +141,50 @@ Scope { // Scope
|
|||||||
font.pixelSize: Appearance.font.pixelSize.title
|
font.pixelSize: Appearance.font.pixelSize.title
|
||||||
text: Translation.tr("Cheat sheet")
|
text: Translation.tr("Cheat sheet")
|
||||||
}
|
}
|
||||||
CheatsheetKeybinds {}
|
PrimaryTabBar { // Tab strip
|
||||||
|
id: tabBar
|
||||||
|
tabButtonList: root.tabButtonList
|
||||||
|
externalTrackedTab: root.selectedTab
|
||||||
|
function onCurrentIndexChanged(currentIndex) {
|
||||||
|
root.selectedTab = currentIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwipeView { // Content pages
|
||||||
|
id: swipeView
|
||||||
|
Layout.topMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex: tabBar.externalTrackedTab
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
tabBar.enableIndicatorAnimation = true;
|
||||||
|
root.selectedTab = currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: Rectangle {
|
||||||
|
width: swipeView.width
|
||||||
|
height: swipeView.height
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatsheetKeybinds {}
|
||||||
|
CheatsheetPeriodicTable {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,15 +192,15 @@ Scope { // Scope
|
|||||||
target: "cheatsheet"
|
target: "cheatsheet"
|
||||||
|
|
||||||
function toggle(): void {
|
function toggle(): void {
|
||||||
cheatsheetLoader.active = !cheatsheetLoader.active
|
cheatsheetLoader.active = !cheatsheetLoader.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
function close(): void {
|
function close(): void {
|
||||||
cheatsheetLoader.active = false
|
cheatsheetLoader.active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(): void {
|
function open(): void {
|
||||||
cheatsheetLoader.active = true
|
cheatsheetLoader.active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,5 +230,4 @@ Scope { // Scope
|
|||||||
cheatsheetLoader.active = false;
|
cheatsheetLoader.active = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import "root:/"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
||||||
|
import "periodic_table.js" as PTable
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
readonly property var elements: PTable.elements
|
||||||
|
readonly property var series: PTable.series
|
||||||
|
property real spacing: 6
|
||||||
|
implicitWidth: mainLayout.implicitWidth
|
||||||
|
implicitHeight: mainLayout.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
spacing: root.spacing
|
||||||
|
|
||||||
|
Repeater { // Main table rows
|
||||||
|
model: root.elements
|
||||||
|
|
||||||
|
delegate: RowLayout { // Table cells
|
||||||
|
id: tableRow
|
||||||
|
spacing: root.spacing
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: tableRow.modelData
|
||||||
|
delegate: ElementTile {
|
||||||
|
required property var modelData
|
||||||
|
element: modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: gap
|
||||||
|
implicitHeight: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater { // Main table rows
|
||||||
|
model: root.series
|
||||||
|
|
||||||
|
delegate: RowLayout { // Table cells
|
||||||
|
id: seriesTableRow
|
||||||
|
spacing: root.spacing
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: seriesTableRow.modelData
|
||||||
|
delegate: ElementTile {
|
||||||
|
required property var modelData
|
||||||
|
element: modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
RippleButton {
|
||||||
|
id: root
|
||||||
|
required property var element
|
||||||
|
opacity: element.type != "empty" ? 1 : 0
|
||||||
|
implicitHeight: 60
|
||||||
|
implicitWidth: 60
|
||||||
|
colBackground: Appearance.colors.colLayer2
|
||||||
|
buttonRadius: Appearance.rounding.small
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
topMargin: 4
|
||||||
|
leftMargin: 4
|
||||||
|
}
|
||||||
|
color: Appearance.colors.colLayer2
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
implicitWidth: Math.max(20, elementNumber.implicitWidth)
|
||||||
|
implicitHeight: Math.max(20, elementNumber.implicitHeight)
|
||||||
|
width: height
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: elementNumber
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Appearance.colors.colOnLayer2
|
||||||
|
text: root.element.number
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.smallest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: elementSymbol
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Appearance.colors.colSecondary
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.huge
|
||||||
|
text: root.element.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: elementName
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: 4
|
||||||
|
}
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.smallest
|
||||||
|
color: Appearance.colors.colOnLayer2
|
||||||
|
text: root.element.name
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
// List of rows
|
||||||
|
const elements = [
|
||||||
|
[
|
||||||
|
{ name: 'Hydrogen', symbol: 'H', number: 1, weight: 1.01, type: 'nonmetal' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: 'Helium', symbol: 'He', number: 2, weight: 4.00, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Lithium', symbol: 'Li', number: 3, weight: 6.94, type: 'metal' },
|
||||||
|
{ name: 'Beryllium', symbol: 'Be', number: 4, weight: 9.01, type: 'metal' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: 'Boron', symbol: 'B', number: 5, weight: 10.81, type: 'nonmetal' },
|
||||||
|
{ name: 'Carbon', symbol: 'C', number: 6, weight: 12.01, type: 'nonmetal' },
|
||||||
|
{ name: 'Nitrogen', symbol: 'N', number: 7, weight: 14.01, type: 'nonmetal' },
|
||||||
|
{ name: 'Oxygen', symbol: 'O', number: 8, weight: 16, type: 'nonmetal' },
|
||||||
|
{ name: 'Fluorine', symbol: 'F', number: 9, weight: 19, type: 'nonmetal' },
|
||||||
|
{ name: 'Neon', symbol: 'Ne', number: 10, weight: 20.18, type: 'noblegas' },
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Sodium', symbol: 'Na', number: 11, weight: 22.99, type: 'metal' },
|
||||||
|
{ name: 'Magnesium', symbol: 'Mg', number: 12, weight: 24.31, type: 'metal' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: 'Aluminum', symbol: 'Al', number: 13, weight: 26.98, type: 'metal' },
|
||||||
|
{ name: 'Silicon', symbol: 'Si', number: 14, weight: 28.09, type: 'nonmetal' },
|
||||||
|
{ name: 'Phosphorus', symbol: 'P', number: 15, weight: 30.97, type: 'nonmetal' },
|
||||||
|
{ name: 'Sulfur', symbol: 'S', number: 16, weight: 32.07, type: 'nonmetal' },
|
||||||
|
{ name: 'Chlorine', symbol: 'Cl', number: 17, weight: 35.45, type: 'nonmetal' },
|
||||||
|
{ name: 'Argon', symbol: 'Ar', number: 18, weight: 39.95, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Potassium', symbol: 'K', number: 19, weight: 39.098, type: 'metal' },
|
||||||
|
{ name: 'Calcium', symbol: 'Ca', number: 20, weight: 40.078, type: 'metal' },
|
||||||
|
{ name: 'Scandium', symbol: 'Sc', number: 21, weight: 44.956, type: 'metal' },
|
||||||
|
{ name: 'Titanium', symbol: 'Ti', number: 22, weight: 47.87, type: 'metal' },
|
||||||
|
{ name: 'Vanadium', symbol: 'V', number: 23, weight: 50.94, type: 'metal' },
|
||||||
|
{ name: 'Chromium', symbol: 'Cr', number: 24, weight: 52, type: 'metal'/*, icon: 'chromium-browser'*/ },
|
||||||
|
{ name: 'Manganese', symbol: 'Mn', number: 25, weight: 54.94, type: 'metal' },
|
||||||
|
{ name: 'Iron', symbol: 'Fe', number: 26, weight: 55.85, type: 'metal' },
|
||||||
|
{ name: 'Cobalt', symbol: 'Co', number: 27, weight: 58.93, type: 'metal' },
|
||||||
|
{ name: 'Nickel', symbol: 'Ni', number: 28, weight: 58.69, type: 'metal' },
|
||||||
|
{ name: 'Copper', symbol: 'Cu', number: 29, weight: 63.55, type: 'metal' },
|
||||||
|
{ name: 'Zinc', symbol: 'Zn', number: 30, weight: 65.38, type: 'metal' },
|
||||||
|
{ name: 'Gallium', symbol: 'Ga', number: 31, weight: 69.72, type: 'metal' },
|
||||||
|
{ name: 'Germanium', symbol: 'Ge', number: 32, weight: 72.63, type: 'metal' },
|
||||||
|
{ name: 'Arsenic', symbol: 'As', number: 33, weight: 74.92, type: 'nonmetal' },
|
||||||
|
{ name: 'Selenium', symbol: 'Se', number: 34, weight: 78.96, type: 'nonmetal' },
|
||||||
|
{ name: 'Bromine', symbol: 'Br', number: 35, weight: 79.904, type: 'nonmetal' },
|
||||||
|
{ name: 'Krypton', symbol: 'Kr', number: 36, weight: 83.8, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Rubidium', symbol: 'Rb', number: 37, weight: 85.47, type: 'metal' },
|
||||||
|
{ name: 'Strontium', symbol: 'Sr', number: 38, weight: 87.62, type: 'metal' },
|
||||||
|
{ name: 'Yttrium', symbol: 'Y', number: 39, weight: 88.91, type: 'metal' },
|
||||||
|
{ name: 'Zirconium', symbol: 'Zr', number: 40, weight: 91.22, type: 'metal' },
|
||||||
|
{ name: 'Niobium', symbol: 'Nb', number: 41, weight: 92.91, type: 'metal' },
|
||||||
|
{ name: 'Molybdenum', symbol: 'Mo', number: 42, weight: 95.94, type: 'metal' },
|
||||||
|
{ name: 'Technetium', symbol: 'Tc', number: 43, weight: 98, type: 'metal' },
|
||||||
|
{ name: 'Ruthenium', symbol: 'Ru', number: 44, weight: 101.07, type: 'metal' },
|
||||||
|
{ name: 'Rhodium', symbol: 'Rh', number: 45, weight: 102.91, type: 'metal' },
|
||||||
|
{ name: 'Palladium', symbol: 'Pd', number: 46, weight: 106.42, type: 'metal' },
|
||||||
|
{ name: 'Silver', symbol: 'Ag', number: 47, weight: 107.87, type: 'metal' },
|
||||||
|
{ name: 'Cadmium', symbol: 'Cd', number: 48, weight: 112.41, type: 'metal' },
|
||||||
|
{ name: 'Indium', symbol: 'In', number: 49, weight: 114.82, type: 'metal' },
|
||||||
|
{ name: 'Tin', symbol: 'Sn', number: 50, weight: 118.71, type: 'metal' },
|
||||||
|
{ name: 'Antimony', symbol: 'Sb', number: 51, weight: 121.76, type: 'metal' },
|
||||||
|
{ name: 'Tellurium', symbol: 'Te', number: 52, weight: 127.6, type: 'nonmetal' },
|
||||||
|
{ name: 'Iodine', symbol: 'I', number: 53, weight: 126.9, type: 'nonmetal' },
|
||||||
|
{ name: 'Xenon', symbol: 'Xe', number: 54, weight: 131.29, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Cesium', symbol: 'Cs', number: 55, weight: 132.91, type: 'metal' },
|
||||||
|
{ name: 'Barium', symbol: 'Ba', number: 56, weight: 137.33, type: 'metal' },
|
||||||
|
{ name: 'Lanthanum', symbol: 'La', number: 57, weight: 138.91, type: 'lanthanum' },
|
||||||
|
{ name: 'Hafnium', symbol: 'Hf', number: 72, weight: 178.49, type: 'metal' },
|
||||||
|
{ name: 'Tantalum', symbol: 'Ta', number: 73, weight: 180.95, type: 'metal' },
|
||||||
|
{ name: 'Tungsten', symbol: 'W', number: 74, weight: 183.84, type: 'metal' },
|
||||||
|
{ name: 'Rhenium', symbol: 'Re', number: 75, weight: 186.21, type: 'metal' },
|
||||||
|
{ name: 'Osmium', symbol: 'Os', number: 76, weight: 190.23, type: 'metal' },
|
||||||
|
{ name: 'Iridium', symbol: 'Ir', number: 77, weight: 192.22, type: 'metal' },
|
||||||
|
{ name: 'Platinum', symbol: 'Pt', number: 78, weight: 195.09, type: 'metal' },
|
||||||
|
{ name: 'Gold', symbol: 'Au', number: 79, weight: 196.97, type: 'metal' },
|
||||||
|
{ name: 'Mercury', symbol: 'Hg', number: 80, weight: 200.59, type: 'metal' },
|
||||||
|
{ name: 'Thallium', symbol: 'Tl', number: 81, weight: 204.38, type: 'metal' },
|
||||||
|
{ name: 'Lead', symbol: 'Pb', number: 82, weight: 207.2, type: 'metal' },
|
||||||
|
{ name: 'Bismuth', symbol: 'Bi', number: 83, weight: 208.98, type: 'metal' },
|
||||||
|
{ name: 'Polonium', symbol: 'Po', number: 84, weight: 209, type: 'metal' },
|
||||||
|
{ name: 'Astatine', symbol: 'At', number: 85, weight: 210, type: 'nonmetal' },
|
||||||
|
{ name: 'Radon', symbol: 'Rn', number: 86, weight: 222, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Francium', symbol: 'Fr', number: 87, weight: 223, type: 'metal' },
|
||||||
|
{ name: 'Radium', symbol: 'Ra', number: 88, weight: 226, type: 'metal' },
|
||||||
|
{ name: 'Actinium', symbol: 'Ac', number: 89, weight: 227, type: 'actinium' },
|
||||||
|
{ name: 'Rutherfordium', symbol: 'Rf', number: 104, weight: 267, type: 'metal' },
|
||||||
|
{ name: 'Dubnium', symbol: 'Db', number: 105, weight: 268, type: 'metal' },
|
||||||
|
{ name: 'Seaborgium', symbol: 'Sg', number: 106, weight: 271, type: 'metal' },
|
||||||
|
{ name: 'Bohrium', symbol: 'Bh', number: 107, weight: 272, type: 'metal' },
|
||||||
|
{ name: 'Hassium', symbol: 'Hs', number: 108, weight: 277, type: 'metal' },
|
||||||
|
{ name: 'Meitnerium', symbol: 'Mt', number: 109, weight: 278, type: 'metal' },
|
||||||
|
{ name: 'Darmstadtium', symbol: 'Ds', number: 110, weight: 281, type: 'metal' },
|
||||||
|
{ name: 'Roentgenium', symbol: 'Rg', number: 111, weight: 280, type: 'metal' },
|
||||||
|
{ name: 'Copernicium', symbol: 'Cn', number: 112, weight: 285, type: 'metal' },
|
||||||
|
{ name: 'Nihonium', symbol: 'Nh', number: 113, weight: 286, type: 'metal' },
|
||||||
|
{ name: 'Flerovium', symbol: 'Fl', number: 114, weight: 289, type: 'metal' },
|
||||||
|
{ name: 'Moscovium', symbol: 'Mc', number: 115, weight: 290, type: 'metal' },
|
||||||
|
{ name: 'Livermorium', symbol: 'Lv', number: 116, weight: 293, type: 'metal' },
|
||||||
|
{ name: 'Tennessine', symbol: 'Ts', number: 117, weight: 294, type: 'metal' },
|
||||||
|
{ name: 'Oganesson', symbol: 'Og', number: 118, weight: 294, type: 'noblegas' },
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
const series = [
|
||||||
|
[
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: 'Cerium', symbol: 'Ce', number: 58, weight: 140.12, type: 'lanthanum' },
|
||||||
|
{ name: 'Praseodymium', symbol: 'Pr', number: 59, weight: 140.91, type: 'lanthanum' },
|
||||||
|
{ name: 'Neodymium', symbol: 'Nd', number: 60, weight: 144.24, type: 'lanthanum' },
|
||||||
|
{ name: 'Promethium', symbol: 'Pm', number: 61, weight: 145, type: 'lanthanum' },
|
||||||
|
{ name: 'Samarium', symbol: 'Sm', number: 62, weight: 150.36, type: 'lanthanum' },
|
||||||
|
{ name: 'Europium', symbol: 'Eu', number: 63, weight: 151.96, type: 'lanthanum' },
|
||||||
|
{ name: 'Gadolinium', symbol: 'Gd', number: 64, weight: 157.25, type: 'lanthanum' },
|
||||||
|
{ name: 'Terbium', symbol: 'Tb', number: 65, weight: 158.93, type: 'lanthanum' },
|
||||||
|
{ name: 'Dysprosium', symbol: 'Dy', number: 66, weight: 162.5, type: 'lanthanum' },
|
||||||
|
{ name: 'Holmium', symbol: 'Ho', number: 67, weight: 164.93, type: 'lanthanum' },
|
||||||
|
{ name: 'Erbium', symbol: 'Er', number: 68, weight: 167.26, type: 'lanthanum' },
|
||||||
|
{ name: 'Thulium', symbol: 'Tm', number: 69, weight: 168.93, type: 'lanthanum' },
|
||||||
|
{ name: 'Ytterbium', symbol: 'Yb', number: 70, weight: 173.04, type: 'lanthanum' },
|
||||||
|
{ name: 'Lutetium', symbol: 'Lu', number: 71, weight: 174.97, type: 'lanthanum' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
{ name: 'Thorium', symbol: 'Th', number: 90, weight: 232.04, type: 'actinium' },
|
||||||
|
{ name: 'Protactinium', symbol: 'Pa', number: 91, weight: 231.04, type: 'actinium' },
|
||||||
|
{ name: 'Uranium', symbol: 'U', number: 92, weight: 238.03, type: 'actinium' },
|
||||||
|
{ name: 'Neptunium', symbol: 'Np', number: 93, weight: 237, type: 'actinium' },
|
||||||
|
{ name: 'Plutonium', symbol: 'Pu', number: 94, weight: 244, type: 'actinium' },
|
||||||
|
{ name: 'Americium', symbol: 'Am', number: 95, weight: 243, type: 'actinium' },
|
||||||
|
{ name: 'Curium', symbol: 'Cm', number: 96, weight: 247, type: 'actinium' },
|
||||||
|
{ name: 'Berkelium', symbol: 'Bk', number: 97, weight: 247, type: 'actinium' },
|
||||||
|
{ name: 'Californium', symbol: 'Cf', number: 98, weight: 251, type: 'actinium' },
|
||||||
|
{ name: 'Einsteinium', symbol: 'Es', number: 99, weight: 252, type: 'actinium' },
|
||||||
|
{ name: 'Fermium', symbol: 'Fm', number: 100, weight: 257, type: 'actinium' },
|
||||||
|
{ name: 'Mendelevium', symbol: 'Md', number: 101, weight: 258, type: 'actinium' },
|
||||||
|
{ name: 'Nobelium', symbol: 'No', number: 102, weight: 259, type: 'actinium' },
|
||||||
|
{ name: 'Lawrencium', symbol: 'Lr', number: 103, weight: 262, type: 'actinium' },
|
||||||
|
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
const niceTypes = {
|
||||||
|
'metal': "Metal",
|
||||||
|
'nonmetal': "Nonmetal",
|
||||||
|
'noblegas': "Noble gas",
|
||||||
|
'lanthanum': "Lanthanum",
|
||||||
|
'actinium': "Actinium"
|
||||||
|
}
|
||||||
@@ -100,7 +100,7 @@ Singleton {
|
|||||||
|
|
||||||
colors: QtObject {
|
colors: QtObject {
|
||||||
property color colSubtext: m3colors.m3outline
|
property color colSubtext: m3colors.m3outline
|
||||||
property color colLayer0: ColorUtils.transparentize(m3colors.m3background, root.transparency)
|
property color colLayer0: ColorUtils.mix(ColorUtils.transparentize(m3colors.m3background, root.transparency), m3colors.m3primary, Config.options.appearance.extraBackgroundTint ? 0.99 : 1)
|
||||||
property color colOnLayer0: m3colors.m3onBackground
|
property color colOnLayer0: m3colors.m3onBackground
|
||||||
property color colLayer0Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.9, root.contentTransparency))
|
property color colLayer0Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.9, root.contentTransparency))
|
||||||
property color colLayer0Active: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.8, root.contentTransparency))
|
property color colLayer0Active: ColorUtils.transparentize(ColorUtils.mix(colLayer0, colOnLayer0, 0.8, root.contentTransparency))
|
||||||
@@ -63,6 +63,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject appearance: JsonObject {
|
property JsonObject appearance: JsonObject {
|
||||||
|
property bool extraBackgroundTint: true
|
||||||
property int fakeScreenRounding: 2 // 0: None | 1: Always | 2: When not fullscreen
|
property int fakeScreenRounding: 2 // 0: None | 1: Always | 2: When not fullscreen
|
||||||
property bool transparency: false
|
property bool transparency: false
|
||||||
property JsonObject palette: JsonObject {
|
property JsonObject palette: JsonObject {
|
||||||
@@ -117,11 +118,19 @@ Singleton {
|
|||||||
property bool monochromeIcons: true
|
property bool monochromeIcons: true
|
||||||
}
|
}
|
||||||
property JsonObject workspaces: JsonObject {
|
property JsonObject workspaces: JsonObject {
|
||||||
|
property bool monochromeIcons: true
|
||||||
property int shown: 10
|
property int shown: 10
|
||||||
property bool showAppIcons: true
|
property bool showAppIcons: true
|
||||||
property bool alwaysShowNumbers: false
|
property bool alwaysShowNumbers: false
|
||||||
property int showNumberDelay: 300 // milliseconds
|
property int showNumberDelay: 300 // milliseconds
|
||||||
}
|
}
|
||||||
|
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 battery: JsonObject {
|
property JsonObject battery: JsonObject {
|
||||||
@@ -133,8 +142,9 @@ Singleton {
|
|||||||
|
|
||||||
property JsonObject dock: JsonObject {
|
property JsonObject dock: JsonObject {
|
||||||
property bool enable: false
|
property bool enable: false
|
||||||
|
property bool monochromeIcons: true
|
||||||
property real height: 60
|
property real height: 60
|
||||||
property real hoverRegionHeight: 3
|
property real hoverRegionHeight: 2
|
||||||
property bool pinnedOnStartup: false
|
property bool pinnedOnStartup: false
|
||||||
property bool hoverToReveal: true // When false, only reveals on empty workspace
|
property bool hoverToReveal: true // When false, only reveals on empty workspace
|
||||||
property list<string> pinnedApps: [ // IDs of pinned entries
|
property list<string> pinnedApps: [ // IDs of pinned entries
|
||||||
@@ -201,7 +211,7 @@ Singleton {
|
|||||||
property JsonObject time: JsonObject {
|
property JsonObject time: JsonObject {
|
||||||
// https://doc.qt.io/qt-6/qtime.html#toString
|
// https://doc.qt.io/qt-6/qtime.html#toString
|
||||||
property string format: "hh:mm"
|
property string format: "hh:mm"
|
||||||
property string dateFormat: "dddd, dd/MM"
|
property string dateFormat: "ddd, dd/MM"
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject windows: JsonObject {
|
property JsonObject windows: JsonObject {
|
||||||
@@ -212,6 +222,10 @@ Singleton {
|
|||||||
property JsonObject hacks: JsonObject {
|
property JsonObject hacks: JsonObject {
|
||||||
property int arbitraryRaceConditionDelay: 20 // milliseconds
|
property int arbitraryRaceConditionDelay: 20 // milliseconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property JsonObject screenshotTool: JsonObject {
|
||||||
|
property bool showContentRegions: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,8 @@ Singleton {
|
|||||||
readonly property string downloads: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
readonly property string downloads: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
||||||
|
|
||||||
// Other dirs used by the shell, without "file://"
|
// Other dirs used by the shell, without "file://"
|
||||||
property string scriptPath: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/scripts`)
|
property string assetsPath: Quickshell.configPath("assets")
|
||||||
|
property string scriptPath: Quickshell.configPath("scripts")
|
||||||
property string favicons: FileUtils.trimFileProtocol(`${Directories.cache}/media/favicons`)
|
property string favicons: FileUtils.trimFileProtocol(`${Directories.cache}/media/favicons`)
|
||||||
property string coverArt: FileUtils.trimFileProtocol(`${Directories.cache}/media/coverart`)
|
property string coverArt: FileUtils.trimFileProtocol(`${Directories.cache}/media/coverart`)
|
||||||
property string booruPreviews: FileUtils.trimFileProtocol(`${Directories.cache}/media/boorus`)
|
property string booruPreviews: FileUtils.trimFileProtocol(`${Directories.cache}/media/boorus`)
|
||||||
@@ -30,17 +31,20 @@ Singleton {
|
|||||||
property string notificationsPath: FileUtils.trimFileProtocol(`${Directories.cache}/notifications/notifications.json`)
|
property string notificationsPath: FileUtils.trimFileProtocol(`${Directories.cache}/notifications/notifications.json`)
|
||||||
property string generatedMaterialThemePath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/colors.json`)
|
property string generatedMaterialThemePath: FileUtils.trimFileProtocol(`${Directories.state}/user/generated/colors.json`)
|
||||||
property string cliphistDecode: FileUtils.trimFileProtocol(`/tmp/quickshell/media/cliphist`)
|
property string cliphistDecode: FileUtils.trimFileProtocol(`/tmp/quickshell/media/cliphist`)
|
||||||
|
property string screenshotTemp: "/tmp/quickshell/media/screenshot"
|
||||||
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
|
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
|
||||||
property string defaultAiPrompts: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/defaults/ai/prompts`)
|
property string defaultAiPrompts: Quickshell.configPath("defaults/ai/prompts")
|
||||||
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
||||||
|
property string aiChats: FileUtils.trimFileProtocol(`${Directories.state}/user/ai/chats`)
|
||||||
// Cleanup on init
|
// Cleanup on init
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${shellConfig}'`])
|
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${favicons}'`])
|
Quickshell.execDetached(["mkdir", "-p", `${favicons}`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
|
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 '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
|
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
|
||||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
|
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
|
||||||
|
Quickshell.execDetached(["mkdir", "-p", `${aiChats}`])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,10 +158,10 @@ function cleanMusicTitle(title) {
|
|||||||
// Japenis brackets
|
// Japenis brackets
|
||||||
title = title.replace(/^ *【[^】]*】/, "") // Touhou
|
title = title.replace(/^ *【[^】]*】/, "") // Touhou
|
||||||
title = title.replace(/^ *《[^》]*》/, "") // ??
|
title = title.replace(/^ *《[^》]*》/, "") // ??
|
||||||
title = title.replace(/^ *「[^」]*」/, "") // OP/ED
|
title = title.replace(/^ *「[^」]*」/, "") // OP/ED thingie
|
||||||
title = title.replace(/^ *『[^』]*』/, "") // OP/ED
|
title = title.replace(/^ *『[^』]*』/, "") // OP/ED thingie
|
||||||
|
|
||||||
return title;
|
return title.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
function friendlyTimeForSeconds(seconds) {
|
function friendlyTimeForSeconds(seconds) {
|
||||||
@@ -20,6 +20,7 @@ Rectangle {
|
|||||||
let total = 0;
|
let total = 0;
|
||||||
for (let i = 0; i < rowLayout.children.length; ++i) {
|
for (let i = 0; i < rowLayout.children.length; ++i) {
|
||||||
const child = rowLayout.children[i];
|
const child = rowLayout.children[i];
|
||||||
|
if (!child.visible) continue;
|
||||||
total += child.baseWidth ?? child.implicitWidth ?? child.width;
|
total += child.baseWidth ?? child.implicitWidth ?? child.width;
|
||||||
}
|
}
|
||||||
return total + rowLayout.spacing * (rowLayout.children.length - 1);
|
return total + rowLayout.spacing * (rowLayout.children.length - 1);
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool colorize: false
|
||||||
|
property color color
|
||||||
property string source: ""
|
property string source: ""
|
||||||
property string iconFolder: "root:/assets/icons" // The folder to check first
|
property string iconFolder: "root:/assets/icons" // The folder to check first
|
||||||
width: 30
|
width: 30
|
||||||
@@ -21,4 +24,13 @@ Item {
|
|||||||
}
|
}
|
||||||
implicitSize: root.height
|
implicitSize: root.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: root.colorize
|
||||||
|
anchors.fill: iconImage
|
||||||
|
sourceComponent: ColorOverlay {
|
||||||
|
source: iconImage
|
||||||
|
color: root.color
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||