mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
Merge branch 'end-4:main' into parallax
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Auto start Hyprland on tty1
|
||||
if test -z "$DISPLAY" ;and test "$XDG_VTNR" -eq 1
|
||||
mkdir -p ~/.cache
|
||||
exec Hyprland > ~/.cache/hyprland.log 2>&1
|
||||
exec start-hyprland > ~/.cache/hyprland.log 2>&1
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# ######## Window rules ########
|
||||
|
||||
# Uncomment to apply global transparency to all windows:
|
||||
# windowrulev2 = opacity 0.89 override 0.89 override, class:.*
|
||||
# windowrule = opacity 0.89 override 0.89 override, match:class .*
|
||||
|
||||
# Disable blur for all xwayland apps
|
||||
# windowrulev2 = noblur, xwayland:1
|
||||
# windowrule = no_blur on, match:xwayland 1
|
||||
|
||||
@@ -31,4 +31,4 @@ plugin {
|
||||
}
|
||||
}
|
||||
|
||||
windowrulev2 = bordercolor rgba(FFB2BCAA) rgba(FFB2BC77),pinned:1
|
||||
windowrule = border_color rgba(FFB2BCAA) rgba(FFB2BC77), match:pin 1
|
||||
|
||||
@@ -22,7 +22,7 @@ general {
|
||||
gaps_workspaces = 50
|
||||
|
||||
border_size = 1
|
||||
col.active_border = rgba(0DB7D4FF)
|
||||
col.active_border = rgba(0DB7D455)
|
||||
col.inactive_border = rgba(31313600)
|
||||
resize_on_border = true
|
||||
|
||||
@@ -31,10 +31,10 @@ general {
|
||||
allow_tearing = true # This just allows the `immediate` window rule to work
|
||||
|
||||
snap {
|
||||
enabled = true
|
||||
window_gap = 4
|
||||
monitor_gap = 5
|
||||
respect_gaps = true
|
||||
enabled = true
|
||||
window_gap = 4
|
||||
monitor_gap = 5
|
||||
respect_gaps = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ dwindle {
|
||||
}
|
||||
|
||||
decoration {
|
||||
# 2 = circle, higher = squircle, 4 = very obvious squircle
|
||||
# Clear squircles look really off; we use only extra .4 here to make the rounding feel more continuous
|
||||
rounding_power = 2.4
|
||||
rounding = 18
|
||||
|
||||
blur {
|
||||
@@ -69,15 +72,15 @@ decoration {
|
||||
shadow {
|
||||
enabled = true
|
||||
ignore_window = true
|
||||
range = 30
|
||||
offset = 0 2
|
||||
render_power = 4
|
||||
color = rgba(00000010)
|
||||
range = 50
|
||||
offset = 0 4
|
||||
render_power = 10
|
||||
color = rgba(00000027)
|
||||
}
|
||||
|
||||
# Dim
|
||||
dim_inactive = true
|
||||
dim_strength = 0.025
|
||||
dim_strength = 0.05
|
||||
dim_special = 0.07
|
||||
}
|
||||
|
||||
@@ -142,7 +145,7 @@ misc {
|
||||
animate_mouse_windowdragging = false
|
||||
enable_swallow = false
|
||||
swallow_regex = (foot|kitty|allacritty|Alacritty)
|
||||
new_window_takes_over_fullscreen = 2
|
||||
on_focus_under_fullscreen = 2
|
||||
allow_session_lock_restore = true
|
||||
session_lock_xray = true
|
||||
initial_workspace_tracking = false
|
||||
|
||||
@@ -1,165 +1,165 @@
|
||||
# ######## Window rules ########
|
||||
|
||||
# Disable blur for xwayland context menus
|
||||
windowrulev2 = noblur,class:^()$,title:^()$
|
||||
windowrule = match:class ^()$, match:title ^()$, no_blur on
|
||||
|
||||
# Disable blur for every window
|
||||
windowrulev2 = noblur, class:.*
|
||||
windowrule = match:class .*, no_blur on
|
||||
|
||||
# Floating
|
||||
windowrulev2 = center, title:^(Open File)(.*)$
|
||||
windowrulev2 = float, title:^(Open File)(.*)$
|
||||
windowrulev2 = center, title:^(Select a File)(.*)$
|
||||
windowrulev2 = float, title:^(Select a File)(.*)$
|
||||
windowrulev2 = center, title:^(Choose wallpaper)(.*)$
|
||||
windowrulev2 = float, title:^(Choose wallpaper)(.*)$
|
||||
windowrulev2 = size 60% 65%, title:^(Choose wallpaper)(.*)$
|
||||
windowrulev2 = center, title:^(Open Folder)(.*)$
|
||||
windowrulev2 = float, title:^(Open Folder)(.*)$
|
||||
windowrulev2 = center, title:^(Save As)(.*)$
|
||||
windowrulev2 = float, title:^(Save As)(.*)$
|
||||
windowrulev2 = center, title:^(Library)(.*)$
|
||||
windowrulev2 = float, title:^(Library)(.*)$
|
||||
windowrulev2 = center, title:^(File Upload)(.*)$
|
||||
windowrulev2 = float, title:^(File Upload)(.*)$
|
||||
windowrulev2 = center, title:^(.*)(wants to save)$
|
||||
windowrulev2 = float, title:^(.*)(wants to save)$
|
||||
windowrulev2 = center, title:^(.*)(wants to open)$
|
||||
windowrulev2 = float, title:^(.*)(wants to open)$
|
||||
windowrulev2 = float, class:^(blueberry\.py)$
|
||||
windowrulev2 = float, class:^(guifetch)$ # FlafyDev/guifetch
|
||||
windowrulev2 = float, class:^(pavucontrol)$
|
||||
windowrulev2 = size 45%, class:^(pavucontrol)$
|
||||
windowrulev2 = center, class:^(pavucontrol)$
|
||||
windowrulev2 = float, class:^(org.pulseaudio.pavucontrol)$
|
||||
windowrulev2 = size 45%, class:^(org.pulseaudio.pavucontrol)$
|
||||
windowrulev2 = center, class:^(org.pulseaudio.pavucontrol)$
|
||||
windowrulev2 = float, class:^(nm-connection-editor)$
|
||||
windowrulev2 = size 45%, class:^(nm-connection-editor)$
|
||||
windowrulev2 = center, class:^(nm-connection-editor)$
|
||||
windowrulev2 = float, class:.*plasmawindowed.*
|
||||
windowrulev2 = float, class:kcm_.*
|
||||
windowrulev2 = float, class:.*bluedevilwizard
|
||||
windowrulev2 = float, title:.*Welcome
|
||||
windowrulev2 = float, title:^(illogical-impulse Settings)$
|
||||
windowrulev2 = float, title:.*Shell conflicts.*
|
||||
windowrulev2 = float, class:org.freedesktop.impl.portal.desktop.kde
|
||||
windowrulev2 = size 60% 65%, class:org.freedesktop.impl.portal.desktop.kde
|
||||
windowrulev2 = float, class:^(Zotero)$
|
||||
windowrulev2 = size 45%, class:^(Zotero)$
|
||||
windowrule = match:title ^(Open File)(.*)$, center on
|
||||
windowrule = match:title ^(Open File)(.*)$, float on
|
||||
windowrule = match:title ^(Select a File)(.*)$, center on
|
||||
windowrule = match:title ^(Select a File)(.*)$, float on
|
||||
windowrule = match:title ^(Choose wallpaper)(.*)$, center on
|
||||
windowrule = match:title ^(Choose wallpaper)(.*)$, float on
|
||||
windowrule = match:title ^(Choose wallpaper)(.*)$, size (monitor_w*.60) (monitor_h*.65)
|
||||
windowrule = match:title ^(Open Folder)(.*)$, center on
|
||||
windowrule = match:title ^(Open Folder)(.*)$, float on
|
||||
windowrule = match:title ^(Save As)(.*)$, center on
|
||||
windowrule = match:title ^(Save As)(.*)$, float on
|
||||
windowrule = match:title ^(Library)(.*)$, center on
|
||||
windowrule = match:title ^(Library)(.*)$, float on
|
||||
windowrule = match:title ^(File Upload)(.*)$, center on
|
||||
windowrule = match:title ^(File Upload)(.*)$, float on
|
||||
windowrule = match:title ^(.*)(wants to save)$, center on
|
||||
windowrule = match:title ^(.*)(wants to save)$, float on
|
||||
windowrule = match:title ^(.*)(wants to open)$, center on
|
||||
windowrule = match:title ^(.*)(wants to open)$, float on
|
||||
windowrule = match:class ^(blueberry\.py)$, float on
|
||||
windowrule = match:class ^(guifetch)$ , float on # FlafyDev/guifetch
|
||||
windowrule = match:class ^(pavucontrol)$, float on
|
||||
windowrule = match:class ^(pavucontrol)$, size (monitor_w*.45) (monitor_h*.45)
|
||||
windowrule = match:class ^(pavucontrol)$, center on
|
||||
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, float on
|
||||
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, size (monitor_w*.45) (monitor_h*.45)
|
||||
windowrule = match:class ^(org.pulseaudio.pavucontrol)$, center on
|
||||
windowrule = match:class ^(nm-connection-editor)$, float on
|
||||
windowrule = match:class ^(nm-connection-editor)$, size (monitor_w*.45) (monitor_h*.45)
|
||||
windowrule = match:class ^(nm-connection-editor)$, center on
|
||||
windowrule = match:class .*plasmawindowed.*, float on
|
||||
windowrule = match:class kcm_.*, float on
|
||||
windowrule = match:class .*bluedevilwizard, float on
|
||||
windowrule = match:title .*Welcome, float on
|
||||
windowrule = match:title ^(illogical-impulse Settings)$, float on
|
||||
windowrule = match:title .*Shell conflicts.*, float on
|
||||
windowrule = match:class org.freedesktop.impl.portal.desktop.kde, float on
|
||||
windowrule = match:class org.freedesktop.impl.portal.desktop.kde, size (monitor_w*.60) (monitor_h*.65)
|
||||
windowrule = match:class ^(Zotero)$, float on
|
||||
windowrule = match:class ^(Zotero)$, size (monitor_w*.45) (monitor_h*.45)
|
||||
|
||||
# Move
|
||||
# kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
|
||||
windowrulev2 = float, class:^(plasma-changeicons)$
|
||||
windowrulev2 = noinitialfocus, class:^(plasma-changeicons)$
|
||||
windowrulev2 = move 999999 999999, class:^(plasma-changeicons)$
|
||||
windowrule = match:class ^(plasma-changeicons)$, float on
|
||||
windowrule = match:class ^(plasma-changeicons)$, no_initial_focus on
|
||||
windowrule = match:class ^(plasma-changeicons)$, move 999999 999999
|
||||
# stupid dolphin copy
|
||||
windowrulev2 = move 40 80, title:^(Copying — Dolphin)$
|
||||
windowrule = match:title ^(Copying — Dolphin)$, move 40 80
|
||||
|
||||
# Tiling
|
||||
windowrulev2 = tile, class:^dev\.warp\.Warp$
|
||||
windowrule = match:class ^dev\.warp\.Warp$, tile on
|
||||
|
||||
# Picture-in-Picture
|
||||
windowrulev2 = float, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrulev2 = keepaspectratio, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrulev2 = move 73% 72%, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrulev2 = size 25%, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrulev2 = float, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrulev2 = pin, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, float on
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, keep_aspect_ratio on
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, move (monitor_w*.73) (monitor_h*.72)
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, size (monitor_w*.25) (monitor_h*.25)
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, float on
|
||||
windowrule = match:title ^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$, pin on
|
||||
|
||||
# --- Tearing ---
|
||||
windowrulev2 = immediate, title:.*\.exe
|
||||
windowrulev2 = immediate, title:.*minecraft.*
|
||||
windowrulev2 = immediate, class:^(steam_app).*
|
||||
windowrule = match:title .*\.exe, immediate on
|
||||
windowrule = match:title .*minecraft.*, immediate on
|
||||
windowrule = match:class ^(steam_app).*, immediate on
|
||||
|
||||
# Fix Jetbrain IDEs focus/rerendering problem
|
||||
windowrulev2=noinitialfocus,class:^jetbrains-.*$,floating:1,title:^$|^\s$|^win\d+$
|
||||
windowrule = match:class ^jetbrains-.*$, match:float 1, match:title ^$|^\s$|^win\d+$, no_initial_focus on
|
||||
|
||||
# No shadow for tiled windows (matches windows that are not floating).
|
||||
windowrulev2 = noshadow, floating:0
|
||||
windowrule = match:float 0, no_shadow on
|
||||
|
||||
# ######## Workspace rules ########
|
||||
workspace = special:special, gapsout:30
|
||||
|
||||
# ######## Layer rules ########
|
||||
layerrule = xray 1, .*
|
||||
# layerrule = noanim, .*
|
||||
layerrule = noanim, walker
|
||||
layerrule = noanim, selection
|
||||
layerrule = noanim, overview
|
||||
layerrule = noanim, anyrun
|
||||
layerrule = noanim, indicator.*
|
||||
layerrule = noanim, osk
|
||||
layerrule = noanim, hyprpicker
|
||||
layerrule = match:namespace .*, xray on
|
||||
# layerrule = match:namespace .*, no_anim on
|
||||
layerrule = match:namespace walker, no_anim on
|
||||
layerrule = match:namespace selection, no_anim on
|
||||
layerrule = match:namespace overview, no_anim on
|
||||
layerrule = match:namespace anyrun, no_anim on
|
||||
layerrule = match:namespace indicator.*, no_anim on
|
||||
layerrule = match:namespace osk, no_anim on
|
||||
layerrule = match:namespace hyprpicker, no_anim on
|
||||
|
||||
layerrule = noanim, noanim
|
||||
layerrule = blur, gtk-layer-shell
|
||||
layerrule = ignorezero, gtk-layer-shell
|
||||
layerrule = blur, launcher
|
||||
layerrule = ignorealpha 0.5, launcher
|
||||
layerrule = blur, notifications
|
||||
layerrule = ignorealpha 0.69, notifications
|
||||
layerrule = blur, logout_dialog # wlogout
|
||||
layerrule = match:namespace noanim, no_anim on
|
||||
layerrule = match:namespace gtk-layer-shell, blur on
|
||||
layerrule = match:namespace gtk-layer-shell, ignore_alpha 0
|
||||
layerrule = match:namespace launcher, blur on
|
||||
layerrule = match:namespace launcher, ignore_alpha 0.5
|
||||
layerrule = match:namespace notifications, blur on
|
||||
layerrule = match:namespace notifications, ignore_alpha 0.69
|
||||
layerrule = match:namespace logout_dialog # wlogout, blur on
|
||||
|
||||
# ags
|
||||
layerrule = animation slide left, sideleft.*
|
||||
layerrule = animation slide right, sideright.*
|
||||
layerrule = blur, session[0-9]*
|
||||
layerrule = blur, bar[0-9]*
|
||||
layerrule = ignorealpha 0.6, bar[0-9]*
|
||||
layerrule = blur, barcorner.*
|
||||
layerrule = ignorealpha 0.6, barcorner.*
|
||||
layerrule = blur, dock[0-9]*
|
||||
layerrule = ignorealpha 0.6, dock[0-9]*
|
||||
layerrule = blur, indicator.*
|
||||
layerrule = ignorealpha 0.6, indicator.*
|
||||
layerrule = blur, overview[0-9]*
|
||||
layerrule = ignorealpha 0.6, overview[0-9]*
|
||||
layerrule = blur, cheatsheet[0-9]*
|
||||
layerrule = ignorealpha 0.6, cheatsheet[0-9]*
|
||||
layerrule = blur, sideright[0-9]*
|
||||
layerrule = ignorealpha 0.6, sideright[0-9]*
|
||||
layerrule = blur, sideleft[0-9]*
|
||||
layerrule = ignorealpha 0.6, sideleft[0-9]*
|
||||
layerrule = blur, indicator.*
|
||||
layerrule = ignorealpha 0.6, indicator.*
|
||||
layerrule = blur, osk[0-9]*
|
||||
layerrule = ignorealpha 0.6, osk[0-9]*
|
||||
layerrule = match:namespace sideleft.*, animation slide left
|
||||
layerrule = match:namespace sideright.*, animation slide right
|
||||
layerrule = match:namespace session[0-9]*, blur on
|
||||
layerrule = match:namespace bar[0-9]*, blur on
|
||||
layerrule = match:namespace bar[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace barcorner.*, blur on
|
||||
layerrule = match:namespace barcorner.*, ignore_alpha 0.6
|
||||
layerrule = match:namespace dock[0-9]*, blur on
|
||||
layerrule = match:namespace dock[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace indicator.*, blur on
|
||||
layerrule = match:namespace indicator.*, ignore_alpha 0.6
|
||||
layerrule = match:namespace overview[0-9]*, blur on
|
||||
layerrule = match:namespace overview[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace cheatsheet[0-9]*, blur on
|
||||
layerrule = match:namespace cheatsheet[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace sideright[0-9]*, blur on
|
||||
layerrule = match:namespace sideright[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace sideleft[0-9]*, blur on
|
||||
layerrule = match:namespace sideleft[0-9]*, ignore_alpha 0.6
|
||||
layerrule = match:namespace indicator.*, blur on
|
||||
layerrule = match:namespace indicator.*, ignore_alpha 0.6
|
||||
layerrule = match:namespace osk[0-9]*, blur on
|
||||
layerrule = match:namespace osk[0-9]*, ignore_alpha 0.6
|
||||
|
||||
# Quickshell
|
||||
layerrule = blurpopups, quickshell:.*
|
||||
layerrule = blur, quickshell:.*
|
||||
layerrule = ignorealpha 0.79, quickshell:.*
|
||||
layerrule = animation slide, quickshell:bar
|
||||
layerrule = noanim, quickshell:actionCenter
|
||||
layerrule = animation slide bottom, quickshell:cheatsheet
|
||||
layerrule = animation slide bottom, quickshell:dock
|
||||
layerrule = animation popin 120%, quickshell:screenCorners
|
||||
layerrule = noanim, quickshell:lockWindowPusher
|
||||
layerrule = animation fade, quickshell:notificationPopup
|
||||
layerrule = noanim, quickshell:overlay
|
||||
layerrule = ignorealpha 1, quickshell:overlay
|
||||
layerrule = noanim, quickshell:overview
|
||||
layerrule = animation slide bottom, quickshell:osk
|
||||
layerrule = noanim, quickshell:polkit
|
||||
layerrule = xray 0, quickshell:popup # No weird color for bar tooltips (this in theory should suffice)
|
||||
layerrule = ignorealpha 1, quickshell:popup # No weird color for bar tooltips (but somehow this is necessary)
|
||||
layerrule = ignorealpha 1, quickshell:mediaControls # Same as above
|
||||
layerrule = animation slide, quickshell:reloadPopup
|
||||
layerrule = noanim, quickshell:regionSelector
|
||||
layerrule = noanim, quickshell:screenshot
|
||||
layerrule = blur, quickshell:session
|
||||
layerrule = noanim, quickshell:session
|
||||
layerrule = ignorealpha 0, quickshell:session
|
||||
layerrule = animation slide right, quickshell:sidebarRight
|
||||
layerrule = animation slide left, quickshell:sidebarLeft
|
||||
layerrule = animation slide, quickshell:verticalBar
|
||||
layerrule = animation slide top, quickshell:wallpaperSelector
|
||||
layerrule = noanim, quickshell:wNotificationCenter
|
||||
layerrule = noanim, quickshell:wOnScreenDisplay
|
||||
layerrule = noanim, quickshell:wStartMenu
|
||||
layerrule = ignorealpha 0, quickshell:wTaskView
|
||||
layerrule = noanim, quickshell:wTaskView
|
||||
layerrule = match:namespace quickshell:.*, blur_popups on
|
||||
layerrule = match:namespace quickshell:.*, blur on
|
||||
layerrule = match:namespace quickshell:.*, ignore_alpha 0.79
|
||||
layerrule = match:namespace quickshell:bar, animation slide
|
||||
layerrule = match:namespace quickshell:actionCenter, no_anim on
|
||||
layerrule = match:namespace quickshell:cheatsheet, animation slide bottom
|
||||
layerrule = match:namespace quickshell:dock, animation slide bottom
|
||||
layerrule = match:namespace quickshell:screenCorners, animation popin 120%
|
||||
layerrule = match:namespace quickshell:lockWindowPusher, no_anim on
|
||||
layerrule = match:namespace quickshell:notificationPopup, animation fade
|
||||
layerrule = match:namespace quickshell:overlay, no_anim on
|
||||
layerrule = match:namespace quickshell:overlay, ignore_alpha 1
|
||||
layerrule = match:namespace quickshell:overview, no_anim on
|
||||
layerrule = match:namespace quickshell:osk, animation slide bottom
|
||||
layerrule = match:namespace quickshell:polkit, no_anim on
|
||||
layerrule = match:namespace quickshell:popup, xray off # No weird color for bar tooltips (this in theory should suffice)
|
||||
layerrule = match:namespace quickshell:popup, ignore_alpha 1 # No weird color for bar tooltips (but somehow this is necessary)
|
||||
layerrule = match:namespace quickshell:mediaControls, ignore_alpha 1 # Same as above
|
||||
layerrule = match:namespace quickshell:reloadPopup, animation slide
|
||||
layerrule = match:namespace quickshell:regionSelector, no_anim on
|
||||
layerrule = match:namespace quickshell:screenshot, no_anim on
|
||||
layerrule = match:namespace quickshell:session, blur on
|
||||
layerrule = match:namespace quickshell:session, no_anim on
|
||||
layerrule = match:namespace quickshell:session, ignore_alpha 0
|
||||
layerrule = match:namespace quickshell:sidebarRight, animation slide right
|
||||
layerrule = match:namespace quickshell:sidebarLeft, animation slide left
|
||||
layerrule = match:namespace quickshell:verticalBar, animation slide
|
||||
layerrule = match:namespace quickshell:wallpaperSelector, animation slide top
|
||||
layerrule = match:namespace quickshell:wNotificationCenter, no_anim on
|
||||
layerrule = match:namespace quickshell:wOnScreenDisplay, no_anim on
|
||||
layerrule = match:namespace quickshell:wStartMenu, no_anim on
|
||||
layerrule = match:namespace quickshell:wTaskView, ignore_alpha 0
|
||||
layerrule = match:namespace quickshell:wTaskView, no_anim on
|
||||
|
||||
# Launchers need to be FAST
|
||||
layerrule = noanim, gtk4-layer-shell
|
||||
layerrule = match:namespace gtk4-layer-shell, no_anim on
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
general {
|
||||
col.active_border = rgba({{colors.outline.default.hex_stripped}}AA)
|
||||
col.inactive_border = rgba({{colors.outline_variant.default.hex_stripped}}AA)
|
||||
col.active_border = rgba({{colors.outline.default.hex_stripped}}77)
|
||||
col.inactive_border = rgba({{colors.outline_variant.default.hex_stripped}}55)
|
||||
}
|
||||
|
||||
misc {
|
||||
@@ -29,4 +29,4 @@ plugin {
|
||||
}
|
||||
}
|
||||
|
||||
windowrulev2 = bordercolor rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77),pinned:1
|
||||
windowrule = border_color rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77), match:pin 1
|
||||
|
||||
@@ -28,7 +28,7 @@ Singleton {
|
||||
property real autoBackgroundTransparency: { // y = 0.5768x^2 - 0.759x + 0.2896
|
||||
let x = wallpaperVibrancy
|
||||
let y = 0.5768 * (x * x) - 0.759 * (x) + 0.2896
|
||||
return Math.max(0, Math.min(0.22, y))
|
||||
return Math.max(0, Math.min(0.22, y)) - 0.12 * (m3colors.darkmode ? 0 : 1)
|
||||
}
|
||||
property real autoContentTransparency: 0.9
|
||||
property real backgroundTransparency: Config?.options.appearance.transparency.enable ? Config?.options.appearance.transparency.automatic ? autoBackgroundTransparency : Config?.options.appearance.transparency.backgroundTransparency : 0
|
||||
|
||||
@@ -78,10 +78,7 @@ Singleton {
|
||||
JsonAdapter {
|
||||
id: configOptionsJsonAdapter
|
||||
|
||||
property list<string> enabledPanels: [
|
||||
"iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"
|
||||
]
|
||||
property string panelFamily: "ii" // "ii", "w"
|
||||
property string panelFamily: "ii" // "ii", "waffle"
|
||||
|
||||
property JsonObject policies: JsonObject {
|
||||
property int ai: 1 // 0: No | 1: Yes | 2: Local
|
||||
@@ -189,7 +186,17 @@ Singleton {
|
||||
property bool useSineCookie: false
|
||||
}
|
||||
property JsonObject digital: JsonObject {
|
||||
property bool adaptiveAlignment: true
|
||||
property bool showDate: true
|
||||
property bool animateChange: true
|
||||
property bool vertical: false
|
||||
property JsonObject font: JsonObject {
|
||||
property string family: "Google Sans Flex"
|
||||
property real weight: 350
|
||||
property real width: 100
|
||||
property real size: 90
|
||||
property real roundness: 0
|
||||
}
|
||||
}
|
||||
property JsonObject quote: JsonObject {
|
||||
property bool enable: false
|
||||
|
||||
@@ -59,7 +59,7 @@ Singleton {
|
||||
property string hyprlandInstanceSignature: ""
|
||||
|
||||
property JsonObject ai: JsonObject {
|
||||
property string model
|
||||
property string model: "gemini-2.5-flash"
|
||||
property real temperature: 0.5
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.services
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
spacing: 10
|
||||
Layout.leftMargin: 8
|
||||
Layout.rightMargin: 8
|
||||
|
||||
property string text: ""
|
||||
property string buttonIcon: ""
|
||||
property alias value: slider.value
|
||||
property alias stopIndicatorValues: slider.stopIndicatorValues
|
||||
property bool usePercentTooltip: true
|
||||
property real from: slider.from
|
||||
property real to: slider.to
|
||||
property real textWidth: 120
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
spacing: 10
|
||||
|
||||
OptionalMaterialSymbol {
|
||||
id: iconWidget
|
||||
icon: root.buttonIcon
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
}
|
||||
StyledText {
|
||||
id: labelWidget
|
||||
Layout.preferredWidth: root.textWidth
|
||||
text: root.text
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
|
||||
StyledSlider {
|
||||
id: slider
|
||||
configuration: StyledSlider.Configuration.XS
|
||||
usePercentTooltip: root.usePercentTooltip
|
||||
value: root.value
|
||||
from: root.from
|
||||
to: root.to
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ Item {
|
||||
|
||||
Rectangle { // The dialog
|
||||
id: dialog
|
||||
color: Appearance.colors.colSurfaceContainerHigh
|
||||
color: Appearance.m3colors.m3surfaceContainerHigh
|
||||
radius: Appearance.rounding.normal
|
||||
anchors.fill: parent
|
||||
anchors.margins: dialogMargin
|
||||
|
||||
@@ -192,7 +192,7 @@ ComboBox {
|
||||
id: popupBackground
|
||||
anchors.fill: parent
|
||||
radius: Appearance.rounding.normal
|
||||
color: Appearance.colors.colSurfaceContainerHigh
|
||||
color: Appearance.m3colors.m3surfaceContainerHigh
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ Slider {
|
||||
property real handleWidth: root.pressed ? handlePressedWidth : handleDefaultWidth
|
||||
property real handleMargins: 4
|
||||
property real trackDotSize: 3
|
||||
property string tooltipContent: `${Math.round(value * 100)}%`
|
||||
property bool usePercentTooltip: true
|
||||
property string tooltipContent: usePercentTooltip ? `${Math.round(((value - from) / (to - from)) * 100)}%` : `${Math.round(value)}`
|
||||
property bool wavy: configuration === StyledSlider.Configuration.Wavy // If true, the progress bar will have a wavy fill effect
|
||||
property bool animateWave: true
|
||||
property real waveAmplitudeMultiplier: wavy ? 0.5 : 0
|
||||
|
||||
Submodule dots/.config/quickshell/ii/modules/common/widgets/shapes updated: 8aa62a41bd...7f0f0709ec
+2
-1
@@ -59,7 +59,8 @@ AbstractWidget {
|
||||
function onReadyChanged() { refreshPlacementIfNeeded() }
|
||||
}
|
||||
function refreshPlacementIfNeeded() {
|
||||
if (!Config.ready || (root.placementStrategy === "free" && root.needsColText)) return;
|
||||
if (!Config.ready) return;
|
||||
if (root.placementStrategy === "free" && !root.needsColText) return;
|
||||
leastBusyRegionProc.wallpaperPath = root.wallpaperPath;
|
||||
leastBusyRegionProc.running = false;
|
||||
leastBusyRegionProc.running = true;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
pixelSize: 20
|
||||
weight: 350
|
||||
// Set empty to prevent conflicts, not meaningless
|
||||
styleName: ""
|
||||
variableAxes: ({})
|
||||
}
|
||||
style: Text.Raised
|
||||
styleColor: Appearance.colors.colShadow
|
||||
animateChange: Config.options.background.widgets.clock.digital.animateChange
|
||||
}
|
||||
@@ -26,7 +26,7 @@ AbstractBackgroundWidget {
|
||||
visibleWhenLocked: true
|
||||
|
||||
property var textHorizontalAlignment: {
|
||||
if (root.forceCenter)
|
||||
if (!Config.options.background.widgets.clock.digital.adaptiveAlignment || root.forceCenter || Config.options.background.widgets.clock.digital.vertical)
|
||||
return Text.AlignHCenter;
|
||||
if (root.x < root.scaledScreenWidth / 3)
|
||||
return Text.AlignLeft;
|
||||
@@ -63,32 +63,9 @@ AbstractBackgroundWidget {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
shown: root.clockStyle === "digital" && (root.shouldShow)
|
||||
fade: false
|
||||
sourceComponent: ColumnLayout {
|
||||
id: clockColumn
|
||||
spacing: 6
|
||||
|
||||
ClockText {
|
||||
font.pixelSize: 90
|
||||
text: DateTime.time
|
||||
}
|
||||
ClockText {
|
||||
Layout.topMargin: -5
|
||||
text: DateTime.longDate
|
||||
}
|
||||
StyledText {
|
||||
// Somehow gets fucked up if made a ClockText???
|
||||
visible: Config.options.background.widgets.clock.quote.enable && Config.options.background.widgets.clock.quote.text.length > 0
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: root.textHorizontalAlignment
|
||||
font {
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
weight: 350
|
||||
}
|
||||
color: root.colText
|
||||
style: Text.Raised
|
||||
styleColor: Appearance.colors.colShadow
|
||||
text: Config.options.background.widgets.clock.quote.text
|
||||
}
|
||||
sourceComponent: DigitalClock {
|
||||
colText: root.colText
|
||||
textHorizontalAlignment: root.textHorizontalAlignment
|
||||
}
|
||||
}
|
||||
StatusRow {
|
||||
@@ -154,19 +131,6 @@ AbstractBackgroundWidget {
|
||||
}
|
||||
}
|
||||
|
||||
component ClockText: StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: root.textHorizontalAlignment
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
pixelSize: 20
|
||||
weight: Font.DemiBold
|
||||
}
|
||||
color: root.colText
|
||||
style: Text.Raised
|
||||
styleColor: Appearance.colors.colShadow
|
||||
animateChange: Config.options.background.widgets.clock.digital.animateChange
|
||||
}
|
||||
component ClockStatusText: Row {
|
||||
id: statusTextRow
|
||||
property alias statusIcon: statusIconWidget.text
|
||||
@@ -190,6 +154,7 @@ AbstractBackgroundWidget {
|
||||
ClockText {
|
||||
id: statusTextWidget
|
||||
color: statusTextRow.textColor
|
||||
horizontalAlignment: root.textHorizontalAlignment
|
||||
anchors.verticalCenter: statusTextRow.verticalCenter
|
||||
font {
|
||||
pixelSize: Appearance.font.pixelSize.large
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
ColumnLayout {
|
||||
id: clockColumn
|
||||
spacing: 4
|
||||
|
||||
property bool isVertical: Config.options.background.widgets.clock.digital.vertical
|
||||
property color colText: Appearance.colors.colOnSecondaryContainer
|
||||
property var textHorizontalAlignment: Text.AlignHCenter
|
||||
|
||||
// Time
|
||||
ClockText {
|
||||
id: timeTextTop
|
||||
text: clockColumn.isVertical ? DateTime.time.split(":")[0].padStart(2, "0") : DateTime.time
|
||||
color: clockColumn.colText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font {
|
||||
pixelSize: Config.options.background.widgets.clock.digital.font.size
|
||||
weight: Config.options.background.widgets.clock.digital.font.weight
|
||||
family: Config.options.background.widgets.clock.digital.font.family
|
||||
variableAxes: ({
|
||||
"wdth": Config.options.background.widgets.clock.digital.font.width,
|
||||
"ROND": Config.options.background.widgets.clock.digital.font.roundness
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
Layout.topMargin: -40
|
||||
Layout.fillWidth: true
|
||||
active: clockColumn.isVertical
|
||||
visible: active
|
||||
sourceComponent: ClockText {
|
||||
id: timeTextBottom
|
||||
text: DateTime.time.split(":")[1].split(" ")[0].padStart(2, "0")
|
||||
color: clockColumn.colText
|
||||
horizontalAlignment: clockColumn.textHorizontalAlignment
|
||||
font {
|
||||
pixelSize: timeTextTop.font.pixelSize
|
||||
weight: timeTextTop.font.weight
|
||||
family: timeTextTop.font.family
|
||||
variableAxes: timeTextTop.font.variableAxes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Date
|
||||
ClockText {
|
||||
visible: Config.options.background.widgets.clock.digital.showDate
|
||||
Layout.topMargin: -20
|
||||
Layout.fillWidth: true
|
||||
text: DateTime.longDate
|
||||
color: clockColumn.colText
|
||||
horizontalAlignment: clockColumn.textHorizontalAlignment
|
||||
}
|
||||
|
||||
// Quote
|
||||
ClockText {
|
||||
visible: Config.options.background.widgets.clock.quote.enable && Config.options.background.widgets.clock.quote.text.length > 0
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
text: Config.options.background.widgets.clock.quote.text
|
||||
animateChange: false
|
||||
color: clockColumn.colText
|
||||
horizontalAlignment: clockColumn.textHorizontalAlignment
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
@@ -60,6 +62,7 @@ Scope {
|
||||
}
|
||||
color: "transparent"
|
||||
|
||||
// Positioning
|
||||
anchors {
|
||||
top: !Config.options.bar.bottom
|
||||
bottom: Config.options.bar.bottom
|
||||
@@ -72,6 +75,14 @@ Scope {
|
||||
bottom: (Config.options.interactions.deadPixelWorkaround.enable && barRoot.anchors.bottom) * -1
|
||||
}
|
||||
|
||||
// Include in focus grab
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addPersistent(barRoot);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removePersistent(barRoot);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hoverRegion
|
||||
hoverEnabled: true
|
||||
|
||||
@@ -54,13 +54,16 @@ Scope { // Scope
|
||||
item: cheatsheetBackground
|
||||
}
|
||||
|
||||
HyprlandFocusGrab { // Click outside to close
|
||||
id: grab
|
||||
windows: [cheatsheetRoot]
|
||||
active: cheatsheetRoot.visible
|
||||
onCleared: () => {
|
||||
if (!active)
|
||||
cheatsheetRoot.hide();
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addDismissable(cheatsheetRoot);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removeDismissable(cheatsheetRoot);
|
||||
}
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
cheatsheetRoot.hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ import qs.modules.common.functions
|
||||
import qs.modules.common.panels.lock
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
LockScreen {
|
||||
@@ -18,24 +16,7 @@ LockScreen {
|
||||
}
|
||||
|
||||
// Push everything down
|
||||
property var windowData: []
|
||||
function saveWindowPositionAndTile() {
|
||||
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "true"]);
|
||||
root.windowData = HyprlandData.windowList.filter(w => (w.floating && w.workspace.id === HyprlandData.activeWorkspace.id));
|
||||
root.windowData.forEach(w => {
|
||||
Hyprland.dispatch(`pseudo address:${w.address}`);
|
||||
Hyprland.dispatch(`settiled address:${w.address}`);
|
||||
Hyprland.dispatch(`movetoworkspacesilent ${w.workspace.id},address:${w.address}`);
|
||||
});
|
||||
}
|
||||
function restoreWindowPositionAndTile() {
|
||||
root.windowData.forEach(w => {
|
||||
Hyprland.dispatch(`setfloating address:${w.address}`);
|
||||
Hyprland.dispatch(`movewindowpixel exact ${w.at[0]} ${w.at[1]}, address:${w.address}`);
|
||||
Hyprland.dispatch(`pseudo address:${w.address}`);
|
||||
});
|
||||
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "false"]);
|
||||
}
|
||||
property var lastWorkspaceId: 1
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
delegate: Scope {
|
||||
@@ -46,11 +27,11 @@ LockScreen {
|
||||
property int horizontalSqueeze: modelData.width * 0.2
|
||||
onShouldPushChanged: {
|
||||
if (shouldPush) {
|
||||
root.saveWindowPositionAndTile();
|
||||
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`]);
|
||||
root.lastWorkspaceId = HyprlandData.activeWorkspace.id;
|
||||
// Set anim to vertical and move to very very big workspace for a sliding up effect
|
||||
Quickshell.execDetached(["hyprctl", "--batch", "keyword animation workspaces,1,7,menu_decel,slidevert; dispatch workspace 2147483647"]);
|
||||
} else {
|
||||
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`]);
|
||||
root.restoreWindowPositionAndTile();
|
||||
Quickshell.execDetached(["hyprctl", "--batch", `dispatch workspace ${root.lastWorkspaceId}; reload`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ Scope {
|
||||
}
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
id: mediaControlsRoot
|
||||
id: panelWindow
|
||||
visible: true
|
||||
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
@@ -98,9 +98,9 @@ Scope {
|
||||
right: Config.options.bar.vertical && Config.options.bar.bottom
|
||||
}
|
||||
margins {
|
||||
top: Config.options.bar.vertical ? ((mediaControlsRoot.screen.height / 2) - widgetHeight * 1.5) : Appearance.sizes.barHeight
|
||||
top: Config.options.bar.vertical ? ((panelWindow.screen.height / 2) - widgetHeight * 1.5) : Appearance.sizes.barHeight
|
||||
bottom: Appearance.sizes.barHeight
|
||||
left: Config.options.bar.vertical ? Appearance.sizes.barHeight : ((mediaControlsRoot.screen.width / 2) - (osdWidth / 2) - widgetWidth)
|
||||
left: Config.options.bar.vertical ? Appearance.sizes.barHeight : ((panelWindow.screen.width / 2) - (osdWidth / 2) - widgetWidth)
|
||||
right: Appearance.sizes.barHeight
|
||||
}
|
||||
|
||||
@@ -108,13 +108,16 @@ Scope {
|
||||
item: playerColumnLayout
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
windows: [mediaControlsRoot]
|
||||
active: mediaControlsLoader.active
|
||||
onCleared: () => {
|
||||
if (!active) {
|
||||
GlobalStates.mediaControlsOpen = false;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addDismissable(panelWindow);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removeDismissable(panelWindow);
|
||||
}
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
GlobalStates.mediaControlsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,10 +140,13 @@ Scope {
|
||||
}
|
||||
}
|
||||
|
||||
Item { // No player placeholder
|
||||
Item {
|
||||
// No player placeholder
|
||||
Layout.alignment: {
|
||||
if (mediaControlsRoot.anchors.left) return Qt.AlignLeft;
|
||||
if (mediaControlsRoot.anchors.right) return Qt.AlignRight;
|
||||
if (panelWindow.anchors.left)
|
||||
return Qt.AlignLeft;
|
||||
if (panelWindow.anchors.right)
|
||||
return Qt.AlignRight;
|
||||
return Qt.AlignHCenter;
|
||||
}
|
||||
Layout.leftMargin: Appearance.sizes.hyprlandGapsOut
|
||||
@@ -153,7 +159,7 @@ Scope {
|
||||
target: placeholderBackground
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Rectangle {
|
||||
id: placeholderBackground
|
||||
anchors.centerIn: parent
|
||||
color: Appearance.colors.colLayer0
|
||||
|
||||
@@ -57,6 +57,13 @@ Scope { // Scope
|
||||
item: oskBackground
|
||||
}
|
||||
|
||||
// Make it usable with other panels
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addPersistent(oskRoot);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removePersistent(oskRoot);
|
||||
}
|
||||
|
||||
// Background
|
||||
StyledRectangularShadow {
|
||||
|
||||
@@ -14,116 +14,96 @@ import Quickshell.Hyprland
|
||||
Scope {
|
||||
id: overviewScope
|
||||
property bool dontAutoCancelSearch: false
|
||||
Variants {
|
||||
id: overviewVariants
|
||||
model: Quickshell.screens
|
||||
PanelWindow {
|
||||
id: root
|
||||
required property var modelData
|
||||
property string searchingText: ""
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
|
||||
property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor?.id)
|
||||
screen: modelData
|
||||
|
||||
PanelWindow {
|
||||
id: panelWindow
|
||||
property string searchingText: ""
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(panelWindow.screen)
|
||||
property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor?.id)
|
||||
visible: GlobalStates.overviewOpen
|
||||
|
||||
WlrLayershell.namespace: "quickshell:overview"
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
// WlrLayershell.keyboardFocus: GlobalStates.overviewOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
color: "transparent"
|
||||
|
||||
mask: Region {
|
||||
item: GlobalStates.overviewOpen ? columnLayout : null
|
||||
}
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onOverviewOpenChanged() {
|
||||
if (!GlobalStates.overviewOpen) {
|
||||
searchWidget.disableExpandAnimation();
|
||||
overviewScope.dontAutoCancelSearch = false;
|
||||
GlobalFocusGrab.dismiss();
|
||||
} else {
|
||||
if (!overviewScope.dontAutoCancelSearch) {
|
||||
searchWidget.cancelSearch();
|
||||
}
|
||||
GlobalFocusGrab.addDismissable(panelWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
GlobalStates.overviewOpen = false;
|
||||
}
|
||||
}
|
||||
implicitWidth: columnLayout.implicitWidth
|
||||
implicitHeight: columnLayout.implicitHeight
|
||||
|
||||
function setSearchingText(text) {
|
||||
searchWidget.setSearchingText(text);
|
||||
searchWidget.focusFirstItem();
|
||||
}
|
||||
|
||||
Column {
|
||||
id: columnLayout
|
||||
visible: GlobalStates.overviewOpen
|
||||
|
||||
WlrLayershell.namespace: "quickshell:overview"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
// WlrLayershell.keyboardFocus: GlobalStates.overviewOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
color: "transparent"
|
||||
|
||||
mask: Region {
|
||||
item: GlobalStates.overviewOpen ? columnLayout : null
|
||||
}
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: parent.top
|
||||
}
|
||||
spacing: -8
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [root]
|
||||
property bool canBeActive: root.monitorIsFocused
|
||||
active: false
|
||||
onCleared: () => {
|
||||
if (!active)
|
||||
GlobalStates.overviewOpen = false;
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
GlobalStates.overviewOpen = false;
|
||||
} else if (event.key === Qt.Key_Left) {
|
||||
if (!panelWindow.searchingText)
|
||||
Hyprland.dispatch("workspace r-1");
|
||||
} else if (event.key === Qt.Key_Right) {
|
||||
if (!panelWindow.searchingText)
|
||||
Hyprland.dispatch("workspace r+1");
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onOverviewOpenChanged() {
|
||||
if (!GlobalStates.overviewOpen) {
|
||||
searchWidget.disableExpandAnimation();
|
||||
overviewScope.dontAutoCancelSearch = false;
|
||||
} else {
|
||||
if (!overviewScope.dontAutoCancelSearch) {
|
||||
searchWidget.cancelSearch();
|
||||
}
|
||||
delayedGrabTimer.start();
|
||||
}
|
||||
SearchWidget {
|
||||
id: searchWidget
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Synchronizer on searchingText {
|
||||
property alias source: panelWindow.searchingText
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: delayedGrabTimer
|
||||
interval: Config.options.hacks.arbitraryRaceConditionDelay
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (!grab.canBeActive)
|
||||
return;
|
||||
grab.active = GlobalStates.overviewOpen;
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: columnLayout.implicitWidth
|
||||
implicitHeight: columnLayout.implicitHeight
|
||||
|
||||
function setSearchingText(text) {
|
||||
searchWidget.setSearchingText(text);
|
||||
searchWidget.focusFirstItem();
|
||||
}
|
||||
|
||||
Column {
|
||||
id: columnLayout
|
||||
visible: GlobalStates.overviewOpen
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: parent.top
|
||||
}
|
||||
spacing: -8
|
||||
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
GlobalStates.overviewOpen = false;
|
||||
} else if (event.key === Qt.Key_Left) {
|
||||
if (!root.searchingText)
|
||||
Hyprland.dispatch("workspace r-1");
|
||||
} else if (event.key === Qt.Key_Right) {
|
||||
if (!root.searchingText)
|
||||
Hyprland.dispatch("workspace r+1");
|
||||
}
|
||||
}
|
||||
|
||||
SearchWidget {
|
||||
id: searchWidget
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Synchronizer on searchingText {
|
||||
property alias source: root.searchingText
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: overviewLoader
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: GlobalStates.overviewOpen && (Config?.options.overview.enable ?? true)
|
||||
sourceComponent: OverviewWidget {
|
||||
panelWindow: root
|
||||
visible: (root.searchingText == "")
|
||||
}
|
||||
Loader {
|
||||
id: overviewLoader
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: GlobalStates.overviewOpen && (Config?.options.overview.enable ?? true)
|
||||
sourceComponent: OverviewWidget {
|
||||
screen: panelWindow.screen
|
||||
visible: (panelWindow.searchingText == "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,15 +114,9 @@ Scope {
|
||||
GlobalStates.overviewOpen = false;
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < overviewVariants.instances.length; i++) {
|
||||
let panelWindow = overviewVariants.instances[i];
|
||||
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
|
||||
overviewScope.dontAutoCancelSearch = true;
|
||||
panelWindow.setSearchingText(Config.options.search.prefix.clipboard);
|
||||
GlobalStates.overviewOpen = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
overviewScope.dontAutoCancelSearch = true;
|
||||
panelWindow.setSearchingText(Config.options.search.prefix.clipboard);
|
||||
GlobalStates.overviewOpen = true;
|
||||
}
|
||||
|
||||
function toggleEmojis() {
|
||||
@@ -150,15 +124,9 @@ Scope {
|
||||
GlobalStates.overviewOpen = false;
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < overviewVariants.instances.length; i++) {
|
||||
let panelWindow = overviewVariants.instances[i];
|
||||
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
|
||||
overviewScope.dontAutoCancelSearch = true;
|
||||
panelWindow.setSearchingText(Config.options.search.prefix.emojis);
|
||||
GlobalStates.overviewOpen = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
overviewScope.dontAutoCancelSearch = true;
|
||||
panelWindow.setSearchingText(Config.options.search.prefix.emojis);
|
||||
GlobalStates.overviewOpen = true;
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
|
||||
@@ -13,8 +13,8 @@ import Quickshell.Hyprland
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property var panelWindow
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(panelWindow.screen)
|
||||
required property var screen
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen)
|
||||
readonly property var toplevels: ToplevelManager.toplevels
|
||||
readonly property int workspacesShown: Config.options.overview.rows * Config.options.overview.columns
|
||||
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown)
|
||||
|
||||
@@ -13,11 +13,15 @@ import Quickshell.Io
|
||||
|
||||
Item { // Wrapper
|
||||
id: root
|
||||
|
||||
readonly property string xdgConfigHome: Directories.config
|
||||
readonly property int typingDebounceInterval: 200
|
||||
readonly property int typingResultLimit: 15 // Should be enough to cover the whole view
|
||||
|
||||
property string searchingText: LauncherSearch.query
|
||||
property bool showResults: searchingText != ""
|
||||
implicitWidth: searchWidgetContent.implicitWidth + Appearance.sizes.elevationMargin * 2
|
||||
implicitHeight: searchBar.implicitHeight + searchBar.verticalPadding * 2 + Appearance.sizes.elevationMargin * 2
|
||||
implicitHeight: searchWidgetContent.implicitHeight + searchBar.verticalPadding * 2 + Appearance.sizes.elevationMargin * 2
|
||||
|
||||
function focusFirstItem() {
|
||||
appResults.currentIndex = 0;
|
||||
@@ -178,30 +182,35 @@ Item { // Wrapper
|
||||
}
|
||||
}
|
||||
|
||||
model: ScriptModel {
|
||||
id: model
|
||||
objectProp: "key"
|
||||
values: LauncherSearch.results
|
||||
onValuesChanged: {
|
||||
root.focusFirstItem();
|
||||
Timer {
|
||||
id: debounceTimer
|
||||
interval: root.typingDebounceInterval
|
||||
onTriggered: {
|
||||
resultModel.values = LauncherSearch.results ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: LauncherSearch
|
||||
function onResultsChanged() {
|
||||
resultModel.values = LauncherSearch.results.slice(0, root.typingResultLimit);
|
||||
root.focusFirstItem();
|
||||
debounceTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
model: ScriptModel {
|
||||
id: resultModel
|
||||
objectProp: "key"
|
||||
}
|
||||
|
||||
delegate: SearchItem {
|
||||
// The selectable item for each search result
|
||||
required property var modelData
|
||||
anchors.left: parent?.left
|
||||
anchors.right: parent?.right
|
||||
entry: modelData
|
||||
query: StringUtils.cleanOnePrefix(root.searchingText, [
|
||||
Config.options.search.prefix.action,
|
||||
Config.options.search.prefix.app,
|
||||
Config.options.search.prefix.clipboard,
|
||||
Config.options.search.prefix.emojis,
|
||||
Config.options.search.prefix.math,
|
||||
Config.options.search.prefix.shellCommand,
|
||||
Config.options.search.prefix.webSearch
|
||||
])
|
||||
query: StringUtils.cleanOnePrefix(root.searchingText, [Config.options.search.prefix.action, Config.options.search.prefix.app, Config.options.search.prefix.clipboard, Config.options.search.prefix.emojis, Config.options.search.prefix.math, Config.options.search.prefix.shellCommand, Config.options.search.prefix.webSearch])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,11 +84,11 @@ Scope { // Scope
|
||||
active: true
|
||||
|
||||
sourceComponent: PanelWindow { // Window
|
||||
id: sidebarRoot
|
||||
id: panelWindow
|
||||
visible: GlobalStates.sidebarLeftOpen
|
||||
|
||||
property bool extend: false
|
||||
property real sidebarWidth: sidebarRoot.extend ? Appearance.sizes.sidebarWidthExtended : Appearance.sizes.sidebarWidth
|
||||
property real sidebarWidth: panelWindow.extend ? Appearance.sizes.sidebarWidthExtended : Appearance.sizes.sidebarWidth
|
||||
property var contentParent: sidebarLeftBackground
|
||||
|
||||
function hide() {
|
||||
@@ -113,15 +113,17 @@ Scope { // Scope
|
||||
item: sidebarLeftBackground
|
||||
}
|
||||
|
||||
HyprlandFocusGrab { // Click outside to close
|
||||
id: grab
|
||||
windows: [ sidebarRoot ]
|
||||
active: sidebarRoot.visible && !root.pin
|
||||
onActiveChanged: { // Focus the selected tab
|
||||
if (active) sidebarLeftBackground.children[0].focusActiveItem()
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
GlobalFocusGrab.addDismissable(panelWindow);
|
||||
} else {
|
||||
GlobalFocusGrab.removeDismissable(panelWindow);
|
||||
}
|
||||
onCleared: () => {
|
||||
if (!active) sidebarRoot.hide()
|
||||
}
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
panelWindow.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +138,7 @@ Scope { // Scope
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: Appearance.sizes.hyprlandGapsOut
|
||||
anchors.leftMargin: Appearance.sizes.hyprlandGapsOut
|
||||
width: sidebarRoot.sidebarWidth - Appearance.sizes.hyprlandGapsOut - Appearance.sizes.elevationMargin
|
||||
width: panelWindow.sidebarWidth - Appearance.sizes.hyprlandGapsOut - Appearance.sizes.elevationMargin
|
||||
height: parent.height - Appearance.sizes.hyprlandGapsOut * 2
|
||||
color: Appearance.colors.colLayer0
|
||||
border.width: 1
|
||||
@@ -149,11 +151,11 @@ Scope { // Scope
|
||||
|
||||
Keys.onPressed: (event) => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
sidebarRoot.hide();
|
||||
panelWindow.hide();
|
||||
}
|
||||
if (event.modifiers === Qt.ControlModifier) {
|
||||
if (event.key === Qt.Key_O) {
|
||||
sidebarRoot.extend = !sidebarRoot.extend;
|
||||
panelWindow.extend = !panelWindow.extend;
|
||||
} else if (event.key === Qt.Key_D) {
|
||||
root.toggleDetach();
|
||||
} else if (event.key === Qt.Key_P) {
|
||||
|
||||
@@ -126,7 +126,7 @@ Button {
|
||||
opacity: root.showActions ? 1 : 0
|
||||
visible: opacity > 0
|
||||
radius: Appearance.rounding.small
|
||||
color: Appearance.colors.colSurfaceContainer
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
implicitHeight: contextMenuColumnLayout.implicitHeight + radius * 2
|
||||
implicitWidth: contextMenuColumnLayout.implicitWidth
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ Scope {
|
||||
property int sidebarWidth: Appearance.sizes.sidebarWidth
|
||||
|
||||
PanelWindow {
|
||||
id: sidebarRoot
|
||||
id: panelWindow
|
||||
visible: GlobalStates.sidebarRightOpen
|
||||
|
||||
function hide() {
|
||||
GlobalStates.sidebarRightOpen = false
|
||||
GlobalStates.sidebarRightOpen = false;
|
||||
}
|
||||
|
||||
exclusiveZone: 0
|
||||
@@ -32,12 +32,17 @@ Scope {
|
||||
bottom: true
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [ sidebarRoot ]
|
||||
active: GlobalStates.sidebarRightOpen
|
||||
onCleared: () => {
|
||||
if (!active) sidebarRoot.hide()
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
GlobalFocusGrab.addDismissable(panelWindow);
|
||||
} else {
|
||||
GlobalFocusGrab.removeDismissable(panelWindow);
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
panelWindow.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,16 +58,14 @@ Scope {
|
||||
height: parent.height - Appearance.sizes.hyprlandGapsOut * 2
|
||||
|
||||
focus: GlobalStates.sidebarRightOpen
|
||||
Keys.onPressed: (event) => {
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
sidebarRoot.hide();
|
||||
panelWindow.hide();
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: SidebarRightContent {}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
@@ -105,5 +108,4 @@ Scope {
|
||||
GlobalStates.sidebarRightOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ Item {
|
||||
anchors.margins: root.dialogMargins
|
||||
implicitHeight: dialogColumnLayout.implicitHeight
|
||||
|
||||
color: Appearance.colors.colSurfaceContainerHigh
|
||||
color: Appearance.m3colors.m3surfaceContainerHigh
|
||||
radius: Appearance.rounding.normal
|
||||
|
||||
function addTask() {
|
||||
|
||||
@@ -66,6 +66,7 @@ Scope {
|
||||
}
|
||||
color: "transparent"
|
||||
|
||||
// Positioning
|
||||
anchors {
|
||||
left: !Config.options.bar.bottom
|
||||
right: Config.options.bar.bottom
|
||||
@@ -73,6 +74,14 @@ Scope {
|
||||
bottom: true
|
||||
}
|
||||
|
||||
// Include in focus grab
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addPersistent(barRoot);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removePersistent(barRoot);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hoverRegion
|
||||
hoverEnabled: true
|
||||
|
||||
@@ -39,12 +39,16 @@ Scope {
|
||||
implicitHeight: Appearance.sizes.wallpaperSelectorHeight
|
||||
implicitWidth: Appearance.sizes.wallpaperSelectorWidth
|
||||
|
||||
HyprlandFocusGrab { // Click outside to close
|
||||
id: grab
|
||||
windows: [ panelWindow ]
|
||||
active: wallpaperSelectorLoader.active
|
||||
onCleared: () => {
|
||||
if (!active) GlobalStates.wallpaperSelectorOpen = false;
|
||||
Component.onCompleted: {
|
||||
GlobalFocusGrab.addDismissable(panelWindow);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
GlobalFocusGrab.removeDismissable(panelWindow);
|
||||
}
|
||||
Connections {
|
||||
target: GlobalFocusGrab
|
||||
function onDismissed() {
|
||||
GlobalStates.wallpaperSelectorOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,9 +53,9 @@ ContentPage {
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
id: settingsClock
|
||||
icon: "clock_loader_40"
|
||||
title: Translation.tr("Widget: Clock")
|
||||
id: settingsClock
|
||||
|
||||
function stylePresent(styleName) {
|
||||
if (!Config.options.background.widgets.clock.showOnlyWhenLocked && Config.options.background.widgets.clock.style === styleName) {
|
||||
@@ -120,61 +120,161 @@ ContentPage {
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: !Config.options.background.widgets.clock.showOnlyWhenLocked
|
||||
title: Translation.tr("Clock style")
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.widgets.clock.style
|
||||
onSelected: newValue => {
|
||||
Config.options.background.widgets.clock.style = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: Translation.tr("Digital"),
|
||||
icon: "timer_10",
|
||||
value: "digital"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Cookie"),
|
||||
icon: "cookie",
|
||||
value: "cookie"
|
||||
ConfigRow {
|
||||
ContentSubsection {
|
||||
visible: !Config.options.background.widgets.clock.showOnlyWhenLocked
|
||||
title: Translation.tr("Clock style")
|
||||
Layout.fillWidth: true
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.widgets.clock.style
|
||||
onSelected: newValue => {
|
||||
Config.options.background.widgets.clock.style = newValue;
|
||||
}
|
||||
]
|
||||
options: [
|
||||
{
|
||||
displayName: Translation.tr("Digital"),
|
||||
icon: "timer_10",
|
||||
value: "digital"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Cookie"),
|
||||
icon: "cookie",
|
||||
value: "cookie"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
title: Translation.tr("Clock style (locked)")
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.widgets.clock.styleLocked
|
||||
onSelected: newValue => {
|
||||
Config.options.background.widgets.clock.styleLocked = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: Translation.tr("Digital"),
|
||||
icon: "timer_10",
|
||||
value: "digital"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Cookie"),
|
||||
icon: "cookie",
|
||||
value: "cookie"
|
||||
ContentSubsection {
|
||||
title: Translation.tr("Clock style (locked)")
|
||||
Layout.fillWidth: false
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.widgets.clock.styleLocked
|
||||
onSelected: newValue => {
|
||||
Config.options.background.widgets.clock.styleLocked = newValue;
|
||||
}
|
||||
]
|
||||
options: [
|
||||
{
|
||||
displayName: Translation.tr("Digital"),
|
||||
icon: "timer_10",
|
||||
value: "digital"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Cookie"),
|
||||
icon: "cookie",
|
||||
value: "cookie"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: settingsClock.digitalPresent
|
||||
title: Translation.tr("Digital clock settings")
|
||||
tooltip: Translation.tr("Font width and roundness settings are only available for some fonts like Google Sans Flex")
|
||||
|
||||
ConfigSwitch {
|
||||
buttonIcon: "animation"
|
||||
text: Translation.tr("Animate time change")
|
||||
checked: Config.options.background.widgets.clock.digital.animateChange
|
||||
onCheckedChanged: {
|
||||
Config.options.background.widgets.clock.digital.animateChange = checked;
|
||||
ConfigRow {
|
||||
uniform: true
|
||||
ConfigSwitch {
|
||||
buttonIcon: "vertical_distribute"
|
||||
text: Translation.tr("Vertical")
|
||||
checked: Config.options.background.widgets.clock.digital.vertical
|
||||
onCheckedChanged: {
|
||||
Config.options.background.widgets.clock.digital.vertical = checked;
|
||||
}
|
||||
}
|
||||
ConfigSwitch {
|
||||
buttonIcon: "animation"
|
||||
text: Translation.tr("Animate time change")
|
||||
checked: Config.options.background.widgets.clock.digital.animateChange
|
||||
onCheckedChanged: {
|
||||
Config.options.background.widgets.clock.digital.animateChange = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigRow {
|
||||
uniform: true
|
||||
|
||||
ConfigSwitch {
|
||||
buttonIcon: "date_range"
|
||||
text: Translation.tr("Show date")
|
||||
checked: Config.options.background.widgets.clock.digital.showDate
|
||||
onCheckedChanged: {
|
||||
Config.options.background.widgets.clock.digital.showDate = checked;
|
||||
}
|
||||
}
|
||||
ConfigSwitch {
|
||||
buttonIcon: "activity_zone"
|
||||
text: Translation.tr("Use adaptive alignment")
|
||||
checked: Config.options.background.widgets.clock.digital.adaptiveAlignment
|
||||
onCheckedChanged: {
|
||||
Config.options.background.widgets.clock.digital.adaptiveAlignment = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Aligns the date and quote to left, center or right depending on its position on the screen.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MaterialTextArea {
|
||||
Layout.fillWidth: true
|
||||
placeholderText: Translation.tr("Font family")
|
||||
text: Config.options.background.widgets.clock.digital.font.family
|
||||
wrapMode: TextEdit.Wrap
|
||||
onTextChanged: {
|
||||
Config.options.background.widgets.clock.digital.font.family = text;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
text: Translation.tr("Font weight")
|
||||
value: Config.options.background.widgets.clock.digital.font.weight
|
||||
usePercentTooltip: false
|
||||
buttonIcon: "format_bold"
|
||||
from: 1
|
||||
to: 1000
|
||||
stopIndicatorValues: [350]
|
||||
onValueChanged: {
|
||||
Config.options.background.widgets.clock.digital.font.weight = value;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
text: Translation.tr("Font size")
|
||||
value: Config.options.background.widgets.clock.digital.font.size
|
||||
usePercentTooltip: false
|
||||
buttonIcon: "format_size"
|
||||
from: 70
|
||||
to: 150
|
||||
stopIndicatorValues: [90]
|
||||
onValueChanged: {
|
||||
Config.options.background.widgets.clock.digital.font.size = value;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
text: Translation.tr("Font width")
|
||||
value: Config.options.background.widgets.clock.digital.font.width
|
||||
usePercentTooltip: false
|
||||
buttonIcon: "fit_width"
|
||||
from: 25
|
||||
to: 125
|
||||
stopIndicatorValues: [100]
|
||||
onValueChanged: {
|
||||
Config.options.background.widgets.clock.digital.font.width = value;
|
||||
}
|
||||
}
|
||||
ConfigSlider {
|
||||
text: Translation.tr("Font roundness")
|
||||
value: Config.options.background.widgets.clock.digital.font.roundness
|
||||
usePercentTooltip: false
|
||||
buttonIcon: "line_curve"
|
||||
from: 0
|
||||
to: 100
|
||||
onValueChanged: {
|
||||
Config.options.background.widgets.clock.digital.font.roundness = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,9 +225,6 @@ ContentPage {
|
||||
onCheckedChanged: {
|
||||
Config.options.appearance.transparency.enable = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Might look ass. Unsupported.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,10 +89,11 @@ Singleton {
|
||||
// Special
|
||||
property color shadow: ColorUtils.transparentize('#161616', 0.62)
|
||||
property color ambientShadow: ColorUtils.transparentize("#000000", 0.75)
|
||||
property color bgPanelFooterBase: ColorUtils.transparentize(root.dark ? root.darkColors.bg0 : root.lightColors.bg0, root.panelBackgroundTransparency)
|
||||
property color bgPanelFooter: ColorUtils.transparentize(bgPanelFooterBase, root.panelLayerTransparency)
|
||||
property color bgPanelFooterBase: root.dark ? root.darkColors.bg0 : root.lightColors.bg0
|
||||
property color bgPanelFooterBackground: ColorUtils.transparentize(root.dark ? root.darkColors.bg0 : root.lightColors.bg0, root.panelBackgroundTransparency)
|
||||
property color bgPanelFooter: ColorUtils.transparentize(bgPanelFooterBackground, root.panelLayerTransparency)
|
||||
property color bgPanelBodyBase: root.dark ? root.darkColors.bgPanelBody : root.lightColors.bgPanelBody
|
||||
property color bgPanelBody: ColorUtils.solveOverlayColor(bgPanelFooterBase,bgPanelBodyBase, 1 - root.panelLayerTransparency)
|
||||
property color bgPanelBody: ColorUtils.solveOverlayColor(bgPanelFooterBackground,bgPanelBodyBase, 1 - root.panelLayerTransparency)
|
||||
property color bgPanelSeparator: ColorUtils.solveOverlayColor(bgPanelBodyBase, root.dark ? root.darkColors.bgPanelSeparator : root.lightColors.bgPanelSeparator, 1 - root.panelBackgroundTransparency)
|
||||
// Layer 0
|
||||
property color bg0Base: root.dark ? root.darkColors.bg0 : root.lightColors.bg0
|
||||
|
||||
@@ -12,6 +12,7 @@ Item {
|
||||
id: root
|
||||
property Item contentItem
|
||||
property real radius: Looks.radius.large
|
||||
property alias color: contentRect.color
|
||||
property alias border: borderRect
|
||||
property alias borderColor: borderRect.border.color
|
||||
property alias borderWidth: borderRect.border.width
|
||||
@@ -42,7 +43,7 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
z: 0
|
||||
|
||||
color: Looks.colors.bgPanelFooterBase
|
||||
color: Looks.colors.bgPanelFooterBackground
|
||||
implicitWidth: contentItem.implicitWidth
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
layer.enabled: true
|
||||
|
||||
@@ -135,7 +135,7 @@ Rectangle {
|
||||
}
|
||||
BodyRectangle {
|
||||
implicitHeight: 80
|
||||
color: Looks.colors.bgPanelFooterBase
|
||||
color: Looks.colors.bgPanelFooterBackground
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 24
|
||||
|
||||
@@ -18,7 +18,7 @@ Item {
|
||||
Component.onCompleted: overlayColor = ColorUtils.transparentize("#000000", 0.4)
|
||||
Behavior on overlayColor {
|
||||
ColorAnimation {
|
||||
duration: 250
|
||||
duration: 150
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: wsBorder.border.width
|
||||
radius: wsBorder.radius - wsBorder.border.width
|
||||
color: Looks.colors.bgPanelFooterBase
|
||||
color: Looks.colors.bgPanelFooterBackground
|
||||
|
||||
implicitHeight: 174
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ WMouseAreaButton {
|
||||
|
||||
property string iconName: AppSearch.guessIcon(hyprlandClient?.class)
|
||||
|
||||
color: drag.active ? ColorUtils.transparentize(Looks.colors.bg1Base) : (containsMouse ? Looks.colors.bg1Base : Looks.colors.bgPanelFooterBase)
|
||||
color: drag.active ? ColorUtils.transparentize(Looks.colors.bg1Base) : (containsMouse ? Looks.colors.bg1Base : Looks.colors.bgPanelFooterBackground)
|
||||
borderColor: ColorUtils.transparentize(Looks.colors.bg2Border, drag.active ? 1 : 0)
|
||||
radius: Looks.radius.xLarge
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.ii.background
|
||||
import qs.modules.ii.bar
|
||||
import qs.modules.ii.cheatsheet
|
||||
import qs.modules.ii.dock
|
||||
import qs.modules.ii.lock
|
||||
import qs.modules.ii.mediaControls
|
||||
import qs.modules.ii.notificationPopup
|
||||
import qs.modules.ii.onScreenDisplay
|
||||
import qs.modules.ii.onScreenKeyboard
|
||||
import qs.modules.ii.overview
|
||||
import qs.modules.ii.polkit
|
||||
import qs.modules.ii.regionSelector
|
||||
import qs.modules.ii.screenCorners
|
||||
import qs.modules.ii.sessionScreen
|
||||
import qs.modules.ii.sidebarLeft
|
||||
import qs.modules.ii.sidebarRight
|
||||
import qs.modules.ii.overlay
|
||||
import qs.modules.ii.verticalBar
|
||||
import qs.modules.ii.wallpaperSelector
|
||||
|
||||
Scope {
|
||||
PanelLoader { extraCondition: !Config.options.bar.vertical; component: Bar {} }
|
||||
PanelLoader { component: Background {} }
|
||||
PanelLoader { component: Cheatsheet {} }
|
||||
PanelLoader { extraCondition: Config.options.dock.enable; component: Dock {} }
|
||||
PanelLoader { component: Lock {} }
|
||||
PanelLoader { component: MediaControls {} }
|
||||
PanelLoader { component: NotificationPopup {} }
|
||||
PanelLoader { component: OnScreenDisplay {} }
|
||||
PanelLoader { component: OnScreenKeyboard {} }
|
||||
PanelLoader { component: Overlay {} }
|
||||
PanelLoader { component: Overview {} }
|
||||
PanelLoader { component: Polkit {} }
|
||||
PanelLoader { component: RegionSelector {} }
|
||||
PanelLoader { component: ScreenCorners {} }
|
||||
PanelLoader { component: SessionScreen {} }
|
||||
PanelLoader { component: SidebarLeft {} }
|
||||
PanelLoader { component: SidebarRight {} }
|
||||
PanelLoader { extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
|
||||
PanelLoader { component: WallpaperSelector {} }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
import qs.modules.common
|
||||
|
||||
LazyLoader {
|
||||
property bool extraCondition: true
|
||||
active: Config.ready && extraCondition
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.waffle.actionCenter
|
||||
import qs.modules.waffle.background
|
||||
import qs.modules.waffle.bar
|
||||
import qs.modules.waffle.lock
|
||||
import qs.modules.waffle.notificationCenter
|
||||
import qs.modules.waffle.notificationPopup
|
||||
import qs.modules.waffle.onScreenDisplay
|
||||
// import qs.modules.waffle.overlay
|
||||
import qs.modules.waffle.polkit
|
||||
import qs.modules.waffle.screenSnip
|
||||
import qs.modules.waffle.startMenu
|
||||
import qs.modules.waffle.sessionScreen
|
||||
import qs.modules.waffle.taskView
|
||||
|
||||
// Fallbacks
|
||||
import qs.modules.ii.cheatsheet
|
||||
import qs.modules.ii.onScreenKeyboard
|
||||
import qs.modules.ii.overlay
|
||||
import qs.modules.ii.wallpaperSelector
|
||||
|
||||
Scope {
|
||||
PanelLoader { component: WaffleActionCenter {} }
|
||||
PanelLoader { component: WaffleBar {} }
|
||||
PanelLoader { component: WaffleBackground {} }
|
||||
PanelLoader { component: WaffleLock {} }
|
||||
PanelLoader { component: WaffleNotificationCenter {} }
|
||||
PanelLoader { component: WaffleNotificationPopup {} }
|
||||
PanelLoader { component: WaffleOSD {} }
|
||||
// PanelLoader { component: WaffleOverlay {} }
|
||||
PanelLoader { component: WafflePolkit {} }
|
||||
PanelLoader { component: WScreenSnip {} }
|
||||
PanelLoader { component: WaffleStartMenu {} }
|
||||
PanelLoader { component: WaffleSessionScreen {} }
|
||||
PanelLoader { component: WaffleTaskView {} }
|
||||
|
||||
PanelLoader { component: Cheatsheet {} }
|
||||
PanelLoader { component: OnScreenKeyboard {} }
|
||||
PanelLoader { component: Overlay {} }
|
||||
PanelLoader { component: WallpaperSelector {} }
|
||||
}
|
||||
@@ -255,19 +255,6 @@ Singleton {
|
||||
// - api_format: The API format of the model. Can be "openai" or "gemini". Default is "openai".
|
||||
// - extraParams: Extra parameters to be passed to the model. This is a JSON object.
|
||||
property var models: Config.options.policies.ai === 2 ? {} : {
|
||||
"gemini-2.0-flash": aiModelComponent.createObject(this, {
|
||||
"name": "Gemini 2.0 Flash",
|
||||
"icon": "google-gemini-symbolic",
|
||||
"description": Translation.tr("Online | Google's model\nFast, can perform searches for up-to-date information"),
|
||||
"homepage": "https://aistudio.google.com",
|
||||
"endpoint": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent",
|
||||
"model": "gemini-2.0-flash",
|
||||
"requires_key": true,
|
||||
"key_id": "gemini",
|
||||
"key_get_link": "https://aistudio.google.com/app/apikey",
|
||||
"key_get_description": Translation.tr("**Pricing**: free. Data used for training.\n\n**Instructions**: Log into Google account, allow AI Studio to create Google Cloud project or whatever it asks, go back and click Get API key"),
|
||||
"api_format": "gemini",
|
||||
}),
|
||||
"gemini-2.5-flash": aiModelComponent.createObject(this, {
|
||||
"name": "Gemini 2.5 Flash",
|
||||
"icon": "google-gemini-symbolic",
|
||||
@@ -281,26 +268,13 @@ Singleton {
|
||||
"key_get_description": Translation.tr("**Pricing**: free. Data used for training.\n\n**Instructions**: Log into Google account, allow AI Studio to create Google Cloud project or whatever it asks, go back and click Get API key"),
|
||||
"api_format": "gemini",
|
||||
}),
|
||||
"gemini-2.5-flash-pro": aiModelComponent.createObject(this, {
|
||||
"name": "Gemini 2.5 Pro",
|
||||
"gemini-3-flash": aiModelComponent.createObject(this, {
|
||||
"name": "Gemini 3 Flash",
|
||||
"icon": "google-gemini-symbolic",
|
||||
"description": Translation.tr("Online | Google's model\nGoogle's state-of-the-art multipurpose model that excels at coding and complex reasoning tasks."),
|
||||
"description": Translation.tr("Online | Google's model\nPro-level intelligence at the speed and pricing of Flash."),
|
||||
"homepage": "https://aistudio.google.com",
|
||||
"endpoint": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:streamGenerateContent",
|
||||
"model": "gemini-2.5-pro",
|
||||
"requires_key": true,
|
||||
"key_id": "gemini",
|
||||
"key_get_link": "https://aistudio.google.com/app/apikey",
|
||||
"key_get_description": Translation.tr("**Pricing**: free. Data used for training.\n\n**Instructions**: Log into Google account, allow AI Studio to create Google Cloud project or whatever it asks, go back and click Get API key"),
|
||||
"api_format": "gemini",
|
||||
}),
|
||||
"gemini-2.5-flash-lite": aiModelComponent.createObject(this, {
|
||||
"name": "Gemini 2.5 Flash-Lite",
|
||||
"icon": "google-gemini-symbolic",
|
||||
"description": Translation.tr("Online | Google's model\nA Gemini 2.5 Flash model optimized for cost-efficiency and high throughput."),
|
||||
"homepage": "https://aistudio.google.com",
|
||||
"endpoint": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:streamGenerateContent",
|
||||
"model": "gemini-2.5-flash-lite",
|
||||
"endpoint": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent",
|
||||
"model": "gemini-3-flash-preview",
|
||||
"requires_key": true,
|
||||
"key_id": "gemini",
|
||||
"key_get_link": "https://aistudio.google.com/app/apikey",
|
||||
@@ -320,19 +294,6 @@ Singleton {
|
||||
"key_get_description": Translation.tr("**Instructions**: Log into Mistral account, go to Keys on the sidebar, click Create new key"),
|
||||
"api_format": "mistral",
|
||||
}),
|
||||
"github-gpt-5-nano": aiModelComponent.createObject(this, {
|
||||
"name": "GPT-5 Nano (GH Models)",
|
||||
"icon": "github-symbolic",
|
||||
"api_format": "openai",
|
||||
"description": Translation.tr("Online via %1 | %2's model").arg("GitHub Models").arg("OpenAI"),
|
||||
"homepage": "https://github.com/marketplace/models",
|
||||
"endpoint": "https://models.inference.ai.azure.com/chat/completions",
|
||||
"model": "gpt-5-nano",
|
||||
"requires_key": true,
|
||||
"key_id": "github",
|
||||
"key_get_link": "https://github.com/settings/tokens",
|
||||
"key_get_description": Translation.tr("**Pricing**: Free tier available with limited rates. See https://docs.github.com/en/billing/concepts/product-billing/github-models\n\n**Instructions**: Generate a GitHub personal access token with Models permission, then set as API key here\n\n**Note**: To use this you will have to set the temperature parameter to 1"),
|
||||
}),
|
||||
"openrouter-deepseek-r1": aiModelComponent.createObject(this, {
|
||||
"name": "DeepSeek R1",
|
||||
"icon": "deepseek-symbolic",
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
|
||||
/**
|
||||
* Manages a HyprlandFocusGrab that's to be shared by all windows.
|
||||
* "Persistent" is for windows that should always be included but not closed on dismiss, like bar and onscreen keyboard.
|
||||
* "Dismissable" is for stuff like sidebars
|
||||
*/
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
signal dismissed()
|
||||
|
||||
property list<var> persistent: []
|
||||
property list<var> dismissable: []
|
||||
|
||||
function dismiss() {
|
||||
root.dismissable = [];
|
||||
root.dismissed();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("[GlobalFocusGrab] Initialized");
|
||||
}
|
||||
|
||||
function addPersistent(window) {
|
||||
if (root.persistent.indexOf(window) === -1) {
|
||||
root.persistent.push(window);
|
||||
}
|
||||
}
|
||||
|
||||
function removePersistent(window) {
|
||||
var index = root.persistent.indexOf(window);
|
||||
if (index !== -1) {
|
||||
root.persistent.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function addDismissable(window) {
|
||||
if (root.dismissable.indexOf(window) === -1) {
|
||||
root.dismissable.push(window);
|
||||
}
|
||||
}
|
||||
|
||||
function removeDismissable(window) {
|
||||
var index = root.dismissable.indexOf(window);
|
||||
if (index !== -1) {
|
||||
root.dismissable.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [...root.persistent, ...root.dismissable]
|
||||
active: root.dismissable.length > 0
|
||||
onCleared: () => {
|
||||
root.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,51 +6,22 @@
|
||||
// Adjust this to make the shell smaller or larger
|
||||
//@ pragma Env QT_SCALE_FACTOR=1
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.ii.background
|
||||
import qs.modules.ii.bar
|
||||
import qs.modules.ii.cheatsheet
|
||||
import qs.modules.ii.dock
|
||||
import qs.modules.ii.lock
|
||||
import qs.modules.ii.mediaControls
|
||||
import qs.modules.ii.notificationPopup
|
||||
import qs.modules.ii.onScreenDisplay
|
||||
import qs.modules.ii.onScreenKeyboard
|
||||
import qs.modules.ii.overview
|
||||
import qs.modules.ii.polkit
|
||||
import qs.modules.ii.regionSelector
|
||||
import qs.modules.ii.screenCorners
|
||||
import qs.modules.ii.sessionScreen
|
||||
import qs.modules.ii.sidebarLeft
|
||||
import qs.modules.ii.sidebarRight
|
||||
import qs.modules.ii.overlay
|
||||
import qs.modules.ii.verticalBar
|
||||
import qs.modules.ii.wallpaperSelector
|
||||
|
||||
import qs.modules.waffle.actionCenter
|
||||
import qs.modules.waffle.background
|
||||
import qs.modules.waffle.bar
|
||||
import qs.modules.waffle.lock
|
||||
import qs.modules.waffle.notificationCenter
|
||||
import qs.modules.waffle.notificationPopup
|
||||
import qs.modules.waffle.onScreenDisplay
|
||||
import qs.modules.waffle.polkit
|
||||
import qs.modules.waffle.screenSnip
|
||||
import qs.modules.waffle.startMenu
|
||||
import qs.modules.waffle.sessionScreen
|
||||
import qs.modules.waffle.taskView
|
||||
import "modules/common"
|
||||
import "services"
|
||||
import "panelFamilies"
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import qs.services
|
||||
|
||||
ShellRoot {
|
||||
id: root
|
||||
|
||||
// Force initialization of some singletons
|
||||
// Stuff for every panel family
|
||||
ReloadPopup {}
|
||||
|
||||
Component.onCompleted: {
|
||||
MaterialThemeLoader.reapplyTheme()
|
||||
Hyprsunset.load()
|
||||
@@ -61,62 +32,33 @@ ShellRoot {
|
||||
Updates.load()
|
||||
}
|
||||
|
||||
// Load enabled stuff
|
||||
// Well, these loaders only *allow* them to be loaded, to always load or not is defined in each component
|
||||
// The media controls for example is not loaded if it's not opened
|
||||
PanelLoader { identifier: "iiBar"; extraCondition: !Config.options.bar.vertical; component: Bar {} }
|
||||
PanelLoader { identifier: "iiBackground"; component: Background {} }
|
||||
PanelLoader { identifier: "iiCheatsheet"; component: Cheatsheet {} }
|
||||
PanelLoader { identifier: "iiDock"; extraCondition: Config.options.dock.enable; component: Dock {} }
|
||||
PanelLoader { identifier: "iiLock"; component: Lock {} }
|
||||
PanelLoader { identifier: "iiMediaControls"; component: MediaControls {} }
|
||||
PanelLoader { identifier: "iiNotificationPopup"; component: NotificationPopup {} }
|
||||
PanelLoader { identifier: "iiOnScreenDisplay"; component: OnScreenDisplay {} }
|
||||
PanelLoader { identifier: "iiOnScreenKeyboard"; component: OnScreenKeyboard {} }
|
||||
PanelLoader { identifier: "iiOverlay"; component: Overlay {} }
|
||||
PanelLoader { identifier: "iiOverview"; component: Overview {} }
|
||||
PanelLoader { identifier: "iiPolkit"; component: Polkit {} }
|
||||
PanelLoader { identifier: "iiRegionSelector"; component: RegionSelector {} }
|
||||
PanelLoader { identifier: "iiScreenCorners"; component: ScreenCorners {} }
|
||||
PanelLoader { identifier: "iiSessionScreen"; component: SessionScreen {} }
|
||||
PanelLoader { identifier: "iiSidebarLeft"; component: SidebarLeft {} }
|
||||
PanelLoader { identifier: "iiSidebarRight"; component: SidebarRight {} }
|
||||
PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
|
||||
PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} }
|
||||
|
||||
PanelLoader { identifier: "wActionCenter"; component: WaffleActionCenter {} }
|
||||
PanelLoader { identifier: "wBar"; component: WaffleBar {} }
|
||||
PanelLoader { identifier: "wBackground"; component: WaffleBackground {} }
|
||||
PanelLoader { identifier: "wLock"; component: WaffleLock {} }
|
||||
PanelLoader { identifier: "wNotificationCenter"; component: WaffleNotificationCenter {} }
|
||||
PanelLoader { identifier: "wNotificationPopup"; component: WaffleNotificationPopup {} }
|
||||
PanelLoader { identifier: "wOnScreenDisplay"; component: WaffleOSD {} }
|
||||
PanelLoader { identifier: "wPolkit"; component: WafflePolkit {} }
|
||||
PanelLoader { identifier: "wScreenSnip"; component: WScreenSnip {} }
|
||||
PanelLoader { identifier: "wStartMenu"; component: WaffleStartMenu {} }
|
||||
PanelLoader { identifier: "wSessionScreen"; component: WaffleSessionScreen {} }
|
||||
PanelLoader { identifier: "wTaskView"; component: WaffleTaskView {} }
|
||||
ReloadPopup {}
|
||||
|
||||
component PanelLoader: LazyLoader {
|
||||
required property string identifier
|
||||
property bool extraCondition: true
|
||||
active: Config.ready && Config.options.enabledPanels.includes(identifier) && extraCondition
|
||||
}
|
||||
|
||||
// Panel families
|
||||
property list<string> families: ["ii", "waffle"]
|
||||
property var panelFamilies: ({
|
||||
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
|
||||
"waffle": ["wActionCenter", "wBar", "wBackground", "wLock", "wNotificationCenter", "wNotificationPopup", "wOnScreenDisplay", "wTaskView", "wPolkit", "wScreenSnip", "wSessionScreen", "wStartMenu", "iiCheatsheet", "iiOnScreenKeyboard", "iiOverlay", "iiWallpaperSelector"],
|
||||
})
|
||||
function cyclePanelFamily() {
|
||||
const currentIndex = families.indexOf(Config.options.panelFamily)
|
||||
const nextIndex = (currentIndex + 1) % families.length
|
||||
Config.options.panelFamily = families[nextIndex]
|
||||
Config.options.enabledPanels = panelFamilies[Config.options.panelFamily]
|
||||
}
|
||||
|
||||
component PanelFamilyLoader: LazyLoader {
|
||||
required property string identifier
|
||||
property bool extraCondition: true
|
||||
active: Config.ready && Config.options.panelFamily === identifier && extraCondition
|
||||
}
|
||||
|
||||
PanelFamilyLoader {
|
||||
identifier: "ii"
|
||||
component: IllogicalImpulseFamily {}
|
||||
}
|
||||
|
||||
PanelFamilyLoader {
|
||||
identifier: "waffle"
|
||||
component: WaffleFamily {}
|
||||
}
|
||||
|
||||
|
||||
// Shortcuts
|
||||
IpcHandler {
|
||||
target: "panelFamily"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Auto start Hyprland on tty1
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" -eq 1 ]; then
|
||||
mkdir -p ~/.cache
|
||||
exec Hyprland > ~/.cache/hyprland.log 2>&1
|
||||
exec start-hyprland > ~/.cache/hyprland.log 2>&1
|
||||
fi
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
# TODO: For Arch(-Linux) specific part please check if pacman exists first, if not it should be skipped.
|
||||
|
||||
# TODO: Is this really needed? `git pull` should do a full upgrade, not partially, which means this script will be updated along with the folder structure together.
|
||||
# Note: The detect_repo_structure function below auto-detects the folder layout
|
||||
# Try to find the packages directory (different names in different versions)
|
||||
if which pacman &>/dev/null; then
|
||||
if [[ -d "${REPO_ROOT}/dist-arch" ]]; then
|
||||
@@ -56,7 +54,6 @@ declare -a IGNORE_SUBSTRING_PATTERNS=()
|
||||
# Track created directories to avoid redundant mkdir calls
|
||||
declare -A CREATED_DIRS
|
||||
|
||||
# TODO: Is this really needed? `git pull` should do a full upgrade, not partially, which means this script will be updated along with the folder structure together.
|
||||
# Auto-detect repository structure
|
||||
detect_repo_structure() {
|
||||
local found_dirs=()
|
||||
@@ -644,23 +641,41 @@ build_packages() {
|
||||
log_info "Building package: $pkg_name"
|
||||
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
log_info "[DRY-RUN] Would build package in directory: $pkg_dir"
|
||||
log_info "[DRY-RUN] Would build package in temp directory and clean up after"
|
||||
continue
|
||||
fi
|
||||
|
||||
cd "$pkg_dir" || {
|
||||
log_error "Failed to change to package directory: $pkg_dir"
|
||||
# Create temp build directory to avoid polluting the repo
|
||||
local build_tmp_dir
|
||||
build_tmp_dir=$(mktemp -d "/tmp/pkgbuild-${pkg_name}-XXXXXX")
|
||||
|
||||
# Copy package files to temp directory (using /. to include hidden files)
|
||||
cp -r "$pkg_dir"/. "$build_tmp_dir/" || {
|
||||
log_error "Failed to copy package files to temp directory"
|
||||
rm -rf "$build_tmp_dir"
|
||||
continue
|
||||
}
|
||||
|
||||
if makepkg -si --noconfirm; then
|
||||
cd "$build_tmp_dir" || {
|
||||
log_error "Failed to change to temp build directory: $build_tmp_dir"
|
||||
rm -rf "$build_tmp_dir"
|
||||
continue
|
||||
}
|
||||
|
||||
if makepkg -sCi --noconfirm; then
|
||||
log_success "Successfully built and installed $pkg_name"
|
||||
((rebuilt_packages++))
|
||||
((rebuilt_packages++)) || true
|
||||
else
|
||||
log_error "Failed to build package $pkg_name"
|
||||
fi
|
||||
|
||||
# Clean up temp build directory
|
||||
cd "$REPO_ROOT" || log_die "Failed to return to repository directory"
|
||||
rm -rf "$build_tmp_dir"
|
||||
log_info "Cleaned up temp build directory"
|
||||
|
||||
# Also clean any old build artifacts in the original package directory
|
||||
rm -rf "${pkg_dir}/src" "${pkg_dir}/pkg" "${pkg_dir}"/*.pkg.tar.* 2>/dev/null || true
|
||||
done
|
||||
|
||||
if [[ $rebuilt_packages -eq 0 ]]; then
|
||||
@@ -852,8 +867,12 @@ if git remote get-url origin &>/dev/null; then
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to pull changes from remote. Continuing with local repository..."
|
||||
log_info "You may need to resolve conflicts manually later."
|
||||
log_warning "Failed to pull changes from remote."
|
||||
log_warning "This could be due to:"
|
||||
log_warning " - Network issues"
|
||||
log_warning " - Uncommitted local changes (use 'git stash' first)"
|
||||
log_warning " - Diverged history (may need 'git pull --rebase')"
|
||||
log_info "Continuing with local repository state..."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -879,68 +898,70 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
|
||||
if [[ "$PKG_TOOLS_AVAILABLE" == true ]]; then
|
||||
if [[ ! -d "$ARCH_PACKAGES_DIR" ]]; then
|
||||
log_warning "No packages directory found (tried: dist-arch, arch-packages, sdata/dist-arch). Skipping package management."
|
||||
log_warning "No packages directory found (tried: dist-arch, arch-packages, sdata/dist-arch)."
|
||||
log_warning "Skipping package management."
|
||||
else
|
||||
changed_pkgbuilds=()
|
||||
for pkg_dir in "$ARCH_PACKAGES_DIR"/*/; do
|
||||
if [[ -f "${pkg_dir}/PKGBUILD" ]]; then
|
||||
pkg_name=$(basename "$pkg_dir")
|
||||
if check_pkgbuild_changed "$pkg_dir"; then
|
||||
changed_pkgbuilds+=("$pkg_name")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#changed_pkgbuilds[@]} -gt 0 ]]; then
|
||||
log_info "Found ${#changed_pkgbuilds[@]} package(s) with changed PKGBUILDs: ${changed_pkgbuilds[*]}"
|
||||
echo
|
||||
echo "Package build options:"
|
||||
echo "1) Build only packages with changed PKGBUILDs"
|
||||
echo "2) List all packages and select which to build"
|
||||
echo "3) Build all packages"
|
||||
echo "4) Skip package building"
|
||||
echo
|
||||
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
pkg_choice="1"
|
||||
log_info "Non-interactive mode: Using default package option: $pkg_choice"
|
||||
elif safe_read "Choose an option (1-4): " pkg_choice "1"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User selected package option: $pkg_choice"
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package building."
|
||||
pkg_choice=""
|
||||
fi
|
||||
|
||||
if [[ -n "$pkg_choice" ]]; then
|
||||
case $pkg_choice in
|
||||
1) build_packages "changed" ;;
|
||||
2)
|
||||
if list_packages; then
|
||||
build_packages "select"
|
||||
# Scan for changed PKGBUILDs
|
||||
changed_pkgbuilds=()
|
||||
for pkg_dir in "$ARCH_PACKAGES_DIR"/*/; do
|
||||
if [[ -f "${pkg_dir}/PKGBUILD" ]]; then
|
||||
pkg_name=$(basename "$pkg_dir")
|
||||
if check_pkgbuild_changed "$pkg_dir"; then
|
||||
changed_pkgbuilds+=("$pkg_name")
|
||||
fi
|
||||
;;
|
||||
3) build_packages "all" ;;
|
||||
4 | *) log_info "Skipping package building" ;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
log_info "No PKGBUILDs have changed since last update."
|
||||
echo
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
check_anyway="N"
|
||||
log_info "Non-interactive mode: Using default for check packages anyway: $check_anyway"
|
||||
elif safe_read "Do you want to check and build packages anyway? (y/N): " check_anyway "N"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User chose to check packages anyway: $check_anyway"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#changed_pkgbuilds[@]} -gt 0 ]]; then
|
||||
log_info "Found ${#changed_pkgbuilds[@]} package(s) with changed PKGBUILDs: ${changed_pkgbuilds[*]}"
|
||||
echo
|
||||
echo "Package build options:"
|
||||
echo "1) Build only packages with changed PKGBUILDs"
|
||||
echo "2) List all packages and select which to build"
|
||||
echo "3) Build all packages"
|
||||
echo "4) Skip package building"
|
||||
echo
|
||||
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
pkg_choice="1"
|
||||
log_info "Non-interactive mode: Using default package option: $pkg_choice"
|
||||
elif safe_read "Choose an option (1-4): " pkg_choice "1"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User selected package option: $pkg_choice"
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package building."
|
||||
pkg_choice=""
|
||||
fi
|
||||
|
||||
if [[ -n "$pkg_choice" ]]; then
|
||||
case $pkg_choice in
|
||||
1) build_packages "changed" ;;
|
||||
2)
|
||||
if list_packages; then
|
||||
build_packages "select"
|
||||
fi
|
||||
;;
|
||||
3) build_packages "all" ;;
|
||||
4|*) log_info "Skipping package building" ;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package management."
|
||||
check_anyway=""
|
||||
fi
|
||||
log_info "No PKGBUILDs have changed since last update."
|
||||
echo
|
||||
if [[ "$NON_INTERACTIVE" == true ]]; then
|
||||
check_anyway="N"
|
||||
log_info "Non-interactive mode: Using default for check packages anyway: $check_anyway"
|
||||
elif safe_read "Do you want to check and build packages anyway? (y/N): " check_anyway "N"; then
|
||||
if [[ "$VERBOSE" == true ]]; then
|
||||
log_info "User chose to check packages anyway: $check_anyway"
|
||||
fi
|
||||
else
|
||||
log_warning "Failed to read input. Skipping package management."
|
||||
check_anyway=""
|
||||
fi
|
||||
|
||||
if [[ -n "$check_anyway" && "$check_anyway" =~ ^[Yy]$ ]]; then
|
||||
if [[ -n "$check_anyway" && "$check_anyway" =~ ^[Yy]$ ]]; then
|
||||
if list_packages; then
|
||||
echo
|
||||
echo "Package build options:"
|
||||
@@ -950,9 +971,9 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
|
||||
if safe_read "Choose an option (1-3): " build_choice "3"; then
|
||||
case $build_choice in
|
||||
1) build_packages "select" ;;
|
||||
2) build_packages "all" ;;
|
||||
3 | *) log_info "Skipping package building" ;;
|
||||
1) build_packages "select" ;;
|
||||
2) build_packages "all" ;;
|
||||
3|*) log_info "Skipping package building" ;;
|
||||
esac
|
||||
else
|
||||
log_info "Skipping package building"
|
||||
@@ -963,10 +984,10 @@ if [[ "$CHECK_PACKAGES" == true ]]; then
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_header "Package Management"
|
||||
log_info "Package checking disabled. Use -p or --packages flag to enable package management."
|
||||
fi
|
||||
else
|
||||
log_header "Package Management"
|
||||
log_info "Package checking disabled. Use -p or --packages flag to enable package management."
|
||||
fi
|
||||
|
||||
# Step 3: Update configuration files
|
||||
|
||||
@@ -118,7 +118,7 @@ function install_dir(){
|
||||
if [ -d $t ];then
|
||||
warning_overwrite
|
||||
fi
|
||||
rsync_dir $s $t
|
||||
v rsync_dir $s $t
|
||||
}
|
||||
function install_dir__sync(){
|
||||
# NOTE: Do not add prefix `v` or `x` when using this function
|
||||
@@ -127,7 +127,7 @@ function install_dir__sync(){
|
||||
if [ -d $t ];then
|
||||
warning_overwrite
|
||||
fi
|
||||
rsync_dir__sync $s $t
|
||||
v rsync_dir__sync $s $t
|
||||
}
|
||||
function install_dir__skip_existed(){
|
||||
# NOTE: Do not add prefix `v` or `x` when using this function
|
||||
@@ -150,7 +150,7 @@ function install_dir__sync_exclude(){
|
||||
if [ -d $t ];then
|
||||
warning_overwrite
|
||||
fi
|
||||
rsync_dir__sync_exclude $s $t "$@"
|
||||
v rsync_dir__sync_exclude $s $t "$@"
|
||||
}
|
||||
function install_google_sans_flex(){
|
||||
local font_name="Google Sans Flex"
|
||||
|
||||
Reference in New Issue
Block a user