From 5d94c0a7d44a2255b81815a52a7056a94a39842d Mon Sep 17 00:00:00 2001 From: nippy Date: Sat, 18 Apr 2026 13:49:56 +0200 Subject: update Raveos themes --- .../DankMaterialShell/quickshell/DMSShell.qml | 1059 ++++++++++++++++++++ 1 file changed, 1059 insertions(+) create mode 100644 raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/DMSShell.qml (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/DMSShell.qml') diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/DMSShell.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/DMSShell.qml new file mode 100644 index 0000000..df3cbb8 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/DMSShell.qml @@ -0,0 +1,1059 @@ +import QtQuick +import Quickshell +import qs.Common +import qs.Modals +import qs.Modals.Changelog +import qs.Modals.Clipboard +import qs.Modals.Greeter +import qs.Modals.Settings +import qs.Modals.DankLauncherV2 +import qs.Modules +import qs.Modules.AppDrawer +import qs.Modules.DankDash +import qs.Modules.ControlCenter +import qs.Modules.Dock +import qs.Modules.Lock +import qs.Modules.Notepad +import qs.Modules.Notifications.Center +import qs.Widgets +import qs.Modules.Notifications.Popup +import qs.Modules.OSD +import qs.Modules.ProcessList +import qs.Modules.DankBar +import qs.Modules.DankBar.Popouts +import qs.Modules.WorkspaceOverlays +import qs.Services + +Item { + id: root + + Instantiator { + id: daemonPluginInstantiator + asynchronous: true + model: Object.keys(PluginService.pluginDaemonComponents) + + delegate: Loader { + id: daemonLoader + property string pluginId: modelData + sourceComponent: PluginService.pluginDaemonComponents[pluginId] + + onLoaded: { + if (item) { + item.pluginService = PluginService; + if (item.popoutService !== undefined) { + item.popoutService = PopoutService; + } + item.pluginId = pluginId; + console.info("Daemon plugin loaded:", pluginId); + } + } + } + } + + Loader { + id: blurredWallpaperBackgroundLoader + active: SettingsData.blurredWallpaperLayer && CompositorService.isNiri + asynchronous: false + + sourceComponent: BlurredWallpaperBackground {} + } + + WallpaperBackground {} + + DesktopWidgetLayer {} + + Lock { + id: lock + } + + Variants { + model: Quickshell.screens + + delegate: Loader { + id: fadeWindowLoader + required property var modelData + active: SettingsData.fadeToLockEnabled + asynchronous: false + + sourceComponent: FadeToLockWindow { + screen: fadeWindowLoader.modelData + + onFadeCompleted: { + IdleService.lockRequested(); + } + + onFadeCancelled: { + console.log("Fade to lock cancelled by user on screen:", fadeWindowLoader.modelData.name); + } + } + + Connections { + target: IdleService + enabled: fadeWindowLoader.item !== null + + function onFadeToLockRequested() { + if (fadeWindowLoader.item) { + fadeWindowLoader.item.startFade(); + } + } + + function onCancelFadeToLock() { + if (fadeWindowLoader.item) { + fadeWindowLoader.item.cancelFade(); + } + } + } + } + } + + Variants { + model: Quickshell.screens + + delegate: Loader { + id: fadeDpmsWindowLoader + required property var modelData + active: SettingsData.fadeToDpmsEnabled + asynchronous: false + + sourceComponent: FadeToDpmsWindow { + screen: fadeDpmsWindowLoader.modelData + + onFadeCompleted: { + IdleService.requestMonitorOff(); + } + + onFadeCancelled: { + console.log("Fade to DPMS cancelled by user on screen:", fadeDpmsWindowLoader.modelData.name); + } + } + + Connections { + target: IdleService + enabled: fadeDpmsWindowLoader.item !== null + + function onFadeToDpmsRequested() { + if (fadeDpmsWindowLoader.item) { + fadeDpmsWindowLoader.item.startFade(); + } + } + + function onCancelFadeToDpms() { + if (fadeDpmsWindowLoader.item) { + fadeDpmsWindowLoader.item.cancelFade(); + } + } + + function onRequestMonitorOn() { + if (!fadeDpmsWindowLoader.item) + return; + fadeDpmsWindowLoader.item.cancelFade(); + } + } + } + } + + property string _barLayoutStateJson: { + const configs = SettingsData.barConfigs; + const mapped = configs.map(c => ({ + id: c.id, + position: c.position, + autoHide: c.autoHide, + visible: c.visible + })).sort((a, b) => { + const aVertical = a.position === SettingsData.Position.Left || a.position === SettingsData.Position.Right; + const bVertical = b.position === SettingsData.Position.Left || b.position === SettingsData.Position.Right; + if (aVertical !== bVertical) { + return aVertical - bVertical; + } + return String(a.id).localeCompare(String(b.id)); + }); + return JSON.stringify(mapped); + } + + on_BarLayoutStateJsonChanged: { + if (typeof dockRecreateDebounce !== "undefined") { + dockRecreateDebounce.restart(); + } + } + + Repeater { + id: dankBarRepeater + model: ScriptModel { + id: barRepeaterModel + values: JSON.parse(root._barLayoutStateJson) + } + + property var hyprlandOverviewLoaderRef: hyprlandOverviewLoader + + delegate: Loader { + id: barLoader + required property var modelData + property var barConfig: SettingsData.barConfigs.find(cfg => cfg.id === modelData.id) || null + active: barConfig?.enabled ?? false + asynchronous: false + + sourceComponent: DankBar { + barConfig: barLoader.barConfig + hyprlandOverviewLoader: dankBarRepeater.hyprlandOverviewLoaderRef + + onColorPickerRequested: { + if (colorPickerModal.shouldBeVisible) { + colorPickerModal.close(); + } else { + colorPickerModal.show(); + } + } + } + } + } + + property bool dockEnabled: false + + Timer { + id: dockRecreateDebounce + interval: 500 + repeat: false + onTriggered: { + root.dockEnabled = false; + Qt.callLater(() => { + root.dockEnabled = true; + }); + } + } + + Timer { + id: loginSoundTimer + // Half a second delay before playing login sound, otherwise the sound may be cut off + // 50 is the minimum that seems to work, but 500 is safer + interval: 500 + repeat: false + onTriggered: { + AudioService.playLoginSoundIfApplicable(); + } + } + + Component.onCompleted: { + dockRecreateDebounce.start(); + // Force PolkitService singleton to initialize + PolkitService.polkitAvailable; + loginSoundTimer.start(); + } + + Loader { + id: dockLoader + active: root.dockEnabled + asynchronous: false + + property var currentPosition: SettingsData.dockPosition + property bool initialized: false + + sourceComponent: Dock { + contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null + } + + onLoaded: { + if (item) { + dockContextMenuLoader.active = true; + } + } + + Component.onCompleted: { + initialized = true; + } + + onCurrentPositionChanged: { + if (!initialized) + return; + const comp = sourceComponent; + sourceComponent = null; + sourceComponent = comp; + } + } + + Loader { + id: dankDashPopoutLoader + + active: false + asynchronous: false + + Component.onCompleted: { + PopoutService.dankDashPopoutLoader = dankDashPopoutLoader; + } + + onLoaded: { + if (item) { + PopoutService.dankDashPopout = item; + PopoutService._onDankDashPopoutLoaded(); + } + } + + sourceComponent: Component { + DankDashPopout { + id: dankDashPopout + onPopoutClosed: PopoutService.unloadDankDash() + } + } + } + + LazyLoader { + id: dockContextMenuLoader + + active: false + + DockContextMenu { + id: dockContextMenu + } + } + + LazyLoader { + id: notificationCenterLoader + + active: false + + Component.onCompleted: { + PopoutService.notificationCenterLoader = notificationCenterLoader; + } + + NotificationCenterPopout { + id: notificationCenter + onPopoutClosed: PopoutService.unloadNotificationCenter() + + Component.onCompleted: { + PopoutService.notificationCenterPopout = notificationCenter; + } + } + } + + Variants { + model: SettingsData.notificationFocusedMonitor ? Quickshell.screens : SettingsData.getFilteredScreens("notifications") + + delegate: NotificationPopupManager { + modelData: item + } + } + + LazyLoader { + id: controlCenterLoader + + active: false + + property var modalRef: colorPickerModal + property LazyLoader powerModalLoaderRef: powerMenuModalLoader + + Component.onCompleted: { + PopoutService.controlCenterLoader = controlCenterLoader; + } + + ControlCenterPopout { + id: controlCenterPopout + colorPickerModal: controlCenterLoader.modalRef + powerMenuModalLoader: controlCenterLoader.powerModalLoaderRef + onPopoutClosed: PopoutService.unloadControlCenter() + + onLockRequested: { + lock.activate(); + } + + Component.onCompleted: { + PopoutService.controlCenterPopout = controlCenterPopout; + } + } + } + + LazyLoader { + id: wifiPasswordModalLoader + active: false + + Component.onCompleted: { + PopoutService.wifiPasswordModalLoader = wifiPasswordModalLoader; + } + + WifiPasswordModal { + id: wifiPasswordModalItem + + Component.onCompleted: { + PopoutService.wifiPasswordModal = wifiPasswordModalItem; + } + } + } + + LazyLoader { + id: wifiQRCodeModalLoader + active: false + + Component.onCompleted: { + PopoutService.wifiQRCodeModalLoader = wifiQRCodeModalLoader; + } + + WifiQRCodeModal { + id: wifiQRCodeModalItem + + Component.onCompleted: { + PopoutService.wifiQRCodeModal = wifiQRCodeModalItem; + } + } + } + + LazyLoader { + id: polkitAuthModalLoader + active: false + + PolkitAuthModal { + id: polkitAuthModal + + Component.onCompleted: { + PopoutService.polkitAuthModal = polkitAuthModal; + } + } + } + + Connections { + target: PolkitService.agent + enabled: PolkitService.polkitAvailable + + function onAuthenticationRequestStarted() { + polkitAuthModalLoader.active = true; + if (polkitAuthModalLoader.item) + polkitAuthModalLoader.item.show(); + } + } + + BluetoothPairingModal { + id: bluetoothPairingModal + + Component.onCompleted: { + PopoutService.bluetoothPairingModal = bluetoothPairingModal; + } + } + + property string lastCredentialsToken: "" + property var lastCredentialsTime: 0 + + Connections { + target: NetworkService + + function onCredentialsNeeded(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo) { + const now = Date.now(); + const timeSinceLastPrompt = now - lastCredentialsTime; + + wifiPasswordModalLoader.active = true; + if (!wifiPasswordModalLoader.item) + return; + + if (wifiPasswordModalLoader.item.visible && timeSinceLastPrompt < 1000) { + NetworkService.cancelCredentials(lastCredentialsToken); + lastCredentialsToken = token; + lastCredentialsTime = now; + wifiPasswordModalLoader.item.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo); + return; + } + + lastCredentialsToken = token; + lastCredentialsTime = now; + wifiPasswordModalLoader.item.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fieldsInfo); + } + } + + LazyLoader { + id: networkInfoModalLoader + + active: false + + NetworkInfoModal { + id: networkInfoModal + + Component.onCompleted: { + PopoutService.networkInfoModal = networkInfoModal; + } + } + } + + LazyLoader { + id: batteryPopoutLoader + + active: false + + Component.onCompleted: { + PopoutService.batteryPopoutLoader = batteryPopoutLoader; + } + + BatteryPopout { + id: batteryPopout + onPopoutClosed: PopoutService.unloadBattery() + + Component.onCompleted: { + PopoutService.batteryPopout = batteryPopout; + } + } + } + + LazyLoader { + id: layoutPopoutLoader + + active: false + + Component.onCompleted: { + PopoutService.layoutPopoutLoader = layoutPopoutLoader; + } + + DWLLayoutPopout { + id: layoutPopout + onPopoutClosed: PopoutService.unloadLayoutPopout() + + Component.onCompleted: { + PopoutService.layoutPopout = layoutPopout; + } + } + } + + LazyLoader { + id: vpnPopoutLoader + + active: false + + Component.onCompleted: { + PopoutService.vpnPopoutLoader = vpnPopoutLoader; + } + + VpnPopout { + id: vpnPopout + onPopoutClosed: PopoutService.unloadVpn() + + Component.onCompleted: { + PopoutService.vpnPopout = vpnPopout; + } + } + } + + LazyLoader { + id: processListPopoutLoader + + active: false + + Component.onCompleted: { + PopoutService.processListPopoutLoader = processListPopoutLoader; + } + + ProcessListPopout { + id: processListPopout + onPopoutClosed: PopoutService.unloadProcessListPopout() + + Component.onCompleted: { + PopoutService.processListPopout = processListPopout; + } + } + } + + LazyLoader { + id: settingsModalLoader + + active: false + + Component.onCompleted: { + PopoutService.settingsModalLoader = settingsModalLoader; + } + + onActiveChanged: { + if (active && item) { + PopoutService.settingsModal = item; + PopoutService._onSettingsModalLoaded(); + } + } + + SettingsModal { + id: settingsModal + property bool wasShown: false + + onVisibleChanged: { + if (visible) { + wasShown = true; + } else if (wasShown) { + PopoutService.unloadSettings(); + } + } + } + } + + LazyLoader { + id: appDrawerLoader + + active: false + + Component.onCompleted: { + PopoutService.appDrawerLoader = appDrawerLoader; + } + + AppDrawerPopout { + id: appDrawerPopout + onPopoutClosed: PopoutService.unloadAppDrawer() + + Component.onCompleted: { + PopoutService.appDrawerPopout = appDrawerPopout; + } + } + } + + LazyLoader { + id: dankLauncherV2ModalLoader + + active: false + + Component.onCompleted: { + PopoutService.dankLauncherV2ModalLoader = dankLauncherV2ModalLoader; + } + + DankLauncherV2Modal { + id: dankLauncherV2Modal + + Component.onCompleted: { + PopoutService.dankLauncherV2Modal = dankLauncherV2Modal; + PopoutService._onDankLauncherV2ModalLoaded(); + } + } + } + + LazyLoader { + id: clipboardHistoryPopoutLoader + + active: false + + Component.onCompleted: { + PopoutService.clipboardHistoryPopoutLoader = clipboardHistoryPopoutLoader; + } + + ClipboardHistoryPopout { + id: clipboardHistoryPopout + onPopoutClosed: PopoutService.unloadClipboardHistoryPopout() + + Component.onCompleted: { + PopoutService.clipboardHistoryPopout = clipboardHistoryPopout; + } + } + } + + MuxModal { + id: muxModal + } + + ClipboardHistoryModal { + id: clipboardHistoryModalPopup + + Component.onCompleted: { + PopoutService.clipboardHistoryModal = clipboardHistoryModalPopup; + } + } + + NotificationModal { + id: notificationModal + + Component.onCompleted: { + PopoutService.notificationModal = notificationModal; + } + } + + BrowserPickerModal { + id: browserPickerModal + } + + AppPickerModal { + id: filePickerModal + title: I18n.tr("Open with...") + viewMode: SettingsData.appPickerViewMode || "grid" + + onViewModeChanged: { + SettingsData.set("appPickerViewMode", viewMode); + } + + function shellEscape(str) { + return "'" + str.replace(/'/g, "'\\''") + "'"; + } + + onApplicationSelected: (app, filePath) => { + if (!app) + return; + let cmd = app.exec || ""; + const escapedPath = shellEscape(filePath); + const escapedUri = shellEscape("file://" + filePath); + + let hasField = false; + if (cmd.includes("%f")) { + cmd = cmd.replace("%f", escapedPath); + hasField = true; + } else if (cmd.includes("%F")) { + cmd = cmd.replace("%F", escapedPath); + hasField = true; + } else if (cmd.includes("%u")) { + cmd = cmd.replace("%u", escapedUri); + hasField = true; + } else if (cmd.includes("%U")) { + cmd = cmd.replace("%U", escapedUri); + hasField = true; + } + + cmd = cmd.replace(/%[ikc]/g, ""); + + if (!hasField) { + cmd += " " + escapedPath; + } + + console.log("FilePicker: Launching", cmd); + + Quickshell.execDetached({ + command: ["sh", "-c", cmd] + }); + } + } + + Connections { + target: DMSService + function onOpenUrlRequested(url) { + if (url.startsWith("dms://theme/install/")) { + var themeId = url.replace("dms://theme/install/", "").split(/[?#]/)[0]; + if (themeId) { + PopoutService.pendingThemeInstall = themeId; + PopoutService.openSettingsWithTab("theme"); + } + return; + } + if (url.startsWith("dms://plugin/install/")) { + var pluginId = url.replace("dms://plugin/install/", "").split(/[?#]/)[0]; + if (pluginId) { + PopoutService.pendingPluginInstall = pluginId; + PopoutService.openSettingsWithTab("plugins"); + } + return; + } + browserPickerModal.url = url; + browserPickerModal.open(); + } + + function onAppPickerRequested(data) { + console.log("DMSShell: App picker requested with data:", JSON.stringify(data)); + + if (!data || !data.target) { + console.warn("DMSShell: Invalid app picker request data"); + return; + } + + filePickerModal.targetData = data.target; + filePickerModal.targetDataLabel = data.requestType || "file"; + + if (data.categories && data.categories.length > 0) { + filePickerModal.categoryFilter = data.categories; + } else { + filePickerModal.categoryFilter = []; + } + + filePickerModal.usageHistoryKey = "filePickerUsageHistory"; + filePickerModal.open(); + } + } + + DankColorPickerModal { + id: colorPickerModal + + Component.onCompleted: { + PopoutService.colorPickerModal = colorPickerModal; + } + } + + LazyLoader { + id: workspaceRenameModalLoader + + active: false + + Component.onCompleted: PopoutService.workspaceRenameModalLoader = workspaceRenameModalLoader + + WorkspaceRenameModal { + id: workspaceRenameModal + } + } + + LazyLoader { + id: windowRuleModalLoader + + active: false + + Component.onCompleted: PopoutService.windowRuleModalLoader = windowRuleModalLoader + + WindowRuleModal { + id: windowRuleModal + } + } + + LazyLoader { + id: processListModalLoader + + active: false + + Component.onCompleted: PopoutService.processListModalLoader = processListModalLoader + + ProcessListModal { + id: processListModal + + Component.onCompleted: { + PopoutService.processListModal = processListModal; + } + } + } + + LazyLoader { + id: systemUpdateLoader + + active: false + + Component.onCompleted: { + PopoutService.systemUpdateLoader = systemUpdateLoader; + } + + SystemUpdatePopout { + id: systemUpdatePopout + onPopoutClosed: PopoutService.unloadSystemUpdate() + + Component.onCompleted: { + PopoutService.systemUpdatePopout = systemUpdatePopout; + } + } + } + + Variants { + id: notepadSlideoutVariants + model: SettingsData.getFilteredScreens("notepad") + + delegate: DankSlideout { + id: notepadSlideout + modelData: item + title: I18n.tr("Notepad") + slideoutWidth: 480 + expandable: true + expandedWidthValue: 960 + customTransparency: SettingsData.notepadTransparencyOverride + + content: Component { + Notepad { + slideout: notepadSlideout + onHideRequested: notepadSlideout.hide() + } + } + + function toggle() { + if (isVisible) { + hide(); + } else { + show(); + } + } + } + + onInstancesChanged: PopoutService.notepadSlideouts = instances + Component.onCompleted: PopoutService.notepadSlideouts = instances + } + + LazyLoader { + id: powerMenuModalLoader + + active: false + + PowerMenuModal { + id: powerMenuModal + + onPowerActionRequested: (action, title, message) => { + switch (action) { + case "logout": + SessionService.logout(); + break; + case "suspend": + SessionService.suspend(); + break; + case "hibernate": + SessionService.hibernate(); + break; + case "reboot": + SessionService.reboot(); + break; + case "poweroff": + SessionService.poweroff(); + break; + } + } + + onLockRequested: { + lock.activate(); + } + + Component.onCompleted: { + PopoutService.powerMenuModal = powerMenuModal; + } + } + } + + LazyLoader { + id: hyprKeybindsModalLoader + + active: false + + KeybindsModal { + id: keybindsModal + + Component.onCompleted: { + PopoutService.hyprKeybindsModal = keybindsModal; + } + } + } + + DMSShellIPC { + powerMenuModalLoader: powerMenuModalLoader + processListModalLoader: processListModalLoader + controlCenterLoader: controlCenterLoader + dankDashPopoutLoader: dankDashPopoutLoader + notepadSlideoutVariants: notepadSlideoutVariants + hyprKeybindsModalLoader: hyprKeybindsModalLoader + dankBarRepeater: dankBarRepeater + hyprlandOverviewLoader: hyprlandOverviewLoader + workspaceRenameModalLoader: workspaceRenameModalLoader + windowRuleModalLoader: windowRuleModalLoader + } + + Variants { + model: SettingsData.getFilteredScreens("toast") + + delegate: Toast { + modelData: item + visible: ToastService.toastVisible + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: VolumeOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: MediaVolumeOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: MediaPlaybackOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: MicMuteOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: BrightnessOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: IdleInhibitorOSD { + modelData: item + } + } + + Loader { + id: powerProfileWatcherLoader + active: SettingsData.osdPowerProfileEnabled + source: "Services/PowerProfileWatcher.qml" + } + + Variants { + model: SettingsData.osdPowerProfileEnabled ? SettingsData.getFilteredScreens("osd") : [] + + delegate: PowerProfileOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: CapsLockOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: AudioOutputOSD { + modelData: item + } + } + + LazyLoader { + id: hyprlandOverviewLoader + active: CompositorService.isHyprland + component: HyprlandOverview { + id: hyprlandOverview + } + } + + LazyLoader { + id: niriOverviewOverlayLoader + active: CompositorService.isNiri && SettingsData.niriOverviewOverlayEnabled + component: NiriOverviewOverlay { + id: niriOverviewOverlay + } + } + + Loader { + id: greeterLoader + active: false + sourceComponent: GreeterModal { + onGreeterCompleted: greeterLoader.active = false + Component.onCompleted: show() + } + + Connections { + target: FirstLaunchService + function onGreeterRequested() { + if (greeterLoader.active && greeterLoader.item) { + greeterLoader.item.show(); + return; + } + greeterLoader.active = true; + } + } + } + + Loader { + id: changelogLoader + active: false + sourceComponent: ChangelogModal { + onChangelogDismissed: changelogLoader.active = false + Component.onCompleted: show() + } + + Connections { + target: ChangelogService + function onChangelogRequested() { + if (changelogLoader.active && changelogLoader.item) { + changelogLoader.item.show(); + return; + } + changelogLoader.active = true; + } + } + } +} -- cgit v1.3