diff --git a/dots/.config/fish/auto-Hypr.fish b/dots/.config/fish/auto-Hypr.fish index 711f31dbe..893451c44 100644 --- a/dots/.config/fish/auto-Hypr.fish +++ b/dots/.config/fish/auto-Hypr.fish @@ -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 diff --git a/dots/.config/hypr/custom/rules.conf b/dots/.config/hypr/custom/rules.conf index b253bc8d1..9b48404e6 100644 --- a/dots/.config/hypr/custom/rules.conf +++ b/dots/.config/hypr/custom/rules.conf @@ -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 \ No newline at end of file +# windowrule = no_blur on, match:xwayland 1 diff --git a/dots/.config/hypr/hyprland/colors.conf b/dots/.config/hypr/hyprland/colors.conf index 5954859e8..28863e35d 100644 --- a/dots/.config/hypr/hyprland/colors.conf +++ b/dots/.config/hypr/hyprland/colors.conf @@ -31,4 +31,4 @@ plugin { } } -windowrulev2 = bordercolor rgba(FFB2BCAA) rgba(FFB2BC77),pinned:1 \ No newline at end of file +windowrule = border_color rgba(FFB2BCAA) rgba(FFB2BC77), match:pin 1 diff --git a/dots/.config/hypr/hyprland/general.conf b/dots/.config/hypr/hyprland/general.conf index 4b12fc84f..aedba4578 100644 --- a/dots/.config/hypr/hyprland/general.conf +++ b/dots/.config/hypr/hyprland/general.conf @@ -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 diff --git a/dots/.config/hypr/hyprland/rules.conf b/dots/.config/hypr/hyprland/rules.conf index 3a3a01ef9..7e9d37cc1 100644 --- a/dots/.config/hypr/hyprland/rules.conf +++ b/dots/.config/hypr/hyprland/rules.conf @@ -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 diff --git a/dots/.config/matugen/templates/hyprland/colors.conf b/dots/.config/matugen/templates/hyprland/colors.conf index d0002e9e7..6de98514f 100644 --- a/dots/.config/matugen/templates/hyprland/colors.conf +++ b/dots/.config/matugen/templates/hyprland/colors.conf @@ -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 diff --git a/dots/.config/quickshell/ii/modules/common/Appearance.qml b/dots/.config/quickshell/ii/modules/common/Appearance.qml index aca8bfa4f..d64253476 100644 --- a/dots/.config/quickshell/ii/modules/common/Appearance.qml +++ b/dots/.config/quickshell/ii/modules/common/Appearance.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 341df9045..b370aca94 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -78,10 +78,7 @@ Singleton { JsonAdapter { id: configOptionsJsonAdapter - property list 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 diff --git a/dots/.config/quickshell/ii/modules/common/Persistent.qml b/dots/.config/quickshell/ii/modules/common/Persistent.qml index 247884028..8367692e3 100644 --- a/dots/.config/quickshell/ii/modules/common/Persistent.qml +++ b/dots/.config/quickshell/ii/modules/common/Persistent.qml @@ -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 } diff --git a/dots/.config/quickshell/ii/modules/common/widgets/ConfigSlider.qml b/dots/.config/quickshell/ii/modules/common/widgets/ConfigSlider.qml new file mode 100644 index 000000000..edc63191a --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/ConfigSlider.qml @@ -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 + } +} \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/common/widgets/SelectionDialog.qml b/dots/.config/quickshell/ii/modules/common/widgets/SelectionDialog.qml index 68d67a32c..6100c0864 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/SelectionDialog.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/SelectionDialog.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml b/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml index 18add2cc3..55504acb2 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml @@ -192,7 +192,7 @@ ComboBox { id: popupBackground anchors.fill: parent radius: Appearance.rounding.normal - color: Appearance.colors.colSurfaceContainerHigh + color: Appearance.m3colors.m3surfaceContainerHigh } } diff --git a/dots/.config/quickshell/ii/modules/common/widgets/StyledSlider.qml b/dots/.config/quickshell/ii/modules/common/widgets/StyledSlider.qml index 98b8eebf3..971a1eb10 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/StyledSlider.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/StyledSlider.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/common/widgets/shapes b/dots/.config/quickshell/ii/modules/common/widgets/shapes index 8aa62a41b..7f0f0709e 160000 --- a/dots/.config/quickshell/ii/modules/common/widgets/shapes +++ b/dots/.config/quickshell/ii/modules/common/widgets/shapes @@ -1 +1 @@ -Subproject commit 8aa62a41bd4cdc4899bdfdc0d9cf103ac34c51f6 +Subproject commit 7f0f0709ec5bbe4c3158c7f5fc68fd890af46618 diff --git a/dots/.config/quickshell/ii/modules/ii/background/widgets/AbstractBackgroundWidget.qml b/dots/.config/quickshell/ii/modules/ii/background/widgets/AbstractBackgroundWidget.qml index b24c33aaa..6d8c14598 100644 --- a/dots/.config/quickshell/ii/modules/ii/background/widgets/AbstractBackgroundWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/background/widgets/AbstractBackgroundWidget.qml @@ -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; diff --git a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockText.qml b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockText.qml new file mode 100644 index 000000000..133a2759c --- /dev/null +++ b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockText.qml @@ -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 +} \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml index 97e1e468a..754b6d1be 100644 --- a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/DigitalClock.qml b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/DigitalClock.qml new file mode 100644 index 000000000..12f49f642 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/DigitalClock.qml @@ -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 + } +} diff --git a/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml b/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml index 0bf1ad917..67e730677 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/ii/cheatsheet/Cheatsheet.qml b/dots/.config/quickshell/ii/modules/ii/cheatsheet/Cheatsheet.qml index f7fb68f68..c5df4fe82 100644 --- a/dots/.config/quickshell/ii/modules/ii/cheatsheet/Cheatsheet.qml +++ b/dots/.config/quickshell/ii/modules/ii/cheatsheet/Cheatsheet.qml @@ -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(); } } diff --git a/dots/.config/quickshell/ii/modules/ii/lock/Lock.qml b/dots/.config/quickshell/ii/modules/ii/lock/Lock.qml index 3aae6ef7b..adeaaa481 100644 --- a/dots/.config/quickshell/ii/modules/ii/lock/Lock.qml +++ b/dots/.config/quickshell/ii/modules/ii/lock/Lock.qml @@ -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`]); } } } diff --git a/dots/.config/quickshell/ii/modules/ii/mediaControls/MediaControls.qml b/dots/.config/quickshell/ii/modules/ii/mediaControls/MediaControls.qml index 3cd620834..3d98be7ca 100644 --- a/dots/.config/quickshell/ii/modules/ii/mediaControls/MediaControls.qml +++ b/dots/.config/quickshell/ii/modules/ii/mediaControls/MediaControls.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/ii/onScreenKeyboard/OnScreenKeyboard.qml b/dots/.config/quickshell/ii/modules/ii/onScreenKeyboard/OnScreenKeyboard.qml index 3407c217f..9dc1068d8 100644 --- a/dots/.config/quickshell/ii/modules/ii/onScreenKeyboard/OnScreenKeyboard.qml +++ b/dots/.config/quickshell/ii/modules/ii/onScreenKeyboard/OnScreenKeyboard.qml @@ -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 { diff --git a/dots/.config/quickshell/ii/modules/ii/overview/Overview.qml b/dots/.config/quickshell/ii/modules/ii/overview/Overview.qml index bf8706eb0..d94404721 100644 --- a/dots/.config/quickshell/ii/modules/ii/overview/Overview.qml +++ b/dots/.config/quickshell/ii/modules/ii/overview/Overview.qml @@ -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 { diff --git a/dots/.config/quickshell/ii/modules/ii/overview/OverviewWidget.qml b/dots/.config/quickshell/ii/modules/ii/overview/OverviewWidget.qml index f1ea1b331..f2a600c6d 100644 --- a/dots/.config/quickshell/ii/modules/ii/overview/OverviewWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/overview/OverviewWidget.qml @@ -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) diff --git a/dots/.config/quickshell/ii/modules/ii/overview/SearchWidget.qml b/dots/.config/quickshell/ii/modules/ii/overview/SearchWidget.qml index 6b982c4d2..6450ccef0 100644 --- a/dots/.config/quickshell/ii/modules/ii/overview/SearchWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/overview/SearchWidget.qml @@ -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]) } } } diff --git a/dots/.config/quickshell/ii/modules/ii/sidebarLeft/SidebarLeft.qml b/dots/.config/quickshell/ii/modules/ii/sidebarLeft/SidebarLeft.qml index fc275976c..1952557bc 100644 --- a/dots/.config/quickshell/ii/modules/ii/sidebarLeft/SidebarLeft.qml +++ b/dots/.config/quickshell/ii/modules/ii/sidebarLeft/SidebarLeft.qml @@ -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) { diff --git a/dots/.config/quickshell/ii/modules/ii/sidebarLeft/anime/BooruImage.qml b/dots/.config/quickshell/ii/modules/ii/sidebarLeft/anime/BooruImage.qml index e403417ba..feeeeb05b 100644 --- a/dots/.config/quickshell/ii/modules/ii/sidebarLeft/anime/BooruImage.qml +++ b/dots/.config/quickshell/ii/modules/ii/sidebarLeft/anime/BooruImage.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/ii/sidebarRight/SidebarRight.qml b/dots/.config/quickshell/ii/modules/ii/sidebarRight/SidebarRight.qml index fcba76710..62946cb61 100644 --- a/dots/.config/quickshell/ii/modules/ii/sidebarRight/SidebarRight.qml +++ b/dots/.config/quickshell/ii/modules/ii/sidebarRight/SidebarRight.qml @@ -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; } } - } diff --git a/dots/.config/quickshell/ii/modules/ii/sidebarRight/todo/TodoWidget.qml b/dots/.config/quickshell/ii/modules/ii/sidebarRight/todo/TodoWidget.qml index 36c885523..8341887fd 100644 --- a/dots/.config/quickshell/ii/modules/ii/sidebarRight/todo/TodoWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/sidebarRight/todo/TodoWidget.qml @@ -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() { diff --git a/dots/.config/quickshell/ii/modules/ii/verticalBar/VerticalBar.qml b/dots/.config/quickshell/ii/modules/ii/verticalBar/VerticalBar.qml index 3851f06d3..bf11091d6 100644 --- a/dots/.config/quickshell/ii/modules/ii/verticalBar/VerticalBar.qml +++ b/dots/.config/quickshell/ii/modules/ii/verticalBar/VerticalBar.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/ii/wallpaperSelector/WallpaperSelector.qml b/dots/.config/quickshell/ii/modules/ii/wallpaperSelector/WallpaperSelector.qml index 197acbf2e..5bd79b56b 100644 --- a/dots/.config/quickshell/ii/modules/ii/wallpaperSelector/WallpaperSelector.qml +++ b/dots/.config/quickshell/ii/modules/ii/wallpaperSelector/WallpaperSelector.qml @@ -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; } } diff --git a/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml b/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml index 86debf5d7..cc7c361bc 100644 --- a/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml @@ -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; } } } diff --git a/dots/.config/quickshell/ii/modules/settings/QuickConfig.qml b/dots/.config/quickshell/ii/modules/settings/QuickConfig.qml index c9c540afa..8a31d7728 100644 --- a/dots/.config/quickshell/ii/modules/settings/QuickConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/QuickConfig.qml @@ -225,9 +225,6 @@ ContentPage { onCheckedChanged: { Config.options.appearance.transparency.enable = checked; } - StyledToolTip { - text: Translation.tr("Might look ass. Unsupported.") - } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index 779835837..7bad59e84 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml index f281a8b7c..01f20d8d2 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/waffle/polkit/WPolkitContent.qml b/dots/.config/quickshell/ii/modules/waffle/polkit/WPolkitContent.qml index 1218efb69..1fcb25072 100644 --- a/dots/.config/quickshell/ii/modules/waffle/polkit/WPolkitContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/polkit/WPolkitContent.qml @@ -135,7 +135,7 @@ Rectangle { } BodyRectangle { implicitHeight: 80 - color: Looks.colors.bgPanelFooterBase + color: Looks.colors.bgPanelFooterBackground RowLayout { anchors.fill: parent anchors.margins: 24 diff --git a/dots/.config/quickshell/ii/modules/waffle/screenSnip/WRectangularSelection.qml b/dots/.config/quickshell/ii/modules/waffle/screenSnip/WRectangularSelection.qml index a0ec287b8..1de501613 100644 --- a/dots/.config/quickshell/ii/modules/waffle/screenSnip/WRectangularSelection.qml +++ b/dots/.config/quickshell/ii/modules/waffle/screenSnip/WRectangularSelection.qml @@ -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 } } diff --git a/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewContent.qml b/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewContent.qml index 4dc6f5bf7..6828098cf 100644 --- a/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewContent.qml @@ -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 diff --git a/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewWindow.qml b/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewWindow.qml index 0cab91fe5..b91655097 100644 --- a/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewWindow.qml +++ b/dots/.config/quickshell/ii/modules/waffle/taskView/TaskViewWindow.qml @@ -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 diff --git a/dots/.config/quickshell/ii/panelFamilies/IllogicalImpulseFamily.qml b/dots/.config/quickshell/ii/panelFamilies/IllogicalImpulseFamily.qml new file mode 100644 index 000000000..f4ffda651 --- /dev/null +++ b/dots/.config/quickshell/ii/panelFamilies/IllogicalImpulseFamily.qml @@ -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 {} } +} diff --git a/dots/.config/quickshell/ii/panelFamilies/PanelLoader.qml b/dots/.config/quickshell/ii/panelFamilies/PanelLoader.qml new file mode 100644 index 000000000..1e7b52f42 --- /dev/null +++ b/dots/.config/quickshell/ii/panelFamilies/PanelLoader.qml @@ -0,0 +1,9 @@ +import QtQuick +import Quickshell + +import qs.modules.common + +LazyLoader { + property bool extraCondition: true + active: Config.ready && extraCondition +} diff --git a/dots/.config/quickshell/ii/panelFamilies/WaffleFamily.qml b/dots/.config/quickshell/ii/panelFamilies/WaffleFamily.qml new file mode 100644 index 000000000..67d35de55 --- /dev/null +++ b/dots/.config/quickshell/ii/panelFamilies/WaffleFamily.qml @@ -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 {} } +} diff --git a/dots/.config/quickshell/ii/services/Ai.qml b/dots/.config/quickshell/ii/services/Ai.qml index ccd237de8..580b3cfdb 100644 --- a/dots/.config/quickshell/ii/services/Ai.qml +++ b/dots/.config/quickshell/ii/services/Ai.qml @@ -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", diff --git a/dots/.config/quickshell/ii/services/GlobalFocusGrab.qml b/dots/.config/quickshell/ii/services/GlobalFocusGrab.qml new file mode 100644 index 000000000..547d79e17 --- /dev/null +++ b/dots/.config/quickshell/ii/services/GlobalFocusGrab.qml @@ -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 persistent: [] + property list 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(); + } + } + +} diff --git a/dots/.config/quickshell/ii/shell.qml b/dots/.config/quickshell/ii/shell.qml index b0fe37a4f..a1cb57baa 100644 --- a/dots/.config/quickshell/ii/shell.qml +++ b/dots/.config/quickshell/ii/shell.qml @@ -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 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" diff --git a/dots/.config/zshrc.d/auto-Hypr.sh b/dots/.config/zshrc.d/auto-Hypr.sh index 55eca5e02..db893c13c 100644 --- a/dots/.config/zshrc.d/auto-Hypr.sh +++ b/dots/.config/zshrc.d/auto-Hypr.sh @@ -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 diff --git a/sdata/subcmd-exp-update/0.run.sh b/sdata/subcmd-exp-update/0.run.sh index 2ab21379c..72c11e770 100644 --- a/sdata/subcmd-exp-update/0.run.sh +++ b/sdata/subcmd-exp-update/0.run.sh @@ -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 diff --git a/sdata/subcmd-install/3.files.sh b/sdata/subcmd-install/3.files.sh index 57c8568e1..956ee4859 100644 --- a/sdata/subcmd-install/3.files.sh +++ b/sdata/subcmd-install/3.files.sh @@ -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"