diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0eb9971 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +launcher/favorites.txt diff --git a/config/config.qml b/config/config.qml index 0808823..76dda17 100644 --- a/config/config.qml +++ b/config/config.qml @@ -6,7 +6,7 @@ import "themes" QtObject { id: root - readonly property var theme: Goldencity + readonly property var theme: Snowy // ──────────────────────────────────────────────────────────────────────── // Widgets @@ -21,7 +21,7 @@ QtObject { // ──────────────────────────────────────────────────────────────────────── // BAR // ──────────────────────────────────────────────────────────────────────── - property string barPosition: "top" + property string barPosition: "bottom" property int barHeight: 35 property int margin: 15 property int radius: 20 @@ -29,7 +29,7 @@ QtObject { // ──────────────────────────────────────────────────────────────────────── // FRAME // ──────────────────────────────────────────────────────────────────────── - property string frameVariant: "card" // "card" or "bar" + property string frameVariant: "bar" // "card" or "bar" property int frameBorderWidth: 3 property int frameBarPadTop: 5 // bar variant: padding from top edge property int frameBarPadBottom: 5 // bar variant: padding from bottom edge @@ -55,7 +55,7 @@ QtObject { property int popupRadius: 18 property int popupBorderWidth: 1 property int popupAnimDuration: 250 - property string popupAnimType: "bubbleslide" // "bubbleslide" or "slide" + property string popupAnimType: "slide" // "bubbleslide" or "slide" // ── Clock Module ───────────────────────────────────────────────────────── property bool clockExtendEnabled: true // seconds extension on hover for clock diff --git a/config/themes/qmldir b/config/themes/qmldir index df46679..8e4819d 100644 --- a/config/themes/qmldir +++ b/config/themes/qmldir @@ -17,5 +17,7 @@ singleton Autumn 1.0 autumn.qml singleton Pinkie 1.0 pinkie.qml singleton Lowlight 1.0 lowlight.qml singleton Tranquil 1.0 tranquil.qml +singleton Snowy 1.0 snowy.qml + diff --git a/config/themes/snowy.qml b/config/themes/snowy.qml new file mode 100644 index 0000000..802e2c8 --- /dev/null +++ b/config/themes/snowy.qml @@ -0,0 +1,367 @@ +pragma Singleton +import QtQuick +import Quickshell + +QtObject { + id: theme + + // ── Wallpaper ────────────────────────────────────────────────────────────── + readonly property string wallpaper: Quickshell.env("HOME") + "/.config/quickshell/wallpapers/snowy.jpg" + + // ── Base Backgrounds ─────────────────────────────────────────────────────── + readonly property color bg: "#cc0f1120" // Deep mountain shadow night + readonly property color bgPanel: "transparent" + readonly property color bgPopup: "#cc0f1120" // Deep slate valley dark + readonly property color bgFrame: bg + + // ── Separators ──────────────────────────────────────────────────────────── + readonly property color separator: "#334a5270" // Cool blue-grey ridge line + + // ── Text ────────────────────────────────────────────────────────────────── + readonly property color textMain: "#ffe8eaf0" // Snow highlight white + readonly property color textDim: "#996a7090" // Hazy blue-grey mist + + // ── Accent & Borders ────────────────────────────────────────────────────── + readonly property color accent: "#ffc4889e" // Alpenglow rose-mauve + readonly property color border: "transparent" + readonly property color frameBorder: "transparent" + readonly property color borderPopup: "transparent" + + // ── Logo Module ──────────────────────────────────────────────────────── + readonly property color logoBg: bgPanel + readonly property color logoBgHover: "#22ffffff" + readonly property color logoBorder: border + readonly property color logoBorderActive: accent + readonly property color logoIcon: textMain + readonly property color logoIconActive: accent + + // ── Mpris Module ────────────────────────────────────────────────────────── + readonly property color mprisAccent: accent + readonly property color mprisTextMain: textMain + readonly property color mprisTextDim: textDim + readonly property color mprisTrackColor: statsTrackColor + readonly property color mprisButtonText: bgPopup + readonly property color mprisAlbumBg: Qt.alpha(accent, 0.08) + readonly property color mprisAlbumBorder: Qt.alpha(accent, 0.15) + readonly property color mprisBtnBg: Qt.alpha(accent, 0.10) + readonly property color mprisBtnBgHover: Qt.alpha(accent, 0.22) + readonly property color mprisBtnBorder: Qt.alpha(accent, 0.20) + readonly property color mprisBtnBorderHover: Qt.alpha(accent, 0.45) + readonly property color mprisBtnIcon: accent + readonly property color mprisBtnIconHover: Qt.lighter(accent, 1.3) + + // ── Stats Module (Variation: Alpine Pulse) ──────────────────────────────── + readonly property color statsBg: bgPanel + readonly property color statsBorder: border + readonly property color statsCpuColor: "#ffc4845a" // Sunlit amber rock face + readonly property color statsMemColor: "#ff8ab4d4" // Glacial sky blue + readonly property color statsDiskColor: "#ff94c4b8" // Frozen teal snowmelt + readonly property color statsTrackColor: "#15ffffff" + readonly property color statsCpuTempColor: "#ffcb6080" // Deep alpenglow crimson + readonly property color statsGpuColor: "#ffb09ad4" // Twilight lavender peak + + // ── SysInfo Module ──────────────────────────────────────────────────────── + readonly property color sysInfoAccent: accent + readonly property color sysInfoTextMain: textMain + readonly property color sysInfoTextDim: textDim + readonly property color sysInfoCpuColor: statsCpuColor + readonly property color sysInfoMemColor: statsMemColor + readonly property color sysInfoDiskColor: statsDiskColor + readonly property color sysInfoCpuTempColor: statsCpuTempColor + readonly property color sysInfoGpuColor: statsGpuColor + readonly property color sysInfoTrackColor: statsTrackColor + + // ── Volume Module (Variation: Frozen Dusk) ──────────────────────────────── + readonly property color volBg: bgPanel + readonly property color volBgHover: "#224a5270" + readonly property color volBorder: border + readonly property color volBorderHover: "#ff73d0ff" // Luminous sky blue + readonly property color volPopupBg: bgPopup + readonly property color volPopupBorder: borderPopup + readonly property color volIcon: "#ff73d0ff" // Luminous sky blue + readonly property color volIconMuted: "#ff4a5270" // Deep slate mute + readonly property color volTrack: "#22ffffff" + readonly property color volHandle: accent + readonly property color volHandleBorder: "#33ffffff" + readonly property color volMuteBg: "#33cb6080" + readonly property color volPickerHover: "#15c4889e" + + // ── Volume Limit Buttons ──────────────────────────────────────────────── + readonly property color volLimitBtn: "transparent" + readonly property color volLimitBtnHover: "#22c4889e" + readonly property color volLimitBtnPress: accent + readonly property color volOutputLimitBtnPress: accent + readonly property color volInputLimitBtnPress: statusInfo + readonly property color volOutputLimitBtnHover: Qt.alpha(accent, 0.08) + readonly property color volInputLimitBtnHover: Qt.alpha(statusInfo, 0.08) + + // ── Clock Module ─────────────────────────────────────────────────────────── + readonly property color clockBg: bgPanel + readonly property color clockBgHover: "#11ffffff" + readonly property color clockBorder: border + readonly property color clockBorderHover: accent + readonly property color clockTime: textMain + readonly property color clockSeconds: "#ffc4889e" // Alpenglow rose + readonly property color clockIcon: accent + + // ── Battery Module ──────────────────────────────────────────────────────── + readonly property color batteryFull: accent + readonly property color batteryCharging: accent + readonly property color batteryCritical: statusErr + readonly property color batteryLow: statusWarn + readonly property color batteryIcon: clockIcon + readonly property color batBg: bgPanel + readonly property color batBgHover: "#11ffffff" + readonly property color batBorder: border + readonly property color batBorderHover: accent + readonly property color batText: textMain + readonly property color batPopupBg: bgPopup + readonly property color batPopupBorder: borderPopup + readonly property color batPopupSeparator: separator + readonly property color batPopupHeader: "#ffc4889e" // Alpenglow rose + readonly property color batPopupText: textMain + readonly property color batPopupDim: textDim + readonly property color batProgressTrack: separator + readonly property color batProfileActiveText: bg + + // ── Network Module ──────────────────────────────────────────────────────── + readonly property color netBg: bgPanel + readonly property color netBgHover: "#11ffffff" + readonly property color netBorder: border + readonly property color netBorderHover: accent + readonly property color netText: textMain + readonly property color netPopupBg: bgPopup + readonly property color netPopupBorder: borderPopup + readonly property color netPopupSeparator: separator + readonly property color netPopupHeader: "#ffc4889e" // Alpenglow rose + readonly property color netPopupText: textMain + readonly property color netPopupDim: textDim + readonly property color netFieldBg: "#22ffffff" + readonly property color netCancelBgHover: "#22ffffff" + readonly property color netConnectText: "#ff0f1120" + readonly property color netApActiveBg: Qt.alpha(accent, 0.15) + readonly property color netApHoverBg: calArrowBgHover + readonly property color netDisconnectBg: Qt.alpha(statusErr, 0.18) + readonly property color netDisconnectBorder: Qt.alpha(statusErr, 0.45) + readonly property color netWiredOkBg: Qt.alpha(statusOk, 0.12) + readonly property color netWiredErrBg: Qt.alpha(statusErr, 0.12) + readonly property color netWiredOkBorder: Qt.alpha(statusOk, 0.4) + readonly property color netWiredErrBorder: Qt.alpha(statusErr, 0.4) + readonly property color netWifiIconOk: "#ff87d97c" // Vibrant meadow green + readonly property color netWifiIconErr: "#ffcb6080" // Alpenglow crimson + readonly property color netEthIconOk: "#ff87d97c" // Vibrant meadow green + readonly property color netEthIconErr: "#ffcb6080" + + // ── Calendar Popup ───────────────────────────────────────────────────────── + readonly property color calCardBg: bgPopup + readonly property color calCardBorder: borderPopup + readonly property color calSeparator: separator + readonly property color calTodayBg: accent + readonly property color borderToday: accent + readonly property color todayText: "#ffffffff" + readonly property color clockPopupHeader: "#ffc4889e" // Alpenglow rose + readonly property color clockPopupText: textMain + readonly property color clockPopupDim: textDim + readonly property color clockPopupDate: textMain + readonly property color clockPopupUtc: textDim + readonly property color calArrowIcon: textDim + readonly property color calArrowIconHover: "#ffc4889e" // Alpenglow rose on hover + readonly property color calArrowBg: "transparent" + readonly property color calArrowBgHover: "#22c4889e" // Soft rose tint + readonly property color calArrowBgPress: "#ffc4889e" // Full alpenglow + + // ── Weather Module ────────────────────────────────────────────────────── + readonly property color weatherAccent: accent + readonly property color weatherTextMain: textMain + readonly property color weatherTextDim: textDim + readonly property color weatherTempColor: "#ffcb6080" // Alpenglow crimson + readonly property color weatherFeelsColor: "#ffb09ad4" // Twilight lavender + readonly property color weatherHumidColor: "#ff8ab4d4" // Glacial sky blue + readonly property color weatherWindColor: "#ff94c4b8" // Frozen teal + + // ── Workspace Module ─────────────────────────────────────────────────────── + readonly property color wsPanelBg: bgPanel + readonly property color wsPanelBorder: "transparent" + readonly property color wsActiveBg: accent + readonly property color wsInactiveBg: "#15ffffff" + readonly property color wsHoverBg: "#334a5270" + readonly property color wsActiveText: "#ff0f1120" + readonly property color wsInactiveText: textMain + readonly property color wsHoverText: "#ffffffff" + readonly property color wsMagicActiveBg: "#ff8ab4d4" // Glacial blue magic + readonly property color wsMagicActiveText: wsActiveText + + // ── Tray Module ──────────────────────────────────────────────────────────── + readonly property color trayBg: bgPanel + readonly property color trayBgHover: "#11ffffff" + readonly property color trayBorder: border + readonly property color trayBorderHover: "#22ffffff" + readonly property color trayIcon: textMain + + // ── Tray Context Menu ────────────────────────────────────────────────────── + readonly property color trayMenuBg: bgPopup + readonly property color trayMenuBorder: borderPopup + readonly property color trayMenuText: textMain + readonly property color trayMenuDim: textDim + readonly property color trayMenuHover: "#22c4889e" // Soft alpenglow rose tint + readonly property color trayMenuCheck: accent + readonly property color trayMenuSeparator: separator + + // ── Launcher (Variation: Summit Mist) ───────────────────────────────────── + readonly property color launcherBg: bgPopup + readonly property color launcherBorder: borderPopup + readonly property color launcherInput: "#44080a12" + readonly property color launcherInputBorderFocus: accent + readonly property color launcherPill: "#444a5270" + readonly property color launcherText: textMain + readonly property color launcherDim: textDim + readonly property color launcherAccent: accent + readonly property color launcherHover: "#22c4889e" + readonly property color launcherSelected: "#44c4889e" + readonly property color launcherModeActiveText: "#ffffffff" + readonly property color launcherModeActiveBg: accent + + // ── Status Colors ────────────────────────────────────────────────────────── + readonly property color statusOk: "#ff87d97c" // Vibrant meadow green + readonly property color statusWarn: "#ffc4845a" // Sunlit amber rock + readonly property color statusErr: "#ffcb6080" // Alpenglow crimson + readonly property color statusInfo: "#ff73d0ff" // Luminous sky blue + + // ── Notifications Module ─────────────────────────────────────────────────── + readonly property color notifBg: bgPanel + readonly property color notifBgHover: "#11ffffff" + readonly property color notifBorder: border + readonly property color notifBorderActive: accent + readonly property color notifIcon: textMain + readonly property color notifIconActive: accent + readonly property color notifBadgeBg: statusErr + readonly property color notifBadgeText: "#ffffffff" + readonly property color notifSeparator: separator + readonly property color notifDnd: separator + + // ── Toast cards (Variation: Alpenglow) ──────────────────────────────────── + readonly property color notifToastBg: bgPopup + readonly property color notifToastBgHover: "#22ffffff" + readonly property color notifToastBorder: borderPopup + readonly property color notifToastText: textMain + readonly property color notifToastDim: textDim + readonly property color notifToastAppName: accent + + // ── Urgency colours ──────────────────────────────────────────────────────── + readonly property color notifUrgencyCritical: statusErr + readonly property color notifUrgencyNormal: accent + readonly property color notifUrgencyLow: textDim + + // ── Progress bar ─────────────────────────────────────────────────────────── + readonly property color notifProgressBg: "#22ffffff" + readonly property color notifProgressFill: accent + + // ── History popup ────────────────────────────────────────────────────────── + readonly property color notifHistoryBg: bgPopup + readonly property color notifHistoryBorder: borderPopup + readonly property color notifHistoryHover: "#11c4889e" + readonly property color notifHistoryEmpty: textDim + + // ── BgDate Module ────────────────────────────────────────────────────────── + readonly property color bgDateText: "#ffffffff" // Pure snow white + readonly property color bgDateShadow: "#88000000" // Deep mountain shadow + readonly property color bgDateSecondsText: bgDateText + + // ── Crypto Module ────────────────────────────────────────────────────────── + readonly property color cryptoBg: bgPanel + readonly property color cryptoBgHover: "#15ffffff" + readonly property color cryptoBorder: border + readonly property color cryptoBorderHover: accent + + readonly property color cryptoIcon: accent + readonly property color cryptoLabel: textDim + readonly property color cryptoValue: textMain + + readonly property color cryptoUp: "#ff87d97c" // ▲ vibrant meadow green + readonly property color cryptoDown: "#ffcb6080" // ▼ alpenglow crimson + + // Popup card + readonly property color cryptoPopupBg: bgPopup + readonly property color cryptoPopupBorder: borderPopup + readonly property color cryptoPopupHeader: "#ffc4889e" // Alpenglow rose + readonly property color cryptoPopupText: textMain + readonly property color cryptoPopupDim: textDim + + // Tinted surfaces + readonly property color cryptoUpBg: Qt.rgba(cryptoUp.r, cryptoUp.g, cryptoUp.b, 0.13) + readonly property color cryptoDownBg: Qt.rgba(cryptoDown.r, cryptoDown.g, cryptoDown.b, 0.13) + readonly property color cryptoChipRemoveBg: Qt.rgba(cryptoDown.r, cryptoDown.g, cryptoDown.b, 0.27) + readonly property color cryptoApplyIdleBg: Qt.rgba(accent.r, accent.g, accent.b, 0.20) + + readonly property color cryptoFieldBg: "#15ffffff" + readonly property color cryptoFieldBgFocus: "#22ffffff" + readonly property color cryptoRangeTrack: "#1affffff" + readonly property color cryptoTextOnAccent: "#ff0f1120" + readonly property color cryptoPlaceholder: Qt.rgba(textDim.r, textDim.g, textDim.b, 0.33) + + // ── Polkit Dialog ────────────────────────────────────────────────────────── + // Overlay + readonly property color polkitOverlayBg: "#bb000000" // dim backdrop + + // Card chrome + readonly property color polkitCardBg: bgPopup + readonly property color polkitCardBorder: border + + // Lock icon + readonly property color polkitIconBg: "#1ec4889e" // translucent rose fill + readonly property color polkitIconBorder: "#44c4889e" // rose ring + readonly property color polkitIconColor: accent // glyph — alpenglow rose + + // Text hierarchy + readonly property color polkitTitle: textMain + readonly property color polkitMessage: "#cce8eaf0" // slightly dimmed snow white + + // Action-ID pill + readonly property color polkitPillBg: "#1a4a5270" // muted slate tint + readonly property color polkitPillText: "#666a7090" // dim blue-grey label + + // Divider + readonly property color polkitDivider: "#334a5270" + + // Supplementary message — error state + readonly property color polkitSuppErrBg: "#1acb6080" // translucent crimson fill + readonly property color polkitSuppErrBorder: "#44cb6080" // crimson ring + readonly property color polkitSuppErrText: statusErr + + // Supplementary message — info / ok state + readonly property color polkitSuppOkBg: "#1aa8c4a0" // translucent pine fill + readonly property color polkitSuppOkBorder: "#44a8c4a0" // pine ring + readonly property color polkitSuppOkText: statusOk + + // Fields + readonly property color polkitFieldBg: "#44080a12" // deep dark fill + readonly property color polkitFieldBorder: "#22ffffff" // inactive border + readonly property color polkitFieldBorderFocus: accent // focused border — alpenglow rose + + // Identity selector + readonly property color polkitUserLabel: "#996a7090" // "User:" prefix + readonly property color polkitUserValue: accent + + // Input prompt + readonly property color polkitInputPrompt: "#886a7090" + + // TextInput + readonly property color polkitInputText: textMain + readonly property color polkitInputSelection: "#55c4889e" // rose selection highlight + readonly property color polkitInputSelectedText: bg + + // Eye toggle + readonly property color polkitEyeIcon: "#666a7090" + readonly property color polkitEyeIconHover: accent + + // Authenticate button + readonly property color polkitAuthBg: "#ddc4889e" // slightly-muted rose fill + readonly property color polkitAuthBgHover: accent // full alpenglow on hover + readonly property color polkitAuthText: bg + + // Cancel button + readonly property color polkitCancelBg: "#0dffffff" + readonly property color polkitCancelBgHover: "#22ffffff" + readonly property color polkitCancelBorder: "#22ffffff" + readonly property color polkitCancelText: "#cce8eaf0" +} diff --git a/launcher/Launcher.qml b/launcher/Launcher.qml index 8b34cfe..a5cc7ff 100644 --- a/launcher/Launcher.qml +++ b/launcher/Launcher.qml @@ -33,14 +33,28 @@ PanelWindow { property var allItems: [] property bool loading: false property int lastCacheUpdate: 0 + property var favoriteIds: [] + readonly property string favoritesPath: Quickshell.env("HOME") + "/.config/quickshell/launcher/favorites.txt" readonly property int defaultIndex: Cfg.Config.launcherSelectFirst ? 0 : -1 readonly property var filteredItems: { const q = searchInput.text.toLowerCase() - if (!q) return allItems.slice(0, 80) - return allItems.filter(i => i.name.toLowerCase().includes(q)) + let filtered + if (!q) { + filtered = allItems.slice(0, 80) + } else { + filtered = allItems.filter(i => i.name.toLowerCase().startsWith(q)) + } + const favs = filtered.filter(i => root.favoriteIds.includes(i.id)) + const rest = filtered.filter(i => !root.favoriteIds.includes(i.id)) + const result = [] + if (favs.length > 0) + result.push(...favs.map(i => Object.assign({}, i, { section: "Favorites" }))) + if (rest.length > 0) + result.push(...rest.map(i => Object.assign({}, i, { section: "All Applications" }))) + return result } function toggle() { @@ -60,6 +74,7 @@ PanelWindow { searchInput.text = "" resultsList.currentIndex = root.defaultIndex loadItems() + loadFavorites() Qt.callLater(() => searchInput.forceActiveFocus()) } @@ -132,6 +147,34 @@ PanelWindow { return args } + function loadFavorites() { + favoritesReadProc.command = ["sh", "-c", "cat " + shellQuote(favoritesPath) + " 2>/dev/null || true"] + favoritesReadProc.running = true + } + + function saveFavorites() { + if (favoriteIds.length === 0) { + favoritesWriteProc.command = ["sh", "-c", ": > " + shellQuote(favoritesPath)] + } else { + const quoted = favoriteIds.map(id => shellQuote(id)).join(" ") + favoritesWriteProc.command = ["sh", "-c", + "printf '%s\\n' " + quoted + " > " + shellQuote(favoritesPath)] + } + favoritesWriteProc.running = true + } + + function toggleFavorite(itemId) { + const arr = favoriteIds.slice() + const idx = arr.indexOf(itemId) + if (idx >= 0) { + arr.splice(idx, 1) + } else { + arr.push(itemId) + } + favoriteIds = arr + saveFavorites() + } + function launch(item) { if (!item || !item.exec) return @@ -194,6 +237,22 @@ PanelWindow { Process { id: launchProc } + Process { + id: favoritesReadProc + property string rawData: "" + stdout: SplitParser { onRead: data => favoritesReadProc.rawData += data + "\n" } + onRunningChanged: { + if (!running) { + if (rawData.trim()) { + root.favoriteIds = rawData.trim().split("\n").filter(l => l.length > 0) + } + rawData = "" + } + } + } + + Process { id: favoritesWriteProc } + MouseArea { anchors.fill: parent @@ -312,6 +371,21 @@ PanelWindow { currentIndex: root.defaultIndex spacing: 2 + section.property: "section" + section.criteria: ViewSection.FullString + section.delegate: Rectangle { + width: resultsList.width + height: 28 + color: "transparent" + Text { + anchors { left: parent.left; leftMargin: 12; verticalCenter: parent.verticalCenter } + text: section + color: t.launcherDim + font.pixelSize: 11 + font.weight: Font.Bold + } + } + onModelChanged: currentIndex = root.defaultIndex ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded } @@ -366,6 +440,18 @@ PanelWindow { Layout.fillWidth: true elide: Text.ElideRight } + + Item { + width: 22; height: 22 + Layout.alignment: Qt.AlignVCenter + + Text { + anchors.centerIn: parent + text: root.favoriteIds.includes(modelData.id) ? "★" : "☆" + color: root.favoriteIds.includes(modelData.id) ? t.launcherAccent : t.launcherDim + font.pixelSize: 14 + } + } } MouseArea { @@ -373,7 +459,13 @@ PanelWindow { hoverEnabled: true onEntered: parent.hovered = true onExited: parent.hovered = false - onClicked: root.launch(modelData) + onClicked: mouse => { + if (mouse.x >= width - 46) { + root.toggleFavorite(modelData.id) + } else { + root.launch(modelData) + } + } } } } diff --git a/wallpapers/snowy.jpg b/wallpapers/snowy.jpg new file mode 100644 index 0000000..256d098 Binary files /dev/null and b/wallpapers/snowy.jpg differ