diff --git a/.config/hypr/hyprland/execs.conf b/.config/hypr/hyprland/execs.conf index 33fc3ffb7..0d04c512e 100644 --- a/.config/hypr/hyprland/execs.conf +++ b/.config/hypr/hyprland/execs.conf @@ -1,7 +1,5 @@ # Bar, wallpaper exec-once = ~/.config/hypr/hyprland/scripts/start_geoclue_agent.sh & gammastep -exec-once = sleep 0.7; [ "$(hyprctl monitors -j | jq 'length')" -eq 1 ] && swww-daemon --format xrgb --no-cache || swww-daemon --format xrgb -exec-once = sleep 0.7; swww img "$(cat ~/.local/state/quickshell/user/generated/wallpaper/path.txt)" --transition-step 100 --transition-fps 120 --transition-type grow --transition-angle 30 --transition-duration 1 exec-once = qs -c $qsConfig & # Input method diff --git a/.config/quickshell/ii/modules/background/Background.qml b/.config/quickshell/ii/modules/background/Background.qml new file mode 100644 index 000000000..cfd0678b7 --- /dev/null +++ b/.config/quickshell/ii/modules/background/Background.qml @@ -0,0 +1,152 @@ +pragma ComponentBehavior: Bound + +import "root:/" +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/services" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Io +import Quickshell.Wayland + +// TODO REMOVE BACKGROUNDWIDGETS + +Scope { + id: root + readonly property bool fixedClockPosition: Config.options.background.fixedClockPosition + readonly property real fixedClockX: Config.options.background.clockX + readonly property real fixedClockY: Config.options.background.clockY + + Variants { + // For each monitor + model: Quickshell.screens + + PanelWindow { + id: bgRoot + + required property var modelData + property string wallpaperPath: Config.options.background.wallpaperPath + // Position + property real clockX: modelData.width / 2 + property real clockY: modelData.height / 2 + property var textHorizontalAlignment: clockX < screen.width / 3 ? Text.AlignLeft : + (clockX > screen.width * 2 / 3 ? Text.AlignRight : Text.AlignHCenter) + // Colors + property color dominantColor: Appearance.colors.colPrimary + property bool dominantColorIsDark: dominantColor.hslLightness < 0.5 + property color colText: ColorUtils.colorWithLightness(Appearance.colors.colPrimary, (dominantColorIsDark ? 0.8 : 0.12)) + + // Layer props + screen: modelData + WlrLayershell.layer: WlrLayer.Bottom + WlrLayershell.namespace: "quickshell:background" + anchors { + top: true + bottom: true + left: true + right: true + } + color: "transparent" + + // Clock positioning + function updateClockPosition() { + leastBusyRegionProc.path = wallpaperPath // Somehow this is needed to make the proc correctly use the new path + leastBusyRegionProc.contentWidth = clock.implicitWidth + leastBusyRegionProc.contentHeight = clock.implicitHeight + leastBusyRegionProc.running = false; + leastBusyRegionProc.running = true; + } + onWallpaperPathChanged: { + // console.log("[Background] Wallpaper path changed to:", wallpaperPath) + bgRoot.updateClockPosition() + } + Process { + id: leastBusyRegionProc + running: true + property string path: bgRoot.wallpaperPath + property int contentWidth: bgRoot.screen.width + property int contentHeight: bgRoot.screen.height + command: [Quickshell.configPath("scripts/images/least_busy_region.py"), + "--screen-width", bgRoot.screen.width, + "--screen-height", bgRoot.screen.height, + "--width", contentWidth, + "--height", contentHeight, + path + ] + stdout: StdioCollector { + id: leastBusyRegionOutputCollector + onStreamFinished: { + const output = leastBusyRegionOutputCollector.text + console.log("[Background] Least busy region output:", output) + if (output.length === 0) return; + const parsedContent = JSON.parse(output) + bgRoot.clockX = parsedContent.center_x + bgRoot.clockY = parsedContent.center_y + bgRoot.dominantColor = parsedContent.dominant_color || Appearance.colors.colPrimary + } + } + } + + // Wallpaper + AnimatedImage { + z: 0 + anchors.fill: parent + source: bgRoot.wallpaperPath + fillMode: Image.PreserveAspectCrop + sourceSize { + width: bgRoot.screen.width + height: bgRoot.screen.height + } + } + + // The clock + Item { + id: clock + z: 1 + anchors { + left: parent.left + top: parent.top + leftMargin: (root.fixedClockPosition ? root.fixedClockX : bgRoot.clockX) - implicitWidth / 2 + topMargin: (root.fixedClockPosition ? root.fixedClockY : bgRoot.clockY) - implicitHeight / 2 + Behavior on leftMargin { + animation: Appearance.animation.elementMove.numberAnimation.createObject(this) + } + Behavior on topMargin { + animation: Appearance.animation.elementMove.numberAnimation.createObject(this) + } + } + + implicitWidth: clockColumn.implicitWidth + implicitHeight: clockColumn.implicitHeight + + ColumnLayout { + id: clockColumn + anchors.centerIn: parent + spacing: -5 + + StyledText { + Layout.fillWidth: true + horizontalAlignment: bgRoot.textHorizontalAlignment + font.pixelSize: 95 + color: bgRoot.colText + style: Text.Raised + styleColor: Appearance.colors.colShadow + text: DateTime.time + } + StyledText { + Layout.fillWidth: true + horizontalAlignment: bgRoot.textHorizontalAlignment + font.pixelSize: 25 + color: bgRoot.colText + style: Text.Raised + styleColor: Appearance.colors.colShadow + text: DateTime.date + } + } + } + } + } +} diff --git a/.config/quickshell/ii/modules/backgroundWidgets/BackgroundWidgets.qml b/.config/quickshell/ii/modules/backgroundWidgets/BackgroundWidgets.qml deleted file mode 100644 index 35f30534e..000000000 --- a/.config/quickshell/ii/modules/backgroundWidgets/BackgroundWidgets.qml +++ /dev/null @@ -1,139 +0,0 @@ -import "root:/" -import "root:/modules/common" -import "root:/modules/common/widgets" -import "root:/services" -import "root:/modules/common/functions/color_utils.js" as ColorUtils -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import Quickshell -import Quickshell.Io -import Quickshell.Wayland -import Quickshell.Hyprland -import Quickshell.Services.UPower - -Scope { - id: root - property string filePath: `${Directories.state}/user/generated/wallpaper/least_busy_region.json` - property real defaultX: (Config.options?.background.clockX ?? -500) - property real defaultY: (Config.options?.background.clockY ?? -500) - property real centerX: defaultX - property real centerY: defaultY - property real effectiveCenterX: Config.options?.background.fixedClockPosition ? defaultX : centerX - property real effectiveCenterY: Config.options?.background.fixedClockPosition ? defaultY : centerY - property color dominantColor: Appearance.colors.colPrimary - property bool dominantColorIsDark: dominantColor.hslLightness < 0.5 - property color colBackground: ColorUtils.transparentize(ColorUtils.mix(Appearance.colors.colPrimary, Appearance.colors.colSecondaryContainer), 1) - property color colText: ColorUtils.colorWithLightness(Appearance.colors.colPrimary, (root.dominantColorIsDark ? 0.8 : 0.12)) - - function updateWidgetPosition(fileContent) { - // console.log("[BackgroundWidgets] Updating widget position with content:", fileContent) - const parsedContent = JSON.parse(fileContent) - root.centerX = parsedContent.center_x - root.centerY = parsedContent.center_y - root.dominantColor = parsedContent.dominant_color || Appearance.colors.colPrimary - } - - Timer { - id: delayedFileRead - interval: Config.options.hacks.arbitraryRaceConditionDelay - running: false - onTriggered: { - root.updateWidgetPosition(leastBusyRegionFileView.text()) - } - } - - FileView { - id: leastBusyRegionFileView - path: Qt.resolvedUrl(root.filePath) - watchChanges: !Config.options?.background.fixedClockPosition - onFileChanged: { - this.reload() - delayedFileRead.start() - } - onLoadedChanged: { - const fileContent = leastBusyRegionFileView.text() - root.updateWidgetPosition(fileContent) - } - } - - Variants { // For each monitor - model: Quickshell.screens - - LazyLoader { - required property var modelData - readonly property HyprlandMonitor monitor: Hyprland.monitorFor(modelData) - activeAsync: !ToplevelManager.activeToplevel?.activated - component: PanelWindow { // Window - id: windowRoot - screen: modelData - property var textHorizontalAlignment: root.effectiveCenterX / monitor.scale < windowRoot.width / 3 ? Text.AlignLeft : - (root.effectiveCenterX / monitor.scale > windowRoot.width * 2 / 3 ? Text.AlignRight : Text.AlignHCenter) - - WlrLayershell.layer: WlrLayer.Bottom - WlrLayershell.namespace: "quickshell:backgroundWidgets" - - anchors { - top: true - bottom:true - left: true - right: true - } - color: "transparent" - // HyprlandWindow.visibleMask: Region { // Buggy with scaled monitors - // item: widgetBackground - // } - - Rectangle { - id: widgetBackground - property real verticalPadding: 20 - property real horizontalPadding: 30 - radius: 40 - color: root.colBackground - implicitHeight: columnLayout.implicitHeight + verticalPadding * 2 - implicitWidth: columnLayout.implicitWidth + horizontalPadding * 2 - anchors { - left: parent.left - top: parent.top - leftMargin: (root.effectiveCenterX / monitor.scale - implicitWidth / 2) - topMargin: (root.effectiveCenterY / monitor.scale - implicitHeight / 2) - Behavior on leftMargin { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - Behavior on topMargin { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - } - - ColumnLayout { - id: columnLayout - anchors.centerIn: parent - spacing: -5 - - StyledText { - Layout.fillWidth: true - horizontalAlignment: windowRoot.textHorizontalAlignment - font.pixelSize: 95 - color: root.colText - style: Text.Raised - styleColor: Appearance.colors.colShadow - text: DateTime.time - } - StyledText { - Layout.fillWidth: true - horizontalAlignment: windowRoot.textHorizontalAlignment - font.pixelSize: 25 - color: root.colText - style: Text.Raised - styleColor: Appearance.colors.colShadow - text: DateTime.date - } - } - } - - } - } - - } - -} diff --git a/.config/quickshell/ii/modules/bar/Bar.qml b/.config/quickshell/ii/modules/bar/Bar.qml index 27d5a6de9..08383c10e 100644 --- a/.config/quickshell/ii/modules/bar/Bar.qml +++ b/.config/quickshell/ii/modules/bar/Bar.qml @@ -3,7 +3,7 @@ import "root:/services" import "root:/modules/common/" import "root:/modules/common/widgets" import "root:/modules/common/functions/color_utils.js" as ColorUtils -import "root:/modules/bar/weather" +import "./weather" import QtQuick import QtQuick.Controls import QtQuick.Layouts diff --git a/.config/quickshell/ii/modules/common/Config.qml b/.config/quickshell/ii/modules/common/Config.qml index 1b9b1dd81..64f136517 100644 --- a/.config/quickshell/ii/modules/common/Config.qml +++ b/.config/quickshell/ii/modules/common/Config.qml @@ -98,6 +98,7 @@ Singleton { property bool fixedClockPosition: false property real clockX: -500 property real clockY: -500 + property string wallpaperPath: Quickshell.configPath("assets/images/default_wallpaper.png") } property JsonObject bar: JsonObject { diff --git a/.config/quickshell/ii/scripts/colors/switchwall.sh b/.config/quickshell/ii/scripts/colors/switchwall.sh index 0d9ffadbf..e0be2dacd 100755 --- a/.config/quickshell/ii/scripts/colors/switchwall.sh +++ b/.config/quickshell/ii/scripts/colors/switchwall.sh @@ -8,6 +8,7 @@ CONFIG_DIR="$XDG_CONFIG_HOME/quickshell/$QUICKSHELL_CONFIG_NAME" CACHE_DIR="$XDG_CACHE_HOME/quickshell" STATE_DIR="$XDG_STATE_HOME/quickshell" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SHELL_CONFIG_FILE="$XDG_CONFIG_HOME/illogical-impulse/config.json" MATUGEN_DIR="$XDG_CONFIG_HOME/matugen" terminalscheme="$SCRIPT_DIR/terminal/scheme-base.json" @@ -59,14 +60,14 @@ post_process() { handle_kde_material_you_colors & # Determine the largest region on the wallpaper that's sufficiently un-busy to put widgets in - if [ ! -f "$MATUGEN_DIR/scripts/least_busy_region.py" ]; then - echo "Error: least_busy_region.py script not found in $MATUGEN_DIR/scripts/" - else - "$MATUGEN_DIR/scripts/least_busy_region.py" \ - --screen-width "$screen_width" --screen-height "$screen_height" \ - --width 300 --height 200 \ - "$wallpaper_path" > "$STATE_DIR"/user/generated/wallpaper/least_busy_region.json - fi + # if [ ! -f "$MATUGEN_DIR/scripts/least_busy_region.py" ]; then + # echo "Error: least_busy_region.py script not found in $MATUGEN_DIR/scripts/" + # else + # "$MATUGEN_DIR/scripts/least_busy_region.py" \ + # --screen-width "$screen_width" --screen-height "$screen_height" \ + # --width 300 --height 200 \ + # "$wallpaper_path" > "$STATE_DIR"/user/generated/wallpaper/least_busy_region.json + # fi } check_and_prompt_upscale() { @@ -227,10 +228,10 @@ switch() { else matugen_args=(image "$imgpath") generate_colors_material_args=(--path "$imgpath") - # Set wallpaper with swww - swww img "$imgpath" --transition-step 100 --transition-fps 120 \ - --transition-type grow --transition-angle 30 --transition-duration 1 \ - --transition-pos "$cursorposx, $cursorposy_inverted" & + # Update wallpaper path in config + if [ -f "$SHELL_CONFIG_FILE" ]; then + jq --arg path "$imgpath" '.background.wallpaperPath = $path' "$SHELL_CONFIG_FILE" > "$SHELL_CONFIG_FILE.tmp" && mv "$SHELL_CONFIG_FILE.tmp" "$SHELL_CONFIG_FILE" + fi remove_restore fi fi @@ -318,7 +319,7 @@ main() { ;; --noswitch) noswitch_flag="1" - imgpath=$(swww query | head -1 | awk -F 'image: ' '{print $2}') + imgpath=$(jq -r '.background.wallpaperPath' "$SHELL_CONFIG_FILE" 2>/dev/null || echo "") shift ;; *) diff --git a/.config/matugen/scripts/least_busy_region.py b/.config/quickshell/ii/scripts/images/least_busy_region.py similarity index 99% rename from .config/matugen/scripts/least_busy_region.py rename to .config/quickshell/ii/scripts/images/least_busy_region.py index a1f2f47b4..bad58bd87 100755 --- a/.config/matugen/scripts/least_busy_region.py +++ b/.config/quickshell/ii/scripts/images/least_busy_region.py @@ -257,7 +257,7 @@ def main(): parser.add_argument("-v", "--visual-output", action="store_true", help="Output image with rectangle") parser.add_argument("--screen-width", type=int, default=1920, help="Screen width for wallpaper scaling") parser.add_argument("--screen-height", type=int, default=1080, help="Screen height for wallpaper scaling") - parser.add_argument("--stride", type=int, default=4, help="Step size for sliding window (higher is faster, less precise)") + parser.add_argument("--stride", type=int, default=10, help="Step size for sliding window (higher is faster, less precise)") parser.add_argument("--screen-mode", choices=["fill", "fit"], default="fill", help="Wallpaper scaling mode: 'fill' (default) or 'fit'") parser.add_argument("--verbose", action="store_true", help="Print verbose output") parser.add_argument("-l", "--largest-region", action="store_true", help="Find the largest region under the variance threshold and output its center") diff --git a/.config/quickshell/ii/services/FirstRunExperience.qml b/.config/quickshell/ii/services/FirstRunExperience.qml index 5bdae4551..350c31593 100644 --- a/.config/quickshell/ii/services/FirstRunExperience.qml +++ b/.config/quickshell/ii/services/FirstRunExperience.qml @@ -27,7 +27,7 @@ Singleton { } function handleFirstRun() { - Quickshell.execDetached(["bash", "-c", `swww query | grep 'image' || '${Directories.wallpaperSwitchScriptPath}' '${root.defaultWallpaperPath}'`]) + Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, root.defaultWallpaperPath]) Quickshell.execDetached(["bash", "-c", `qs -p '${root.welcomeQmlPath}'`]) } diff --git a/.config/quickshell/ii/shell.qml b/.config/quickshell/ii/shell.qml index 68d1502ff..a026342dd 100644 --- a/.config/quickshell/ii/shell.qml +++ b/.config/quickshell/ii/shell.qml @@ -6,7 +6,7 @@ //@ pragma Env QT_SCALE_FACTOR=1 import "./modules/common/" -import "./modules/backgroundWidgets/" +import "./modules/background/" import "./modules/bar/" import "./modules/cheatsheet/" import "./modules/dock/" @@ -30,7 +30,7 @@ ShellRoot { // Enable/disable modules here. False = not loaded at all, so rest assured // no unnecessary stuff will take up memory if you decide to only use, say, the overview. property bool enableBar: true - property bool enableBackgroundWidgets: true + property bool enableBackground: true property bool enableCheatsheet: true property bool enableDock: true property bool enableMediaControls: true @@ -53,7 +53,7 @@ ShellRoot { } LazyLoader { active: enableBar; component: Bar {} } - LazyLoader { active: enableBackgroundWidgets; component: BackgroundWidgets {} } + LazyLoader { active: enableBackground; component: Background {} } LazyLoader { active: enableCheatsheet; component: Cheatsheet {} } LazyLoader { active: enableDock && Config.options.dock.enable; component: Dock {} } LazyLoader { active: enableMediaControls; component: MediaControls {} } diff --git a/arch-packages/illogical-impulse-widgets/PKGBUILD b/arch-packages/illogical-impulse-widgets/PKGBUILD index ae26fc90e..9aa690dc2 100644 --- a/arch-packages/illogical-impulse-widgets/PKGBUILD +++ b/arch-packages/illogical-impulse-widgets/PKGBUILD @@ -13,7 +13,6 @@ depends=( hyprpicker nm-connection-editor quickshell-git - swww translate-shell wlogout )