summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml471
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml409
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml51
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml250
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml78
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml156
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml27
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml21
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml260
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml155
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml87
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml174
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml197
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml166
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml51
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml178
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml291
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml496
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml312
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml771
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml256
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml1894
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js128
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml465
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml105
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js237
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml1075
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml510
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js254
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml196
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml498
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js265
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml114
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml340
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml199
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml212
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml920
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml253
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml258
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml97
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml130
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml127
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml74
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml70
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml183
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml66
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml237
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml50
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml492
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml427
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml109
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml74
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml333
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml60
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml78
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml75
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml165
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml347
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml633
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml155
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml155
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml225
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml412
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml809
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml609
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml144
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml522
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml382
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml1023
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml764
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml170
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml1184
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml230
73 files changed, 0 insertions, 23391 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml
deleted file mode 100644
index 2188111..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml
+++ /dev/null
@@ -1,471 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Modals.Common
-import qs.Widgets
-import qs.Services
-
-DankModal {
- id: root
-
- property string title: I18n.tr("Select Application")
- property string targetData: ""
- property string targetDataLabel: ""
- property string searchQuery: ""
- property int selectedIndex: 0
- property int gridColumns: SettingsData.appLauncherGridColumns
- property bool keyboardNavigationActive: false
- property string viewMode: "grid"
- property var categoryFilter: []
- property var usageHistoryKey: ""
- property bool showTargetData: true
-
- signal applicationSelected(var app, string targetData)
-
- shouldBeVisible: false
- allowStacking: true
- modalWidth: 520
- modalHeight: 500
-
- onBackgroundClicked: close()
-
- onDialogClosed: {
- searchQuery = ""
- selectedIndex = 0
- keyboardNavigationActive = false
- }
-
- onOpened: {
- searchQuery = ""
- updateApplicationList()
- selectedIndex = 0
- Qt.callLater(() => {
- if (contentLoader.item && contentLoader.item.searchField) {
- contentLoader.item.searchField.text = ""
- contentLoader.item.searchField.forceActiveFocus()
- }
- })
- }
-
- function updateApplicationList() {
- applicationsModel.clear()
- const apps = AppSearchService.applications
- const usageHistory = usageHistoryKey && SettingsData[usageHistoryKey] ? SettingsData[usageHistoryKey] : {}
- let filteredApps = []
-
- for (const app of apps) {
- if (!app || !app.categories) continue
-
- let matchesCategory = categoryFilter.length === 0
-
- if (categoryFilter.length > 0) {
- try {
- for (const cat of app.categories) {
- if (categoryFilter.includes(cat)) {
- matchesCategory = true
- break
- }
- }
- } catch (e) {
- console.warn("AppPicker: Error iterating categories for", app.name, ":", e)
- continue
- }
- }
-
- if (matchesCategory) {
- const name = app.name || ""
- const lowerName = name.toLowerCase()
- const lowerQuery = searchQuery.toLowerCase()
-
- if (searchQuery === "" || lowerName.includes(lowerQuery)) {
- filteredApps.push({
- name: name,
- icon: app.icon || "application-x-executable",
- exec: app.exec || app.execString || "",
- startupClass: app.startupWMClass || "",
- appData: app
- })
- }
- }
- }
-
- filteredApps.sort((a, b) => {
- const aId = a.appData.id || a.appData.execString || a.appData.exec || ""
- const bId = b.appData.id || b.appData.execString || b.appData.exec || ""
- const aUsage = usageHistory[aId] ? usageHistory[aId].count : 0
- const bUsage = usageHistory[bId] ? usageHistory[bId].count : 0
- if (aUsage !== bUsage) {
- return bUsage - aUsage
- }
- return (a.name || "").localeCompare(b.name || "")
- })
-
- filteredApps.forEach(app => {
- applicationsModel.append({
- name: app.name,
- icon: app.icon,
- exec: app.exec,
- startupClass: app.startupClass,
- appId: app.appData.id || app.appData.execString || app.appData.exec || ""
- })
- })
-
- console.log("AppPicker: Found " + filteredApps.length + " applications")
- }
-
- onSearchQueryChanged: updateApplicationList()
-
- ListModel {
- id: applicationsModel
- }
-
- content: Component {
- FocusScope {
- id: appContent
-
- property alias searchField: searchField
-
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- root.close()
- event.accepted = true
- }
-
- Keys.onPressed: event => {
- if (applicationsModel.count === 0) return
-
- // Toggle view mode with Tab key
- if (event.key === Qt.Key_Tab) {
- root.viewMode = root.viewMode === "grid" ? "list" : "grid"
- event.accepted = true
- return
- }
-
- if (root.viewMode === "grid") {
- if (event.key === Qt.Key_Left) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.max(0, root.selectedIndex - 1)
- event.accepted = true
- } else if (event.key === Qt.Key_Right) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + 1)
- event.accepted = true
- } else if (event.key === Qt.Key_Up) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.max(0, root.selectedIndex - root.gridColumns)
- event.accepted = true
- } else if (event.key === Qt.Key_Down) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + root.gridColumns)
- event.accepted = true
- }
- } else {
- if (event.key === Qt.Key_Up) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.max(0, root.selectedIndex - 1)
- event.accepted = true
- } else if (event.key === Qt.Key_Down) {
- root.keyboardNavigationActive = true
- root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + 1)
- event.accepted = true
- }
- }
-
- if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
- if (root.selectedIndex >= 0 && root.selectedIndex < applicationsModel.count) {
- const app = applicationsModel.get(root.selectedIndex)
- launchApplication(app)
- }
- event.accepted = true
- }
- }
-
- Column {
- width: parent.width - Theme.spacingS * 2
- height: parent.height - Theme.spacingS * 2
- x: Theme.spacingS
- y: Theme.spacingS
- spacing: Theme.spacingS
-
- Item {
- width: parent.width
- height: 40
-
- StyledText {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- text: root.title
- font.pixelSize: Theme.fontSizeLarge + 4
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
-
- Row {
- spacing: 4
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
-
- DankActionButton {
- buttonSize: 36
- circular: false
- iconName: "view_list"
- iconSize: 20
- iconColor: root.viewMode === "list" ? Theme.primary : Theme.surfaceText
- backgroundColor: root.viewMode === "list" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
- onClicked: {
- root.viewMode = "list"
- }
- }
-
- DankActionButton {
- buttonSize: 36
- circular: false
- iconName: "grid_view"
- iconSize: 20
- iconColor: root.viewMode === "grid" ? Theme.primary : Theme.surfaceText
- backgroundColor: root.viewMode === "grid" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
- onClicked: {
- root.viewMode = "grid"
- }
- }
- }
- }
-
- DankTextField {
- id: searchField
-
- width: parent.width - Theme.spacingS * 2
- anchors.horizontalCenter: parent.horizontalCenter
- height: 52
- cornerRadius: Theme.cornerRadius
- backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- normalBorderColor: Theme.outlineMedium
- focusedBorderColor: Theme.primary
- leftIconName: "search"
- leftIconSize: Theme.iconSize
- leftIconColor: Theme.surfaceVariantText
- leftIconFocusedColor: Theme.primary
- showClearButton: true
- font.pixelSize: Theme.fontSizeLarge
- enabled: root.shouldBeVisible
- ignoreLeftRightKeys: root.viewMode !== "list"
- ignoreTabKeys: true
- keyForwardTargets: [appContent]
-
- onTextEdited: {
- root.searchQuery = text
- }
-
- Keys.onPressed: function (event) {
- if (event.key === Qt.Key_Escape) {
- root.close()
- event.accepted = true
- return
- }
-
- const isEnterKey = [Qt.Key_Return, Qt.Key_Enter].includes(event.key)
- const hasText = text.length > 0
-
- if (isEnterKey && hasText) {
- if (root.keyboardNavigationActive && applicationsModel.count > 0) {
- const app = applicationsModel.get(root.selectedIndex)
- launchApplication(app)
- } else if (applicationsModel.count > 0) {
- const app = applicationsModel.get(0)
- launchApplication(app)
- }
- event.accepted = true
- return
- }
-
- const navigationKeys = [Qt.Key_Down, Qt.Key_Up, Qt.Key_Left, Qt.Key_Right, Qt.Key_Tab, Qt.Key_Backtab]
- const isNavigationKey = navigationKeys.includes(event.key)
- const isEmptyEnter = isEnterKey && !hasText
-
- event.accepted = !(isNavigationKey || isEmptyEnter)
- }
-
- Connections {
- function onShouldBeVisibleChanged() {
- if (!root.shouldBeVisible) {
- searchField.focus = false
- }
- }
-
- target: root
- }
- }
-
- Rectangle {
- width: parent.width
- height: {
- let usedHeight = 40 + Theme.spacingS
- usedHeight += 52 + Theme.spacingS
- if (root.showTargetData) {
- usedHeight += 36 + Theme.spacingS
- }
- return parent.height - usedHeight
- }
- radius: Theme.cornerRadius
- color: "transparent"
-
- DankListView {
- id: appList
-
- property int itemHeight: 60
- property int itemSpacing: Theme.spacingS
-
- function ensureVisible(index) {
- if (index < 0 || index >= count) return
-
- const itemY = index * (itemHeight + itemSpacing)
- const itemBottom = itemY + itemHeight
- if (itemY < contentY) {
- contentY = itemY
- } else if (itemBottom > contentY + height) {
- contentY = itemBottom - height
- }
- }
-
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: Theme.spacingS
- anchors.bottomMargin: Theme.spacingS
-
- visible: root.viewMode === "list"
- model: applicationsModel
- currentIndex: root.selectedIndex
- clip: true
- spacing: itemSpacing
-
- onCurrentIndexChanged: {
- root.selectedIndex = currentIndex
- if (root.keyboardNavigationActive) {
- ensureVisible(currentIndex)
- }
- }
-
- delegate: AppLauncherListDelegate {
- listView: appList
- itemHeight: 60
- iconSize: 40
- showDescription: false
-
- isCurrentItem: index === root.selectedIndex
- keyboardNavigationActive: root.keyboardNavigationActive
- hoverUpdatesSelection: true
-
- onItemClicked: (idx, modelData) => {
- launchApplication(modelData)
- }
-
- onKeyboardNavigationReset: {
- root.keyboardNavigationActive = false
- }
- }
- }
-
- DankGridView {
- id: appGrid
-
- function ensureVisible(index) {
- if (index < 0 || index >= count) return
-
- const itemY = Math.floor(index / root.gridColumns) * cellHeight
- const itemBottom = itemY + cellHeight
- if (itemY < contentY) {
- contentY = itemY
- } else if (itemBottom > contentY + height) {
- contentY = itemBottom - height
- }
- }
-
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: Theme.spacingS
- anchors.bottomMargin: Theme.spacingS
-
- visible: root.viewMode === "grid"
- model: applicationsModel
- cellWidth: width / root.gridColumns
- cellHeight: 120
- clip: true
- currentIndex: root.selectedIndex
-
- onCurrentIndexChanged: {
- root.selectedIndex = currentIndex
- if (root.keyboardNavigationActive) {
- ensureVisible(currentIndex)
- }
- }
-
- delegate: AppLauncherGridDelegate {
- gridView: appGrid
- cellWidth: appGrid.cellWidth
- cellHeight: appGrid.cellHeight
-
- currentIndex: root.selectedIndex
- keyboardNavigationActive: root.keyboardNavigationActive
- hoverUpdatesSelection: true
-
- onItemClicked: (idx, modelData) => {
- launchApplication(modelData)
- }
-
- onKeyboardNavigationReset: {
- root.keyboardNavigationActive = false
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 36
- radius: Theme.cornerRadius
- color: Theme.withAlpha(Theme.surfaceContainerHigh, 0.5)
- border.color: Theme.outlineMedium
- border.width: 1
- visible: root.showTargetData && root.targetData.length > 0
-
- StyledText {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- text: root.targetDataLabel.length > 0 ? root.targetDataLabel + ": " + root.targetData : root.targetData
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- elide: Text.ElideMiddle
- wrapMode: Text.NoWrap
- maximumLineCount: 1
- }
- }
- }
-
- function launchApplication(app) {
- if (!app) return
-
- root.applicationSelected(app, root.targetData)
-
- if (usageHistoryKey && app.appId) {
- const usageHistory = SettingsData[usageHistoryKey] || {}
- const currentCount = usageHistory[app.appId] ? usageHistory[app.appId].count : 0
- usageHistory[app.appId] = {
- count: currentCount + 1,
- lastUsed: Date.now(),
- name: app.name
- }
- SettingsData.set(usageHistoryKey, usageHistory)
- }
-
- root.close()
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml
deleted file mode 100644
index cd3c9b7..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml
+++ /dev/null
@@ -1,409 +0,0 @@
-import QtQuick
-import Quickshell.Hyprland
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:bluetooth-pairing"
-
- HyprlandFocusGrab {
- windows: [root.contentWindow]
- active: root.useHyprlandFocusGrab && root.shouldHaveFocus
- }
-
- property string deviceName: ""
- property string deviceAddress: ""
- property string requestType: ""
- property string token: ""
- property int passkey: 0
- property string pinInput: ""
- property string passkeyInput: ""
-
- function show(pairingData) {
- console.log("BluetoothPairingModal.show() called:", JSON.stringify(pairingData));
- token = pairingData.token || "";
- deviceName = pairingData.deviceName || "";
- deviceAddress = pairingData.deviceAddr || "";
- requestType = pairingData.requestType || "";
- passkey = pairingData.passkey || 0;
- pinInput = "";
- passkeyInput = "";
-
- console.log("BluetoothPairingModal: Calling open()");
- open();
- Qt.callLater(() => {
- if (contentLoader.item) {
- if (requestType === "pin" && contentLoader.item.pinInputField) {
- contentLoader.item.pinInputField.forceActiveFocus();
- } else if (requestType === "passkey" && contentLoader.item.passkeyInputField) {
- contentLoader.item.passkeyInputField.forceActiveFocus();
- }
- }
- });
- }
-
- shouldBeVisible: false
- allowStacking: true
- keepPopoutsOpen: true
- modalWidth: 420
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 240
-
- onShouldBeVisibleChanged: () => {
- if (!shouldBeVisible) {
- pinInput = "";
- passkeyInput = "";
- }
- }
-
- onOpened: {
- Qt.callLater(() => {
- if (contentLoader.item) {
- if (requestType === "pin" && contentLoader.item.pinInputField) {
- contentLoader.item.pinInputField.forceActiveFocus();
- } else if (requestType === "passkey" && contentLoader.item.passkeyInputField) {
- contentLoader.item.passkeyInputField.forceActiveFocus();
- }
- }
- });
- }
-
- onBackgroundClicked: () => {
- if (token) {
- DMSService.bluetoothCancelPairing(token);
- }
- close();
- token = "";
- pinInput = "";
- passkeyInput = "";
- }
-
- content: Component {
- FocusScope {
- id: pairingContent
-
- property alias pinInputField: pinInputField
- property alias passkeyInputField: passkeyInputField
-
- anchors.fill: parent
- focus: true
- implicitHeight: mainColumn.implicitHeight
-
- Keys.onEscapePressed: event => {
- if (token) {
- DMSService.bluetoothCancelPairing(token);
- }
- close();
- token = "";
- pinInput = "";
- passkeyInput = "";
- event.accepted = true;
- }
-
- Column {
- id: mainColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingM
- spacing: requestType === "pin" || requestType === "passkey" ? Theme.spacingM : Theme.spacingS
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Pair Bluetooth Device")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: {
- switch (requestType) {
- case "confirm":
- return I18n.tr("Confirm passkey for ") + deviceName;
- case "display-passkey":
- return I18n.tr("Enter this passkey on ") + deviceName;
- case "authorize":
- return I18n.tr("Authorize pairing with ") + deviceName;
- case "pin":
- return I18n.tr("Enter PIN for ") + deviceName;
- case "passkey":
- return I18n.tr("Enter passkey for ") + deviceName;
- default:
- if (requestType.startsWith("authorize-service"))
- return I18n.tr("Authorize service for ") + deviceName;
- return deviceName;
- }
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width - 40
- elide: Text.ElideRight
- }
- }
-
- Rectangle {
- width: parent.width
- height: 50
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: pinInputField.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: pinInputField.activeFocus ? 2 : 1
- visible: requestType === "pin"
-
- MouseArea {
- anchors.fill: parent
- onClicked: () => {
- pinInputField.forceActiveFocus();
- }
- }
-
- DankTextField {
- id: pinInputField
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: pinInput
- placeholderText: I18n.tr("Enter PIN")
- backgroundColor: "transparent"
- enabled: root.shouldBeVisible
- onTextEdited: () => {
- pinInput = text;
- }
- onAccepted: () => {
- submitPairing();
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 50
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: passkeyInputField.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: passkeyInputField.activeFocus ? 2 : 1
- visible: requestType === "passkey"
-
- MouseArea {
- anchors.fill: parent
- onClicked: () => {
- passkeyInputField.forceActiveFocus();
- }
- }
-
- DankTextField {
- id: passkeyInputField
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: passkeyInput
- placeholderText: I18n.tr("Enter 6-digit passkey")
- backgroundColor: "transparent"
- enabled: root.shouldBeVisible
- onTextEdited: () => {
- passkeyInput = text;
- }
- onAccepted: () => {
- submitPairing();
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 56
- radius: Theme.cornerRadius
- color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency)
- visible: requestType === "confirm" || requestType === "display-passkey"
-
- Column {
- anchors.centerIn: parent
- spacing: 2
-
- StyledText {
- text: I18n.tr("Passkey:")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: String(passkey).padStart(6, "0")
- font.pixelSize: Theme.fontSizeXLarge
- color: Theme.surfaceText
- font.weight: Font.Bold
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- }
-
- Item {
- width: parent.width
- height: 36
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- Rectangle {
- width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: cancelText
-
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: () => {
- if (token) {
- DMSService.bluetoothCancelPairing(token);
- }
- close();
- token = "";
- pinInput = "";
- passkeyInput = "";
- }
- }
- }
-
- Rectangle {
- width: Math.max(80, pairText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: pairArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
- enabled: {
- if (requestType === "pin")
- return pinInput.length > 0;
- if (requestType === "passkey")
- return passkeyInput.length === 6;
- return true;
- }
- opacity: enabled ? 1 : 0.5
-
- StyledText {
- id: pairText
-
- anchors.centerIn: parent
- text: {
- switch (requestType) {
- case "confirm":
- case "display-passkey":
- return I18n.tr("Confirm");
- case "authorize":
- return I18n.tr("Authorize");
- default:
- if (requestType.startsWith("authorize-service"))
- return I18n.tr("Authorize");
- return I18n.tr("Pair");
- }
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: pairArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- enabled: parent.enabled
- onClicked: () => {
- submitPairing();
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
-
- DankActionButton {
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: () => {
- if (token) {
- DMSService.bluetoothCancelPairing(token);
- }
- close();
- token = "";
- pinInput = "";
- passkeyInput = "";
- }
- }
- }
- }
-
- function submitPairing() {
- const secrets = {};
-
- switch (requestType) {
- case "pin":
- secrets["pin"] = pinInput;
- break;
- case "passkey":
- secrets["passkey"] = passkeyInput;
- break;
- case "confirm":
- case "display-passkey":
- case "authorize":
- secrets["decision"] = "yes";
- break;
- default:
- if (requestType.startsWith("authorize-service")) {
- secrets["decision"] = "yes";
- }
- break;
- }
-
- DMSService.bluetoothSubmitPairing(token, secrets, true, response => {
- if (response.error) {
- ToastService.showError(I18n.tr("Pairing failed"), response.error);
- }
- });
-
- close();
- token = "";
- pinInput = "";
- passkeyInput = "";
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml
deleted file mode 100644
index e4afcb8..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml
+++ /dev/null
@@ -1,51 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Modals
-
-AppPickerModal {
- id: root
-
- property string url: ""
-
- title: I18n.tr("Open with...")
- targetData: url
- targetDataLabel: ""
- categoryFilter: ["WebBrowser", "X-WebBrowser"]
- viewMode: SettingsData.browserPickerViewMode || "grid"
- usageHistoryKey: "browserUsageHistory"
- showTargetData: true
-
- function shellEscape(str) {
- return "'" + str.replace(/'/g, "'\\''") + "'"
- }
-
- onApplicationSelected: (app, url) => {
- if (!app) return
-
- let cmd = app.exec || ""
- const escapedUrl = shellEscape(url)
-
- let hasField = false
- if (cmd.includes("%u")) { cmd = cmd.replace("%u", escapedUrl); hasField = true }
- else if (cmd.includes("%U")) { cmd = cmd.replace("%U", escapedUrl); hasField = true }
- else if (cmd.includes("%f")) { cmd = cmd.replace("%f", escapedUrl); hasField = true }
- else if (cmd.includes("%F")) { cmd = cmd.replace("%F", escapedUrl); hasField = true }
-
- cmd = cmd.replace(/%[ikc]/g, "")
-
- if (!hasField) {
- cmd += " " + escapedUrl
- }
-
- console.log("BrowserPicker: Launching", cmd)
-
- Quickshell.execDetached({
- command: ["sh", "-c", cmd]
- })
- }
-
- onViewModeChanged: {
- SettingsData.set("browserPickerViewMode", viewMode)
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml
deleted file mode 100644
index 8fd3129..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml
+++ /dev/null
@@ -1,250 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Column {
- id: root
-
- readonly property real logoSize: Math.round(Theme.iconSize * 2.8)
- readonly property real badgeHeight: Math.round(Theme.fontSizeSmall * 1.7)
-
- topPadding: Theme.spacingL
- spacing: Theme.spacingL
-
- Column {
- width: parent.width
- spacing: Theme.spacingM
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Image {
- width: root.logoSize
- height: width * (569.94629 / 506.50931)
- anchors.verticalCenter: parent.verticalCenter
- fillMode: Image.PreserveAspectFit
- smooth: true
- mipmap: true
- asynchronous: true
- source: "file://" + Theme.shellDir + "/assets/danklogonormal.svg"
- layer.enabled: true
- layer.smooth: true
- layer.mipmap: true
- layer.effect: MultiEffect {
- saturation: 0
- colorization: 1
- colorizationColor: Theme.primary
- }
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- Row {
- spacing: Theme.spacingS
-
- StyledText {
- text: "DMS " + ChangelogService.currentVersion
- font.pixelSize: Theme.fontSizeXLarge + 2
- font.weight: Font.Bold
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Rectangle {
- width: codenameText.implicitWidth + Theme.spacingM * 2
- height: root.badgeHeight
- radius: root.badgeHeight / 2
- color: Theme.primaryContainer
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- id: codenameText
- anchors.centerIn: parent
- text: "Saffron Bloom"
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.primary
- }
- }
- }
-
- StyledText {
- text: "New launcher, enhanced plugin system, KDE Connect, & more"
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.3
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingM
-
- StyledText {
- text: "What's New"
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- Grid {
- width: parent.width
- columns: 2
- rowSpacing: Theme.spacingS
- columnSpacing: Theme.spacingS
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "space_dashboard"
- title: "Dank Launcher V2"
- description: "New capabilities & plugins"
- onClicked: PopoutService.openDankLauncherV2()
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "smartphone"
- title: "Phone Connect"
- description: "KDE Connect & Valent"
- onClicked: Qt.openUrlExternally("https://github.com/AvengeMedia/dms-plugins/tree/master/DankKDEConnect")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "monitor_heart"
- title: "System Monitor"
- description: "Redesigned process list"
- onClicked: PopoutService.showProcessListModal()
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "window"
- title: "Window Rules"
- description: "niri window rule manager"
- visible: CompositorService.isNiri
- onClicked: PopoutService.openSettingsWithTab("window_rules")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "notifications_active"
- title: "Enhanced Notifications"
- description: "Configurable rules & styling"
- visible: !CompositorService.isNiri
- onClicked: PopoutService.openSettingsWithTab("notifications")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "dock_to_bottom"
- title: "Dock Enhancements"
- description: "Bar dock widget & more"
- onClicked: PopoutService.openSettingsWithTab("dock")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "volume_up"
- title: "Audio Aliases"
- description: "Custom device names"
- onClicked: PopoutService.openSettingsWithTab("audio")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "extension"
- title: "Enhanced Plugin System"
- description: "Enables new types of plugins"
- onClicked: PopoutService.openSettingsWithTab("plugins")
- }
-
- ChangelogFeatureCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "light_mode"
- title: "Auto Light/Dark"
- description: "Automatic mode switching"
- onClicked: PopoutService.openSettingsWithTab("theme")
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.3
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- spacing: Theme.spacingS
-
- DankIcon {
- name: "warning"
- size: Theme.iconSizeSmall
- color: Theme.warning
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: "Upgrade Notes"
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- width: parent.width
- height: upgradeNotesColumn.height + Theme.spacingM * 2
- radius: Theme.cornerRadius
- color: Theme.withAlpha(Theme.warning, 0.08)
- border.width: 1
- border.color: Theme.withAlpha(Theme.warning, 0.2)
-
- Column {
- id: upgradeNotesColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingS
-
- ChangelogUpgradeNote {
- width: parent.width
- text: "Spotlight replaced by Dank Launcher V2 — check settings for new options"
- }
-
- ChangelogUpgradeNote {
- width: parent.width
- text: "Plugin API updated — third-party plugins may need updates"
- }
- }
- }
-
- // StyledText {
- // text: "See full release notes for migration steps"
- // font.pixelSize: Theme.fontSizeSmall
- // color: Theme.surfaceVariantText
- // width: parent.width
- // }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml
deleted file mode 100644
index eab4f70..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml
+++ /dev/null
@@ -1,78 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property string iconName: ""
- property string title: ""
- property string description: ""
-
- signal clicked
-
- readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.3)
-
- height: Math.round(Theme.fontSizeMedium * 4.2)
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.fill: parent
- radius: parent.radius
- color: Theme.primary
- opacity: mouseArea.containsMouse ? 0.12 : 0
- }
-
- Row {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingS
-
- Rectangle {
- width: root.iconContainerSize
- height: root.iconContainerSize
- radius: Math.round(root.iconContainerSize * 0.28)
- color: Theme.primaryContainer
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: root.iconName
- size: Theme.iconSize - 6
- color: Theme.primary
- }
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
- width: parent.width - root.iconContainerSize - Theme.spacingS
-
- StyledText {
- text: root.title
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- StyledText {
- text: root.description
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- width: parent.width
- elide: Text.ElideRight
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.clicked()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml
deleted file mode 100644
index 524298b..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml
+++ /dev/null
@@ -1,156 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- readonly property int modalWidth: 680
- readonly property int modalHeight: screen ? Math.min(720, screen.height - 80) : 720
-
- signal changelogDismissed
-
- function show() {
- visible = true;
- }
-
- objectName: "changelogModal"
- title: i18n("What's New")
- minimumSize: Qt.size(modalWidth, modalHeight)
- maximumSize: Qt.size(modalWidth, modalHeight)
- color: Theme.surfaceContainer
- visible: false
-
- FocusScope {
- id: contentFocusScope
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- root.dismiss();
- event.accepted = true;
- }
-
- Keys.onPressed: event => {
- switch (event.key) {
- case Qt.Key_Return:
- case Qt.Key_Enter:
- root.dismiss();
- event.accepted = true;
- break;
- }
- }
-
- MouseArea {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- height: headerRow.height + Theme.spacingM
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- Item {
- id: headerRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- height: Math.round(Theme.fontSizeMedium * 2.85)
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported && windowControls.canMaximize
- iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.dismiss()
-
- DankTooltip {
- text: i18n("Close")
- }
- }
- }
- }
-
- DankFlickable {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: headerRow.bottom
- anchors.bottom: footerRow.top
- anchors.topMargin: Theme.spacingS
- clip: true
- contentHeight: mainColumn.height + Theme.spacingL * 2
- contentWidth: width
-
- ChangelogContent {
- id: mainColumn
- anchors.horizontalCenter: parent.horizontalCenter
- width: Math.min(600, parent.width - Theme.spacingXL * 2)
- }
- }
-
- Rectangle {
- id: footerRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: Math.round(Theme.fontSizeMedium * 4.5)
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.top: parent.top
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.5
- }
-
- Row {
- anchors.centerIn: parent
- spacing: Theme.spacingM
-
- DankButton {
- text: i18n("Read Full Release Notes")
- iconName: "open_in_new"
- backgroundColor: Theme.surfaceContainerHighest
- textColor: Theme.surfaceText
- onClicked: Qt.openUrlExternally("https://danklinux.com/blog/v1-4-release")
- }
-
- DankButton {
- text: i18n("Got It")
- iconName: "check"
- backgroundColor: Theme.primary
- textColor: Theme.primaryText
- onClicked: root.dismiss()
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-
- function dismiss() {
- ChangelogService.dismissChangelog();
- changelogDismissed();
- visible = false;
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml
deleted file mode 100644
index 545eb9a..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml
+++ /dev/null
@@ -1,27 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Row {
- id: root
-
- property alias text: noteText.text
-
- spacing: Theme.spacingS
-
- DankIcon {
- name: "arrow_right"
- size: Theme.iconSizeSmall - 2
- color: Theme.surfaceVariantText
- anchors.top: parent.top
- anchors.topMargin: 2
- }
-
- StyledText {
- id: noteText
- width: root.width - Theme.iconSizeSmall - Theme.spacingS
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- wrapMode: Text.WordWrap
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml
deleted file mode 100644
index f796ffe..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml
+++ /dev/null
@@ -1,21 +0,0 @@
-pragma Singleton
-
-import QtQuick
-import Quickshell
-
-Singleton {
- id: root
- readonly property int previewLength: 100
- readonly property int longTextThreshold: 200
- readonly property int modalWidth: 650
- readonly property int modalHeight: 550
- readonly property int popoutWidth: 550
- readonly property int popoutHeight: 500
- readonly property int itemHeight: 72
- readonly property int thumbnailSize: 100
- readonly property int retryInterval: 50
- readonly property int viewportBuffer: 100
- readonly property int extendedBuffer: 200
- readonly property int keyboardHintsHeight: 80
- readonly property int headerHeight: 32
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml
deleted file mode 100644
index e00bc22..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml
+++ /dev/null
@@ -1,260 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Widgets
-
-Item {
- id: clipboardContent
-
- required property var modal
- required property var clearConfirmDialog
-
- property alias searchField: searchField
- property alias clipboardListView: clipboardListView
-
- anchors.fill: parent
-
- Column {
- id: headerColumn
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingM
- focus: false
-
- ClipboardHeader {
- id: header
- width: parent.width
- totalCount: modal.totalCount
- showKeyboardHints: modal.showKeyboardHints
- activeTab: modal.activeTab
- pinnedCount: modal.pinnedCount
- onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints
- onTabChanged: tabName => modal.activeTab = tabName
- onClearAllClicked: {
- const hasPinned = modal.pinnedCount > 0;
- const message = hasPinned ? I18n.tr("This will delete all unpinned entries. %1 pinned entries will be kept.").arg(modal.pinnedCount) : I18n.tr("This will permanently delete all clipboard history.");
- clearConfirmDialog.show(I18n.tr("Clear History?"), message, function () {
- modal.clearAll();
- modal.hide();
- }, function () {});
- }
- onCloseClicked: modal.hide()
- }
-
- DankTextField {
- id: searchField
- width: parent.width
- placeholderText: ""
- leftIconName: "search"
- showClearButton: true
- focus: true
- ignoreTabKeys: true
- keyForwardTargets: [modal.modalFocusScope]
- onTextChanged: {
- modal.searchText = text;
- modal.updateFilteredModel();
- }
- Keys.onEscapePressed: function (event) {
- modal.hide();
- event.accepted = true;
- }
- Component.onCompleted: {
- Qt.callLater(function () {
- forceActiveFocus();
- });
- }
-
- Connections {
- target: modal
- function onOpened() {
- Qt.callLater(function () {
- searchField.forceActiveFocus();
- });
- }
- }
- }
- }
-
- Item {
- id: listContainer
- anchors.top: headerColumn.bottom
- anchors.topMargin: Theme.spacingM
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.bottomMargin: (modal.showKeyboardHints ? (ClipboardConstants.keyboardHintsHeight + Theme.spacingM * 2) : 0) + Theme.spacingXS
- clip: true
-
- DankListView {
- id: clipboardListView
- anchors.fill: parent
- model: ScriptModel {
- values: clipboardContent.modal.unpinnedEntries
- objectProp: "id"
- }
- visible: modal.activeTab === "recents"
-
- currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0
- spacing: Theme.spacingXS
- interactive: true
- flickDeceleration: 1500
- maximumFlickVelocity: 2000
- boundsBehavior: Flickable.DragAndOvershootBounds
- boundsMovement: Flickable.FollowBoundsBehavior
- pressDelay: 0
- flickableDirection: Flickable.VerticalFlick
-
- function ensureVisible(index) {
- if (index < 0 || index >= count) {
- return;
- }
- positionViewAtIndex(index, ListView.Contain);
- }
-
- onCurrentIndexChanged: {
- if (clipboardContent.modal?.keyboardNavigationActive && currentIndex >= 0) {
- ensureVisible(currentIndex);
- }
- }
-
- StyledText {
- text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No recent clipboard entries found") : I18n.tr("Connecting to clipboard service…")
- anchors.centerIn: parent
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- visible: clipboardContent.modal.unpinnedEntries.length === 0
- }
-
- delegate: ClipboardEntry {
- required property int index
- required property var modelData
-
- width: clipboardListView.width
- height: ClipboardConstants.itemHeight
- entry: modelData
- entryIndex: index + 1
- itemIndex: index
- isSelected: clipboardContent.modal?.keyboardNavigationActive && index === clipboardContent.modal.selectedIndex
- modal: clipboardContent.modal
- listView: clipboardListView
- onCopyRequested: clipboardContent.modal.copyEntry(modelData)
- onDeleteRequested: clipboardContent.modal.deleteEntry(modelData)
- onPinRequested: clipboardContent.modal.pinEntry(modelData)
- onUnpinRequested: clipboardContent.modal.unpinEntry(modelData)
- }
- }
-
- DankListView {
- id: savedListView
- anchors.fill: parent
- model: ScriptModel {
- values: clipboardContent.modal.pinnedEntries
- objectProp: "id"
- }
- visible: modal.activeTab === "saved"
-
- currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0
- spacing: Theme.spacingXS
- interactive: true
- flickDeceleration: 1500
- maximumFlickVelocity: 2000
- boundsBehavior: Flickable.DragAndOvershootBounds
- boundsMovement: Flickable.FollowBoundsBehavior
- pressDelay: 0
- flickableDirection: Flickable.VerticalFlick
-
- function ensureVisible(index) {
- if (index < 0 || index >= count) {
- return;
- }
- positionViewAtIndex(index, ListView.Contain);
- }
-
- onCurrentIndexChanged: {
- if (clipboardContent.modal?.keyboardNavigationActive && currentIndex >= 0) {
- ensureVisible(currentIndex);
- }
- }
-
- StyledText {
- text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No saved clipboard entries") : I18n.tr("Connecting to clipboard service…")
- anchors.centerIn: parent
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- visible: clipboardContent.modal.pinnedEntries.length === 0
- }
-
- delegate: ClipboardEntry {
- required property int index
- required property var modelData
-
- width: savedListView.width
- height: ClipboardConstants.itemHeight
- entry: modelData
- entryIndex: index + 1
- itemIndex: index
- isSelected: clipboardContent.modal?.keyboardNavigationActive && index === clipboardContent.modal.selectedIndex
- modal: clipboardContent.modal
- listView: savedListView
- onCopyRequested: clipboardContent.modal.copyEntry(modelData)
- onDeleteRequested: clipboardContent.modal.deletePinnedEntry(modelData)
- onPinRequested: clipboardContent.modal.pinEntry(modelData)
- onUnpinRequested: clipboardContent.modal.unpinEntry(modelData)
- }
- }
-
- Rectangle {
- id: bottomFade
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: 24
- z: 100
- visible: {
- const listView = modal.activeTab === "recents" ? clipboardListView : savedListView;
- if (listView.contentHeight <= listView.height)
- return false;
- const atBottom = listView.contentY >= listView.contentHeight - listView.height - 5;
- return !atBottom;
- }
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "transparent"
- }
- GradientStop {
- position: 1.0
- color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- }
- }
- }
- }
-
- Loader {
- id: keyboardHintsLoader
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.bottomMargin: active ? Theme.spacingM : 0
- active: modal.showKeyboardHints
- height: active ? ClipboardConstants.keyboardHintsHeight : 0
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- sourceComponent: ClipboardKeyboardHints {
- wtypeAvailable: modal.wtypeAvailable
- enterToPaste: SettingsData.clipboardEnterToPaste
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml
deleted file mode 100644
index 53a2ece..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml
+++ /dev/null
@@ -1,155 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- required property var entry
- required property int entryIndex
- required property int itemIndex
- required property bool isSelected
- required property var modal
- required property var listView
-
- signal copyRequested
- signal deleteRequested
- signal pinRequested
- signal unpinRequested
-
- readonly property string entryType: modal ? modal.getEntryType(entry) : "text"
- readonly property string entryPreview: modal ? modal.getEntryPreview(entry) : ""
- readonly property bool hasPinnedDuplicate: !entry.pinned && ClipboardService.hashedPinnedEntry(entry.hash)
-
- radius: Theme.cornerRadius
- color: {
- if (isSelected) {
- return Theme.primaryPressed;
- }
- return mouseArea.containsMouse ? Theme.primaryHoverLight : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
- }
-
- DankRipple {
- id: rippleLayer
- rippleColor: Theme.surfaceText
- cornerRadius: root.radius
- }
-
- Rectangle {
- id: indexBadge
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- width: 24
- height: 24
- radius: 12
- color: Theme.primarySelected
-
- StyledText {
- anchors.centerIn: parent
- text: entryIndex.toString()
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Bold
- color: Theme.primary
- }
- }
-
- Row {
- id: actionButtons
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- DankActionButton {
- iconName: "push_pin"
- iconSize: Theme.iconSize - 6
- iconColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primary : Theme.surfaceText
- backgroundColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primarySelected : "transparent"
- onClicked: entry.pinned ? unpinRequested() : pinRequested()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 6
- iconColor: Theme.surfaceText
- onClicked: deleteRequested()
- }
- }
-
- Item {
- anchors.left: indexBadge.right
- anchors.leftMargin: Theme.spacingM
- anchors.right: actionButtons.left
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- // height: contentColumn.implicitHeight
- height: ClipboardConstants.itemHeight
- clip: true
-
- ClipboardThumbnail {
- id: thumbnail
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- width: entryType === "image" ? ClipboardConstants.thumbnailSize : Theme.iconSize
- height: entryType === "image" ? ClipboardConstants.itemHeight - 4 : Theme.iconSize // 100 - 4 = 96, 96:72 = 4:3
- entry: root.entry
- entryType: root.entryType
- modal: root.modal
- listView: root.listView
- itemIndex: root.itemIndex
- }
-
- Column {
- id: contentColumn
- anchors.left: thumbnail.right
- anchors.leftMargin: Theme.spacingM
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- StyledText {
- text: {
- switch (entryType) {
- case "image":
- return I18n.tr("Image") + " • " + entryPreview;
- case "long_text":
- return I18n.tr("Long Text");
- default:
- return I18n.tr("Text");
- }
- }
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.primary
- font.weight: Font.Medium
- width: parent.width
- elide: Text.ElideRight
- }
-
- StyledText {
- text: entryPreview
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width
- wrapMode: Text.WordWrap
- maximumLineCount: entryType === "long_text" ? 3 : 1
- elide: Text.ElideRight
- textFormat: Text.PlainText
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- anchors.rightMargin: 80
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => {
- const pos = mouseArea.mapToItem(root, mouse.x, mouse.y);
- rippleLayer.trigger(pos.x, pos.y);
- }
- onClicked: copyRequested()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml
deleted file mode 100644
index fedba15..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml
+++ /dev/null
@@ -1,87 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-import qs.Modals.Clipboard
-
-Item {
- id: header
-
- property int totalCount: 0
- property bool showKeyboardHints: false
- property string activeTab: "recents"
- property int pinnedCount: 0
-
- signal keyboardHintsToggled
- signal clearAllClicked
- signal closeClicked
- signal tabChanged(string tabName)
-
- height: ClipboardConstants.headerHeight
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: "content_paste"
- size: Theme.iconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Clipboard History") + ` (${totalCount})`
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- DankActionButton {
- iconName: "push_pin"
- iconSize: Theme.iconSize - 4
- iconColor: header.activeTab === "saved" ? Theme.primary : Theme.surfaceText
- visible: header.pinnedCount > 0
- tooltipText: I18n.tr("Saved")
- onClicked: tabChanged("saved")
- }
-
- DankActionButton {
- iconName: "history"
- iconSize: Theme.iconSize - 4
- iconColor: header.activeTab === "recents" ? Theme.primary : Theme.surfaceText
- tooltipText: I18n.tr("History")
- onClicked: tabChanged("recents")
- }
-
- DankActionButton {
- iconName: "info"
- iconSize: Theme.iconSize - 4
- iconColor: showKeyboardHints ? Theme.primary : Theme.surfaceText
- tooltipText: I18n.tr("Keyboard Shortcuts")
- onClicked: keyboardHintsToggled()
- }
-
- DankActionButton {
- iconName: "delete_sweep"
- iconSize: Theme.iconSize
- iconColor: Theme.surfaceText
- tooltipText: I18n.tr("Clear All")
- onClicked: clearAllClicked()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: closeClicked()
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml
deleted file mode 100644
index 2f76cc7..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml
+++ /dev/null
@@ -1,174 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell.Hyprland
-import qs.Common
-import qs.Modals.Clipboard
-import qs.Modals.Common
-import qs.Services
-
-DankModal {
- id: clipboardHistoryModal
-
- layerNamespace: "dms:clipboard"
-
- HyprlandFocusGrab {
- windows: [clipboardHistoryModal.contentWindow]
- active: clipboardHistoryModal.useHyprlandFocusGrab && clipboardHistoryModal.shouldHaveFocus
- }
-
- property string activeTab: "recents"
- onActiveTabChanged: {
- ClipboardService.selectedIndex = 0;
- ClipboardService.keyboardNavigationActive = false;
- }
- property bool showKeyboardHints: false
- property Component clipboardContent
- property int activeImageLoads: 0
- readonly property int maxConcurrentLoads: 3
-
- readonly property bool clipboardAvailable: ClipboardService.clipboardAvailable
- readonly property bool wtypeAvailable: ClipboardService.wtypeAvailable
- readonly property int totalCount: ClipboardService.totalCount
- readonly property var clipboardEntries: ClipboardService.clipboardEntries
- readonly property var pinnedEntries: ClipboardService.pinnedEntries
- readonly property int pinnedCount: ClipboardService.pinnedCount
- readonly property var unpinnedEntries: ClipboardService.unpinnedEntries
- readonly property int selectedIndex: ClipboardService.selectedIndex
- readonly property bool keyboardNavigationActive: ClipboardService.keyboardNavigationActive
- property string searchText: ClipboardService.searchText
- onSearchTextChanged: ClipboardService.searchText = searchText
-
- Ref {
- service: ClipboardService
- }
-
- function updateFilteredModel() {
- ClipboardService.updateFilteredModel();
- }
-
- function pasteSelected() {
- ClipboardService.pasteSelected(instantClose);
- }
-
- function toggle() {
- if (shouldBeVisible) {
- hide();
- } else {
- show();
- }
- }
-
- function show() {
- open();
- activeImageLoads = 0;
- shouldHaveFocus = true;
- ClipboardService.reset();
- if (clipboardAvailable)
- ClipboardService.refresh();
- keyboardController.reset();
-
- Qt.callLater(function () {
- if (contentLoader.item?.searchField) {
- contentLoader.item.searchField.text = "";
- contentLoader.item.searchField.forceActiveFocus();
- }
- });
- }
-
- function hide() {
- close();
- }
-
- onDialogClosed: {
- activeImageLoads = 0;
- ClipboardService.reset();
- keyboardController.reset();
- }
-
- function refreshClipboard() {
- ClipboardService.refresh();
- }
-
- function copyEntry(entry) {
- ClipboardService.copyEntry(entry, hide);
- }
-
- function deleteEntry(entry) {
- ClipboardService.deleteEntry(entry);
- }
-
- function deletePinnedEntry(entry) {
- ClipboardService.deletePinnedEntry(entry, clearConfirmDialog);
- }
-
- function pinEntry(entry) {
- ClipboardService.pinEntry(entry);
- }
-
- function unpinEntry(entry) {
- ClipboardService.unpinEntry(entry);
- }
-
- function clearAll() {
- ClipboardService.clearAll();
- }
-
- function getEntryPreview(entry) {
- return ClipboardService.getEntryPreview(entry);
- }
-
- function getEntryType(entry) {
- return ClipboardService.getEntryType(entry);
- }
-
- visible: false
- modalWidth: ClipboardConstants.modalWidth
- modalHeight: ClipboardConstants.modalHeight
- backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- cornerRadius: Theme.cornerRadius
- borderColor: Theme.outlineMedium
- borderWidth: 1
- enableShadow: true
- onBackgroundClicked: hide()
- modalFocusScope.Keys.onPressed: function (event) {
- keyboardController.handleKey(event);
- }
- content: clipboardContent
-
- ClipboardKeyboardController {
- id: keyboardController
- modal: clipboardHistoryModal
- }
-
- ConfirmModal {
- id: clearConfirmDialog
- confirmButtonText: I18n.tr("Clear All")
- confirmButtonColor: Theme.primary
- onVisibleChanged: {
- if (visible) {
- clipboardHistoryModal.shouldHaveFocus = false;
- return;
- }
- Qt.callLater(function () {
- if (!clipboardHistoryModal.shouldBeVisible) {
- return;
- }
- clipboardHistoryModal.shouldHaveFocus = true;
- clipboardHistoryModal.modalFocusScope.forceActiveFocus();
- if (clipboardHistoryModal.contentLoader.item?.searchField) {
- clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus();
- }
- });
- }
- }
-
- property var confirmDialog: clearConfirmDialog
-
- clipboardContent: Component {
- ClipboardContent {
- modal: clipboardHistoryModal
- clearConfirmDialog: clipboardHistoryModal.confirmDialog
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml
deleted file mode 100644
index c4f0296..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml
+++ /dev/null
@@ -1,197 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Modals.Clipboard
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankPopout {
- id: root
-
- layerNamespace: "dms:clipboard-popout"
-
- property var parentWidget: null
- property var triggerScreen: null
- property string activeTab: "recents"
- property bool showKeyboardHints: false
- property int activeImageLoads: 0
- readonly property int maxConcurrentLoads: 3
-
- readonly property bool clipboardAvailable: ClipboardService.clipboardAvailable
- readonly property bool wtypeAvailable: ClipboardService.wtypeAvailable
- readonly property int totalCount: ClipboardService.totalCount
- readonly property var clipboardEntries: ClipboardService.clipboardEntries
- readonly property var pinnedEntries: ClipboardService.pinnedEntries
- readonly property int pinnedCount: ClipboardService.pinnedCount
- readonly property var unpinnedEntries: ClipboardService.unpinnedEntries
- readonly property int selectedIndex: ClipboardService.selectedIndex
- readonly property bool keyboardNavigationActive: ClipboardService.keyboardNavigationActive
- property string searchText: ClipboardService.searchText
- onSearchTextChanged: ClipboardService.searchText = searchText
-
- readonly property var modalFocusScope: contentLoader.item ?? null
-
- Ref {
- service: ClipboardService
- }
-
- function updateFilteredModel() {
- ClipboardService.updateFilteredModel();
- }
-
- function pasteSelected() {
- ClipboardService.pasteSelected(instantClose);
- }
-
- function instantClose() {
- close();
- }
-
- function show() {
- open();
- activeImageLoads = 0;
- ClipboardService.reset();
- if (clipboardAvailable)
- ClipboardService.refresh();
- keyboardController.reset();
-
- Qt.callLater(function () {
- if (contentLoader.item?.searchField) {
- contentLoader.item.searchField.text = "";
- contentLoader.item.searchField.forceActiveFocus();
- }
- });
- }
-
- function hide() {
- close();
- activeImageLoads = 0;
- ClipboardService.reset();
- keyboardController.reset();
- }
-
- function refreshClipboard() {
- ClipboardService.refresh();
- }
-
- function copyEntry(entry) {
- ClipboardService.copyEntry(entry, hide);
- }
-
- function deleteEntry(entry) {
- ClipboardService.deleteEntry(entry);
- }
-
- function deletePinnedEntry(entry) {
- ClipboardService.deletePinnedEntry(entry, clearConfirmDialog);
- }
-
- function pinEntry(entry) {
- ClipboardService.pinEntry(entry);
- }
-
- function unpinEntry(entry) {
- ClipboardService.unpinEntry(entry);
- }
-
- function clearAll() {
- ClipboardService.clearAll();
- }
-
- function getEntryPreview(entry) {
- return ClipboardService.getEntryPreview(entry);
- }
-
- function getEntryType(entry) {
- return ClipboardService.getEntryType(entry);
- }
-
- popupWidth: ClipboardConstants.popoutWidth
- popupHeight: ClipboardConstants.popoutHeight
- triggerWidth: 55
- positioning: ""
- screen: triggerScreen
- shouldBeVisible: false
- contentHandlesKeys: true
-
- onBackgroundClicked: hide()
-
- onShouldBeVisibleChanged: {
- if (!shouldBeVisible)
- return;
- if (clipboardAvailable)
- ClipboardService.refresh();
- keyboardController.reset();
- Qt.callLater(function () {
- if (contentLoader.item?.searchField) {
- contentLoader.item.searchField.text = "";
- contentLoader.item.searchField.forceActiveFocus();
- }
- });
- }
-
- onPopoutClosed: {
- activeImageLoads = 0;
- ClipboardService.reset();
- keyboardController.reset();
- }
-
- ClipboardKeyboardController {
- id: keyboardController
- modal: root
- }
-
- ConfirmModal {
- id: clearConfirmDialog
- confirmButtonText: I18n.tr("Clear All")
- confirmButtonColor: Theme.primary
- }
-
- property var confirmDialog: clearConfirmDialog
-
- content: Component {
- FocusScope {
- id: contentFocusScope
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- focus: true
-
- property alias searchField: clipboardContentItem.searchField
-
- Keys.onPressed: function (event) {
- keyboardController.handleKey(event);
- }
-
- Component.onCompleted: {
- if (root.shouldBeVisible)
- forceActiveFocus();
- }
-
- Connections {
- target: root
- function onShouldBeVisibleChanged() {
- if (root.shouldBeVisible) {
- Qt.callLater(() => contentFocusScope.forceActiveFocus());
- }
- }
- function onOpened() {
- Qt.callLater(() => {
- if (clipboardContentItem.searchField) {
- clipboardContentItem.searchField.forceActiveFocus();
- }
- });
- }
- }
-
- ClipboardContent {
- id: clipboardContentItem
- modal: root
- clearConfirmDialog: root.confirmDialog
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml
deleted file mode 100644
index f2a457e..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml
+++ /dev/null
@@ -1,166 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Services
-
-QtObject {
- id: keyboardController
-
- required property var modal
-
- function reset() {
- ClipboardService.selectedIndex = 0;
- ClipboardService.keyboardNavigationActive = false;
- modal.showKeyboardHints = false;
- }
-
- function selectNext() {
- const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries;
- if (!entries || entries.length === 0) {
- return;
- }
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = Math.min(ClipboardService.selectedIndex + 1, entries.length - 1);
- }
-
- function selectPrevious() {
- const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries;
- if (!entries || entries.length === 0) {
- return;
- }
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = Math.max(ClipboardService.selectedIndex - 1, 0);
- }
-
- function copySelected() {
- const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries;
- if (!entries || entries.length === 0 || ClipboardService.selectedIndex < 0 || ClipboardService.selectedIndex >= entries.length) {
- return;
- }
- const selectedEntry = entries[ClipboardService.selectedIndex];
- modal.copyEntry(selectedEntry);
- }
-
- function deleteSelected() {
- const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries;
- if (!entries || entries.length === 0 || ClipboardService.selectedIndex < 0 || ClipboardService.selectedIndex >= entries.length) {
- return;
- }
- const selectedEntry = entries[ClipboardService.selectedIndex];
- if (modal.activeTab === "saved") {
- modal.deletePinnedEntry(selectedEntry);
- } else {
- modal.deleteEntry(selectedEntry);
- }
- }
-
- function handleKey(event) {
- switch (event.key) {
- case Qt.Key_Escape:
- if (ClipboardService.keyboardNavigationActive) {
- ClipboardService.keyboardNavigationActive = false;
- } else {
- modal.hide();
- }
- event.accepted = true;
- return;
- case Qt.Key_Down:
- case Qt.Key_Tab:
- if (!ClipboardService.keyboardNavigationActive) {
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = 0;
- } else {
- selectNext();
- }
- event.accepted = true;
- return;
- case Qt.Key_Up:
- case Qt.Key_Backtab:
- if (!ClipboardService.keyboardNavigationActive) {
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = 0;
- } else if (ClipboardService.selectedIndex === 0) {
- ClipboardService.keyboardNavigationActive = false;
- } else {
- selectPrevious();
- }
- event.accepted = true;
- return;
- case Qt.Key_F10:
- modal.showKeyboardHints = !modal.showKeyboardHints;
- event.accepted = true;
- return;
- }
-
- if (event.modifiers & Qt.ControlModifier) {
- switch (event.key) {
- case Qt.Key_N:
- case Qt.Key_J:
- if (!ClipboardService.keyboardNavigationActive) {
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = 0;
- } else {
- selectNext();
- }
- event.accepted = true;
- return;
- case Qt.Key_P:
- case Qt.Key_K:
- if (!ClipboardService.keyboardNavigationActive) {
- ClipboardService.keyboardNavigationActive = true;
- ClipboardService.selectedIndex = 0;
- } else if (ClipboardService.selectedIndex === 0) {
- ClipboardService.keyboardNavigationActive = false;
- } else {
- selectPrevious();
- }
- event.accepted = true;
- return;
- case Qt.Key_C:
- if (ClipboardService.keyboardNavigationActive) {
- copySelected();
- event.accepted = true;
- }
- return;
- }
- }
-
- if (event.modifiers & Qt.ShiftModifier) {
- switch (event.key) {
- case Qt.Key_Delete:
- modal.clearAll();
- modal.hide();
- event.accepted = true;
- return;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (ClipboardService.keyboardNavigationActive) {
- if (SettingsData.clipboardEnterToPaste) {
- copySelected();
- } else {
- modal.pasteSelected();
- }
- event.accepted = true;
- }
- return;
- }
- }
-
- if (ClipboardService.keyboardNavigationActive) {
- switch (event.key) {
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (SettingsData.clipboardEnterToPaste) {
- modal.pasteSelected();
- } else {
- copySelected();
- }
- event.accepted = true;
- return;
- case Qt.Key_Delete:
- deleteSelected();
- event.accepted = true;
- return;
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml
deleted file mode 100644
index 0285952..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml
+++ /dev/null
@@ -1,51 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: keyboardHints
-
- property bool wtypeAvailable: false
- property bool enterToPaste: false
- readonly property string hintsText: {
- if (!wtypeAvailable)
- return I18n.tr("Shift+Del: Clear All • Esc: Close");
- return enterToPaste ? I18n.tr("Shift+Enter: Copy • Shift+Del: Clear All • Esc: Close", "Keyboard hints when enter-to-paste is enabled") : I18n.tr("Shift+Enter: Paste • Shift+Del: Clear All • Esc: Close");
- }
-
- height: ClipboardConstants.keyboardHintsHeight
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95)
- border.color: Theme.primary
- border.width: 2
- opacity: visible ? 1 : 0
- z: 100
-
- Column {
- anchors.centerIn: parent
- spacing: 2
-
- StyledText {
- text: keyboardHints.enterToPaste
- ? I18n.tr("↑/↓: Navigate • Enter: Paste • Del: Delete • F10: Help", "Keyboard hints when enter-to-paste is enabled")
- : I18n.tr("↑/↓: Navigate • Enter/Ctrl+C: Copy • Del: Delete • F10: Help")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: keyboardHints.hintsText
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml
deleted file mode 100644
index 26a9210..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml
+++ /dev/null
@@ -1,178 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: thumbnail
-
- required property var entry
- required property string entryType
- required property var modal
- required property var listView
- required property int itemIndex
-
- Image {
- id: thumbnailImage
-
- property bool isVisible: false
- property string cachedImageData: ""
- property bool loadQueued: false
-
- anchors.fill: parent
- source: cachedImageData ? `data:image/png;base64,${cachedImageData}` : ""
- fillMode: Image.PreserveAspectCrop
- smooth: true
- cache: false
- visible: false
- asynchronous: true
- sourceSize.width: 128
- sourceSize.height: 128
-
- function tryLoadImage() {
- if (thumbnailImage.loadQueued || entryType !== "image" || thumbnailImage.cachedImageData) {
- return;
- }
- thumbnailImage.loadQueued = true;
- if (modal.activeImageLoads < modal.maxConcurrentLoads) {
- modal.activeImageLoads++;
- thumbnailImage.loadImage();
- } else {
- retryTimer.restart();
- }
- }
-
- function loadImage() {
- DMSService.sendRequest("clipboard.getEntry", {
- "id": entry.id
- }, function (response) {
- thumbnailImage.loadQueued = false;
- if (modal.activeImageLoads > 0) {
- modal.activeImageLoads--;
- }
- if (response.error) {
- console.warn("ClipboardThumbnail: Failed to load image:", entry.id);
- return;
- }
- const data = response.result?.data;
- if (data) {
- thumbnailImage.cachedImageData = data;
- }
- });
- }
-
- Timer {
- id: retryTimer
- interval: ClipboardConstants.retryInterval
- onTriggered: {
- if (!thumbnailImage.loadQueued) {
- return;
- }
- if (modal.activeImageLoads < modal.maxConcurrentLoads) {
- modal.activeImageLoads++;
- thumbnailImage.loadImage();
- } else {
- retryTimer.restart();
- }
- }
- }
-
- Component.onCompleted: {
- if (entryType !== "image" || listView.height <= 0) {
- return;
- }
-
- const itemY = itemIndex * (ClipboardConstants.itemHeight + listView.spacing);
- const viewTop = listView.contentY;
- const viewBottom = viewTop + listView.height;
- isVisible = (itemY + ClipboardConstants.itemHeight >= viewTop && itemY <= viewBottom);
-
- if (isVisible) {
- tryLoadImage();
- }
- }
-
- Timer {
- id: visibilityTimer
- interval: 100
- onTriggered: thumbnailImage.checkVisibility()
- }
-
- function checkVisibility() {
- if (entryType !== "image" || listView.height <= 0 || isVisible) {
- return;
- }
- const itemY = itemIndex * (ClipboardConstants.itemHeight + listView.spacing);
- const viewTop = listView.contentY - ClipboardConstants.viewportBuffer;
- const viewBottom = viewTop + listView.height + ClipboardConstants.extendedBuffer;
- const nowVisible = (itemY + ClipboardConstants.itemHeight >= viewTop && itemY <= viewBottom);
- if (nowVisible) {
- isVisible = true;
- tryLoadImage();
- }
- }
-
- Connections {
- target: listView
-
- function onContentYChanged() {
- if (thumbnailImage.isVisible || entryType !== "image") {
- return;
- }
- visibilityTimer.restart();
- }
-
- function onHeightChanged() {
- if (thumbnailImage.isVisible || entryType !== "image") {
- return;
- }
- visibilityTimer.restart();
- }
- }
- }
-
- MultiEffect {
- anchors.fill: parent
- anchors.margins: 2
- source: thumbnailImage
- maskEnabled: true
- maskSource: clipboardRoundedRectangularMask
- visible: entryType === "image" && thumbnailImage.status === Image.Ready && thumbnailImage.source != ""
- maskThresholdMin: 0.5
- maskSpreadAtMin: 1
- }
-
- Item {
- id: clipboardRoundedRectangularMask
- width: ClipboardConstants.thumbnailSize
- height: ClipboardConstants.itemHeight - 4
- layer.enabled: true
- layer.smooth: true
- visible: false
-
- Rectangle {
- anchors.fill: parent
- radius: Theme.cornerRadius / 2 // Thumbnail corner radius is divided by 2 so it doesnt look weird on large corner radius (eg: 32px)
- color: "black"
- antialiasing: true
- }
- }
-
- DankIcon {
- visible: !(entryType === "image" && thumbnailImage.status === Image.Ready && thumbnailImage.source != "")
- name: {
- switch (entryType) {
- case "image":
- return "image";
- case "long_text":
- return "subject";
- default:
- return "content_copy";
- }
- }
- size: Theme.iconSize
- color: Theme.primary
- anchors.centerIn: parent
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml
deleted file mode 100644
index b9c9b90..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml
+++ /dev/null
@@ -1,291 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modals.Common
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:confirm-modal"
- keepPopoutsOpen: true
-
- property string confirmTitle: ""
- property string confirmMessage: ""
- property string confirmButtonText: "Confirm"
- property string cancelButtonText: "Cancel"
- property color confirmButtonColor: Theme.primary
- property var onConfirm: function () {}
- property var onCancel: function () {}
- property int selectedButton: -1
- property bool keyboardNavigation: false
-
- function show(title, message, onConfirmCallback, onCancelCallback) {
- confirmTitle = title || "";
- confirmMessage = message || "";
- confirmButtonText = "Confirm";
- cancelButtonText = "Cancel";
- confirmButtonColor = Theme.primary;
- onConfirm = onConfirmCallback || (() => {});
- onCancel = onCancelCallback || (() => {});
- selectedButton = -1;
- keyboardNavigation = false;
- open();
- }
-
- function showWithOptions(options) {
- confirmTitle = options.title || "";
- confirmMessage = options.message || "";
- confirmButtonText = options.confirmText || "Confirm";
- cancelButtonText = options.cancelText || "Cancel";
- confirmButtonColor = options.confirmColor || Theme.primary;
- onConfirm = options.onConfirm || (() => {});
- onCancel = options.onCancel || (() => {});
- selectedButton = -1;
- keyboardNavigation = false;
- open();
- }
-
- function selectButton() {
- close();
- if (selectedButton === 0) {
- if (onCancel) {
- onCancel();
- }
- } else {
- if (onConfirm) {
- onConfirm();
- }
- }
- }
-
- shouldBeVisible: false
- allowStacking: true
- modalWidth: 350
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 160
- enableShadow: true
- shouldHaveFocus: true
- onBackgroundClicked: {
- close();
- if (onCancel) {
- onCancel();
- }
- }
- onOpened: {
- Qt.callLater(function () {
- modalFocusScope.forceActiveFocus();
- modalFocusScope.focus = true;
- shouldHaveFocus = true;
- });
- }
- modalFocusScope.Keys.onPressed: function (event) {
- switch (event.key) {
- case Qt.Key_Escape:
- close();
- if (onCancel) {
- onCancel();
- }
- event.accepted = true;
- break;
- case Qt.Key_Left:
- case Qt.Key_Up:
- keyboardNavigation = true;
- selectedButton = 0;
- event.accepted = true;
- break;
- case Qt.Key_Right:
- case Qt.Key_Down:
- keyboardNavigation = true;
- selectedButton = 1;
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = (selectedButton + 1) % 2;
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = selectedButton === -1 ? 1 : (selectedButton - 1 + 2) % 2;
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = 1;
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = 0;
- event.accepted = true;
- }
- break;
- case Qt.Key_H:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = 0;
- event.accepted = true;
- }
- break;
- case Qt.Key_L:
- if (event.modifiers & Qt.ControlModifier) {
- keyboardNavigation = true;
- selectedButton = 1;
- event.accepted = true;
- }
- break;
- case Qt.Key_Tab:
- keyboardNavigation = true;
- selectedButton = selectedButton === -1 ? 0 : (selectedButton + 1) % 2;
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (selectedButton !== -1) {
- selectButton();
- } else {
- selectedButton = 1;
- selectButton();
- }
- event.accepted = true;
- break;
- }
- }
-
- content: Component {
- Item {
- anchors.fill: parent
- implicitHeight: mainColumn.implicitHeight
-
- Column {
- id: mainColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.leftMargin: Theme.spacingL
- anchors.rightMargin: Theme.spacingL
- anchors.topMargin: Theme.spacingL
- spacing: 0
-
- StyledText {
- text: confirmTitle
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- }
-
- Item {
- width: 1
- height: Theme.spacingL
- }
-
- StyledText {
- text: confirmMessage
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
-
- Item {
- width: 1
- height: Theme.spacingL * 1.5
- }
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: 120
- height: 40
- radius: Theme.cornerRadius
- color: {
- if (keyboardNavigation && selectedButton === 0) {
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- } else if (cancelButton.containsMouse) {
- return Theme.surfacePressed;
- } else {
- return Theme.surfaceVariantAlpha;
- }
- }
- border.color: (keyboardNavigation && selectedButton === 0) ? Theme.primary : "transparent"
- border.width: (keyboardNavigation && selectedButton === 0) ? 1 : 0
-
- StyledText {
- text: cancelButtonText
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: cancelButton
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- selectedButton = 0;
- selectButton();
- }
- }
- }
-
- Rectangle {
- width: 120
- height: 40
- radius: Theme.cornerRadius
- color: {
- const baseColor = confirmButtonColor;
- if (keyboardNavigation && selectedButton === 1) {
- return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 1);
- } else if (confirmButton.containsMouse) {
- return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 0.9);
- } else {
- return baseColor;
- }
- }
- border.color: (keyboardNavigation && selectedButton === 1) ? "white" : "transparent"
- border.width: (keyboardNavigation && selectedButton === 1) ? 1 : 0
-
- StyledText {
- text: confirmButtonText
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.primaryText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: confirmButton
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- selectedButton = 1;
- selectButton();
- }
- }
- }
- }
-
- Item {
- width: 1
- height: Theme.spacingL
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml
deleted file mode 100644
index cafa133..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml
+++ /dev/null
@@ -1,496 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Wayland
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- property string layerNamespace: "dms:modal"
- property alias content: contentLoader.sourceComponent
- property alias contentLoader: contentLoader
- property Item directContent: null
- property real modalWidth: 400
- property real modalHeight: 300
- property var targetScreen
- readonly property var effectiveScreen: contentWindow.screen ?? targetScreen
- readonly property real screenWidth: effectiveScreen?.width ?? 1920
- readonly property real screenHeight: effectiveScreen?.height ?? 1080
- readonly property real dpr: effectiveScreen ? CompositorService.getScreenScale(effectiveScreen) : 1
- property bool showBackground: true
- property real backgroundOpacity: 0.5
- property string positioning: "center"
- property point customPosition: Qt.point(0, 0)
- property bool closeOnEscapeKey: true
- property bool closeOnBackgroundClick: true
- property string animationType: "scale"
- property int animationDuration: Theme.modalAnimationDuration
- property real animationScaleCollapsed: 0.96
- property real animationOffset: Theme.spacingL
- property list<real> animationEnterCurve: Theme.expressiveCurves.expressiveDefaultSpatial
- property list<real> animationExitCurve: Theme.expressiveCurves.emphasized
- property color backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- property color borderColor: Theme.outlineMedium
- property real borderWidth: 0
- property real cornerRadius: Theme.cornerRadius
- property bool enableShadow: true
- property alias modalFocusScope: focusScope
- property bool shouldBeVisible: false
- property bool shouldHaveFocus: shouldBeVisible
- property bool allowFocusOverride: false
- property bool allowStacking: false
- property bool keepContentLoaded: false
- property bool keepPopoutsOpen: false
- property var customKeyboardFocus: null
- property bool useOverlayLayer: false
- readonly property alias contentWindow: contentWindow
- readonly property alias clickCatcher: clickCatcher
- readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab
- readonly property bool useBackground: showBackground && SettingsData.modalDarkenBackground
- readonly property bool useSingleWindow: CompositorService.isHyprland || useBackground
-
- signal opened
- signal dialogClosed
- signal backgroundClicked
-
- property bool animationsEnabled: true
-
- function open() {
- closeTimer.stop();
- const focusedScreen = CompositorService.getFocusedScreen();
- const screenChanged = focusedScreen && contentWindow.screen !== focusedScreen;
- if (focusedScreen) {
- if (screenChanged)
- contentWindow.visible = false;
- contentWindow.screen = focusedScreen;
- if (!useSingleWindow) {
- if (screenChanged)
- clickCatcher.visible = false;
- clickCatcher.screen = focusedScreen;
- }
- }
- if (screenChanged) {
- Qt.callLater(() => root._finishOpen());
- } else {
- _finishOpen();
- }
- }
-
- function _finishOpen() {
- ModalManager.openModal(root);
- shouldBeVisible = true;
- if (!useSingleWindow)
- clickCatcher.visible = true;
- contentWindow.visible = true;
- shouldHaveFocus = false;
- Qt.callLater(() => shouldHaveFocus = Qt.binding(() => shouldBeVisible));
- }
-
- function close() {
- shouldBeVisible = false;
- shouldHaveFocus = false;
- ModalManager.closeModal(root);
- closeTimer.restart();
- }
-
- function instantClose() {
- animationsEnabled = false;
- shouldBeVisible = false;
- shouldHaveFocus = false;
- ModalManager.closeModal(root);
- closeTimer.stop();
- contentWindow.visible = false;
- if (!useSingleWindow)
- clickCatcher.visible = false;
- dialogClosed();
- Qt.callLater(() => animationsEnabled = true);
- }
-
- function toggle() {
- shouldBeVisible ? close() : open();
- }
-
- Connections {
- target: ModalManager
- function onCloseAllModalsExcept(excludedModal) {
- if (excludedModal !== root && !allowStacking && shouldBeVisible)
- close();
- }
- }
-
- Connections {
- target: Quickshell
- function onScreensChanged() {
- if (!contentWindow.screen)
- return;
- const currentScreenName = contentWindow.screen.name;
- let screenStillExists = false;
- for (let i = 0; i < Quickshell.screens.length; i++) {
- if (Quickshell.screens[i].name === currentScreenName) {
- screenStillExists = true;
- break;
- }
- }
- if (screenStillExists)
- return;
- const newScreen = CompositorService.getFocusedScreen();
- if (newScreen) {
- contentWindow.screen = newScreen;
- if (!useSingleWindow)
- clickCatcher.screen = newScreen;
- }
- }
- }
-
- Timer {
- id: closeTimer
- interval: animationDuration + 50
- onTriggered: {
- if (shouldBeVisible)
- return;
- contentWindow.visible = false;
- if (!useSingleWindow)
- clickCatcher.visible = false;
- dialogClosed();
- }
- }
-
- readonly property var shadowLevel: Theme.elevationLevel3
- readonly property real shadowFallbackOffset: 6
- readonly property real shadowRenderPadding: (root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled) ? Theme.elevationRenderPadding(shadowLevel, Theme.elevationLightDirection, shadowFallbackOffset, 8, 16) : 0
- readonly property real shadowMotionPadding: animationType === "slide" ? 30 : Math.max(0, animationOffset)
- readonly property real shadowBuffer: Theme.snap(shadowRenderPadding + shadowMotionPadding, dpr)
- readonly property real alignedWidth: Theme.px(modalWidth, dpr)
- readonly property real alignedHeight: Theme.px(modalHeight, dpr)
-
- readonly property real alignedX: Theme.snap((() => {
- switch (positioning) {
- case "center":
- return (screenWidth - alignedWidth) / 2;
- case "top-right":
- return Math.max(Theme.spacingL, screenWidth - alignedWidth - Theme.spacingL);
- case "custom":
- return customPosition.x;
- default:
- return 0;
- }
- })(), dpr)
-
- readonly property real alignedY: Theme.snap((() => {
- switch (positioning) {
- case "center":
- return (screenHeight - alignedHeight) / 2;
- case "top-right":
- return Theme.barHeight + Theme.spacingXS;
- case "custom":
- return customPosition.y;
- default:
- return 0;
- }
- })(), dpr)
-
- PanelWindow {
- id: clickCatcher
- visible: false
- color: "transparent"
-
- WlrLayershell.namespace: root.layerNamespace + ":clickcatcher"
- WlrLayershell.layer: WlrLayershell.Top
- WlrLayershell.exclusiveZone: -1
- WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
-
- anchors {
- top: true
- left: true
- right: true
- bottom: true
- }
-
- mask: Region {
- item: Rectangle {
- x: root.alignedX
- y: root.alignedY
- width: root.alignedWidth
- height: root.alignedHeight
- }
- intersection: Intersection.Xor
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: root.closeOnBackgroundClick && root.shouldBeVisible
- onClicked: root.backgroundClicked()
- }
- }
-
- PanelWindow {
- id: contentWindow
- visible: false
- color: "transparent"
-
- WindowBlur {
- targetWindow: contentWindow
- readonly property real s: Math.min(1, modalContainer.scaleValue)
- blurX: modalContainer.x + modalContainer.width * (1 - s) * 0.5 + Theme.snap(modalContainer.animX, root.dpr)
- blurY: modalContainer.y + modalContainer.height * (1 - s) * 0.5 + Theme.snap(modalContainer.animY, root.dpr)
- blurWidth: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.width * s : 0
- blurHeight: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.height * s : 0
- blurRadius: root.cornerRadius
- }
-
- WlrLayershell.namespace: root.layerNamespace
- WlrLayershell.layer: {
- if (root.useOverlayLayer)
- return WlrLayershell.Overlay;
- switch (Quickshell.env("DMS_MODAL_LAYER")) {
- case "bottom":
- console.error("DankModal: 'bottom' layer is not valid for modals. Defaulting to 'top' layer.");
- return WlrLayershell.Top;
- case "background":
- console.error("DankModal: 'background' layer is not valid for modals. Defaulting to 'top' layer.");
- return WlrLayershell.Top;
- case "overlay":
- return WlrLayershell.Overlay;
- default:
- return WlrLayershell.Top;
- }
- }
- WlrLayershell.exclusiveZone: -1
- WlrLayershell.keyboardFocus: {
- if (customKeyboardFocus !== null)
- return customKeyboardFocus;
- if (!shouldHaveFocus)
- return WlrKeyboardFocus.None;
- if (root.useHyprlandFocusGrab)
- return WlrKeyboardFocus.OnDemand;
- return WlrKeyboardFocus.Exclusive;
- }
-
- anchors {
- left: true
- top: true
- right: root.useSingleWindow
- bottom: root.useSingleWindow
- }
-
- WlrLayershell.margins {
- left: root.useSingleWindow ? 0 : Math.max(0, Theme.snap(root.alignedX - shadowBuffer, dpr))
- top: root.useSingleWindow ? 0 : Math.max(0, Theme.snap(root.alignedY - shadowBuffer, dpr))
- right: 0
- bottom: 0
- }
-
- implicitWidth: root.useSingleWindow ? 0 : root.alignedWidth + (shadowBuffer * 2)
- implicitHeight: root.useSingleWindow ? 0 : root.alignedHeight + (shadowBuffer * 2)
-
- onVisibleChanged: {
- if (visible) {
- opened();
- } else {
- if (Qt.inputMethod) {
- Qt.inputMethod.hide();
- Qt.inputMethod.reset();
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: root.useSingleWindow && root.closeOnBackgroundClick && root.shouldBeVisible
- z: -2
- onClicked: root.backgroundClicked()
- }
-
- Rectangle {
- anchors.fill: parent
- z: -1
- color: "black"
- opacity: root.useBackground ? (root.shouldBeVisible ? root.backgroundOpacity : 0) : 0
- visible: root.useBackground
-
- Behavior on opacity {
- enabled: root.animationsEnabled
- DankAnim {
- duration: root.animationDuration
- easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
- }
- }
- }
-
- Item {
- id: modalContainer
- x: root.useSingleWindow ? root.alignedX : shadowBuffer
- y: root.useSingleWindow ? root.alignedY : shadowBuffer
-
- width: root.alignedWidth
- height: root.alignedHeight
-
- MouseArea {
- anchors.fill: parent
- enabled: root.useSingleWindow && root.shouldBeVisible
- hoverEnabled: false
- acceptedButtons: Qt.AllButtons
- onPressed: mouse.accepted = true
- onClicked: mouse.accepted = true
- z: -1
- }
-
- readonly property bool slide: root.animationType === "slide"
- readonly property real offsetX: slide ? 15 : 0
- readonly property real offsetY: slide ? -30 : root.animationOffset
-
- property real animX: 0
- property real animY: 0
- property real scaleValue: root.animationScaleCollapsed
-
- onOffsetXChanged: animX = Theme.snap(root.shouldBeVisible ? 0 : offsetX, root.dpr)
- onOffsetYChanged: animY = Theme.snap(root.shouldBeVisible ? 0 : offsetY, root.dpr)
-
- Connections {
- target: root
- function onShouldBeVisibleChanged() {
- modalContainer.animX = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetX, root.dpr);
- modalContainer.animY = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetY, root.dpr);
- modalContainer.scaleValue = root.shouldBeVisible ? 1.0 : root.animationScaleCollapsed;
- }
- }
-
- Behavior on animX {
- enabled: root.animationsEnabled
- DankAnim {
- duration: root.animationDuration
- easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
- }
- }
-
- Behavior on animY {
- enabled: root.animationsEnabled
- DankAnim {
- duration: root.animationDuration
- easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
- }
- }
-
- Behavior on scaleValue {
- enabled: root.animationsEnabled
- DankAnim {
- duration: root.animationDuration
- easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
- }
- }
-
- Item {
- id: contentContainer
- anchors.centerIn: parent
- width: parent.width
- height: parent.height
- clip: false
-
- Item {
- id: animatedContent
- anchors.fill: parent
- clip: false
- opacity: root.shouldBeVisible ? 1 : 0
- scale: modalContainer.scaleValue
- x: Theme.snap(modalContainer.animX, root.dpr) + (parent.width - width) * (1 - modalContainer.scaleValue) * 0.5
- y: Theme.snap(modalContainer.animY, root.dpr) + (parent.height - height) * (1 - modalContainer.scaleValue) * 0.5
-
- Behavior on opacity {
- enabled: root.animationsEnabled
- NumberAnimation {
- duration: animationDuration
- easing.type: Easing.BezierSpline
- easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
- }
- }
-
- ElevationShadow {
- id: modalShadowLayer
- anchors.fill: parent
- level: root.shadowLevel
- fallbackOffset: root.shadowFallbackOffset
- targetRadius: root.cornerRadius
- targetColor: root.backgroundColor
- borderColor: root.borderColor
- borderWidth: root.borderWidth
- shadowEnabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
- }
-
- Rectangle {
- anchors.fill: parent
- radius: root.cornerRadius
- color: "transparent"
- border.color: BlurService.borderColor
- border.width: BlurService.borderWidth
- z: 100
- }
-
- FocusScope {
- anchors.fill: parent
- focus: root.shouldBeVisible
- clip: false
-
- Item {
- id: directContentWrapper
- anchors.fill: parent
- visible: root.directContent !== null
- focus: true
- clip: false
-
- Component.onCompleted: {
- if (root.directContent) {
- root.directContent.parent = directContentWrapper;
- root.directContent.anchors.fill = directContentWrapper;
- Qt.callLater(() => root.directContent.forceActiveFocus());
- }
- }
-
- Connections {
- target: root
- function onDirectContentChanged() {
- if (root.directContent) {
- root.directContent.parent = directContentWrapper;
- root.directContent.anchors.fill = directContentWrapper;
- Qt.callLater(() => root.directContent.forceActiveFocus());
- }
- }
- }
- }
-
- Loader {
- id: contentLoader
- anchors.fill: parent
- active: root.directContent === null && (root.keepContentLoaded || root.shouldBeVisible || contentWindow.visible)
- asynchronous: false
- focus: true
- clip: false
- visible: root.directContent === null
-
- onLoaded: {
- if (item) {
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
- }
- }
- }
- }
- }
-
- FocusScope {
- id: focusScope
- objectName: "modalFocusScope"
- anchors.fill: parent
- visible: root.shouldBeVisible || contentWindow.visible
- focus: root.shouldBeVisible
- Keys.onEscapePressed: event => {
- if (root.closeOnEscapeKey && shouldHaveFocus) {
- root.close();
- event.accepted = true;
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml
deleted file mode 100644
index c65f3e0..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml
+++ /dev/null
@@ -1,312 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modals.Common
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:input-modal"
- keepPopoutsOpen: true
-
- property string inputTitle: ""
- property string inputMessage: ""
- property string inputPlaceholder: ""
- property string inputText: ""
- property string confirmButtonText: "Confirm"
- property string cancelButtonText: "Cancel"
- property color confirmButtonColor: Theme.primary
- property var onConfirm: function (text) {}
- property var onCancel: function () {}
- property int selectedButton: -1
- property bool keyboardNavigation: false
-
- function show(title, message, onConfirmCallback, onCancelCallback) {
- inputTitle = title || "";
- inputMessage = message || "";
- inputPlaceholder = "";
- inputText = "";
- confirmButtonText = "Confirm";
- cancelButtonText = "Cancel";
- confirmButtonColor = Theme.primary;
- onConfirm = onConfirmCallback || ((text) => {});
- onCancel = onCancelCallback || (() => {});
- selectedButton = -1;
- keyboardNavigation = false;
- open();
- }
-
- function showWithOptions(options) {
- inputTitle = options.title || "";
- inputMessage = options.message || "";
- inputPlaceholder = options.placeholder || "";
- inputText = options.initialText || "";
- confirmButtonText = options.confirmText || "Confirm";
- cancelButtonText = options.cancelText || "Cancel";
- confirmButtonColor = options.confirmColor || Theme.primary;
- onConfirm = options.onConfirm || ((text) => {});
- onCancel = options.onCancel || (() => {});
- selectedButton = -1;
- keyboardNavigation = false;
- open();
- }
-
- function confirmAndClose() {
- const text = inputText;
- close();
- if (onConfirm) {
- onConfirm(text);
- }
- }
-
- function cancelAndClose() {
- close();
- if (onCancel) {
- onCancel();
- }
- }
-
- function selectButton() {
- if (selectedButton === 0) {
- cancelAndClose();
- } else {
- confirmAndClose();
- }
- }
-
- shouldBeVisible: false
- allowStacking: true
- modalWidth: 350
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 200
- enableShadow: true
- shouldHaveFocus: true
- onBackgroundClicked: cancelAndClose()
- onOpened: {
- Qt.callLater(function () {
- if (contentLoader.item && contentLoader.item.textInputRef) {
- contentLoader.item.textInputRef.forceActiveFocus();
- }
- });
- }
-
- content: Component {
- FocusScope {
- anchors.fill: parent
- implicitHeight: mainColumn.implicitHeight
- focus: true
-
- property alias textInputRef: textInput
-
- Keys.onPressed: function (event) {
- const textFieldFocused = textInput.activeFocus;
-
- switch (event.key) {
- case Qt.Key_Escape:
- root.cancelAndClose();
- event.accepted = true;
- break;
- case Qt.Key_Tab:
- if (textFieldFocused) {
- root.keyboardNavigation = true;
- root.selectedButton = 0;
- textInput.focus = false;
- } else {
- root.keyboardNavigation = true;
- if (root.selectedButton === -1) {
- root.selectedButton = 0;
- } else if (root.selectedButton === 0) {
- root.selectedButton = 1;
- } else {
- root.selectedButton = -1;
- textInput.forceActiveFocus();
- }
- }
- event.accepted = true;
- break;
- case Qt.Key_Left:
- if (!textFieldFocused) {
- root.keyboardNavigation = true;
- root.selectedButton = 0;
- event.accepted = true;
- }
- break;
- case Qt.Key_Right:
- if (!textFieldFocused) {
- root.keyboardNavigation = true;
- root.selectedButton = 1;
- event.accepted = true;
- }
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (root.selectedButton !== -1) {
- root.selectButton();
- } else {
- root.confirmAndClose();
- }
- event.accepted = true;
- break;
- }
- }
-
- Column {
- id: mainColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.leftMargin: Theme.spacingL
- anchors.rightMargin: Theme.spacingL
- anchors.topMargin: Theme.spacingL
- spacing: 0
-
- StyledText {
- text: root.inputTitle
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- }
-
- Item {
- width: 1
- height: Theme.spacingL
- }
-
- StyledText {
- text: root.inputMessage
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- visible: root.inputMessage !== ""
- }
-
- Item {
- width: 1
- height: root.inputMessage !== "" ? Theme.spacingL : 0
- visible: root.inputMessage !== ""
- }
-
- Rectangle {
- width: parent.width
- height: 40
- radius: Theme.cornerRadius
- color: Theme.surfaceVariantAlpha
- border.color: textInput.activeFocus ? Theme.primary : "transparent"
- border.width: textInput.activeFocus ? 1 : 0
-
- TextInput {
- id: textInput
-
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- verticalAlignment: TextInput.AlignVCenter
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- selectionColor: Theme.primary
- selectedTextColor: Theme.primaryText
- clip: true
- text: root.inputText
- onTextChanged: root.inputText = text
-
- StyledText {
- anchors.fill: parent
- verticalAlignment: Text.AlignVCenter
- font.pixelSize: Theme.fontSizeMedium
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4)
- text: root.inputPlaceholder
- visible: textInput.text === "" && !textInput.activeFocus
- }
- }
- }
-
- Item {
- width: 1
- height: Theme.spacingL * 1.5
- }
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: 120
- height: 40
- radius: Theme.cornerRadius
- color: {
- if (root.keyboardNavigation && root.selectedButton === 0) {
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- } else if (cancelButton.containsMouse) {
- return Theme.surfacePressed;
- } else {
- return Theme.surfaceVariantAlpha;
- }
- }
- border.color: (root.keyboardNavigation && root.selectedButton === 0) ? Theme.primary : "transparent"
- border.width: (root.keyboardNavigation && root.selectedButton === 0) ? 1 : 0
-
- StyledText {
- text: root.cancelButtonText
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: cancelButton
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.cancelAndClose()
- }
- }
-
- Rectangle {
- width: 120
- height: 40
- radius: Theme.cornerRadius
- color: {
- const baseColor = root.confirmButtonColor;
- if (root.keyboardNavigation && root.selectedButton === 1) {
- return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 1);
- } else if (confirmButton.containsMouse) {
- return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 0.9);
- } else {
- return baseColor;
- }
- }
- border.color: (root.keyboardNavigation && root.selectedButton === 1) ? "white" : "transparent"
- border.width: (root.keyboardNavigation && root.selectedButton === 1) ? 1 : 0
-
- StyledText {
- text: root.confirmButtonText
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.primaryText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: confirmButton
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.confirmAndClose()
- }
- }
- }
-
- Item {
- width: 1
- height: Theme.spacingL
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml
deleted file mode 100644
index 8a33878..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml
+++ /dev/null
@@ -1,771 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Hyprland
-import Quickshell.Io
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:color-picker"
-
- HyprlandFocusGrab {
- windows: [root.contentWindow]
- active: root.useHyprlandFocusGrab && root.shouldHaveFocus
- }
-
- property string pickerTitle: I18n.tr("Choose Color")
- property color selectedColor: SessionData.recentColors.length > 0 ? SessionData.recentColors[0] : Theme.primary
- property var onColorSelectedCallback: null
-
- signal colorSelected(color selectedColor)
-
- property color currentColor: Theme.primary
- property real hue: 0
- property real saturation: 1
- property real value: 1
- property real alpha: 1
- property real gradientX: 0
- property real gradientY: 0
-
- readonly property var standardColors: ["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#d32f2f", "#c2185b", "#7b1fa2", "#512da8", "#303f9f", "#1976d2", "#0288d1", "#0097a7", "#00796b", "#388e3c", "#689f38", "#afb42b", "#fbc02d", "#ffa000", "#f57c00", "#e64a19", "#c62828", "#ad1457", "#6a1b9a", "#4527a0", "#283593", "#1565c0", "#0277bd", "#00838f", "#00695c", "#2e7d32", "#558b2f", "#9e9d24", "#f9a825", "#ff8f00", "#ef6c00", "#d84315", "#ffffff", "#9e9e9e", "#212121"]
-
- function show() {
- currentColor = selectedColor;
- updateFromColor(currentColor);
- open();
- }
-
- function hide() {
- onColorSelectedCallback = null;
- close();
- }
-
- function hideInstant() {
- instantClose();
- }
-
- function toggle() {
- if (shouldBeVisible) {
- hide();
- } else {
- show();
- }
- }
-
- function toggleInstant() {
- if (shouldBeVisible) {
- hideInstant();
- } else {
- show();
- }
- }
-
- onColorSelected: color => {
- if (onColorSelectedCallback) {
- onColorSelectedCallback(color);
- }
- }
-
- function copyColorToClipboard(colorValue) {
- Quickshell.execDetached(["dms", "cl", "copy", colorValue]);
- ToastService.showInfo(`Color ${colorValue} copied`);
- SessionData.addRecentColor(currentColor);
- }
-
- function updateFromColor(color) {
- hue = color.hsvHue;
- saturation = color.hsvSaturation;
- value = color.hsvValue;
- alpha = color.a;
- gradientX = saturation;
- gradientY = 1 - value;
- }
-
- function updateColor() {
- currentColor = Qt.hsva(hue, saturation, value, alpha);
- }
-
- function updateColorFromGradient(x, y) {
- saturation = Math.max(0, Math.min(1, x));
- value = Math.max(0, Math.min(1, 1 - y));
- updateColor();
- selectedColor = currentColor;
- }
-
- function applyPickedColor(colorStr) {
- if (colorStr.length < 7 || !colorStr.startsWith('#'))
- return;
- const pickedColor = Qt.color(colorStr);
- root.selectedColor = pickedColor;
- root.currentColor = pickedColor;
- root.updateFromColor(pickedColor);
- copyColorToClipboard(colorStr);
- root.show();
- }
-
- function pickColorFromScreen() {
- hideInstant();
- Proc.runCommand("dms-color-pick", ["dms", "color", "pick", "--json"], (output, exitCode) => {
- if (exitCode !== 0) {
- console.warn("dms color pick exited with code:", exitCode);
- root.show();
- return;
- }
- try {
- const result = JSON.parse(output);
- if (result.hex) {
- applyPickedColor(result.hex);
- } else {
- console.warn("Failed to parse dms color pick output: missing hex");
- root.show();
- }
- } catch (e) {
- console.warn("Failed to parse dms color pick JSON:", e);
- root.show();
- }
- }, 0, Proc.noTimeout);
- }
-
- modalWidth: 680
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 680
- backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- cornerRadius: Theme.cornerRadius
- borderColor: Theme.outlineMedium
- borderWidth: 1
- keepContentLoaded: true
- allowStacking: true
-
- onBackgroundClicked: hide()
-
- IpcHandler {
- function open(): string {
- root.show();
- return "COLOR_PICKER_MODAL_OPEN_SUCCESS";
- }
-
- function openColor(color: string): string {
- root.selectedColor = Qt.color(color);
- root.currentColor = Qt.color(color);
- root.updateFromColor(Qt.color(color));
- return open();
- }
-
- function close(): string {
- root.hide();
- return "COLOR_PICKER_MODAL_CLOSE_SUCCESS";
- }
-
- function closeInstant(): string {
- root.hideInstant();
- return "COLOR_PICKER_MODAL_CLOSE_INSTANT_SUCCESS";
- }
-
- function toggle(): string {
- root.toggle();
- return "COLOR_PICKER_MODAL_TOGGLE_SUCCESS";
- }
-
- function toggleInstant(): string {
- root.toggleInstant();
- return "COLOR_PICKER_MODAL_TOGGLE_INSTANT_SUCCESS";
- }
-
- target: "color-picker"
- }
-
- content: Component {
- FocusScope {
- id: colorContent
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property alias hexInput: hexInput
-
- anchors.fill: parent
- implicitHeight: mainColumn.implicitHeight
- focus: true
-
- Keys.onEscapePressed: event => {
- root.hide();
- event.accepted = true;
- }
-
- Column {
- id: mainColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingM
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- Column {
- width: parent.width - 90
- spacing: Theme.spacingXS
-
- StyledText {
- text: root.pickerTitle
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- StyledText {
- text: I18n.tr("Select a color from the palette or use custom sliders")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- anchors.left: parent.left
- }
- }
-
- DankActionButton {
- iconName: "colorize"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: () => {
- root.pickColorFromScreen();
- }
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: () => {
- root.hide();
- }
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- Rectangle {
- id: gradientPicker
- width: parent.width - 70
- height: 280
- radius: Theme.cornerRadius
- border.color: Theme.outlineStrong
- border.width: 1
- clip: true
-
- Rectangle {
- anchors.fill: parent
- color: Qt.hsva(root.hue, 1, 1, 1)
-
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- orientation: Gradient.Horizontal
- GradientStop {
- position: 0.0
- color: "#ffffff"
- }
- GradientStop {
- position: 1.0
- color: "transparent"
- }
- }
- }
-
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- orientation: Gradient.Vertical
- GradientStop {
- position: 0.0
- color: "transparent"
- }
- GradientStop {
- position: 1.0
- color: "#000000"
- }
- }
- }
- }
-
- Rectangle {
- id: pickerCircle
- width: 16
- height: 16
- radius: 8
- border.color: "white"
- border.width: 2
- color: "transparent"
- x: root.gradientX * parent.width - width / 2
- y: root.gradientY * parent.height - height / 2
-
- Rectangle {
- anchors.centerIn: parent
- width: parent.width - 4
- height: parent.height - 4
- radius: width / 2
- border.color: "black"
- border.width: 1
- color: "transparent"
- }
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.CrossCursor
- onPressed: mouse => {
- const x = Math.max(0, Math.min(1, mouse.x / width));
- const y = Math.max(0, Math.min(1, mouse.y / height));
- root.gradientX = x;
- root.gradientY = y;
- root.updateColorFromGradient(x, y);
- }
- onPositionChanged: mouse => {
- if (pressed) {
- const x = Math.max(0, Math.min(1, mouse.x / width));
- const y = Math.max(0, Math.min(1, mouse.y / height));
- root.gradientX = x;
- root.gradientY = y;
- root.updateColorFromGradient(x, y);
- }
- }
- }
- }
-
- Rectangle {
- id: hueSlider
- width: 50
- height: 280
- radius: Theme.cornerRadius
- border.color: Theme.outlineStrong
- border.width: 1
-
- gradient: Gradient {
- orientation: Gradient.Vertical
- GradientStop {
- position: 0.00
- color: "#ff0000"
- }
- GradientStop {
- position: 0.17
- color: "#ffff00"
- }
- GradientStop {
- position: 0.33
- color: "#00ff00"
- }
- GradientStop {
- position: 0.50
- color: "#00ffff"
- }
- GradientStop {
- position: 0.67
- color: "#0000ff"
- }
- GradientStop {
- position: 0.83
- color: "#ff00ff"
- }
- GradientStop {
- position: 1.00
- color: "#ff0000"
- }
- }
-
- Rectangle {
- id: hueIndicator
- width: parent.width
- height: 4
- color: "white"
- border.color: "black"
- border.width: 1
- y: root.hue * parent.height - height / 2
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.SizeVerCursor
- onPressed: mouse => {
- const h = Math.max(0, Math.min(1, mouse.y / height));
- root.hue = h;
- root.updateColor();
- root.selectedColor = root.currentColor;
- }
- onPositionChanged: mouse => {
- if (pressed) {
- const h = Math.max(0, Math.min(1, mouse.y / height));
- root.hue = h;
- root.updateColor();
- root.selectedColor = root.currentColor;
- }
- }
- }
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- StyledText {
- text: I18n.tr("Material Colors")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- GridView {
- width: parent.width
- height: 140
- cellWidth: 38
- cellHeight: 38
- clip: true
- interactive: false
- model: root.standardColors
-
- delegate: Rectangle {
- width: 36
- height: 36
- color: modelData
- radius: 4
- border.color: Theme.outlineStrong
- border.width: 1
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: () => {
- const pickedColor = Qt.color(modelData);
- root.selectedColor = pickedColor;
- root.currentColor = pickedColor;
- root.updateFromColor(pickedColor);
- }
- }
- }
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- Column {
- width: 210
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Recent Colors")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingXS
-
- Repeater {
- model: 5
-
- Rectangle {
- width: 36
- height: 36
- radius: 4
- border.color: Theme.outlineStrong
- border.width: 1
-
- color: {
- if (index < SessionData.recentColors.length) {
- return SessionData.recentColors[index];
- }
- return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
- }
-
- opacity: index < SessionData.recentColors.length ? 1.0 : 0.3
-
- MouseArea {
- anchors.fill: parent
- cursorShape: index < SessionData.recentColors.length ? Qt.PointingHandCursor : Qt.ArrowCursor
- enabled: index < SessionData.recentColors.length
- onClicked: () => {
- if (index < SessionData.recentColors.length) {
- const pickedColor = SessionData.recentColors[index];
- root.selectedColor = pickedColor;
- root.currentColor = pickedColor;
- root.updateFromColor(pickedColor);
- }
- }
- }
- }
- }
- }
- }
-
- Column {
- width: parent.width - 330
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Opacity")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- DankSlider {
- width: parent.width
- value: Math.round(root.alpha * 100)
- minimum: 0
- maximum: 100
- showValue: false
- onSliderValueChanged: newValue => {
- root.alpha = newValue / 100;
- root.updateColor();
- root.selectedColor = root.currentColor;
- }
- }
- }
-
- Rectangle {
- width: 100
- height: 50
- radius: Theme.cornerRadius
- color: root.currentColor
- border.color: Theme.outlineStrong
- border.width: 2
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- Column {
- width: (parent.width - Theme.spacingM * 2) / 3
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Hex")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingXS
-
- DankTextField {
- id: hexInput
- width: parent.width - 36
- height: 36
- text: root.currentColor.toString()
- font.pixelSize: Theme.fontSizeMedium
- textColor: {
- if (text.length === 0)
- return Theme.surfaceText;
- const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/;
- return hexPattern.test(text) ? Theme.surfaceText : Theme.error;
- }
- placeholderText: "#000000"
- backgroundColor: Theme.surfaceHover
- borderWidth: 1
- focusedBorderWidth: 2
- topPadding: Theme.spacingS
- bottomPadding: Theme.spacingS
- onAccepted: () => {
- const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/;
- if (!hexPattern.test(text))
- return;
- const color = Qt.color(text);
- if (color) {
- root.selectedColor = color;
- root.currentColor = color;
- root.updateFromColor(color);
- }
- }
- }
-
- DankActionButton {
- iconName: "content_copy"
- iconSize: Theme.iconSize - 6
- iconColor: Theme.surfaceText
- buttonSize: 36
- anchors.verticalCenter: parent.verticalCenter
- onClicked: () => {
- root.copyColorToClipboard(hexInput.text);
- }
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM * 2) / 3
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("RGB")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingXS
-
- Rectangle {
- width: parent.width - 36
- height: 36
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: Theme.outline
- border.width: 1
-
- StyledText {
- anchors.centerIn: parent
- text: {
- const r = Math.round(root.currentColor.r * 255);
- const g = Math.round(root.currentColor.g * 255);
- const b = Math.round(root.currentColor.b * 255);
- if (root.alpha < 1) {
- const a = Math.round(root.alpha * 255);
- return `${r}, ${g}, ${b}, ${a}`;
- }
- return `${r}, ${g}, ${b}`;
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- }
- }
-
- DankActionButton {
- iconName: "content_copy"
- iconSize: Theme.iconSize - 6
- iconColor: Theme.surfaceText
- buttonSize: 36
- anchors.verticalCenter: parent.verticalCenter
- onClicked: () => {
- const r = Math.round(root.currentColor.r * 255);
- const g = Math.round(root.currentColor.g * 255);
- const b = Math.round(root.currentColor.b * 255);
- let rgbString;
- if (root.alpha < 1) {
- const a = Math.round(root.alpha * 255);
- rgbString = `rgba(${r}, ${g}, ${b}, ${a})`;
- } else {
- rgbString = `rgb(${r}, ${g}, ${b})`;
- }
- Quickshell.execDetached(["dms", "cl", "copy", rgbString]);
- ToastService.showInfo(`${rgbString} copied`);
- }
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM * 2) / 3
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("HSV")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- anchors.left: parent.left
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingXS
-
- Rectangle {
- width: parent.width - 36
- height: 36
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: Theme.outline
- border.width: 1
-
- StyledText {
- anchors.centerIn: parent
- text: {
- const h = Math.round(root.hue * 360);
- const s = Math.round(root.saturation * 100);
- const v = Math.round(root.value * 100);
- if (root.alpha < 1) {
- const a = Math.round(root.alpha * 100);
- return `${h}°, ${s}%, ${v}%, ${a}%`;
- }
- return `${h}°, ${s}%, ${v}%`;
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- }
- }
-
- DankActionButton {
- iconName: "content_copy"
- iconSize: Theme.iconSize - 6
- iconColor: Theme.surfaceText
- buttonSize: 36
- anchors.verticalCenter: parent.verticalCenter
- onClicked: () => {
- const h = Math.round(root.hue * 360);
- const s = Math.round(root.saturation * 100);
- const v = Math.round(root.value * 100);
- let hsvString;
- if (root.alpha < 1) {
- const a = Math.round(root.alpha * 100);
- hsvString = `${h}, ${s}, ${v}, ${a}`;
- } else {
- hsvString = `${h}, ${s}, ${v}`;
- }
- Quickshell.execDetached(["dms", "cl", "copy", hsvString]);
- ToastService.showInfo(`HSV ${hsvString} copied`);
- }
- }
- }
- }
- }
-
- DankButton {
- visible: root.onColorSelectedCallback !== null && root.onColorSelectedCallback !== undefined
- width: 70
- buttonHeight: 36
- text: I18n.tr("Save")
- backgroundColor: Theme.primary
- textColor: Theme.background
- anchors.right: parent.right
- onClicked: {
- SessionData.addRecentColor(root.currentColor);
- root.colorSelected(root.currentColor);
- root.hide();
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml
deleted file mode 100644
index 31ada32..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml
+++ /dev/null
@@ -1,256 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var selectedItem: null
- property var controller: null
- property bool expanded: false
- property int selectedActionIndex: 0
-
- function getPluginContextMenuActions() {
- if (selectedItem?.type !== "plugin" || !selectedItem?.pluginId)
- return [];
- var instance = PluginService.pluginInstances[selectedItem.pluginId];
- if (!instance)
- return [];
- if (typeof instance.getContextMenuActions !== "function")
- return [];
- var actions = instance.getContextMenuActions(selectedItem.data);
- if (!Array.isArray(actions))
- return [];
- return actions;
- }
-
- readonly property var actions: {
- var result = [];
- if (selectedItem?.primaryAction) {
- result.push(selectedItem.primaryAction);
- }
-
- switch (selectedItem?.type) {
- case "plugin":
- var pluginActions = getPluginContextMenuActions();
- for (var i = 0; i < pluginActions.length; i++) {
- var act = pluginActions[i];
- result.push({
- name: act.text || act.name || "",
- icon: act.icon || "play_arrow",
- action: "plugin_action",
- pluginAction: act.action
- });
- }
- break;
- case "plugin_browse":
- if (selectedItem?.actions) {
- for (var i = 0; i < selectedItem.actions.length; i++) {
- result.push(selectedItem.actions[i]);
- }
- }
- break;
- case "app":
- if (selectedItem?.isCore)
- break;
- if (SessionService.nvidiaCommand) {
- result.push({
- name: I18n.tr("Launch on dGPU"),
- icon: "memory",
- action: "launch_dgpu"
- });
- }
- if (selectedItem?.actions) {
- for (var i = 0; i < selectedItem.actions.length; i++) {
- result.push(selectedItem.actions[i]);
- }
- }
- break;
- }
- return result;
- }
-
- readonly property bool hasActions: {
- switch (selectedItem?.type) {
- case "app":
- return !selectedItem?.isCore;
- case "plugin":
- return getPluginContextMenuActions().length > 0;
- case "plugin_browse":
- return selectedItem?.actions?.length > 0;
- default:
- return actions.length > 1;
- }
- }
-
- width: parent?.width ?? 200
- height: expanded && hasActions ? 52 : 0
- color: Theme.surfaceContainerHigh
- radius: Theme.cornerRadius
-
- clip: true
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Rectangle {
- anchors.top: parent.top
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- }
-
- Item {
- anchors.fill: parent
- anchors.margins: Theme.spacingS
-
- Flickable {
- id: actionsFlickable
- anchors.left: parent.left
- anchors.right: tabHint.left
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- height: parent.height
- contentWidth: actionsRow.width
- contentHeight: height
- clip: true
- boundsBehavior: Flickable.StopAtBounds
- flickableDirection: Flickable.HorizontalFlick
-
- Row {
- id: actionsRow
- height: parent.height
- spacing: Theme.spacingS
-
- Repeater {
- model: root.actions
-
- Rectangle {
- id: actionButton
-
- required property var modelData
- required property int index
-
- width: actionContent.implicitWidth + Theme.spacingM * 2
- height: actionsRow.height
- radius: Theme.cornerRadius
- color: index === root.selectedActionIndex ? Theme.primaryHover : actionArea.containsMouse ? Theme.surfaceHover : "transparent"
-
- Row {
- id: actionContent
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: actionButton.modelData?.icon ?? "play_arrow"
- size: 16
- color: actionButton.index === root.selectedActionIndex ? Theme.primary : Theme.surfaceText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: actionButton.modelData?.name ?? ""
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: actionButton.index === root.selectedActionIndex ? Theme.primary : Theme.surfaceText
- }
- }
-
- MouseArea {
- id: actionArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (root.controller && root.selectedItem) {
- root.controller.executeAction(root.selectedItem, actionButton.modelData);
- }
- }
- onEntered: root.selectedActionIndex = actionButton.index
- }
- }
- }
- }
- }
-
- StyledText {
- id: tabHint
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- visible: root.hasActions
- text: "Tab"
- font.pixelSize: Theme.fontSizeSmall - 2
- color: Theme.outlineButton
- }
- }
-
- function toggle() {
- expanded = !expanded;
- selectedActionIndex = 0;
- }
-
- function show() {
- expanded = true;
- selectedActionIndex = actions.length > 1 ? 1 : 0;
- }
-
- function hide() {
- expanded = false;
- selectedActionIndex = 0;
- }
-
- function cycleAction(reverse = false) {
- if (actions.length > 0) {
- if (! reverse)
- selectedActionIndex = (selectedActionIndex + 1) % actions.length;
- else
- selectedActionIndex = (selectedActionIndex - 1) % actions.length;
- ensureSelectedVisible();
- }
- }
-
- function ensureSelectedVisible() {
- if (selectedActionIndex < 0 || !actionsRow.children || selectedActionIndex >= actionsRow.children.length)
- return;
- var buttonX = 0;
- for (var i = 0; i < selectedActionIndex; i++) {
- var child = actionsRow.children[i];
- if (child)
- buttonX += child.width + actionsRow.spacing;
- }
-
- var button = actionsRow.children[selectedActionIndex];
- if (!button)
- return;
- var buttonRight = buttonX + button.width;
- var viewLeft = actionsFlickable.contentX;
- var viewRight = viewLeft + actionsFlickable.width;
-
- if (buttonX < viewLeft) {
- actionsFlickable.contentX = Math.max(0, buttonX - Theme.spacingS);
- } else if (buttonRight > viewRight) {
- actionsFlickable.contentX = Math.min(actionsFlickable.contentWidth - actionsFlickable.width, buttonRight - actionsFlickable.width + Theme.spacingS);
- }
- }
-
- function executeSelectedAction() {
- if (!controller || !selectedItem || selectedActionIndex >= actions.length)
- return;
- var action = actions[selectedActionIndex];
- if (action.action === "plugin_action" && typeof action.pluginAction === "function") {
- action.pluginAction();
- controller.performSearch();
- controller.itemExecuted();
- } else {
- controller.executeAction(selectedItem, action);
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml
deleted file mode 100644
index 67cb606..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml
+++ /dev/null
@@ -1,1894 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import qs.Common
-import qs.Services
-import "Scorer.js" as Scorer
-import "ControllerUtils.js" as Utils
-import "NavigationHelpers.js" as Nav
-import "ItemTransformers.js" as Transform
-
-Item {
- id: root
-
- property string searchQuery: ""
- property string searchMode: "all"
- property string previousSearchMode: "all"
- property bool autoSwitchedToFiles: false
- property bool isFileSearching: false
- property var sections: []
- property var flatModel: []
- property int selectedFlatIndex: 0
- property var selectedItem: null
- property bool isSearching: false
- property string activePluginId: ""
- property var collapsedSections: ({})
- property bool keyboardNavigationActive: false
- property bool active: false
- property var _modeSectionsCache: ({})
- property bool _queryDrivenSearch: false
- property bool _diskCacheConsumed: false
- property var sectionViewModes: ({})
- property var pluginViewPreferences: ({})
- property int gridColumns: SettingsData.appLauncherGridColumns
- property int viewModeVersion: 0
- property string viewModeContext: "spotlight"
-
- signal itemExecuted
- signal searchCompleted
- signal modeChanged(string mode)
- signal queryChanged(string query)
- signal viewModeChanged(string sectionId, string mode)
- signal searchQueryRequested(string query)
-
- onActiveChanged: {
- if (!active) {
- SessionData.addLauncherHistory(searchQuery);
-
- sections = [];
- flatModel = [];
- selectedItem = null;
- _clearModeCache();
- }
- }
-
- onSearchModeChanged: {
- if (searchMode === "apps") {
- _loadAppCategories();
- } else {
- appCategory = "";
- appCategories = [];
- }
- }
-
- Connections {
- target: SettingsData
- function onSortAppsAlphabeticallyChanged() {
- AppSearchService.invalidateLauncherCache();
- _clearModeCache();
- }
- }
-
- Connections {
- target: AppSearchService
- function onCacheVersionChanged() {
- if (!active)
- return;
- _clearModeCache();
- if (searchMode === "apps") {
- _loadAppCategories();
- performSearch();
- } else if (!searchQuery && searchMode === "all") {
- performSearch();
- }
- }
- }
-
- Connections {
- target: PluginService
- function onRequestLauncherUpdate(pluginId) {
- if (!active)
- return;
- if (activePluginId === pluginId) {
- if (activePluginCategories.length <= 1)
- loadPluginCategories(pluginId);
- performSearch();
- return;
- }
- if (searchQuery)
- performSearch();
- }
- }
-
- Process {
- id: wtypeProcess
- command: ["wtype", "-M", "ctrl", "-P", "v", "-p", "v", "-m", "ctrl"]
- running: false
- }
-
- Process {
- id: copyProcess
- running: false
- onExited: pasteTimer.start()
- }
-
- Timer {
- id: pasteTimer
- interval: 200
- repeat: false
- onTriggered: wtypeProcess.running = true
- }
-
- function pasteSelected() {
- if (!selectedItem)
- return;
- if (!SessionService.wtypeAvailable) {
- ToastService.showError("wtype not available - install wtype for paste support");
- return;
- }
-
- const pluginId = selectedItem.pluginId;
- if (!pluginId)
- return;
- const pasteArgs = AppSearchService.getPluginPasteArgs(pluginId, selectedItem.data);
- if (!pasteArgs)
- return;
- copyProcess.command = pasteArgs;
- copyProcess.running = true;
- itemExecuted();
- }
-
- readonly property var sectionDefinitions: [
- {
- id: "favorites",
- title: I18n.tr("Pinned"),
- icon: "push_pin",
- priority: 1,
- defaultViewMode: "list"
- },
- {
- id: "apps",
- title: I18n.tr("Applications"),
- icon: "apps",
- priority: 2,
- defaultViewMode: "list"
- },
- {
- id: "browse_plugins",
- title: I18n.tr("Browse"),
- icon: "category",
- priority: 2.5,
- defaultViewMode: "grid"
- },
- {
- id: "files",
- title: I18n.tr("Files"),
- icon: "folder",
- priority: 4,
- defaultViewMode: "list"
- },
- {
- id: "fallback",
- title: I18n.tr("Commands"),
- icon: "terminal",
- priority: 5,
- defaultViewMode: "list"
- }
- ]
-
- property int historyIndex: -1
- property string typingBackup: ""
-
- function navigateHistory(direction) {
- let history = SessionData.launcherQueryHistory;
- if (history.length === 0)
- return;
-
- if (historyIndex === -1)
- typingBackup = searchQuery;
-
- let nextIndex = historyIndex + (direction === "up" ? 1 : -1);
- if (nextIndex >= history.length)
- nextIndex = history.length - 1;
- if (nextIndex < -1)
- nextIndex = -1;
-
- if (nextIndex === historyIndex)
- return;
- historyIndex = nextIndex;
-
- let targetText = (historyIndex === -1) ? typingBackup : history[historyIndex];
-
- setSearchQuery(targetText);
- searchQueryRequested(targetText);
- }
-
- property string fileSearchType: "all"
- property string fileSearchExt: ""
- property string fileSearchFolder: ""
- property string fileSearchSort: "score"
-
- property string pluginFilter: ""
- property string activePluginName: ""
- property var activePluginCategories: []
- property string activePluginCategory: ""
- property string appCategory: ""
- property var appCategories: []
-
- function getSectionViewMode(sectionId) {
- if (sectionId === "browse_plugins")
- return "list";
- if (pluginViewPreferences[sectionId]?.enforced)
- return pluginViewPreferences[sectionId].mode;
- if (sectionViewModes[sectionId])
- return sectionViewModes[sectionId];
-
- var savedModes = viewModeContext === "appDrawer" ? (SettingsData.appDrawerSectionViewModes || {}) : (SettingsData.spotlightSectionViewModes || {});
- if (savedModes[sectionId])
- return savedModes[sectionId];
-
- for (var i = 0; i < sectionDefinitions.length; i++) {
- if (sectionDefinitions[i].id === sectionId)
- return sectionDefinitions[i].defaultViewMode || "list";
- }
-
- if (pluginViewPreferences[sectionId]?.mode)
- return pluginViewPreferences[sectionId].mode;
-
- return "list";
- }
-
- function setSectionViewMode(sectionId, mode) {
- if (sectionId === "browse_plugins")
- return;
- if (pluginViewPreferences[sectionId]?.enforced)
- return;
- sectionViewModes = Object.assign({}, sectionViewModes, {
- [sectionId]: mode
- });
- viewModeVersion++;
- if (viewModeContext === "appDrawer") {
- var savedModes = Object.assign({}, SettingsData.appDrawerSectionViewModes || {}, {
- [sectionId]: mode
- });
- SettingsData.appDrawerSectionViewModes = savedModes;
- } else {
- var savedModes = Object.assign({}, SettingsData.spotlightSectionViewModes || {}, {
- [sectionId]: mode
- });
- SettingsData.spotlightSectionViewModes = savedModes;
- }
- viewModeChanged(sectionId, mode);
- }
-
- function canChangeSectionViewMode(sectionId) {
- if (sectionId === "browse_plugins")
- return false;
- return !pluginViewPreferences[sectionId]?.enforced;
- }
-
- function canCollapseSection(sectionId) {
- return searchMode === "all";
- }
-
- function setPluginViewPreference(pluginId, mode, enforced) {
- var prefs = Object.assign({}, pluginViewPreferences);
- prefs[pluginId] = {
- mode: mode,
- enforced: enforced || false
- };
- pluginViewPreferences = prefs;
- }
-
- function applyActivePluginViewPreference(pluginId, isBuiltIn) {
- var sectionId = "plugin_" + pluginId;
- var pref = null;
- if (isBuiltIn) {
- var builtIn = AppSearchService.builtInPlugins[pluginId];
- if (builtIn && builtIn.viewMode) {
- pref = {
- mode: builtIn.viewMode,
- enforced: builtIn.viewModeEnforced === true
- };
- }
- } else {
- pref = PluginService.getPluginViewPreference(pluginId);
- }
-
- if (pref && pref.mode) {
- setPluginViewPreference(sectionId, pref.mode, pref.enforced);
- } else {
- var prefs = Object.assign({}, pluginViewPreferences);
- delete prefs[sectionId];
- pluginViewPreferences = prefs;
- }
- }
-
- function clearActivePluginViewPreference() {
- var prefs = {};
- for (var key in pluginViewPreferences) {
- if (!key.startsWith("plugin_")) {
- prefs[key] = pluginViewPreferences[key];
- }
- }
- pluginViewPreferences = prefs;
- }
-
- property int _searchVersion: 0
- property bool _pluginPhasePending: false
- property bool _pluginPhaseForceFirst: false
- property var _phase1Items: []
-
- Timer {
- id: searchDebounce
- interval: 60
- onTriggered: root.performSearch()
- }
-
- Timer {
- id: pluginPhaseTimer
- interval: 1
- onTriggered: root._performPluginPhase()
- }
-
- Timer {
- id: fileSearchDebounce
- interval: 200
- onTriggered: root.performFileSearch()
- }
-
- function getOrTransformApp(app) {
- return AppSearchService.getOrTransformApp(app, transformApp);
- }
-
- function setSearchQuery(query) {
- _searchVersion++;
- _queryDrivenSearch = true;
- _pluginPhasePending = false;
- _phase1Items = [];
- pluginPhaseTimer.stop();
- searchQuery = query;
- searchDebounce.restart();
-
- var filesInAll = searchMode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll);
- if (searchMode !== "plugins" && (searchMode === "files" || query.startsWith("/") || filesInAll) && query.length > 0) {
- fileSearchDebounce.restart();
- }
- }
-
- function setMode(mode, isAutoSwitch) {
- if (searchMode === mode)
- return;
- if (isAutoSwitch) {
- previousSearchMode = searchMode;
- autoSwitchedToFiles = true;
- } else {
- autoSwitchedToFiles = false;
- }
- searchMode = mode;
- modeChanged(mode);
- performSearch();
- var filesInAll = mode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll) && searchQuery.length > 0;
- if (mode === "files" || filesInAll) {
- fileSearchDebounce.restart();
- }
- }
-
- function restorePreviousMode() {
- if (!autoSwitchedToFiles)
- return;
- autoSwitchedToFiles = false;
- searchMode = previousSearchMode;
- modeChanged(previousSearchMode);
- performSearch();
- }
-
- function cycleMode(reverse = false) {
- var modes = ["all", "apps", "files", "plugins"];
- var currentIndex = modes.indexOf(searchMode);
- if (!reverse)
- var nextIndex = (currentIndex + 1) % modes.length;
- else
- var nextIndex = (currentIndex - 1 + modes.length) % modes.length;
- setMode(modes[nextIndex]);
- }
-
- function reset() {
- searchQuery = "";
- searchMode = "all";
- previousSearchMode = "all";
- autoSwitchedToFiles = false;
- isFileSearching = false;
- fileSearchType = "all";
- fileSearchExt = "";
- fileSearchFolder = "";
- fileSearchSort = "score";
- sections = [];
- flatModel = [];
- selectedFlatIndex = 0;
- selectedItem = null;
- isSearching = false;
- activePluginId = "";
- activePluginName = "";
- activePluginCategories = [];
- activePluginCategory = "";
- appCategory = "";
- appCategories = [];
- pluginFilter = "";
- collapsedSections = {};
- _clearModeCache();
- _queryDrivenSearch = false;
- _pluginPhasePending = false;
- _pluginPhaseForceFirst = false;
- _phase1Items = [];
- pluginPhaseTimer.stop();
- }
-
- function loadPluginCategories(pluginId) {
- if (!pluginId) {
- if (activePluginCategories.length > 0) {
- activePluginCategories = [];
- activePluginCategory = "";
- }
- return;
- }
-
- const categories = AppSearchService.getPluginLauncherCategories(pluginId);
- if (categories.length === activePluginCategories.length) {
- let same = true;
- for (let i = 0; i < categories.length; i++) {
- if (categories[i].id !== activePluginCategories[i]?.id) {
- same = false;
- break;
- }
- }
- if (same)
- return;
- }
- activePluginCategories = categories;
- activePluginCategory = "";
- AppSearchService.setPluginLauncherCategory(pluginId, "");
- }
-
- function setActivePluginCategory(categoryId) {
- if (activePluginCategory === categoryId)
- return;
- activePluginCategory = categoryId;
- AppSearchService.setPluginLauncherCategory(activePluginId, categoryId);
- performSearch();
- }
-
- function setAppCategory(category) {
- if (appCategory === category)
- return;
- appCategory = category;
- _queryDrivenSearch = true;
- _clearModeCache();
- performSearch();
- }
-
- function _loadAppCategories() {
- appCategories = AppSearchService.getAllCategories();
- }
-
- function setFileSearchType(type) {
- if (fileSearchType === type)
- return;
- fileSearchType = type;
- performFileSearch();
- }
-
- function setFileSearchExt(ext) {
- if (fileSearchExt === ext)
- return;
- fileSearchExt = ext;
- performFileSearch();
- }
-
- function setFileSearchFolder(folder) {
- if (fileSearchFolder === folder)
- return;
- fileSearchFolder = folder;
- performFileSearch();
- }
-
- function setFileSearchSort(sort) {
- if (fileSearchSort === sort)
- return;
- fileSearchSort = sort;
- performFileSearch();
- }
-
- function clearPluginFilter() {
- if (pluginFilter) {
- pluginFilter = "";
- performSearch();
- return true;
- }
- return false;
- }
-
- function preserveSelectionAfterUpdate(forceFirst) {
- if (forceFirst)
- return function () {
- return getFirstItemIndex();
- };
- var previousSelectedId = selectedItem?.id || "";
- return function (newFlatModel) {
- if (!previousSelectedId)
- return getFirstItemIndex();
- for (var i = 0; i < newFlatModel.length; i++) {
- if (!newFlatModel[i].isHeader && newFlatModel[i].item?.id === previousSelectedId)
- return i;
- }
- return getFirstItemIndex();
- };
- }
-
- function performSearch() {
- queryChanged(searchQuery);
-
- var currentVersion = _searchVersion;
- isSearching = true;
- var shouldResetSelection = _queryDrivenSearch;
- _queryDrivenSearch = false;
- var restoreSelection = preserveSelectionAfterUpdate(shouldResetSelection);
-
- var cachedSections = AppSearchService.getCachedDefaultSections();
- if (!cachedSections && !_diskCacheConsumed && !searchQuery && searchMode === "all" && !pluginFilter) {
- _diskCacheConsumed = true;
- var diskSections = _loadDiskCache();
- if (diskSections) {
- activePluginId = "";
- activePluginName = "";
- activePluginCategories = [];
- activePluginCategory = "";
- clearActivePluginViewPreference();
- for (var i = 0; i < diskSections.length; i++) {
- if (collapsedSections[diskSections[i].id] !== undefined)
- diskSections[i].collapsed = collapsedSections[diskSections[i].id];
- }
- _applyHighlights(diskSections, "");
- flatModel = Scorer.flattenSections(diskSections);
- sections = diskSections;
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
- isSearching = false;
- searchCompleted();
- return;
- }
- }
-
- if (cachedSections && !searchQuery && searchMode === "all" && !pluginFilter) {
- activePluginId = "";
- activePluginName = "";
- activePluginCategories = [];
- activePluginCategory = "";
- clearActivePluginViewPreference();
- var modeCache = _getCachedModeData("all");
- if (modeCache) {
- _applyHighlights(modeCache.sections, "");
- sections = modeCache.sections;
- flatModel = modeCache.flatModel;
- } else {
- var newSections = cachedSections.map(function (s) {
- var copy = Object.assign({}, s, {
- items: s.items ? s.items.slice() : []
- });
- if (collapsedSections[s.id] !== undefined)
- copy.collapsed = collapsedSections[s.id];
- return copy;
- });
- _applyHighlights(newSections, "");
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- _setCachedModeData("all", sections, flatModel);
- }
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
- isSearching = false;
- searchCompleted();
- return;
- }
-
- var allItems = [];
-
- var triggerMatch = detectTrigger(searchQuery);
- if (triggerMatch.pluginId) {
- var pluginChanged = activePluginId !== triggerMatch.pluginId;
- activePluginId = triggerMatch.pluginId;
- activePluginName = getPluginName(triggerMatch.pluginId, triggerMatch.isBuiltIn);
- applyActivePluginViewPreference(triggerMatch.pluginId, triggerMatch.isBuiltIn);
-
- if (pluginChanged && !triggerMatch.isBuiltIn)
- loadPluginCategories(triggerMatch.pluginId);
-
- var pluginItems = getPluginItems(triggerMatch.pluginId, triggerMatch.query);
- for (var k = 0; k < pluginItems.length; k++)
- allItems.push(pluginItems[k]);
-
- if (triggerMatch.isBuiltIn) {
- var builtInItems = AppSearchService.getBuiltInLauncherItems(triggerMatch.pluginId, triggerMatch.query);
- for (var j = 0; j < builtInItems.length; j++) {
- allItems.push(transformBuiltInLauncherItem(builtInItems[j], triggerMatch.pluginId));
- }
- }
-
- var dynamicDefs = buildDynamicSectionDefs(allItems);
- var scoredItems = Scorer.scoreItems(allItems, triggerMatch.query, getFrecencyForItem);
- var sortAlpha = !triggerMatch.query && SettingsData.sortAppsAlphabetically;
- var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, 500);
-
- for (var sid in collapsedSections) {
- for (var i = 0; i < newSections.length; i++) {
- if (newSections[i].id === sid) {
- newSections[i].collapsed = collapsedSections[sid];
- }
- }
- }
-
- _applyHighlights(newSections, triggerMatch.query);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
-
- isSearching = false;
- searchCompleted();
- return;
- }
-
- activePluginId = "";
- activePluginName = "";
- activePluginCategories = [];
- activePluginCategory = "";
- clearActivePluginViewPreference();
-
- if (searchMode === "files") {
- var fileQuery = searchQuery.startsWith("/") ? searchQuery.substring(1).trim() : searchQuery.trim();
- isFileSearching = fileQuery.length >= 2 && DSearchService.dsearchAvailable;
- sections = [];
- flatModel = [];
- selectedFlatIndex = 0;
- selectedItem = null;
- isSearching = false;
- searchCompleted();
- return;
- }
-
- if (searchMode === "apps") {
- var isCategoryFiltered = appCategory && appCategory !== I18n.tr("All");
- var cachedSections = AppSearchService.getCachedDefaultSections();
- if (cachedSections && !searchQuery && !isCategoryFiltered) {
- var modeCache = _getCachedModeData("apps");
- if (modeCache) {
- _applyHighlights(modeCache.sections, "");
- sections = modeCache.sections;
- flatModel = modeCache.flatModel;
- } else {
- var appSectionIds = ["favorites", "apps"];
- var newSections = cachedSections.filter(function (s) {
- return appSectionIds.indexOf(s.id) !== -1;
- }).map(function (s) {
- var copy = Object.assign({}, s, {
- items: s.items ? s.items.slice() : []
- });
- if (collapsedSections[s.id] !== undefined)
- copy.collapsed = collapsedSections[s.id];
- return copy;
- });
- _applyHighlights(newSections, "");
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- _setCachedModeData("apps", sections, flatModel);
- }
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
- isSearching = false;
- searchCompleted();
- return;
- }
-
- if (isCategoryFiltered) {
- var rawApps = AppSearchService.getAppsInCategory(appCategory);
- for (var i = 0; i < rawApps.length; i++) {
- allItems.push(getOrTransformApp(rawApps[i]));
- }
- // Also include core apps (DMS Settings etc.) that match this category
- var allCoreApps = AppSearchService.getCoreApps("");
- for (var i = 0; i < allCoreApps.length; i++) {
- var coreAppCats = AppSearchService.getCategoriesForApp(allCoreApps[i]);
- if (coreAppCats.indexOf(appCategory) !== -1)
- allItems.push(transformCoreApp(allCoreApps[i]));
- }
- } else {
- var apps = searchApps(searchQuery);
- for (var i = 0; i < apps.length; i++) {
- allItems.push(apps[i]);
- }
- }
-
- var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem);
- var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically;
- var newSections = Scorer.groupBySection(scoredItems, sectionDefinitions, sortAlpha, searchQuery ? 50 : 500);
-
- for (var sid in collapsedSections) {
- for (var i = 0; i < newSections.length; i++) {
- if (newSections[i].id === sid) {
- newSections[i].collapsed = collapsedSections[sid];
- }
- }
- }
-
- _applyHighlights(newSections, searchQuery);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
-
- isSearching = false;
- searchCompleted();
- return;
- }
-
- if (searchMode === "plugins") {
- if (!searchQuery && !pluginFilter) {
- var browseItems = getPluginBrowseItems();
- for (var k = 0; k < browseItems.length; k++)
- allItems.push(browseItems[k]);
- } else if (pluginFilter) {
- var isBuiltInFilter = !!AppSearchService.builtInPlugins[pluginFilter];
- applyActivePluginViewPreference(pluginFilter, isBuiltInFilter);
-
- var filterItems = getPluginItems(pluginFilter, searchQuery);
- for (var k = 0; k < filterItems.length; k++)
- allItems.push(filterItems[k]);
-
- var builtInItems = AppSearchService.getBuiltInLauncherItems(pluginFilter, searchQuery);
- for (var j = 0; j < builtInItems.length; j++) {
- allItems.push(transformBuiltInLauncherItem(builtInItems[j], pluginFilter));
- }
- } else {
- var emptyTriggerPlugins = getEmptyTriggerPlugins();
- for (var i = 0; i < emptyTriggerPlugins.length; i++) {
- var pluginId = emptyTriggerPlugins[i];
- var pItems = getPluginItems(pluginId, searchQuery);
- for (var k = 0; k < pItems.length; k++)
- allItems.push(pItems[k]);
- }
-
- var builtInLauncherPlugins = getBuiltInEmptyTriggerLaunchers();
- for (var i = 0; i < builtInLauncherPlugins.length; i++) {
- var pluginId = builtInLauncherPlugins[i];
- var blItems = AppSearchService.getBuiltInLauncherItems(pluginId, searchQuery);
- for (var j = 0; j < blItems.length; j++) {
- allItems.push(transformBuiltInLauncherItem(blItems[j], pluginId));
- }
- }
- }
-
- var dynamicDefs = buildDynamicSectionDefs(allItems);
- var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem);
- var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically;
- var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, 500);
-
- for (var sid in collapsedSections) {
- for (var i = 0; i < newSections.length; i++) {
- if (newSections[i].id === sid) {
- newSections[i].collapsed = collapsedSections[sid];
- }
- }
- }
-
- _applyHighlights(newSections, searchQuery);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
-
- isSearching = false;
- searchCompleted();
- return;
- }
-
- var apps = searchApps(searchQuery);
- for (var i = 0; i < apps.length; i++) {
- allItems.push(apps[i]);
- }
-
- if (searchMode === "all") {
- if (searchQuery && searchQuery.length >= 2) {
- _pluginPhasePending = true;
- _phase1Items = allItems.slice();
- _pluginPhaseForceFirst = shouldResetSelection;
- pluginPhaseTimer.restart();
- isSearching = true;
- searchCompleted();
- return;
- } else if (!searchQuery) {
- var emptyTriggerOrdered = getEmptyTriggerPluginsOrdered();
- for (var i = 0; i < emptyTriggerOrdered.length; i++) {
- var plugin = emptyTriggerOrdered[i];
- if (plugin.isBuiltIn) {
- var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery);
- for (var j = 0; j < blItems.length; j++)
- allItems.push(transformBuiltInLauncherItem(blItems[j], plugin.id));
- } else {
- var pItems = getPluginItems(plugin.id, searchQuery);
- for (var j = 0; j < pItems.length; j++)
- allItems.push(pItems[j]);
- }
- }
-
- var browseItems = getPluginBrowseItems();
- for (var i = 0; i < browseItems.length; i++)
- allItems.push(browseItems[i]);
- }
- }
-
- var dynamicDefs = buildDynamicSectionDefs(allItems);
-
- if (currentVersion !== _searchVersion) {
- isSearching = false;
- return;
- }
-
- var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem);
- var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically;
- var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, searchQuery ? 50 : 500);
-
- if (currentVersion !== _searchVersion) {
- isSearching = false;
- return;
- }
-
- for (var i = 0; i < newSections.length; i++) {
- var sid = newSections[i].id;
- if (collapsedSections[sid] !== undefined) {
- newSections[i].collapsed = collapsedSections[sid];
- }
- }
-
- _applyHighlights(newSections, searchQuery);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
-
- if (!AppSearchService.isCacheValid() && !searchQuery && searchMode === "all" && !pluginFilter) {
- AppSearchService.setCachedDefaultSections(sections, flatModel);
- _saveDiskCache(sections);
- }
-
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
-
- isSearching = _pluginPhasePending;
- searchCompleted();
- }
-
- function _performPluginPhase() {
- _pluginPhasePending = false;
- if (!searchQuery || searchQuery.length < 2 || searchMode !== "all")
- return;
-
- var currentVersion = _searchVersion;
- var restoreSelection = preserveSelectionAfterUpdate(_pluginPhaseForceFirst);
- var allItems = _phase1Items;
- _phase1Items = [];
-
- var allPluginsOrdered = getAllVisiblePluginsOrdered();
- var maxPerPlugin = 10;
- for (var i = 0; i < allPluginsOrdered.length; i++) {
- if (currentVersion !== _searchVersion)
- return;
- var plugin = allPluginsOrdered[i];
- if (plugin.isBuiltIn) {
- var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery);
- var blLimit = Math.min(blItems.length, maxPerPlugin);
- for (var j = 0; j < blLimit; j++) {
- var item = transformBuiltInLauncherItem(blItems[j], plugin.id);
- item._preScored = 900 - j;
- allItems.push(item);
- }
- } else {
- var pItems = getPluginItems(plugin.id, searchQuery, maxPerPlugin);
- for (var j = 0; j < pItems.length; j++) {
- pItems[j]._preScored = 900 - j;
- allItems.push(pItems[j]);
- }
- }
- }
-
- if (currentVersion !== _searchVersion)
- return;
-
- var dynamicDefs = buildDynamicSectionDefs(allItems);
- var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem);
- var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, false, 50);
-
- if (currentVersion !== _searchVersion)
- return;
-
- for (var i = 0; i < newSections.length; i++) {
- var sid = newSections[i].id;
- if (collapsedSections[sid] !== undefined)
- newSections[i].collapsed = collapsedSections[sid];
- }
-
- _applyHighlights(newSections, searchQuery);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- selectedFlatIndex = restoreSelection(flatModel);
- updateSelectedItem();
- isSearching = false;
- searchCompleted();
- }
-
- function performFileSearch() {
- if (!DSearchService.dsearchAvailable)
- return;
- var fileQuery = "";
- var effectiveType = fileSearchType || "all";
- var includeFiles = SettingsData.dankLauncherV2IncludeFilesInAll;
- var includeFolders = SettingsData.dankLauncherV2IncludeFoldersInAll;
-
- if (searchQuery.startsWith("/")) {
- fileQuery = searchQuery.substring(1).trim();
- } else if (searchMode === "files") {
- fileQuery = searchQuery.trim();
- } else if (searchMode === "all" && (includeFiles || includeFolders)) {
- fileQuery = searchQuery.trim();
- if (includeFiles && !includeFolders)
- effectiveType = "file";
- else if (!includeFiles && includeFolders)
- effectiveType = "dir";
- else
- effectiveType = "all";
- } else {
- return;
- }
-
- if (fileQuery.length < 2) {
- isFileSearching = false;
- return;
- }
-
- isFileSearching = true;
-
- var splitBothTypes = searchMode === "all" && includeFiles && includeFolders && DSearchService.supportsTypeFilter;
- var queryTypes = splitBothTypes ? ["file", "dir"] : [effectiveType];
- var pending = queryTypes.length;
- var aggregatedItems = [];
-
- for (var t = 0; t < queryTypes.length; t++) {
- var queryType = queryTypes[t];
- var params = {
- limit: 20,
- fuzzy: true,
- sort: fileSearchSort || "score",
- desc: true
- };
-
- if (DSearchService.supportsTypeFilter) {
- params.type = (queryType && queryType !== "all") ? queryType : "all";
- }
- if (fileSearchExt) {
- params.ext = fileSearchExt;
- }
- if (fileSearchFolder) {
- params.folder = fileSearchFolder;
- }
-
- DSearchService.search(fileQuery, params, function (response) {
- pending--;
- if (!response.error) {
- var hits = response.result?.hits || [];
- for (var i = 0; i < hits.length; i++) {
- var hit = hits[i];
- var docTypes = hit.locations?.doc_type;
- var isDir = docTypes ? !!docTypes["dir"] : false;
- aggregatedItems.push(transformFileResult({
- path: hit.id || "",
- score: hit.score || 0,
- is_dir: isDir
- }));
- }
- }
- if (pending > 0)
- return;
-
- isFileSearching = false;
- _applyFileSearchResults(aggregatedItems, effectiveType);
- });
- }
- }
-
- function _applyFileSearchResults(fileItems, effectiveType) {
- var fileSections = [];
- var showType = effectiveType;
- var order = SettingsData.launcherPluginOrder || [];
- var filesOrderIdx = order.indexOf("__files");
- var foldersOrderIdx = order.indexOf("__folders");
- var filesPriority = filesOrderIdx !== -1 ? 2.6 + filesOrderIdx * 0.01 : 4;
- var foldersPriority = foldersOrderIdx !== -1 ? 2.6 + foldersOrderIdx * 0.01 : 4.1;
-
- if (showType === "all" && DSearchService.supportsTypeFilter) {
- var onlyFiles = [];
- var onlyDirs = [];
- for (var j = 0; j < fileItems.length; j++) {
- if (fileItems[j].data?.is_dir)
- onlyDirs.push(fileItems[j]);
- else
- onlyFiles.push(fileItems[j]);
- }
- if (onlyFiles.length > 0) {
- fileSections.push({
- id: "files",
- title: I18n.tr("Files"),
- icon: "insert_drive_file",
- priority: filesPriority,
- items: onlyFiles,
- collapsed: collapsedSections["files"] || false,
- flatStartIndex: 0
- });
- }
- if (onlyDirs.length > 0) {
- fileSections.push({
- id: "folders",
- title: I18n.tr("Folders"),
- icon: "folder",
- priority: foldersPriority,
- items: onlyDirs,
- collapsed: collapsedSections["folders"] || false,
- flatStartIndex: 0
- });
- }
- } else {
- var filesIcon = showType === "dir" ? "folder" : showType === "file" ? "insert_drive_file" : "folder";
- var filesTitle = showType === "dir" ? I18n.tr("Folders") : I18n.tr("Files");
- var singlePriority = showType === "dir" ? foldersPriority : filesPriority;
- if (fileItems.length > 0) {
- fileSections.push({
- id: "files",
- title: filesTitle,
- icon: filesIcon,
- priority: singlePriority,
- items: fileItems,
- collapsed: collapsedSections["files"] || false,
- flatStartIndex: 0
- });
- }
- }
-
- var newSections;
- if (searchMode === "files") {
- newSections = fileSections;
- } else {
- var existingNonFile = sections.filter(function (s) {
- return s.id !== "files" && s.id !== "folders";
- });
- newSections = existingNonFile.concat(fileSections);
- }
- newSections.sort(function (a, b) {
- return a.priority - b.priority;
- });
- _applyHighlights(newSections, searchQuery);
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
- selectedFlatIndex = getFirstItemIndex();
- updateSelectedItem();
- }
-
- function searchApps(query) {
- var apps = AppSearchService.searchApplications(query);
- var items = [];
-
- for (var i = 0; i < apps.length; i++) {
- items.push(getOrTransformApp(apps[i]));
- }
-
- var coreApps = AppSearchService.getCoreApps(query);
- for (var i = 0; i < coreApps.length; i++) {
- items.push(transformCoreApp(coreApps[i]));
- }
-
- return items;
- }
-
- function transformApp(app) {
- var appId = app.id || app.execString || app.exec || "";
- var override = SessionData.getAppOverride(appId);
- return Transform.transformApp(app, override, [], I18n.tr("Launch"));
- }
-
- function transformCoreApp(app) {
- return Transform.transformCoreApp(app, I18n.tr("Open"));
- }
-
- function transformBuiltInLauncherItem(item, pluginId) {
- return Transform.transformBuiltInLauncherItem(item, pluginId, I18n.tr("Open"));
- }
-
- function transformFileResult(file) {
- return Transform.transformFileResult(file, I18n.tr("Open"), I18n.tr("Open folder"), I18n.tr("Copy path"), I18n.tr("Open in terminal"));
- }
-
- function detectTrigger(query) {
- if (!query || query.length === 0)
- return {
- pluginId: null,
- query: query
- };
-
- var pluginTriggers = PluginService.getAllPluginTriggers();
- for (var trigger in pluginTriggers) {
- if (trigger && query.startsWith(trigger)) {
- return {
- pluginId: pluginTriggers[trigger],
- query: query.substring(trigger.length).trim()
- };
- }
- }
-
- var builtInTriggers = AppSearchService.getBuiltInLauncherTriggers();
- for (var trigger in builtInTriggers) {
- if (trigger && query.startsWith(trigger)) {
- return {
- pluginId: builtInTriggers[trigger],
- query: query.substring(trigger.length).trim(),
- isBuiltIn: true
- };
- }
- }
-
- return {
- pluginId: null,
- query: query
- };
- }
-
- function getEmptyTriggerPlugins() {
- var plugins = PluginService.getPluginsWithEmptyTrigger();
- var visible = plugins.filter(function (pluginId) {
- return SettingsData.getPluginAllowWithoutTrigger(pluginId);
- });
- return sortPluginIdsByOrder(visible);
- }
-
- function getAllLauncherPluginIds() {
- var launchers = PluginService.getLauncherPlugins();
- return Object.keys(launchers);
- }
-
- function getVisibleLauncherPluginIds() {
- var launchers = PluginService.getLauncherPlugins();
- var visible = Object.keys(launchers).filter(function (pluginId) {
- return SettingsData.getPluginAllowWithoutTrigger(pluginId);
- });
- return sortPluginIdsByOrder(visible);
- }
-
- function getAllBuiltInLauncherIds() {
- var launchers = AppSearchService.getBuiltInLauncherPlugins();
- return Object.keys(launchers);
- }
-
- function getVisibleBuiltInLauncherIds() {
- var launchers = AppSearchService.getBuiltInLauncherPlugins();
- var visible = Object.keys(launchers).filter(function (pluginId) {
- return SettingsData.getPluginAllowWithoutTrigger(pluginId);
- });
- return sortPluginIdsByOrder(visible);
- }
-
- function sortPluginIdsByOrder(pluginIds) {
- return Utils.sortPluginIdsByOrder(pluginIds, SettingsData.launcherPluginOrder || []);
- }
-
- function getAllVisiblePluginsOrdered() {
- var thirdPartyLaunchers = PluginService.getLauncherPlugins() || {};
- var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins() || {};
- var all = [];
- for (var id in thirdPartyLaunchers) {
- if (SettingsData.getPluginAllowWithoutTrigger(id))
- all.push({
- id: id,
- isBuiltIn: false
- });
- }
- for (var id in builtInLaunchers) {
- if (SettingsData.getPluginAllowWithoutTrigger(id))
- all.push({
- id: id,
- isBuiltIn: true
- });
- }
- return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []);
- }
-
- function getEmptyTriggerPluginsOrdered() {
- var thirdParty = PluginService.getPluginsWithEmptyTrigger() || [];
- var builtIn = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger() || [];
- var all = [];
- for (var i = 0; i < thirdParty.length; i++) {
- var id = thirdParty[i];
- if (SettingsData.getPluginAllowWithoutTrigger(id))
- all.push({
- id: id,
- isBuiltIn: false
- });
- }
- for (var i = 0; i < builtIn.length; i++) {
- var id = builtIn[i];
- if (SettingsData.getPluginAllowWithoutTrigger(id))
- all.push({
- id: id,
- isBuiltIn: true
- });
- }
- return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []);
- }
-
- function getPluginBrowseItems() {
- var items = [];
- var browseLabel = I18n.tr("Browse");
- var triggerLabel = I18n.tr("Trigger: %1");
- var noTriggerLabel = I18n.tr("No trigger");
-
- var launchers = PluginService.getLauncherPlugins();
- for (var pluginId in launchers) {
- var trigger = PluginService.getPluginTrigger(pluginId);
- var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId);
- items.push(Transform.createPluginBrowseItem(pluginId, launchers[pluginId], trigger, false, isAllowed, browseLabel, triggerLabel, noTriggerLabel));
- }
-
- var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins();
- for (var pluginId in builtInLaunchers) {
- var trigger = AppSearchService.getBuiltInPluginTrigger(pluginId);
- var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId);
- items.push(Transform.createPluginBrowseItem(pluginId, builtInLaunchers[pluginId], trigger, true, isAllowed, browseLabel, triggerLabel, noTriggerLabel));
- }
-
- return items;
- }
-
- function getBuiltInEmptyTriggerLaunchers() {
- var plugins = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger();
- var visible = plugins.filter(function (pluginId) {
- return SettingsData.getPluginAllowWithoutTrigger(pluginId);
- });
- return sortPluginIdsByOrder(visible);
- }
-
- function getPluginItems(pluginId, query, limit) {
- var items = AppSearchService.getPluginItemsForPlugin(pluginId, query);
- var count = limit > 0 && limit < items.length ? limit : items.length;
- var transformed = [];
-
- for (var i = 0; i < count; i++) {
- transformed.push(transformPluginItem(items[i], pluginId));
- }
-
- return transformed;
- }
-
- function getPluginName(pluginId, isBuiltIn) {
- if (isBuiltIn) {
- var plugin = AppSearchService.builtInPlugins[pluginId];
- return plugin ? plugin.name : pluginId;
- }
- var launchers = PluginService.getLauncherPlugins();
- if (launchers[pluginId]) {
- return launchers[pluginId].name || pluginId;
- }
- return pluginId;
- }
-
- function getPluginMetadata(pluginId) {
- var builtIn = AppSearchService.builtInPlugins[pluginId];
- if (builtIn) {
- return {
- name: builtIn.name || pluginId,
- icon: builtIn.cornerIcon || "extension"
- };
- }
- var launchers = PluginService.getLauncherPlugins();
- if (launchers[pluginId]) {
- var rawIcon = launchers[pluginId].icon || "extension";
- return {
- name: launchers[pluginId].name || pluginId,
- icon: Utils.stripIconPrefix(rawIcon)
- };
- }
- return {
- name: pluginId,
- icon: "extension"
- };
- }
-
- function buildDynamicSectionDefs(items) {
- var baseDefs = sectionDefinitions.slice();
- var pluginSections = {};
- var order = SettingsData.launcherPluginOrder || [];
- var orderMap = {};
- for (var k = 0; k < order.length; k++)
- orderMap[order[k]] = k;
- var unorderedPriority = 2.6 + order.length * 0.01;
-
- for (var i = 0; i < items.length; i++) {
- var section = items[i].section;
- if (!section || !section.startsWith("plugin_"))
- continue;
- if (pluginSections[section])
- continue;
- var pluginId = section.substring(7);
- var meta = getPluginMetadata(pluginId);
- var viewPref = getPluginViewPref(pluginId);
- var orderIdx = orderMap[pluginId];
- var priority;
- if (orderIdx !== undefined) {
- priority = 2.6 + orderIdx * 0.01;
- } else {
- priority = unorderedPriority;
- unorderedPriority += 0.01;
- }
-
- pluginSections[section] = {
- id: section,
- title: meta.name,
- icon: meta.icon,
- priority: priority,
- defaultViewMode: viewPref.mode || "list"
- };
-
- if (viewPref.mode)
- setPluginViewPreference(section, viewPref.mode, viewPref.enforced);
- }
-
- for (var sectionId in pluginSections) {
- baseDefs.push(pluginSections[sectionId]);
- }
-
- baseDefs.sort(function (a, b) {
- return a.priority - b.priority;
- });
- return baseDefs;
- }
-
- function getPluginViewPref(pluginId) {
- var builtIn = AppSearchService.builtInPlugins[pluginId];
- if (builtIn && builtIn.viewMode) {
- return {
- mode: builtIn.viewMode,
- enforced: builtIn.viewModeEnforced === true
- };
- }
-
- var pref = PluginService.getPluginViewPreference(pluginId);
- if (pref && pref.mode) {
- return pref;
- }
-
- return {
- mode: "list",
- enforced: false
- };
- }
-
- function transformPluginItem(item, pluginId) {
- return Transform.transformPluginItem(item, pluginId, I18n.tr("Select"));
- }
-
- function getFrecencyForItem(item) {
- if (item.type !== "app")
- return null;
-
- var appId = item.id;
- var usageRanking = AppUsageHistoryData.appUsageRanking || {};
-
- var idVariants = [appId, appId.replace(".desktop", "")];
- var usageData = null;
-
- for (var i = 0; i < idVariants.length; i++) {
- if (usageRanking[idVariants[i]]) {
- usageData = usageRanking[idVariants[i]];
- break;
- }
- }
-
- return {
- usageCount: usageData?.usageCount || 0
- };
- }
-
- function getFirstItemIndex() {
- return Nav.getFirstItemIndex(flatModel);
- }
-
- function _getCachedModeData(mode) {
- return _modeSectionsCache[mode] || null;
- }
-
- function _setCachedModeData(mode, sectionsData, flatModelData) {
- var cache = Object.assign({}, _modeSectionsCache);
- cache[mode] = {
- sections: sectionsData,
- flatModel: flatModelData
- };
- _modeSectionsCache = cache;
- }
-
- function _clearModeCache() {
- _modeSectionsCache = {};
- }
-
- function _saveDiskCache(sectionsData) {
- var serializable = [];
- for (var i = 0; i < sectionsData.length; i++) {
- var s = sectionsData[i];
- var items = [];
- var srcItems = s.items || [];
- for (var j = 0; j < srcItems.length; j++) {
- var it = srcItems[j];
- items.push({
- id: it.id,
- type: it.type,
- name: it.name || "",
- subtitle: it.subtitle || "",
- icon: it.icon || "",
- iconType: it.iconType || "image",
- iconFull: it.iconFull || "",
- section: it.section || "",
- isCore: it.isCore || false,
- isBuiltInLauncher: it.isBuiltInLauncher || false,
- pluginId: it.pluginId || ""
- });
- }
- serializable.push({
- id: s.id,
- title: s.title || "",
- icon: s.icon || "",
- priority: s.priority || 0,
- items: items
- });
- }
- CacheData.saveLauncherCache(serializable);
- }
-
- function _actionsFromDesktopEntry(appId) {
- if (!appId)
- return [];
- var entry = DesktopEntries.heuristicLookup(appId);
- if (!entry || !entry.actions || entry.actions.length === 0)
- return [];
- var result = [];
- for (var i = 0; i < entry.actions.length; i++) {
- result.push({
- name: entry.actions[i].name,
- icon: "play_arrow",
- actionData: entry.actions[i]
- });
- }
- return result;
- }
-
- function _loadDiskCache() {
- var cached = CacheData.loadLauncherCache();
- if (!cached || !Array.isArray(cached) || cached.length === 0)
- return null;
-
- var sectionsData = [];
- for (var i = 0; i < cached.length; i++) {
- var s = cached[i];
- var items = [];
- var srcItems = s.items || [];
- for (var j = 0; j < srcItems.length; j++) {
- var it = srcItems[j];
- items.push({
- id: it.id || "",
- type: it.type || "app",
- name: it.name || "",
- subtitle: it.subtitle || "",
- icon: it.icon || "",
- iconType: it.iconType || "image",
- iconFull: it.iconFull || "",
- section: it.section || "",
- isCore: it.isCore || false,
- isBuiltInLauncher: it.isBuiltInLauncher || false,
- pluginId: it.pluginId || "",
- data: {
- id: it.id
- },
- actions: _actionsFromDesktopEntry(it.id),
- primaryAction: it.type === "app" && !it.isCore ? {
- name: I18n.tr("Launch"),
- icon: "open_in_new",
- action: "launch"
- } : null,
- _diskCached: true,
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: undefined
- });
- }
- sectionsData.push({
- id: s.id || "",
- title: s.title || "",
- icon: s.icon || "",
- priority: s.priority || 0,
- items: items,
- collapsed: false,
- flatStartIndex: 0
- });
- }
- return sectionsData;
- }
-
- function updateSelectedItem() {
- if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
- var entry = flatModel[selectedFlatIndex];
- selectedItem = entry.isHeader ? null : entry.item;
- } else {
- selectedItem = null;
- }
- }
-
- function _applyHighlights(sectionsData, query) {
- if (!query || query.length === 0) {
- for (var i = 0; i < sectionsData.length; i++) {
- var items = sectionsData[i].items;
- for (var j = 0; j < items.length; j++) {
- var item = items[j];
- item._hName = item.name || "";
- item._hSub = item.subtitle || "";
- item._hRich = false;
- }
- }
- return;
- }
-
- var highlightColor = Theme.primary;
- var nameColor = Theme.surfaceText;
- var subColor = Theme.surfaceVariantText;
- var lowerQuery = query.toLowerCase();
-
- for (var i = 0; i < sectionsData.length; i++) {
- var items = sectionsData[i].items;
- for (var j = 0; j < items.length; j++) {
- var item = items[j];
- item._hName = _highlightField(item.name || "", lowerQuery, query.length, nameColor, highlightColor);
- item._hSub = _highlightField(item.subtitle || "", lowerQuery, query.length, subColor, highlightColor);
- item._hRich = true;
- }
- }
- }
-
- function _highlightField(text, lowerQuery, queryLen, baseColor, highlightColor) {
- if (!text)
- return "";
- var idx = text.toLowerCase().indexOf(lowerQuery);
- if (idx === -1)
- return text;
- var before = text.substring(0, idx);
- var match = text.substring(idx, idx + queryLen);
- var after = text.substring(idx + queryLen);
- return '<span style="color:' + baseColor + '">' + before + '</span><span style="color:' + highlightColor + '; font-weight:600">' + match + '</span><span style="color:' + baseColor + '">' + after + '</span>';
- }
-
- function getCurrentSectionViewMode() {
- if (selectedFlatIndex < 0 || selectedFlatIndex >= flatModel.length)
- return "list";
- var entry = flatModel[selectedFlatIndex];
- if (!entry || entry.isHeader)
- return "list";
- return getSectionViewMode(entry.sectionId);
- }
-
- function getGridColumns(sectionId) {
- return Nav.getGridColumns(getSectionViewMode(sectionId), gridColumns);
- }
-
- function _cancelPendingSelectionReset() {
- _queryDrivenSearch = false;
- _pluginPhaseForceFirst = false;
- }
-
- function selectNext() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculateNextIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectPrevious() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculatePrevIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectRight() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewMode);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectLeft() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewMode);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectNextSection() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculateNextSectionIndex(flatModel, selectedFlatIndex);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectPreviousSection() {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculatePrevSectionIndex(flatModel, selectedFlatIndex);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectPageDown(visibleItems) {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectPageUp(visibleItems) {
- keyboardNavigationActive = true;
- _cancelPendingSelectionReset();
- var newIndex = Nav.calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems);
- if (newIndex !== selectedFlatIndex) {
- selectedFlatIndex = newIndex;
- updateSelectedItem();
- }
- }
-
- function selectIndex(index) {
- keyboardNavigationActive = false;
- if (index >= 0 && index < flatModel.length && !flatModel[index].isHeader) {
- selectedFlatIndex = index;
- updateSelectedItem();
- }
- }
-
- function toggleSection(sectionId) {
- _clearModeCache();
- var newCollapsed = Object.assign({}, collapsedSections);
- var currentState = newCollapsed[sectionId];
-
- if (currentState === undefined) {
- for (var i = 0; i < sections.length; i++) {
- if (sections[i].id === sectionId) {
- currentState = sections[i].collapsed || false;
- break;
- }
- }
- }
-
- newCollapsed[sectionId] = !currentState;
- collapsedSections = newCollapsed;
-
- var newSections = sections.slice();
- for (var i = 0; i < newSections.length; i++) {
- if (newSections[i].id === sectionId) {
- newSections[i] = Object.assign({}, newSections[i], {
- collapsed: newCollapsed[sectionId]
- });
- }
- }
- flatModel = Scorer.flattenSections(newSections);
- sections = newSections;
-
- if (selectedFlatIndex >= flatModel.length) {
- selectedFlatIndex = getFirstItemIndex();
- }
- updateSelectedItem();
- }
-
- function executeSelected() {
- if (searchDebounce.running) {
- searchDebounce.stop();
- performSearch();
- }
- if (!selectedItem)
- return;
- executeItem(selectedItem);
- }
-
- function executeItem(item) {
- if (!item)
- return;
-
- SessionData.addLauncherHistory(searchQuery);
-
- if (item.type === "plugin_browse") {
- var browsePluginId = item.data?.pluginId;
- if (!browsePluginId)
- return;
- var browseTrigger = item.data.isBuiltIn ? AppSearchService.getBuiltInPluginTrigger(browsePluginId) : PluginService.getPluginTrigger(browsePluginId);
-
- if (browseTrigger && browseTrigger.length > 0) {
- searchQueryRequested(browseTrigger);
- } else {
- setMode("plugins");
- pluginFilter = browsePluginId;
- performSearch();
- }
- return;
- }
-
- switch (item.type) {
- case "app":
- if (item.isCore) {
- AppSearchService.executeCoreApp(item.data);
- } else if (item.data?.isAction) {
- launchAppAction(item.data);
- } else {
- launchApp(item.data);
- }
- break;
- case "plugin":
- if (item.isBuiltInLauncher) {
- AppSearchService.executeBuiltInLauncherItem(item.data);
- } else {
- AppSearchService.executePluginItem(item.data, item.pluginId);
- }
- break;
- case "file":
- openFile(item.data?.path);
- break;
- default:
- return;
- }
-
- itemExecuted();
- }
-
- function executeAction(item, action) {
- if (!item || !action)
- return;
- switch (action.action) {
- case "launch":
- executeItem(item);
- break;
- case "open":
- openFile(item.data.path);
- break;
- case "open_folder":
- openFolder(item.data.path);
- break;
- case "copy_path":
- copyToClipboard(item.data.path);
- break;
- case "open_terminal":
- openTerminal(item.data.path);
- break;
- case "copy":
- copyToClipboard(item.name);
- break;
- case "execute":
- executeItem(item);
- break;
- case "launch_dgpu":
- if (item.type === "app" && item.data) {
- launchAppWithNvidia(item.data);
- }
- break;
- case "toggle_all_visibility":
- if (item.type === "plugin_browse" && item.data?.pluginId) {
- var pluginId = item.data.pluginId;
- var currentState = SettingsData.getPluginAllowWithoutTrigger(pluginId);
- SettingsData.setPluginAllowWithoutTrigger(pluginId, !currentState);
- performSearch();
- }
- return;
- default:
- if (item.type === "app" && action.actionData) {
- launchAppAction({
- parentApp: item.data,
- actionData: action.actionData
- });
- }
- }
-
- itemExecuted();
- }
-
- function _resolveDesktopEntry(app) {
- if (!app)
- return null;
- if (app.command)
- return app;
- var id = app.id || app.execString || app.exec || "";
- if (!id)
- return null;
- return DesktopEntries.heuristicLookup(id);
- }
-
- function launchApp(app) {
- var entry = _resolveDesktopEntry(app);
- if (!entry)
- return;
- SessionService.launchDesktopEntry(entry);
- AppUsageHistoryData.addAppUsage(entry);
- }
-
- function launchAppWithNvidia(app) {
- var entry = _resolveDesktopEntry(app);
- if (!entry)
- return;
- SessionService.launchDesktopEntry(entry, true);
- AppUsageHistoryData.addAppUsage(entry);
- }
-
- function launchAppAction(actionItem) {
- if (!actionItem || !actionItem.actionData)
- return;
- var entry = _resolveDesktopEntry(actionItem.parentApp);
- if (!entry)
- return;
- SessionService.launchDesktopAction(entry, actionItem.actionData);
- AppUsageHistoryData.addAppUsage(entry);
- }
-
- function openFile(path) {
- if (!path)
- return;
- Qt.openUrlExternally("file://" + path);
- }
-
- function openFolder(path) {
- if (!path)
- return;
- var folder = path.substring(0, path.lastIndexOf("/"));
- Qt.openUrlExternally("file://" + folder);
- }
-
- function openTerminal(path) {
- if (!path)
- return;
- var terminal = Quickshell.env("TERMINAL") || "xterm";
- Quickshell.execDetached({
- command: [terminal],
- workingDirectory: path
- });
- }
-
- function copyToClipboard(text) {
- if (!text)
- return;
- Quickshell.execDetached(["dms", "cl", "copy", text]);
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js
deleted file mode 100644
index a06285f..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js
+++ /dev/null
@@ -1,128 +0,0 @@
-.pragma library
-
-function getFileIcon(filename) {
- var ext = filename.lastIndexOf(".") > 0 ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : "";
-
- switch (ext) {
- case "pdf":
- return "picture_as_pdf";
- case "doc":
- case "docx":
- case "odt":
- return "description";
- case "xls":
- case "xlsx":
- case "ods":
- return "table_chart";
- case "ppt":
- case "pptx":
- case "odp":
- return "slideshow";
- case "txt":
- case "md":
- case "rst":
- return "article";
- case "jpg":
- case "jpeg":
- case "png":
- case "gif":
- case "svg":
- case "webp":
- return "image";
- case "mp3":
- case "wav":
- case "flac":
- case "ogg":
- return "audio_file";
- case "mp4":
- case "mkv":
- case "avi":
- case "webm":
- return "video_file";
- case "zip":
- case "tar":
- case "gz":
- case "7z":
- case "rar":
- return "folder_zip";
- case "js":
- case "ts":
- case "py":
- case "rs":
- case "go":
- case "java":
- case "c":
- case "cpp":
- case "h":
- return "code";
- case "html":
- case "css":
- case "htm":
- return "web";
- case "json":
- case "xml":
- case "yaml":
- case "yml":
- return "data_object";
- case "sh":
- case "bash":
- case "zsh":
- return "terminal";
- default:
- return "insert_drive_file";
- }
-}
-
-function stripIconPrefix(iconName) {
- if (!iconName)
- return "extension";
- if (iconName.startsWith("unicode:"))
- return iconName.substring(8);
- if (iconName.startsWith("material:"))
- return iconName.substring(9);
- if (iconName.startsWith("image:"))
- return iconName.substring(6);
- return iconName;
-}
-
-function detectIconType(iconName) {
- if (!iconName)
- return "material";
- if (iconName.startsWith("unicode:"))
- return "unicode";
- if (iconName.startsWith("material:"))
- return "material";
- if (iconName.startsWith("image:"))
- return "image";
- if (iconName.indexOf("/") >= 0 || iconName.indexOf(".") >= 0)
- return "image";
- if (/^[a-z]+-[a-z]/.test(iconName.toLowerCase()))
- return "image";
- return "material";
-}
-
-function sortPluginIdsByOrder(pluginIds, order) {
- if (!order || order.length === 0)
- return pluginIds;
- var orderMap = {};
- for (var i = 0; i < order.length; i++)
- orderMap[order[i]] = i;
- return pluginIds.slice().sort(function (a, b) {
- var aOrder = orderMap[a] !== undefined ? orderMap[a] : 9999;
- var bOrder = orderMap[b] !== undefined ? orderMap[b] : 9999;
- return aOrder - bOrder;
- });
-}
-
-function sortPluginsOrdered(plugins, order) {
- if (!order || order.length === 0)
- return plugins;
- var orderMap = {};
- for (var i = 0; i < order.length; i++)
- orderMap[order[i]] = i;
- return plugins.sort(function (a, b) {
- var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
- var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
- return aOrder - bOrder;
- });
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml
deleted file mode 100644
index 859022c..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml
+++ /dev/null
@@ -1,465 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Wayland
-import Quickshell.Hyprland
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- visible: false
-
- property bool spotlightOpen: false
- property bool keyboardActive: false
- property bool contentVisible: false
- property var spotlightContent: launcherContentLoader.item
- property bool openedFromOverview: false
- property bool isClosing: false
- property bool _pendingInitialize: false
- property string _pendingQuery: ""
- property string _pendingMode: ""
- readonly property bool unloadContentOnClose: SettingsData.dankLauncherV2UnloadOnClose
-
- readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab
- readonly property var effectiveScreen: launcherWindow.screen
- readonly property real screenWidth: effectiveScreen?.width ?? 1920
- readonly property real screenHeight: effectiveScreen?.height ?? 1080
- readonly property real dpr: effectiveScreen ? CompositorService.getScreenScale(effectiveScreen) : 1
-
- readonly property int baseWidth: {
- switch (SettingsData.dankLauncherV2Size) {
- case "micro":
- return 500;
- case "medium":
- return 720;
- case "large":
- return 860;
- default:
- return 620;
- }
- }
- readonly property int baseHeight: {
- switch (SettingsData.dankLauncherV2Size) {
- case "micro":
- return 480;
- case "medium":
- return 720;
- case "large":
- return 860;
- default:
- return 600;
- }
- }
- readonly property int modalWidth: Math.min(baseWidth, screenWidth - 100)
- readonly property int modalHeight: Math.min(baseHeight, screenHeight - 100)
- readonly property real modalX: (screenWidth - modalWidth) / 2
- readonly property real modalY: (screenHeight - modalHeight) / 2
-
- readonly property color backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- readonly property real cornerRadius: Theme.cornerRadius
- readonly property color borderColor: {
- if (!SettingsData.dankLauncherV2BorderEnabled)
- return Theme.outlineMedium;
- switch (SettingsData.dankLauncherV2BorderColor) {
- case "primary":
- return Theme.primary;
- case "secondary":
- return Theme.secondary;
- case "outline":
- return Theme.outline;
- case "surfaceText":
- return Theme.surfaceText;
- default:
- return Theme.primary;
- }
- }
- readonly property int borderWidth: SettingsData.dankLauncherV2BorderEnabled ? SettingsData.dankLauncherV2BorderThickness : 0
-
- signal dialogClosed
-
- function _ensureContentLoadedAndInitialize(query, mode) {
- _pendingQuery = query || "";
- _pendingMode = mode || "";
- _pendingInitialize = true;
- contentVisible = true;
- launcherContentLoader.active = true;
-
- if (spotlightContent) {
- _initializeAndShow(_pendingQuery, _pendingMode);
- _pendingInitialize = false;
- }
- }
-
- function _initializeAndShow(query, mode) {
- if (!spotlightContent)
- return;
- contentVisible = true;
- spotlightContent.searchField.forceActiveFocus();
-
- var targetQuery = "";
-
- if (query) {
- targetQuery = query;
- } else if (SettingsData.rememberLastQuery) {
- targetQuery = SessionData.launcherLastQuery || "";
- }
-
- if (spotlightContent.searchField) {
- spotlightContent.searchField.text = targetQuery;
- }
- if (spotlightContent.controller) {
- var targetMode = mode || SessionData.launcherLastMode || "all";
- spotlightContent.controller.searchMode = targetMode;
- spotlightContent.controller.activePluginId = "";
- spotlightContent.controller.activePluginName = "";
- spotlightContent.controller.pluginFilter = "";
- spotlightContent.controller.fileSearchType = "all";
- spotlightContent.controller.fileSearchExt = "";
- spotlightContent.controller.fileSearchFolder = "";
- spotlightContent.controller.fileSearchSort = "score";
- spotlightContent.controller.collapsedSections = {};
- spotlightContent.controller.selectedFlatIndex = 0;
- spotlightContent.controller.selectedItem = null;
- spotlightContent.controller.historyIndex = -1;
- spotlightContent.controller.searchQuery = targetQuery;
-
- spotlightContent.controller.performSearch();
- }
- if (spotlightContent.resetScroll) {
- spotlightContent.resetScroll();
- }
- if (spotlightContent.actionPanel) {
- spotlightContent.actionPanel.hide();
- }
- }
-
- function _finishShow(query, mode) {
- spotlightOpen = true;
- isClosing = false;
- openedFromOverview = false;
-
- keyboardActive = true;
- ModalManager.openModal(root);
- if (useHyprlandFocusGrab)
- focusGrab.active = true;
-
- _ensureContentLoadedAndInitialize(query || "", mode || "");
- }
-
- function show() {
- closeCleanupTimer.stop();
-
- var focusedScreen = CompositorService.getFocusedScreen();
- if (focusedScreen && launcherWindow.screen !== focusedScreen) {
- spotlightOpen = false;
- isClosing = false;
- launcherWindow.screen = focusedScreen;
- Qt.callLater(() => root._finishShow("", ""));
- return;
- }
-
- _finishShow("", "");
- }
-
- function showWithQuery(query) {
- closeCleanupTimer.stop();
-
- var focusedScreen = CompositorService.getFocusedScreen();
- if (focusedScreen && launcherWindow.screen !== focusedScreen) {
- spotlightOpen = false;
- isClosing = false;
- launcherWindow.screen = focusedScreen;
- Qt.callLater(() => root._finishShow(query, ""));
- return;
- }
-
- _finishShow(query, "");
- }
-
- function hide() {
- if (!spotlightOpen)
- return;
- openedFromOverview = false;
- isClosing = true;
- contentVisible = false;
-
- keyboardActive = false;
- spotlightOpen = false;
- focusGrab.active = false;
- ModalManager.closeModal(root);
-
- closeCleanupTimer.start();
- }
-
- function toggle() {
- spotlightOpen ? hide() : show();
- }
-
- function showWithMode(mode) {
- closeCleanupTimer.stop();
-
- var focusedScreen = CompositorService.getFocusedScreen();
- if (focusedScreen && launcherWindow.screen !== focusedScreen) {
- spotlightOpen = false;
- isClosing = false;
- launcherWindow.screen = focusedScreen;
- Qt.callLater(() => root._finishShow("", mode));
- return;
- }
-
- spotlightOpen = true;
- isClosing = false;
- openedFromOverview = false;
-
- keyboardActive = true;
- ModalManager.openModal(root);
- if (useHyprlandFocusGrab)
- focusGrab.active = true;
-
- _ensureContentLoadedAndInitialize("", mode);
- }
-
- function toggleWithMode(mode) {
- if (spotlightOpen) {
- hide();
- } else {
- showWithMode(mode);
- }
- }
-
- function toggleWithQuery(query) {
- if (spotlightOpen) {
- hide();
- } else {
- showWithQuery(query);
- }
- }
-
- Timer {
- id: closeCleanupTimer
- interval: Theme.modalAnimationDuration + 50
- repeat: false
- onTriggered: {
- isClosing = false;
- if (root.unloadContentOnClose)
- launcherContentLoader.active = false;
- dialogClosed();
- }
- }
-
- Connections {
- target: spotlightContent?.controller ?? null
-
- function onModeChanged(mode) {
- if (spotlightContent.controller.autoSwitchedToFiles)
- return;
- SessionData.setLauncherLastMode(mode);
- }
- }
-
- HyprlandFocusGrab {
- id: focusGrab
- windows: [launcherWindow]
- active: false
-
- onCleared: {
- if (spotlightOpen) {
- hide();
- }
- }
- }
-
- Connections {
- target: ModalManager
- function onCloseAllModalsExcept(excludedModal) {
- if (excludedModal !== root && spotlightOpen) {
- hide();
- }
- }
- }
-
- Connections {
- target: Quickshell
- function onScreensChanged() {
- if (Quickshell.screens.length === 0)
- return;
-
- const screenName = launcherWindow.screen?.name;
- if (screenName) {
- for (let i = 0; i < Quickshell.screens.length; i++) {
- if (Quickshell.screens[i].name === screenName)
- return;
- }
- }
-
- if (spotlightOpen)
- hide();
-
- const newScreen = CompositorService.getFocusedScreen() ?? Quickshell.screens[0];
- if (newScreen)
- launcherWindow.screen = newScreen;
- }
- }
-
- PanelWindow {
- id: launcherWindow
- visible: spotlightOpen || isClosing
- color: "transparent"
- exclusionMode: ExclusionMode.Ignore
-
- WindowBlur {
- targetWindow: launcherWindow
- readonly property real s: Math.min(1, modalContainer.scale)
- blurX: root.modalX + root.modalWidth * (1 - s) * 0.5
- blurY: root.modalY + root.modalHeight * (1 - s) * 0.5
- blurWidth: (contentVisible && modalContainer.opacity > 0) ? root.modalWidth * s : 0
- blurHeight: (contentVisible && modalContainer.opacity > 0) ? root.modalHeight * s : 0
- blurRadius: root.cornerRadius
- }
-
- WlrLayershell.namespace: "dms:spotlight"
- WlrLayershell.layer: {
- switch (Quickshell.env("DMS_MODAL_LAYER")) {
- case "bottom":
- console.error("DankModal: 'bottom' layer is not valid for modals. Defaulting to 'top' layer.");
- return WlrLayershell.Top;
- case "background":
- console.error("DankModal: 'background' layer is not valid for modals. Defaulting to 'top' layer.");
- return WlrLayershell.Top;
- case "overlay":
- return WlrLayershell.Overlay;
- default:
- return WlrLayershell.Top;
- }
- }
- WlrLayershell.keyboardFocus: keyboardActive ? (root.useHyprlandFocusGrab ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.Exclusive) : WlrKeyboardFocus.None
-
- anchors {
- top: true
- bottom: true
- left: true
- right: true
- }
-
- mask: Region {
- item: spotlightOpen ? fullScreenMask : null
- }
-
- Item {
- id: fullScreenMask
- anchors.fill: parent
- }
-
- Rectangle {
- id: backgroundDarken
- anchors.fill: parent
- color: "black"
- opacity: contentVisible && SettingsData.modalDarkenBackground ? 0.5 : 0
- visible: contentVisible || opacity > 0
-
- Behavior on opacity {
- DankAnim {
- duration: Theme.modalAnimationDuration
- easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: spotlightOpen
- onClicked: mouse => {
- var contentX = modalContainer.x;
- var contentY = modalContainer.y;
- var contentW = modalContainer.width;
- var contentH = modalContainer.height;
-
- if (mouse.x < contentX || mouse.x > contentX + contentW || mouse.y < contentY || mouse.y > contentY + contentH) {
- root.hide();
- }
- }
- }
-
- Item {
- id: modalContainer
- x: root.modalX
- y: root.modalY
- width: root.modalWidth
- height: root.modalHeight
- visible: contentVisible || opacity > 0
-
- opacity: contentVisible ? 1 : 0
- scale: contentVisible ? 1 : 0.96
- transformOrigin: Item.Center
-
- Behavior on opacity {
- DankAnim {
- duration: Theme.modalAnimationDuration
- easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
- }
- }
-
- Behavior on scale {
- DankAnim {
- duration: Theme.modalAnimationDuration
- easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
- }
- }
-
- ElevationShadow {
- id: launcherShadowLayer
- anchors.fill: parent
- level: Theme.elevationLevel3
- fallbackOffset: 6
- targetColor: root.backgroundColor
- borderColor: root.borderColor
- borderWidth: root.borderWidth
- targetRadius: root.cornerRadius
- shadowEnabled: Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
- }
-
- MouseArea {
- anchors.fill: parent
- onPressed: mouse => mouse.accepted = true
- }
-
- FocusScope {
- anchors.fill: parent
- focus: keyboardActive
-
- Loader {
- id: launcherContentLoader
- anchors.fill: parent
- active: !root.unloadContentOnClose || root.spotlightOpen || root.isClosing || root.contentVisible || root._pendingInitialize
- asynchronous: false
- sourceComponent: LauncherContent {
- focus: true
- parentModal: root
- }
-
- onLoaded: {
- if (root._pendingInitialize) {
- root._initializeAndShow(root._pendingQuery, root._pendingMode);
- root._pendingInitialize = false;
- }
- }
- }
-
- Keys.onEscapePressed: event => {
- root.hide();
- event.accepted = true;
- }
- }
-
- Rectangle {
- anchors.fill: parent
- radius: root.cornerRadius
- color: "transparent"
- border.color: BlurService.borderColor
- border.width: BlurService.borderWidth
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml
deleted file mode 100644
index a7f39c3..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml
+++ /dev/null
@@ -1,105 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var item: null
- property bool isSelected: false
- property bool isHovered: itemArea.containsMouse
- property var controller: null
- property int flatIndex: -1
-
- signal clicked
- signal rightClicked(real mouseX, real mouseY)
-
- readonly property string iconValue: {
- if (!item)
- return "";
- switch (item.iconType) {
- case "material":
- case "nerd":
- return "material:" + (item.icon || "apps");
- case "unicode":
- return "unicode:" + (item.icon || "");
- case "composite":
- return item.iconFull || "";
- case "image":
- default:
- return item.icon || "";
- }
- }
-
- readonly property int computedIconSize: Math.min(48, Math.max(32, width * 0.45))
-
- radius: Theme.cornerRadius
- color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : "transparent"
-
- DankRipple {
- id: rippleLayer
- rippleColor: Theme.surfaceText
- cornerRadius: root.radius
- }
-
- Column {
- anchors.centerIn: parent
- anchors.margins: Theme.spacingS
- spacing: Theme.spacingS
- width: parent.width - Theme.spacingM
-
- AppIconRenderer {
- width: root.computedIconSize
- height: root.computedIconSize
- anchors.horizontalCenter: parent.horizontalCenter
- iconValue: root.iconValue
- iconSize: root.computedIconSize
- fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
- iconColor: root.isSelected ? Theme.primary : Theme.surfaceText
- materialIconSizeAdjustment: root.computedIconSize * 0.3
- }
-
- Text {
- width: parent.width
- text: root.item?._hName ?? root.item?.name ?? ""
- textFormat: root.item?._hRich ? Text.RichText : Text.PlainText
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- font.family: Theme.fontFamily
- color: root.isSelected ? Theme.primary : Theme.surfaceText
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignHCenter
- maximumLineCount: 2
- wrapMode: Text.Wrap
- }
- }
-
- MouseArea {
- id: itemArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onPressed: mouse => {
- if (mouse.button === Qt.LeftButton)
- rippleLayer.trigger(mouse.x, mouse.y);
- }
- onClicked: mouse => {
- if (mouse.button === Qt.RightButton) {
- var scenePos = mapToItem(null, mouse.x, mouse.y);
- root.rightClicked(scenePos.x, scenePos.y);
- } else {
- root.clicked();
- }
- }
-
- onPositionChanged: {
- if (root.controller) {
- root.controller.keyboardNavigationActive = false;
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js
deleted file mode 100644
index 61c108c..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js
+++ /dev/null
@@ -1,237 +0,0 @@
-.pragma library
-
- .import "ControllerUtils.js" as Utils
-
-function transformApp(app, override, defaultActions, primaryActionLabel) {
- var appId = app.id || app.execString || app.exec || "";
-
- var actions = [];
- if (app.actions && app.actions.length > 0) {
- for (var i = 0; i < app.actions.length; i++) {
- actions.push({
- name: app.actions[i].name,
- icon: "play_arrow",
- actionData: app.actions[i]
- });
- }
- }
-
- return {
- id: appId,
- type: "app",
- name: override?.name || app.name || "",
- subtitle: override?.comment || app.comment || "",
- icon: override?.icon || app.icon || "application-x-executable",
- iconType: "image",
- section: "apps",
- data: app,
- keywords: app.keywords || [],
- actions: actions,
- primaryAction: {
- name: primaryActionLabel,
- icon: "open_in_new",
- action: "launch"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: undefined
- };
-}
-
-function transformCoreApp(app, openLabel) {
- var iconName = "apps";
- var iconType = "material";
-
- if (app.icon) {
- if (app.icon.startsWith("svg+corner:")) {
- iconType = "composite";
- } else if (app.icon.startsWith("material:")) {
- iconName = app.icon.substring(9);
- } else {
- iconName = app.icon;
- iconType = "image";
- }
- }
-
- return {
- id: app.builtInPluginId || app.action || "",
- type: "app",
- name: app.name || "",
- subtitle: app.comment || "",
- icon: iconName,
- iconType: iconType,
- iconFull: app.icon,
- section: "apps",
- data: app,
- isCore: true,
- actions: [],
- primaryAction: {
- name: openLabel,
- icon: "open_in_new",
- action: "launch"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: undefined
- };
-}
-
-function transformBuiltInLauncherItem(item, pluginId, openLabel) {
- var rawIcon = item.icon || "extension";
- var icon = Utils.stripIconPrefix(rawIcon);
- var iconType = item.iconType;
- if (!iconType) {
- if (rawIcon.startsWith("material:"))
- iconType = "material";
- else if (rawIcon.startsWith("unicode:"))
- iconType = "unicode";
- else
- iconType = "image";
- }
-
- return {
- id: item.action || "",
- type: "plugin",
- name: item.name || "",
- subtitle: item.comment || "",
- icon: icon,
- iconType: iconType,
- section: "plugin_" + pluginId,
- data: item,
- pluginId: pluginId,
- isBuiltInLauncher: true,
- keywords: item.keywords || [],
- actions: [],
- primaryAction: {
- name: openLabel,
- icon: "open_in_new",
- action: "execute"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: item._preScored
- };
-}
-
-function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel, openTerminalLabel) {
- var filename = file.path ? file.path.split("/").pop() : "";
- var dirname = file.path ? file.path.substring(0, file.path.lastIndexOf("/")) : "";
- var isDir = file.is_dir || false;
-
- var actions = [];
- if (isDir) {
- if (openTerminalLabel) {
- actions.push({
- name: openTerminalLabel,
- icon: "terminal",
- action: "open_terminal"
- });
- }
- } else {
- actions.push({
- name: openFolderLabel,
- icon: "folder_open",
- action: "open_folder"
- });
- }
- actions.push({
- name: copyPathLabel,
- icon: "content_copy",
- action: "copy_path"
- });
-
- return {
- id: file.path || "",
- type: "file",
- name: filename,
- subtitle: dirname,
- icon: isDir ? "folder" : Utils.getFileIcon(filename),
- iconType: "material",
- section: "files",
- data: file,
- actions: actions,
- primaryAction: {
- name: openLabel,
- icon: "open_in_new",
- action: "open"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: undefined
- };
-}
-
-function transformPluginItem(item, pluginId, selectLabel) {
- var rawIcon = item.icon || "extension";
- var icon = Utils.stripIconPrefix(rawIcon);
- var iconType = item.iconType;
- if (!iconType) {
- if (rawIcon.startsWith("material:"))
- iconType = "material";
- else if (rawIcon.startsWith("unicode:"))
- iconType = "unicode";
- else
- iconType = "image";
- }
-
- return {
- id: item.id || item.name || "",
- type: "plugin",
- name: item.name || "",
- subtitle: item.comment || item.description || "",
- icon: icon,
- iconType: iconType,
- section: "plugin_" + pluginId,
- data: item,
- pluginId: pluginId,
- keywords: item.keywords || [],
- actions: item.actions || [],
- primaryAction: item.primaryAction || {
- name: selectLabel,
- icon: "check",
- action: "execute"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: item._preScored
- };
-}
-
-function createPluginBrowseItem(pluginId, plugin, trigger, isBuiltIn, isAllowed, browseLabel, triggerLabel, noTriggerLabel) {
- var rawIcon = isBuiltIn ? (plugin.cornerIcon || "extension") : (plugin.icon || "extension");
- return {
- id: "browse_" + pluginId,
- type: "plugin_browse",
- name: plugin.name || pluginId,
- subtitle: trigger ? triggerLabel.replace("%1", trigger) : noTriggerLabel,
- icon: isBuiltIn ? rawIcon : Utils.stripIconPrefix(rawIcon),
- iconType: isBuiltIn ? "material" : Utils.detectIconType(rawIcon),
- section: "browse_plugins",
- data: {
- pluginId: pluginId,
- plugin: plugin,
- isBuiltIn: isBuiltIn
- },
- actions: [
- {
- name: "All",
- icon: isAllowed ? "visibility" : "visibility_off",
- action: "toggle_all_visibility"
- }
- ],
- primaryAction: {
- name: browseLabel,
- icon: "arrow_forward",
- action: "browse_plugin"
- },
- _hName: "",
- _hSub: "",
- _hRich: false,
- _preScored: undefined
- };
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml
deleted file mode 100644
index 4372515..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml
+++ /dev/null
@@ -1,1075 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FocusScope {
- id: root
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property var parentModal: null
- property string viewModeContext: "spotlight"
- property alias searchField: searchField
- property alias controller: controller
- property alias resultsList: resultsList
- property alias actionPanel: actionPanel
-
- property bool editMode: false
- property var editingApp: null
- property string editAppId: ""
-
- function resetScroll() {
- resultsList.resetScroll();
- }
-
- function focusSearchField() {
- searchField.forceActiveFocus();
- }
-
- function openEditMode(app) {
- if (!app)
- return;
- editingApp = app;
- editAppId = app.id || app.execString || app.exec || "";
- var existing = SessionData.getAppOverride(editAppId);
- editNameField.text = existing?.name || "";
- editIconField.text = existing?.icon || "";
- editCommentField.text = existing?.comment || "";
- editEnvVarsField.text = existing?.envVars || "";
- editExtraFlagsField.text = existing?.extraFlags || "";
- editDgpuToggle.checked = existing?.launchOnDgpu || false;
- editMode = true;
- Qt.callLater(() => editNameField.forceActiveFocus());
- }
-
- function closeEditMode() {
- editMode = false;
- editingApp = null;
- editAppId = "";
- Qt.callLater(() => searchField.forceActiveFocus());
- }
-
- function saveAppOverride() {
- var override = {};
- if (editNameField.text.trim())
- override.name = editNameField.text.trim();
- if (editIconField.text.trim())
- override.icon = editIconField.text.trim();
- if (editCommentField.text.trim())
- override.comment = editCommentField.text.trim();
- if (editEnvVarsField.text.trim())
- override.envVars = editEnvVarsField.text.trim();
- if (editExtraFlagsField.text.trim())
- override.extraFlags = editExtraFlagsField.text.trim();
- if (editDgpuToggle.checked)
- override.launchOnDgpu = true;
- SessionData.setAppOverride(editAppId, override);
- closeEditMode();
- }
-
- function resetAppOverride() {
- SessionData.clearAppOverride(editAppId);
- closeEditMode();
- }
-
- function showContextMenu(item, x, y, fromKeyboard) {
- if (!item)
- return;
- if (!contextMenu.hasContextMenuActions(item))
- return;
- contextMenu.show(x, y, item, fromKeyboard);
- }
-
- anchors.fill: parent
- focus: true
-
- Controller {
- id: controller
- active: root.parentModal?.spotlightOpen ?? true
- viewModeContext: root.viewModeContext
-
- onItemExecuted: {
- if (root.parentModal) {
- root.parentModal.hide();
- }
- if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
- NiriService.toggleOverview();
- }
- }
- }
-
- LauncherContextMenu {
- id: contextMenu
- parent: root
- controller: root.controller
- searchField: root.searchField
- parentHandler: root
-
- onEditAppRequested: app => {
- root.openEditMode(app);
- }
- }
-
- Keys.onPressed: event => {
- if (editMode) {
- if (event.key === Qt.Key_Escape) {
- closeEditMode();
- event.accepted = true;
- }
- return;
- }
-
- var hasCtrl = event.modifiers & Qt.ControlModifier;
- event.accepted = true;
-
- switch (event.key) {
- case Qt.Key_Escape:
- if (actionPanel.expanded) {
- actionPanel.hide();
- return;
- }
- if (controller.clearPluginFilter())
- return;
- if (root.parentModal)
- root.parentModal.hide();
- return;
- case Qt.Key_Backspace:
- if (searchField.text.length === 0) {
- if (controller.clearPluginFilter())
- return;
- if (controller.autoSwitchedToFiles) {
- controller.restorePreviousMode();
- return;
- }
- }
- event.accepted = false;
- return;
- case Qt.Key_Down:
- if (hasCtrl) {
- controller.navigateHistory("down");
- } else {
- controller.selectNext();
- }
- return;
- case Qt.Key_Up:
- if (hasCtrl) {
- controller.navigateHistory("up");
- } else {
- controller.selectPrevious();
- }
- return;
- case Qt.Key_PageDown:
- controller.selectPageDown(8);
- return;
- case Qt.Key_PageUp:
- controller.selectPageUp(8);
- return;
- case Qt.Key_Right:
- if (hasCtrl) {
- controller.cycleMode();
- return;
- }
- if (controller.getCurrentSectionViewMode() !== "list") {
- controller.selectRight();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_Left:
- if (hasCtrl) {
- const reverse = true;
- controller.cycleMode(reverse);
- return;
- }
- if (controller.getCurrentSectionViewMode() !== "list") {
- controller.selectLeft();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_H:
- if (hasCtrl) {
- const reverse = true;
- controller.cycleMode(reverse);
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_J:
- if (hasCtrl) {
- controller.selectNext();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_K:
- if (hasCtrl) {
- controller.selectPrevious();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_L:
- if (hasCtrl) {
- controller.cycleMode();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_N:
- if (hasCtrl) {
- controller.selectNextSection();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_P:
- if (hasCtrl) {
- controller.selectPreviousSection();
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_Tab:
- if (hasCtrl && actionPanel.hasActions) {
- actionPanel.expanded ? actionPanel.cycleAction() : actionPanel.show();
- return;
- }
- controller.selectNext();
- return;
- case Qt.Key_Backtab:
- if (hasCtrl && actionPanel.expanded) {
- const reverse = true;
- actionPanel.expanded ? actionPanel.cycleAction(reverse) : actionPanel.show();
- return;
- }
- controller.selectPrevious();
- return;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (event.modifiers & Qt.ShiftModifier) {
- controller.pasteSelected();
- return;
- }
- if (actionPanel.expanded && actionPanel.selectedActionIndex > 0) {
- actionPanel.executeSelectedAction();
- } else {
- controller.executeSelected();
- }
- return;
- case Qt.Key_Menu:
- case Qt.Key_F10:
- if (contextMenu.hasContextMenuActions(controller.selectedItem)) {
- var scenePos = resultsList.getSelectedItemPosition();
- var localPos = root.mapFromItem(null, scenePos.x, scenePos.y);
- showContextMenu(controller.selectedItem, localPos.x, localPos.y, true);
- }
- return;
- case Qt.Key_1:
- if (hasCtrl) {
- controller.setMode("all");
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_2:
- if (hasCtrl) {
- controller.setMode("apps");
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_3:
- if (hasCtrl) {
- controller.setMode("files");
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_4:
- if (hasCtrl) {
- controller.setMode("plugins");
- return;
- }
- event.accepted = false;
- return;
- case Qt.Key_Slash:
- if (event.modifiers === Qt.NoModifier && searchField.text.length === 0) {
- controller.setMode("files", true);
- return;
- }
- event.accepted = false;
- return;
- default:
- event.accepted = false;
- }
- }
-
- Item {
- anchors.fill: parent
- visible: !editMode && !(root.parentModal?.isClosing ?? false)
-
- Item {
- id: footerBar
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.leftMargin: root.parentModal?.borderWidth ?? 1
- anchors.rightMargin: root.parentModal?.borderWidth ?? 1
- anchors.bottomMargin: root.parentModal?.borderWidth ?? 1
- readonly property bool showFooter: SettingsData.dankLauncherV2Size !== "micro" && SettingsData.dankLauncherV2ShowFooter
- height: showFooter ? 36 : 0
- visible: showFooter
- clip: true
-
- Rectangle {
- anchors.fill: parent
- anchors.topMargin: -Theme.cornerRadius
- color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- radius: Theme.cornerRadius
- }
-
- Row {
- id: modeButtonsRow
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingXS
- anchors.verticalCenter: parent.verticalCenter
- layoutDirection: I18n.isRtl ? Qt.RightToLeft : Qt.LeftToRight
- spacing: 2
-
- Repeater {
- model: [
- {
- id: "all",
- label: I18n.tr("All"),
- icon: "search"
- },
- {
- id: "apps",
- label: I18n.tr("Apps"),
- icon: "apps"
- },
- {
- id: "files",
- label: I18n.tr("Files"),
- icon: "folder"
- },
- {
- id: "plugins",
- label: I18n.tr("Plugins"),
- icon: "extension"
- }
- ]
-
- Rectangle {
- required property var modelData
- required property int index
-
- width: buttonContent.width + Theme.spacingM * 2
- height: 28
- radius: Theme.cornerRadius
- color: controller.searchMode === modelData.id || modeArea.containsMouse ? Theme.primaryContainer : "transparent"
-
- Row {
- id: buttonContent
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: modelData.icon
- size: 14
- color: controller.searchMode === modelData.id ? Theme.primary : Theme.surfaceVariantText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: modelData.label
- font.pixelSize: Theme.fontSizeSmall
- color: controller.searchMode === modelData.id ? Theme.primary : Theme.surfaceText
- }
- }
-
- MouseArea {
- id: modeArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: controller.setMode(modelData.id)
- }
- }
- }
- }
-
- Row {
- id: hintsRow
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- layoutDirection: I18n.isRtl ? Qt.RightToLeft : Qt.LeftToRight
- spacing: Theme.spacingM
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: "↑↓ " + I18n.tr("nav")
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: "↵ " + I18n.tr("open")
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: "Ctrl-Tab " + I18n.tr("actions")
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- visible: actionPanel.hasActions
- }
- }
- }
-
- Column {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.bottom: footerBar.top
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingM
- spacing: Theme.spacingXS
- clip: false
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- Rectangle {
- id: pluginBadge
- visible: controller.activePluginName.length > 0
- width: visible ? pluginBadgeContent.implicitWidth + Theme.spacingM : 0
- height: searchField.height
- radius: 16
- color: Theme.primary
-
- Row {
- id: pluginBadgeContent
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: "extension"
- size: 14
- color: Theme.primaryText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: controller.activePluginName
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.primaryText
- }
- }
-
- Behavior on width {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- DankTextField {
- id: searchField
- width: parent.width - (pluginBadge.visible ? pluginBadge.width + Theme.spacingS : 0)
- cornerRadius: Theme.cornerRadius
- backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- normalBorderColor: Theme.outlineMedium
- focusedBorderColor: Theme.primary
- leftIconName: controller.activePluginId ? "extension" : controller.searchQuery.startsWith("/") ? "folder" : "search"
- leftIconSize: Theme.iconSize
- leftIconColor: Theme.surfaceVariantText
- leftIconFocusedColor: Theme.primary
- showClearButton: true
- textColor: Theme.surfaceText
- font.pixelSize: Theme.fontSizeLarge
- enabled: root.parentModal ? root.parentModal.spotlightOpen : true
- placeholderText: ""
- ignoreUpDownKeys: true
- ignoreTabKeys: true
- keyForwardTargets: [root]
-
- onTextChanged: {
- controller.setSearchQuery(text);
- if (actionPanel.expanded) {
- actionPanel.hide();
- }
- }
-
- Keys.onPressed: event => {
- if (event.key === Qt.Key_Escape) {
- if (root.parentModal) {
- root.parentModal.hide();
- }
- event.accepted = true;
- } else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)) {
- if (actionPanel.expanded && actionPanel.selectedActionIndex > 0) {
- actionPanel.executeSelectedAction();
- } else {
- controller.executeSelected();
- }
- event.accepted = true;
- }
- }
- }
- }
-
- Row {
- id: categoryRow
- width: parent.width
- readonly property bool showPluginCategories: controller.activePluginCategories.length > 0
- height: showPluginCategories ? 36 : 0
- visible: showPluginCategories
- spacing: Theme.spacingS
-
- clip: true
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- DankDropdown {
- id: categoryDropdown
- visible: categoryRow.showPluginCategories
- width: Math.min(200, parent.width)
- compactMode: true
- dropdownWidth: 200
- popupWidth: 240
- maxPopupHeight: 300
- enableFuzzySearch: controller.activePluginCategories.length > 8
- currentValue: {
- const cats = controller.activePluginCategories;
- const current = controller.activePluginCategory;
- if (!current)
- return cats.length > 0 ? cats[0].name : "";
- for (let i = 0; i < cats.length; i++) {
- if (cats[i].id === current)
- return cats[i].name;
- }
- return cats.length > 0 ? cats[0].name : "";
- }
- options: {
- const cats = controller.activePluginCategories;
- const names = [];
- for (let i = 0; i < cats.length; i++)
- names.push(cats[i].name);
- return names;
- }
-
- onValueChanged: value => {
- const cats = controller.activePluginCategories;
- for (let i = 0; i < cats.length; i++) {
- if (cats[i].name === value) {
- controller.setActivePluginCategory(cats[i].id);
- return;
- }
- }
- }
- }
- }
-
- Item {
- id: fileFilterRow
- width: parent.width
- height: showFileFilters ? fileFilterContent.height : 0
- visible: showFileFilters
-
- readonly property bool showFileFilters: controller.searchMode === "files"
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Row {
- id: fileFilterContent
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- id: typeChips
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
- visible: DSearchService.supportsTypeFilter
-
- Repeater {
- model: [
- {
- id: "all",
- label: I18n.tr("All"),
- icon: "search"
- },
- {
- id: "file",
- label: I18n.tr("Files"),
- icon: "insert_drive_file"
- },
- {
- id: "dir",
- label: I18n.tr("Folders"),
- icon: "folder"
- }
- ]
-
- Rectangle {
- required property var modelData
- required property int index
-
- width: chipContent.width + Theme.spacingM * 2
- height: sortDropdown.height
- radius: Theme.cornerRadius
- color: controller.fileSearchType === modelData.id || chipArea.containsMouse ? Theme.primaryContainer : "transparent"
-
- Row {
- id: chipContent
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: modelData.icon
- size: 14
- color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceVariantText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: modelData.label
- font.pixelSize: Theme.fontSizeSmall
- color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceText
- }
- }
-
- MouseArea {
- id: chipArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: controller.setFileSearchType(modelData.id)
- }
- }
- }
- }
-
- Rectangle {
- width: 1
- height: 20
- anchors.verticalCenter: parent.verticalCenter
- color: Theme.outlineMedium
- visible: typeChips.visible
- }
-
- DankDropdown {
- id: sortDropdown
- anchors.verticalCenter: parent.verticalCenter
- width: Math.min(130, parent.width / 3)
- compactMode: true
- dropdownWidth: 130
- popupWidth: 150
- maxPopupHeight: 200
- currentValue: {
- switch (controller.fileSearchSort) {
- case "score":
- return I18n.tr("Score");
- case "name":
- return I18n.tr("Name");
- case "modified":
- return I18n.tr("Modified");
- case "size":
- return I18n.tr("Size");
- default:
- return I18n.tr("Score");
- }
- }
- options: [I18n.tr("Score"), I18n.tr("Name"), I18n.tr("Modified"), I18n.tr("Size")]
-
- onValueChanged: value => {
- var sortMap = {};
- sortMap[I18n.tr("Score")] = "score";
- sortMap[I18n.tr("Name")] = "name";
- sortMap[I18n.tr("Modified")] = "modified";
- sortMap[I18n.tr("Size")] = "size";
- controller.setFileSearchSort(sortMap[value] || "score");
- }
- }
-
- DankTextField {
- id: extFilterField
- anchors.verticalCenter: parent.verticalCenter
- width: Math.min(100, parent.width / 4)
- height: sortDropdown.height
- placeholderText: I18n.tr("ext")
- font.pixelSize: Theme.fontSizeSmall
- showClearButton: text.length > 0
-
- onTextChanged: {
- controller.setFileSearchExt(text.trim());
- }
- }
- }
- }
-
- Item {
- width: parent.width
- height: parent.height - searchField.height - categoryRow.height - fileFilterRow.height - actionPanel.height - Theme.spacingXS * ((categoryRow.visible ? 1 : 0) + (fileFilterRow.visible ? 1 : 0) + 2)
- ResultsList {
- id: resultsList
- anchors.fill: parent
- controller: root.controller
-
- onItemRightClicked: (index, item, sceneX, sceneY) => {
- if (item && contextMenu.hasContextMenuActions(item)) {
- var localPos = root.mapFromItem(null, sceneX, sceneY);
- root.showContextMenu(item, localPos.x, localPos.y, false);
- }
- }
- }
- }
-
- ActionPanel {
- id: actionPanel
- width: parent.width
- selectedItem: controller.selectedItem
- controller: controller
- }
- }
- }
-
- Connections {
- target: controller
- function onSelectedItemChanged() {
- if (actionPanel.expanded && !actionPanel.hasActions) {
- actionPanel.hide();
- }
- }
- function onSearchQueryRequested(query) {
- searchField.text = query;
- searchField.cursorPosition = query.length;
- }
- function onModeChanged() {
- extFilterField.text = "";
- }
- }
-
- FocusScope {
- id: editView
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- visible: editMode
- focus: editMode
-
- Keys.onPressed: event => {
- if (event.key === Qt.Key_Escape) {
- closeEditMode();
- event.accepted = true;
- } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
- if (event.modifiers & Qt.ControlModifier) {
- saveAppOverride();
- event.accepted = true;
- }
- } else if (event.key === Qt.Key_S && event.modifiers & Qt.ControlModifier) {
- saveAppOverride();
- event.accepted = true;
- }
- }
-
- Column {
- anchors.fill: parent
- spacing: Theme.spacingM
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- Rectangle {
- width: 40
- height: 40
- radius: Theme.cornerRadius
- color: backButtonArea.containsMouse ? Theme.surfaceHover : "transparent"
-
- DankIcon {
- anchors.centerIn: parent
- name: "arrow_back"
- size: 20
- color: Theme.surfaceText
- }
-
- MouseArea {
- id: backButtonArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: closeEditMode()
- }
- }
-
- Image {
- width: 40
- height: 40
- source: Paths.resolveIconUrl(editingApp?.icon || "application-x-executable")
- sourceSize.width: 40
- sourceSize.height: 40
- fillMode: Image.PreserveAspectFit
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
-
- StyledText {
- text: I18n.tr("Edit App")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: editingApp?.name || ""
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- }
-
- Flickable {
- width: parent.width
- height: parent.height - y - buttonsRow.height - Theme.spacingM
- contentHeight: editFieldsColumn.height
- clip: true
- boundsBehavior: Flickable.StopAtBounds
-
- Column {
- id: editFieldsColumn
- width: parent.width
- spacing: Theme.spacingS
-
- Column {
- width: parent.width
- spacing: 4
-
- StyledText {
- text: I18n.tr("Name")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- DankTextField {
- id: editNameField
- width: parent.width
- placeholderText: editingApp?.name || ""
- keyNavigationTab: editIconField
- keyNavigationBacktab: editExtraFlagsField
- }
- }
-
- Column {
- width: parent.width
- spacing: 4
-
- StyledText {
- text: I18n.tr("Icon")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- DankTextField {
- id: editIconField
- width: parent.width
- placeholderText: editingApp?.icon || ""
- keyNavigationTab: editCommentField
- keyNavigationBacktab: editNameField
- }
- }
-
- Column {
- width: parent.width
- spacing: 4
-
- StyledText {
- text: I18n.tr("Description")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- DankTextField {
- id: editCommentField
- width: parent.width
- placeholderText: editingApp?.comment || ""
- keyNavigationTab: editEnvVarsField
- keyNavigationBacktab: editIconField
- }
- }
-
- Column {
- width: parent.width
- spacing: 4
-
- StyledText {
- text: I18n.tr("Environment Variables")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: "KEY=value KEY2=value2"
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- }
-
- DankTextField {
- id: editEnvVarsField
- width: parent.width
- placeholderText: "VAR=value"
- keyNavigationTab: editExtraFlagsField
- keyNavigationBacktab: editCommentField
- }
- }
-
- Column {
- width: parent.width
- spacing: 4
-
- StyledText {
- text: I18n.tr("Extra Arguments")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- DankTextField {
- id: editExtraFlagsField
- width: parent.width
- placeholderText: "--flag --option=value"
- keyNavigationTab: editNameField
- keyNavigationBacktab: editEnvVarsField
- }
- }
-
- DankToggle {
- id: editDgpuToggle
- width: parent.width
- text: I18n.tr("Launch on dGPU by default")
- visible: SessionService.nvidiaCommand.length > 0
- checked: false
- onToggled: checked => editDgpuToggle.checked = checked
- }
- }
- }
-
- Row {
- id: buttonsRow
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- id: resetButton
- width: 90
- height: 40
- radius: Theme.cornerRadius
- color: resetButtonArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariantAlpha
- visible: SessionData.getAppOverride(editAppId) !== null
-
- StyledText {
- text: I18n.tr("Reset")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.error
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: resetButtonArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: resetAppOverride()
- }
- }
-
- Rectangle {
- id: cancelButton
- width: 90
- height: 40
- radius: Theme.cornerRadius
- color: cancelButtonArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariantAlpha
-
- StyledText {
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: cancelButtonArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: closeEditMode()
- }
- }
-
- Rectangle {
- id: saveButton
- width: 90
- height: 40
- radius: Theme.cornerRadius
- color: saveButtonArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.9) : Theme.primary
-
- StyledText {
- text: I18n.tr("Save")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.primaryText
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: saveButtonArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: saveAppOverride()
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml
deleted file mode 100644
index 3c55590..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml
+++ /dev/null
@@ -1,510 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import QtQuick.Controls
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Popup {
- id: root
-
- property var item: null
- property var controller: null
- property var searchField: null
- property var parentHandler: null
-
- signal hideRequested
- signal editAppRequested(var app)
-
- function hasContextMenuActions(spotlightItem) {
- if (!spotlightItem)
- return false;
- if (spotlightItem.type === "app")
- return true;
- if (spotlightItem.type === "plugin" && spotlightItem.pluginId) {
- var instance = PluginService.pluginInstances[spotlightItem.pluginId];
- if (!instance)
- return false;
- if (typeof instance.getContextMenuActions !== "function")
- return false;
- var actions = instance.getContextMenuActions(spotlightItem.data);
- return Array.isArray(actions) && actions.length > 0;
- }
- return false;
- }
-
- readonly property bool isCoreApp: item?.type === "app" && !!item?.isCore
- readonly property var coreAppData: isCoreApp ? item?.data ?? null : null
- readonly property var desktopEntry: !isCoreApp ? (item?.data ?? null) : null
- readonly property string appId: {
- if (isCoreApp) {
- return item?.id || coreAppData?.builtInPluginId || "";
- }
- return desktopEntry?.id || desktopEntry?.execString || "";
- }
- readonly property bool isPinned: appId ? SessionData.isPinnedApp(appId) : false
- readonly property bool isRegularApp: item?.type === "app" && !item.isCore && desktopEntry
- readonly property bool isPluginItem: item?.type === "plugin"
-
- function getPluginContextMenuActions() {
- if (!isPluginItem || !item?.pluginId)
- return [];
-
- var instance = PluginService.pluginInstances[item.pluginId];
- if (!instance)
- return [];
- if (typeof instance.getContextMenuActions !== "function")
- return [];
-
- var actions = instance.getContextMenuActions(item.data);
- if (!Array.isArray(actions))
- return [];
-
- return actions;
- }
-
- function executePluginAction(actionOrObj) {
- var actionFunc = typeof actionOrObj === "function" ? actionOrObj : actionOrObj?.action;
- var closeLauncher = typeof actionOrObj === "object" && actionOrObj?.closeLauncher;
-
- if (typeof actionFunc === "function")
- actionFunc();
-
- if (closeLauncher) {
- controller?.itemExecuted();
- } else {
- controller?.performSearch();
- }
- hide();
- }
-
- readonly property var menuItems: {
- var items = [];
-
- if (isPluginItem) {
- var pluginActions = getPluginContextMenuActions();
- for (var i = 0; i < pluginActions.length; i++) {
- var act = pluginActions[i];
- items.push({
- type: "item",
- icon: act.icon || "play_arrow",
- text: act.text || act.name || "",
- pluginAction: act
- });
- }
- return items;
- }
-
- if (item?.type === "app") {
- items.push({
- type: "item",
- icon: isPinned ? "keep_off" : "push_pin",
- text: isPinned ? I18n.tr("Unpin from Dock") : I18n.tr("Pin to Dock"),
- action: togglePin
- });
- }
-
- if (isRegularApp) {
- items.push({
- type: "item",
- icon: "visibility_off",
- text: I18n.tr("Hide App"),
- action: hideCurrentApp
- });
- items.push({
- type: "item",
- icon: "edit",
- text: I18n.tr("Edit App"),
- action: editCurrentApp
- });
- }
-
- if (item?.actions && item.actions.length > 0) {
- items.push({
- type: "separator"
- });
- for (var i = 0; i < item.actions.length; i++) {
- var act = item.actions[i];
- items.push({
- type: "item",
- icon: act.icon || "play_arrow",
- text: act.name || "",
- actionData: act
- });
- }
- }
-
- items.push({
- type: "separator"
- });
-
- if (isRegularApp && SessionService.nvidiaCommand) {
- items.push({
- type: "item",
- icon: "memory",
- text: I18n.tr("Launch on dGPU"),
- action: launchWithNvidia
- });
- }
-
- items.push({
- type: "item",
- icon: "launch",
- text: I18n.tr("Launch"),
- action: launchApp
- });
-
- return items;
- }
-
- function show(x, y, spotlightItem, fromKeyboard) {
- if (!spotlightItem?.data)
- return;
- item = spotlightItem;
- selectedMenuIndex = fromKeyboard ? 0 : -1;
- keyboardNavigation = fromKeyboard;
-
- if (parentHandler)
- parentHandler.enabled = false;
-
- Qt.callLater(() => {
- var parentW = parent?.width ?? 500;
- var parentH = parent?.height ?? 600;
- var menuW = width > 0 ? width : 200;
- var menuH = height > 0 ? height : 200;
- var margin = 8;
-
- var posX = x + 4;
- var posY = y + 4;
-
- if (posX + menuW > parentW - margin) {
- posX = Math.max(margin, parentW - menuW - margin);
- }
- if (posY + menuH > parentH - margin) {
- posY = Math.max(margin, parentH - menuH - margin);
- }
-
- root.x = posX;
- root.y = posY;
- open();
- });
- }
-
- function hide() {
- if (parentHandler)
- parentHandler.enabled = true;
- close();
- }
-
- function togglePin() {
- if (!appId)
- return;
- if (isPinned)
- SessionData.removePinnedApp(appId);
- else
- SessionData.addPinnedApp(appId);
- hide();
- }
-
- function hideCurrentApp() {
- if (!appId)
- return;
- SessionData.hideApp(appId);
- controller?.performSearch();
- hide();
- }
-
- function editCurrentApp() {
- if (!desktopEntry)
- return;
- editAppRequested(desktopEntry);
- hide();
- }
-
- function launchApp() {
- if (isCoreApp) {
- if (!coreAppData)
- return;
- AppSearchService.executeCoreApp(coreAppData);
- controller?.itemExecuted();
- hide();
- return;
- }
- if (!desktopEntry)
- return;
- SessionService.launchDesktopEntry(desktopEntry);
- AppUsageHistoryData.addAppUsage(desktopEntry);
- controller?.itemExecuted();
- hide();
- }
-
- function launchWithNvidia() {
- if (!desktopEntry)
- return;
- SessionService.launchDesktopEntry(desktopEntry, true);
- AppUsageHistoryData.addAppUsage(desktopEntry);
- controller?.itemExecuted();
- hide();
- }
-
- function executeDesktopAction(actionData) {
- if (!desktopEntry || !actionData)
- return;
- SessionService.launchDesktopAction(desktopEntry, actionData.actionData || actionData);
- AppUsageHistoryData.addAppUsage(desktopEntry);
- controller?.itemExecuted();
- hide();
- }
-
- property int selectedMenuIndex: 0
- property bool keyboardNavigation: false
-
- readonly property int visibleItemCount: {
- var count = 0;
- for (var i = 0; i < menuItems.length; i++) {
- if (menuItems[i].type === "item")
- count++;
- }
- return count;
- }
-
- function selectNext() {
- if (visibleItemCount > 0)
- selectedMenuIndex = (selectedMenuIndex + 1) % visibleItemCount;
- }
-
- function selectPrevious() {
- if (visibleItemCount > 0)
- selectedMenuIndex = (selectedMenuIndex - 1 + visibleItemCount) % visibleItemCount;
- }
-
- function activateSelected() {
- var itemIndex = 0;
- for (var i = 0; i < menuItems.length; i++) {
- if (menuItems[i].type !== "item")
- continue;
- if (itemIndex === selectedMenuIndex) {
- var menuItem = menuItems[i];
- if (menuItem.action)
- menuItem.action();
- else if (menuItem.pluginAction)
- executePluginAction(menuItem.pluginAction);
- else if (menuItem.actionData)
- executeDesktopAction(menuItem.actionData);
- return;
- }
- itemIndex++;
- }
- }
-
- width: menuContainer.implicitWidth
- height: menuContainer.implicitHeight
- padding: 0
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
- modal: true
- dim: false
- background: Item {}
-
- onOpened: {
- Qt.callLater(() => keyboardHandler.forceActiveFocus());
- }
-
- onClosed: {
- if (parentHandler)
- parentHandler.enabled = true;
- if (searchField?.visible) {
- Qt.callLater(() => searchField.forceActiveFocus());
- }
- }
-
- enter: Transition {
- NumberAnimation {
- property: "opacity"
- from: 0
- to: 1
- duration: Theme.shortDuration
- easing.type: Theme.emphasizedEasing
- }
- }
-
- exit: Transition {
- NumberAnimation {
- property: "opacity"
- from: 1
- to: 0
- duration: Theme.shortDuration
- easing.type: Theme.emphasizedEasing
- }
- }
-
- contentItem: Item {
- id: keyboardHandler
- focus: true
- implicitWidth: menuContainer.implicitWidth
- implicitHeight: menuContainer.implicitHeight
-
- Keys.onPressed: event => {
- switch (event.key) {
- case Qt.Key_Down:
- root.selectNext();
- event.accepted = true;
- return;
- case Qt.Key_Up:
- root.selectPrevious();
- event.accepted = true;
- return;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- root.activateSelected();
- event.accepted = true;
- return;
- case Qt.Key_Escape:
- case Qt.Key_Left:
- root.hide();
- event.accepted = true;
- return;
- }
- }
-
- Rectangle {
- id: menuContainer
- anchors.fill: parent
- implicitWidth: Math.max(180, menuColumn.implicitWidth + Theme.spacingS * 2)
- implicitHeight: menuColumn.implicitHeight + Theme.spacingS * 2
- color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- radius: Theme.cornerRadius
- border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
- border.width: 1
-
- Rectangle {
- anchors.fill: parent
- anchors.topMargin: 4
- anchors.leftMargin: 2
- anchors.rightMargin: -2
- anchors.bottomMargin: -4
- radius: parent.radius
- color: Qt.rgba(0, 0, 0, 0.15)
- z: -1
- }
-
- Column {
- id: menuColumn
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- spacing: 1
-
- Repeater {
- model: root.menuItems
-
- Item {
- id: menuItemDelegate
- required property var modelData
- required property int index
-
- width: menuColumn.width
- height: modelData.type === "separator" ? 5 : 32
-
- readonly property int itemIndex: {
- var count = 0;
- for (var i = 0; i < index; i++) {
- if (root.menuItems[i].type === "item")
- count++;
- }
- return count;
- }
-
- Rectangle {
- visible: menuItemDelegate.modelData.type === "separator"
- width: parent.width - Theme.spacingS * 2
- height: parent.height
- anchors.horizontalCenter: parent.horizontalCenter
- color: "transparent"
-
- Rectangle {
- anchors.centerIn: parent
- width: parent.width
- height: 1
- color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
- }
- }
-
- Rectangle {
- visible: menuItemDelegate.modelData.type === "item"
- width: parent.width
- height: parent.height
- radius: Theme.cornerRadius
- color: {
- if (root.keyboardNavigation && root.selectedMenuIndex === menuItemDelegate.itemIndex) {
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2);
- }
- return itemMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent";
- }
-
- Row {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingS
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- Item {
- width: Theme.iconSize - 2
- height: Theme.iconSize - 2
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- visible: (menuItemDelegate.modelData?.icon ?? "").length > 0
- name: menuItemDelegate.modelData?.icon ?? ""
- size: Theme.iconSize - 2
- color: Theme.surfaceText
- opacity: 0.7
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- StyledText {
- text: menuItemDelegate.modelData.text || ""
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- font.weight: Font.Normal
- anchors.verticalCenter: parent.verticalCenter
- elide: Text.ElideRight
- width: parent.width - (Theme.iconSize - 2) - Theme.spacingS
- }
- }
-
- DankRipple {
- id: menuItemRipple
- rippleColor: Theme.surfaceText
- cornerRadius: Theme.cornerRadius
- }
-
- MouseArea {
- id: itemMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onEntered: {
- root.keyboardNavigation = false;
- root.selectedMenuIndex = menuItemDelegate.itemIndex;
- }
- onPressed: mouse => menuItemRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- var menuItem = menuItemDelegate.modelData;
- if (menuItem.action)
- menuItem.action();
- else if (menuItem.pluginAction)
- root.executePluginAction(menuItem.pluginAction);
- else if (menuItem.actionData)
- root.executeDesktopAction(menuItem.actionData);
- }
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js
deleted file mode 100644
index 1e78b11..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js
+++ /dev/null
@@ -1,254 +0,0 @@
-.pragma library
-
-function getFirstItemIndex(flatModel) {
- for (var i = 0; i < flatModel.length; i++) {
- if (!flatModel[i].isHeader)
- return i;
- }
- return 0;
-}
-
-function findNextNonHeaderIndex(flatModel, startIndex) {
- for (var i = startIndex; i < flatModel.length; i++) {
- if (!flatModel[i].isHeader)
- return i;
- }
- return -1;
-}
-
-function findPrevNonHeaderIndex(flatModel, startIndex) {
- for (var i = startIndex; i >= 0; i--) {
- if (!flatModel[i].isHeader)
- return i;
- }
- return -1;
-}
-
-function getSectionBounds(flatModel, sectionId) {
- if (flatModel._sectionBounds && flatModel._sectionBounds[sectionId])
- return flatModel._sectionBounds[sectionId];
-
- var start = -1, end = -1;
- for (var i = 0; i < flatModel.length; i++) {
- if (flatModel[i].isHeader && flatModel[i].section?.id === sectionId) {
- start = i + 1;
- } else if (start >= 0 && !flatModel[i].isHeader && flatModel[i].sectionId === sectionId) {
- end = i;
- } else if (start >= 0 && end >= 0 && flatModel[i].sectionId !== sectionId) {
- break;
- }
- }
- return {
- start: start,
- end: end,
- count: end >= start ? end - start + 1 : 0
- };
-}
-
-function getGridColumns(viewMode, gridColumns) {
- switch (viewMode) {
- case "tile":
- return 3;
- case "grid":
- return gridColumns;
- default:
- return 1;
- }
-}
-
-function calculateNextIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var entry = flatModel[selectedFlatIndex];
- if (!entry || entry.isHeader) {
- var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
- return next !== -1 ? next : selectedFlatIndex;
- }
-
- var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId);
- if (actualViewMode === "list") {
- var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
- return next !== -1 ? next : selectedFlatIndex;
- }
-
- var bounds = getSectionBounds(flatModel, entry.sectionId);
- var cols = getGridColumns(actualViewMode, gridColumns);
- var posInSection = selectedFlatIndex - bounds.start;
- var newPosInSection = posInSection + cols;
-
- if (newPosInSection < bounds.count) {
- return bounds.start + newPosInSection;
- }
-
- var currentRow = Math.floor(posInSection / cols);
- var lastRow = Math.floor((bounds.count - 1) / cols);
- if (currentRow < lastRow) {
- return bounds.start + bounds.count - 1;
- }
-
- var nextSection = findNextNonHeaderIndex(flatModel, bounds.end + 1);
- return nextSection !== -1 ? nextSection : selectedFlatIndex;
-}
-
-function calculatePrevIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var entry = flatModel[selectedFlatIndex];
- if (!entry || entry.isHeader) {
- var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
- return prev !== -1 ? prev : selectedFlatIndex;
- }
-
- var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId);
- if (actualViewMode === "list") {
- var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
- return prev !== -1 ? prev : selectedFlatIndex;
- }
-
- var bounds = getSectionBounds(flatModel, entry.sectionId);
- var cols = getGridColumns(actualViewMode, gridColumns);
- var posInSection = selectedFlatIndex - bounds.start;
- var newPosInSection = posInSection - cols;
-
- if (newPosInSection >= 0) {
- return bounds.start + newPosInSection;
- }
-
- var prevItem = findPrevNonHeaderIndex(flatModel, bounds.start - 1);
- return prevItem !== -1 ? prevItem : selectedFlatIndex;
-}
-
-function calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var entry = flatModel[selectedFlatIndex];
- if (!entry || entry.isHeader) {
- var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
- return next !== -1 ? next : selectedFlatIndex;
- }
-
- var viewMode = getSectionViewModeFn(entry.sectionId);
- if (viewMode === "list") {
- var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
- return next !== -1 ? next : selectedFlatIndex;
- }
-
- var bounds = getSectionBounds(flatModel, entry.sectionId);
- var posInSection = selectedFlatIndex - bounds.start;
- if (posInSection + 1 < bounds.count) {
- return bounds.start + posInSection + 1;
- }
- return selectedFlatIndex;
-}
-
-function calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var entry = flatModel[selectedFlatIndex];
- if (!entry || entry.isHeader) {
- var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
- return prev !== -1 ? prev : selectedFlatIndex;
- }
-
- var viewMode = getSectionViewModeFn(entry.sectionId);
- if (viewMode === "list") {
- var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
- return prev !== -1 ? prev : selectedFlatIndex;
- }
-
- var bounds = getSectionBounds(flatModel, entry.sectionId);
- var posInSection = selectedFlatIndex - bounds.start;
- if (posInSection > 0) {
- return bounds.start + posInSection - 1;
- }
- return selectedFlatIndex;
-}
-
-function calculateNextSectionIndex(flatModel, selectedFlatIndex) {
- var currentSection = null;
- if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
- currentSection = flatModel[selectedFlatIndex].sectionId;
- }
-
- var foundCurrent = false;
- for (var i = 0; i < flatModel.length; i++) {
- if (flatModel[i].isHeader) {
- if (foundCurrent) {
- for (var j = i + 1; j < flatModel.length; j++) {
- if (!flatModel[j].isHeader)
- return j;
- }
- }
- if (flatModel[i].section.id === currentSection) {
- foundCurrent = true;
- }
- }
- }
- return selectedFlatIndex;
-}
-
-function calculatePrevSectionIndex(flatModel, selectedFlatIndex) {
- var currentSection = null;
- if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
- currentSection = flatModel[selectedFlatIndex].sectionId;
- }
-
- var lastSectionStart = -1;
- var prevSectionStart = -1;
-
- for (var i = 0; i < flatModel.length; i++) {
- if (flatModel[i].isHeader) {
- if (flatModel[i].section.id === currentSection) {
- break;
- }
- prevSectionStart = lastSectionStart;
- lastSectionStart = i;
- }
- }
-
- if (prevSectionStart >= 0) {
- for (var j = prevSectionStart + 1; j < flatModel.length; j++) {
- if (!flatModel[j].isHeader)
- return j;
- }
- }
- return selectedFlatIndex;
-}
-
-function calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var itemsToSkip = visibleItems || 8;
- var newIndex = selectedFlatIndex;
-
- for (var i = 0; i < itemsToSkip; i++) {
- var next = findNextNonHeaderIndex(flatModel, newIndex + 1);
- if (next === -1)
- break;
- newIndex = next;
- }
-
- return newIndex;
-}
-
-function calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems) {
- if (flatModel.length === 0)
- return selectedFlatIndex;
-
- var itemsToSkip = visibleItems || 8;
- var newIndex = selectedFlatIndex;
-
- for (var i = 0; i < itemsToSkip; i++) {
- var prev = findPrevNonHeaderIndex(flatModel, newIndex - 1);
- if (prev === -1)
- break;
- newIndex = prev;
- }
-
- return newIndex;
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml
deleted file mode 100644
index 0a50cd3..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml
+++ /dev/null
@@ -1,196 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var item: null
- property bool isSelected: false
- property bool isHovered: itemArea.containsMouse || allModeToggleArea.containsMouse
- property var controller: null
- property int flatIndex: -1
-
- signal clicked
- signal rightClicked(real mouseX, real mouseY)
-
- readonly property string iconValue: {
- if (!item)
- return "";
- switch (item.iconType) {
- case "material":
- case "nerd":
- return "material:" + (item.icon || "apps");
- case "unicode":
- return "unicode:" + (item.icon || "");
- case "composite":
- return item.iconFull || "";
- case "image":
- default:
- return item.icon || "";
- }
- }
-
- width: parent?.width ?? 200
- height: 52
- color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : "transparent"
- radius: Theme.cornerRadius
-
- DankRipple {
- id: rippleLayer
- rippleColor: Theme.surfaceText
- cornerRadius: root.radius
- }
-
- MouseArea {
- id: itemArea
- z: 1
- anchors.fill: parent
- anchors.rightMargin: root.item?.type === "plugin_browse" ? 40 : 0
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onPressed: mouse => {
- if (mouse.button === Qt.LeftButton)
- rippleLayer.trigger(mouse.x, mouse.y);
- }
- onClicked: mouse => {
- if (mouse.button === Qt.RightButton) {
- var scenePos = mapToItem(null, mouse.x, mouse.y);
- root.rightClicked(scenePos.x, scenePos.y);
- } else {
- root.clicked();
- }
- }
-
- onPositionChanged: {
- if (root.controller)
- root.controller.keyboardNavigationActive = false;
- }
- }
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- AppIconRenderer {
- width: 36
- height: 36
- anchors.verticalCenter: parent.verticalCenter
- iconValue: root.iconValue
- iconSize: 36
- fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
- materialIconSizeAdjustment: 12
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- width: parent.width - 36 - Theme.spacingM * 3 - rightContent.width
- spacing: 2
-
- Text {
- width: parent.width
- text: root.item?._hName ?? root.item?.name ?? ""
- textFormat: root.item?._hRich ? Text.RichText : Text.PlainText
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- font.family: Theme.fontFamily
- color: Theme.surfaceText
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignLeft
- }
-
- Text {
- width: parent.width
- text: root.item?._hSub ?? root.item?.subtitle ?? ""
- textFormat: root.item?._hRich ? Text.RichText : Text.PlainText
- font.pixelSize: Theme.fontSizeSmall
- font.family: Theme.fontFamily
- color: Theme.surfaceVariantText
- elide: Text.ElideRight
- clip: true
- visible: (root.item?.subtitle ?? "").length > 0
- horizontalAlignment: Text.AlignLeft
- }
- }
-
- Row {
- id: rightContent
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- Rectangle {
- id: allModeToggle
- visible: root.item?.type === "plugin_browse"
- width: 28
- height: 28
- radius: 14
- anchors.verticalCenter: parent.verticalCenter
- color: allModeToggleArea.containsMouse ? Theme.surfaceHover : "transparent"
-
- property bool isAllowed: {
- if (root.item?.type !== "plugin_browse")
- return false;
- var pluginId = root.item?.data?.pluginId;
- if (!pluginId)
- return false;
- SettingsData.launcherPluginVisibility;
- return SettingsData.getPluginAllowWithoutTrigger(pluginId);
- }
-
- DankIcon {
- anchors.centerIn: parent
- name: allModeToggle.isAllowed ? "visibility" : "visibility_off"
- size: 18
- color: allModeToggle.isAllowed ? Theme.primary : Theme.surfaceVariantText
- }
-
- MouseArea {
- id: allModeToggleArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- var pluginId = root.item?.data?.pluginId;
- if (!pluginId)
- return;
- SettingsData.setPluginAllowWithoutTrigger(pluginId, !allModeToggle.isAllowed);
- }
- }
- }
-
- Rectangle {
- visible: !!root.item?.type && root.item.type !== "app" && root.item.type !== "plugin_browse"
- width: typeBadge.implicitWidth + Theme.spacingS * 2
- height: 20
- radius: 10
- color: Theme.surfaceVariantAlpha
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- id: typeBadge
- anchors.centerIn: parent
- text: {
- if (!root.item)
- return "";
- switch (root.item.type) {
- case "plugin":
- return I18n.tr("Plugin");
- case "file":
- return root.item.data?.is_dir ? I18n.tr("Folder") : I18n.tr("File");
- default:
- return "";
- }
- }
- font.pixelSize: Theme.fontSizeSmall - 2
- color: Theme.surfaceVariantText
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml
deleted file mode 100644
index 53a2d45..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml
+++ /dev/null
@@ -1,498 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- property var controller: null
- property int gridColumns: controller?.gridColumns ?? 4
- property var _visualRows: []
- property var _flatIndexToRowMap: ({})
- property var _cumulativeHeights: []
-
- signal itemRightClicked(int index, var item, real mouseX, real mouseY)
-
- function _rebuildVisualModel() {
- var sections = root.controller?.sections ?? [];
- var rows = [];
- var indexMap = {};
- var cumHeights = [];
- var cumY = 0;
-
- for (var s = 0; s < sections.length; s++) {
- var section = sections[s];
- var sectionId = section.id;
-
- cumHeights.push(cumY);
- rows.push({
- _rowId: "h_" + sectionId,
- type: "header",
- section: section,
- sectionId: sectionId,
- height: 32
- });
- cumY += 32;
-
- if (section.collapsed)
- continue;
-
- var versionTrigger = root.controller?.viewModeVersion ?? 0;
- void (versionTrigger);
- var mode = root.controller?.getSectionViewMode(sectionId) ?? "list";
- var items = section.items ?? [];
- var flatStartIndex = section.flatStartIndex ?? 0;
-
- if (mode === "list") {
- for (var i = 0; i < items.length; i++) {
- var flatIdx = flatStartIndex + i;
- indexMap[flatIdx] = rows.length;
- cumHeights.push(cumY);
- rows.push({
- _rowId: items[i].id,
- type: "list_item",
- item: items[i],
- flatIndex: flatIdx,
- sectionId: sectionId,
- height: 52
- });
- cumY += 52;
- }
- } else {
- var cols = root.controller?.getGridColumns(sectionId) ?? root.gridColumns;
- var cellWidth = mode === "tile" ? Math.floor(root.width / 3) : Math.floor(root.width / root.gridColumns);
- var cellHeight = mode === "tile" ? cellWidth * 0.75 : cellWidth + 24;
- var numRows = Math.ceil(items.length / cols);
-
- for (var r = 0; r < numRows; r++) {
- var rowItems = [];
- for (var c = 0; c < cols; c++) {
- var idx = r * cols + c;
- if (idx >= items.length)
- break;
- var fi = flatStartIndex + idx;
- indexMap[fi] = rows.length;
- rowItems.push({
- item: items[idx],
- flatIndex: fi
- });
- }
- cumHeights.push(cumY);
- rows.push({
- _rowId: "gr_" + sectionId + "_" + r,
- type: "grid_row",
- items: rowItems,
- sectionId: sectionId,
- viewMode: mode,
- cols: cols,
- height: cellHeight
- });
- cumY += cellHeight;
- }
- }
- }
-
- root._flatIndexToRowMap = indexMap;
- root._cumulativeHeights = cumHeights;
- root._visualRows = rows;
- }
-
- onGridColumnsChanged: Qt.callLater(_rebuildVisualModel)
- onWidthChanged: Qt.callLater(_rebuildVisualModel)
-
- Connections {
- target: root.controller
- function onSectionsChanged() {
- Qt.callLater(root._rebuildVisualModel);
- }
- function onViewModeVersionChanged() {
- Qt.callLater(root._rebuildVisualModel);
- }
- function onSearchModeChanged() {
- root._visualRows = [];
- root._cumulativeHeights = [];
- root._flatIndexToRowMap = {};
- }
- }
-
- function resetScroll() {
- mainListView.contentY = mainListView.originY;
- }
-
- function ensureVisible(index) {
- if (index < 0 || !controller?.flatModel || index >= controller.flatModel.length)
- return;
- var entry = controller.flatModel[index];
- if (!entry || entry.isHeader)
- return;
- var rowIndex = _flatIndexToRowMap[index];
- if (rowIndex === undefined)
- return;
-
- mainListView.positionViewAtIndex(rowIndex, ListView.Contain);
-
- if (stickyHeader.visible && rowIndex < _cumulativeHeights.length) {
- var rowY = _cumulativeHeights[rowIndex];
- var scrollY = mainListView.contentY - mainListView.originY;
- if (rowY < scrollY + stickyHeader.height) {
- mainListView.contentY = Math.max(mainListView.originY, rowY - stickyHeader.height + mainListView.originY);
- }
- }
- }
-
- function getSelectedItemPosition() {
- var fallback = mapToItem(null, width / 2, height / 2);
- if (!controller?.flatModel || controller.selectedFlatIndex < 0)
- return fallback;
-
- var entry = controller.flatModel[controller.selectedFlatIndex];
- if (!entry || entry.isHeader)
- return fallback;
-
- var rowIndex = _flatIndexToRowMap[controller.selectedFlatIndex];
- if (rowIndex === undefined)
- return fallback;
-
- var rowY = (rowIndex < _cumulativeHeights.length) ? _cumulativeHeights[rowIndex] : 0;
- var row = _visualRows[rowIndex];
- if (!row)
- return fallback;
-
- var itemX = width / 2;
- var itemH = row.height;
-
- if (row.type === "grid_row") {
- var rowItems = row.items;
- for (var i = 0; i < rowItems.length; i++) {
- if (rowItems[i].flatIndex === controller.selectedFlatIndex) {
- var cellWidth = row.viewMode === "tile" ? Math.floor(width / 3) : Math.floor(width / row.cols);
- itemX = i * cellWidth + cellWidth / 2;
- break;
- }
- }
- }
-
- var visualY = rowY - mainListView.contentY + mainListView.originY + itemH / 2;
- var clampedY = Math.max(40, Math.min(height - 40, visualY));
- return mapToItem(null, itemX, clampedY);
- }
-
- Connections {
- target: root.controller
- function onSelectedFlatIndexChanged() {
- if (root.controller?.keyboardNavigationActive) {
- Qt.callLater(() => root.ensureVisible(root.controller.selectedFlatIndex));
- }
- }
- }
-
- DankListView {
- id: mainListView
- anchors.fill: parent
- clip: true
- scrollBarTopMargin: (root.controller?.sections?.length > 0) ? 32 : 0
-
- model: ScriptModel {
- values: root._visualRows
- objectProp: "_rowId"
- }
-
- add: null
- remove: null
- displaced: null
- move: null
-
- delegate: Item {
- id: delegateRoot
- required property var modelData
- required property int index
-
- width: mainListView.width
- height: modelData?.height ?? 52
-
- SectionHeader {
- anchors.fill: parent
- visible: delegateRoot.modelData?.type === "header"
- section: delegateRoot.modelData?.section ?? null
- controller: root.controller
- viewMode: {
- var vt = root.controller?.viewModeVersion ?? 0;
- void (vt);
- return root.controller?.getSectionViewMode(delegateRoot.modelData?.sectionId ?? "") ?? "list";
- }
- canChangeViewMode: {
- var vt = root.controller?.viewModeVersion ?? 0;
- void (vt);
- return root.controller?.canChangeSectionViewMode(delegateRoot.modelData?.sectionId ?? "") ?? false;
- }
- canCollapse: root.controller?.canCollapseSection(delegateRoot.modelData?.sectionId ?? "") ?? false
- }
-
- ResultItem {
- anchors.fill: parent
- visible: delegateRoot.modelData?.type === "list_item"
- item: delegateRoot.modelData?.type === "list_item" ? (delegateRoot.modelData?.item ?? null) : null
- isSelected: delegateRoot.modelData?.type === "list_item" && (delegateRoot.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex
- controller: root.controller
- flatIndex: delegateRoot.modelData?.type === "list_item" ? (delegateRoot.modelData?.flatIndex ?? -1) : -1
-
- onClicked: {
- if (root.controller && delegateRoot.modelData?.item) {
- root.controller.executeItem(delegateRoot.modelData.item);
- }
- }
-
- onRightClicked: (mouseX, mouseY) => {
- root.itemRightClicked(delegateRoot.modelData?.flatIndex ?? -1, delegateRoot.modelData?.item ?? null, mouseX, mouseY);
- }
- }
-
- Row {
- id: gridRowContent
- anchors.fill: parent
- visible: delegateRoot.modelData?.type === "grid_row"
-
- Repeater {
- model: delegateRoot.modelData?.type === "grid_row" ? (delegateRoot.modelData?.items ?? []) : []
-
- Item {
- id: gridCellDelegate
- required property var modelData
- required property int index
-
- readonly property real cellWidth: delegateRoot.modelData?.viewMode === "tile" ? Math.floor(delegateRoot.width / 3) : Math.floor(delegateRoot.width / (delegateRoot.modelData?.cols ?? root.gridColumns))
-
- width: cellWidth
- height: delegateRoot.height
-
- GridItem {
- width: parent.width - 4
- height: parent.height - 4
- anchors.centerIn: parent
- visible: delegateRoot.modelData?.viewMode === "grid"
- item: gridCellDelegate.modelData?.item ?? null
- isSelected: (gridCellDelegate.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex
- controller: root.controller
- flatIndex: gridCellDelegate.modelData?.flatIndex ?? -1
-
- onClicked: {
- if (root.controller && gridCellDelegate.modelData?.item) {
- root.controller.executeItem(gridCellDelegate.modelData.item);
- }
- }
-
- onRightClicked: (mouseX, mouseY) => {
- root.itemRightClicked(gridCellDelegate.modelData?.flatIndex ?? -1, gridCellDelegate.modelData?.item ?? null, mouseX, mouseY);
- }
- }
-
- TileItem {
- width: parent.width - 4
- height: parent.height - 4
- anchors.centerIn: parent
- visible: delegateRoot.modelData?.viewMode === "tile"
- item: gridCellDelegate.modelData?.item ?? null
- isSelected: (gridCellDelegate.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex
- controller: root.controller
- flatIndex: gridCellDelegate.modelData?.flatIndex ?? -1
-
- onClicked: {
- if (root.controller && gridCellDelegate.modelData?.item) {
- root.controller.executeItem(gridCellDelegate.modelData.item);
- }
- }
-
- onRightClicked: (mouseX, mouseY) => {
- root.itemRightClicked(gridCellDelegate.modelData?.flatIndex ?? -1, gridCellDelegate.modelData?.item ?? null, mouseX, mouseY);
- }
- }
- }
- }
- }
- }
- }
-
- Rectangle {
- id: bottomShadow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: 24
- z: 100
- visible: {
- if (BlurService.enabled)
- return false;
- if (mainListView.contentHeight <= mainListView.height)
- return false;
- var atBottom = mainListView.contentY >= mainListView.contentHeight - mainListView.height + mainListView.originY - 5;
- if (atBottom)
- return false;
-
- var flatModel = root.controller?.flatModel;
- if (!flatModel || flatModel.length === 0)
- return false;
- var lastItemIdx = -1;
- for (var i = flatModel.length - 1; i >= 0; i--) {
- if (!flatModel[i].isHeader) {
- lastItemIdx = i;
- break;
- }
- }
- if (lastItemIdx >= 0 && root.controller?.selectedFlatIndex === lastItemIdx)
- return false;
- return true;
- }
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "transparent"
- }
- GradientStop {
- position: 1.0
- color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- }
- }
- }
-
- Rectangle {
- id: stickyHeader
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- height: 32
- z: 101
- color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- visible: stickyHeaderSection !== null
-
- readonly property int versionTrigger: root.controller?.viewModeVersion ?? 0
-
- readonly property var stickyHeaderSection: {
- var scrollY = mainListView.contentY - mainListView.originY;
- if (scrollY <= 0)
- return null;
-
- var rows = root._visualRows;
- var heights = root._cumulativeHeights;
- if (rows.length === 0 || heights.length === 0)
- return null;
-
- var lo = 0;
- var hi = rows.length - 1;
- while (lo < hi) {
- var mid = (lo + hi + 1) >> 1;
- if (mid < heights.length && heights[mid] <= scrollY)
- lo = mid;
- else
- hi = mid - 1;
- }
-
- for (var i = lo; i >= 0; i--) {
- if (rows[i].type === "header")
- return rows[i].section;
- }
- return null;
- }
-
- SectionHeader {
- width: parent.width
- section: stickyHeader.stickyHeaderSection
- controller: root.controller
- viewMode: {
- void (stickyHeader.versionTrigger);
- return root.controller?.getSectionViewMode(stickyHeader.stickyHeaderSection?.id) ?? "list";
- }
- canChangeViewMode: {
- void (stickyHeader.versionTrigger);
- return root.controller?.canChangeSectionViewMode(stickyHeader.stickyHeaderSection?.id) ?? false;
- }
- canCollapse: {
- void (stickyHeader.versionTrigger);
- return root.controller?.canCollapseSection(stickyHeader.stickyHeaderSection?.id) ?? false;
- }
- isSticky: true
- }
- }
-
- Item {
- anchors.centerIn: parent
- visible: (!root.controller?.sections || root.controller.sections.length === 0) && !root.controller?.isFileSearching
- width: emptyColumn.implicitWidth
- height: emptyColumn.implicitHeight
-
- Column {
- id: emptyColumn
- spacing: Theme.spacingM
-
- DankIcon {
- anchors.horizontalCenter: parent.horizontalCenter
- name: getEmptyIcon()
- size: 48
- color: Theme.outlineButton
-
- function getEmptyIcon() {
- var mode = root.controller?.searchMode ?? "all";
- switch (mode) {
- case "files":
- var fileType = root.controller?.fileSearchType ?? "all";
- switch (fileType) {
- case "dir":
- return "folder_open";
- case "file":
- return "insert_drive_file";
- default:
- return "folder_open";
- }
- case "plugins":
- return "extension";
- case "apps":
- return "apps";
- default:
- return "search_off";
- }
- }
- }
-
- StyledText {
- anchors.horizontalCenter: parent.horizontalCenter
- text: getEmptyText()
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- horizontalAlignment: Text.AlignHCenter
-
- function getEmptyText() {
- var mode = root.controller?.searchMode ?? "all";
- var hasQuery = root.controller?.searchQuery?.length > 0;
-
- switch (mode) {
- case "files":
- if (!DSearchService.dsearchAvailable)
- return I18n.tr("File search requires dsearch\nInstall from github.com/AvengeMedia/danksearch");
- if (!hasQuery)
- return I18n.tr("Type to search files");
- if (root.controller.searchQuery.length < 2)
- return I18n.tr("Type at least 2 characters");
- var fileType = root.controller?.fileSearchType ?? "all";
- switch (fileType) {
- case "dir":
- return I18n.tr("No folders found");
- case "file":
- return I18n.tr("No files found");
- default:
- return I18n.tr("No results found");
- }
- case "plugins":
- return hasQuery ? I18n.tr("No plugin results") : I18n.tr("Browse or search plugins");
- case "apps":
- return I18n.tr("No apps found");
- default:
- return I18n.tr("No results found");
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js
deleted file mode 100644
index 7d54df7..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js
+++ /dev/null
@@ -1,265 +0,0 @@
-.pragma library
-
-const Weights = {
- exactMatch: 10000,
- prefixMatch: 5000,
- wordBoundary: 3000,
- substring: 500,
- fuzzy: 100,
- frecency: 2000,
- typeBonus: {
- app: 1000,
- plugin: 900,
- file: 800,
- action: 600
- }
-}
-
-function tokenize(text) {
- return text.toLowerCase().trim().split(/[\s\-_]+/).filter(function (w) { return w.length > 0 })
-}
-
-function hasWordBoundaryMatch(text, query) {
- var textWords = tokenize(text)
- var queryWords = tokenize(query)
-
- if (queryWords.length === 0) return false
- if (queryWords.length > textWords.length) return false
-
- for (var i = 0; i <= textWords.length - queryWords.length; i++) {
- var allMatch = true
- for (var j = 0; j < queryWords.length; j++) {
- if (!textWords[i + j].startsWith(queryWords[j])) {
- allMatch = false
- break
- }
- }
- if (allMatch) return true
- }
- return false
-}
-
-function levenshteinDistance(s1, s2) {
- var len1 = s1.length
- var len2 = s2.length
- var prev = new Array(len2 + 1)
- var curr = new Array(len2 + 1)
-
- for (var j = 0; j <= len2; j++)
- prev[j] = j
-
- for (var i = 1; i <= len1; i++) {
- curr[0] = i
- for (var j = 1; j <= len2; j++) {
- var cost = s1[i - 1] === s2[j - 1] ? 0 : 1
- curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost)
- }
- var tmp = prev
- prev = curr
- curr = tmp
- }
- return prev[len2]
-}
-
-function fuzzyScore(text, query) {
- var maxDistance = query.length === 3 ? 1 : query.length <= 6 ? 2 : 3
- var bestScore = 0
-
- if (Math.abs(text.length - query.length) <= maxDistance) {
- var distance = levenshteinDistance(text, query)
- if (distance <= maxDistance) {
- var maxLen = Math.max(text.length, query.length)
- bestScore = 1 - (distance / maxLen)
- }
- }
-
- var words = tokenize(text)
- for (var i = 0; i < words.length && bestScore < 0.8; i++) {
- if (Math.abs(words[i].length - query.length) > maxDistance) continue
- var wordDistance = levenshteinDistance(words[i], query)
- if (wordDistance <= maxDistance) {
- var wordMaxLen = Math.max(words[i].length, query.length)
- var score = 1 - (wordDistance / wordMaxLen)
- bestScore = Math.max(bestScore, score)
- }
- }
-
- return bestScore
-}
-
-function getTimeBucketWeight(daysSinceUsed) {
- for (var i = 0; i < TimeBuckets.length; i++) {
- if (daysSinceUsed <= TimeBuckets[i].maxDays) {
- return TimeBuckets[i].weight
- }
- }
- return 10
-}
-
-function calculateTextScore(name, query) {
- if (name === query) return Weights.exactMatch
- if (name.startsWith(query)) return Weights.prefixMatch
- if (hasWordBoundaryMatch(name, query)) return Weights.wordBoundary
- if (name.includes(query)) return Weights.substring
-
- if (query.length >= 3) {
- var fs = fuzzyScore(name, query)
- if (fs > 0) return fs * Weights.fuzzy
- }
-
- return 0
-}
-
-function score(item, query, frecencyData) {
- var typeBonus = Weights.typeBonus[item.type] || 0
-
- if (!query || query.length === 0) {
- var usageCount = frecencyData ? frecencyData.usageCount : 0
- return typeBonus + (usageCount * 100)
- }
-
- var name = (item.name || "").toLowerCase()
- var q = query.toLowerCase()
-
- var textScore = calculateTextScore(name, q)
-
- if (textScore === 0 && item.subtitle) {
- var subtitleScore = calculateTextScore(item.subtitle.toLowerCase(), q)
- textScore = subtitleScore * 0.5
- }
-
- if (textScore === 0 && item.keywords) {
- for (var i = 0; i < item.keywords.length; i++) {
- var keywordScore = calculateTextScore(item.keywords[i].toLowerCase(), q)
- if (keywordScore > 0) {
- textScore = keywordScore * 0.3
- break
- }
- }
- }
-
- if (textScore === 0) return 0
-
- var usageBonus = frecencyData ? Math.min(frecencyData.usageCount * 50, Weights.frecency) : 0
-
- return textScore + usageBonus + typeBonus
-}
-
-function scoreItems(items, query, getFrecencyFn) {
- var scored = []
-
- for (var i = 0; i < items.length; i++) {
- var item = items[i]
- var itemScore
-
- if (item._preScored !== undefined && (query || item._preScored > 900)) {
- itemScore = item._preScored
- } else {
- var frecencyData = getFrecencyFn ? getFrecencyFn(item) : null
- itemScore = score(item, query, frecencyData)
- }
-
- if (itemScore > 0 || !query || query.length === 0) {
- scored.push({
- item: item,
- score: itemScore
- })
- }
- }
-
- scored.sort(function (a, b) {
- return b.score - a.score
- })
-
- return scored
-}
-
-function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSection) {
- var sections = {}
- var result = []
- var limit = maxPerSection || 50
-
- for (var i = 0; i < sectionOrder.length; i++) {
- var sectionId = sectionOrder[i].id
- sections[sectionId] = {
- id: sectionId,
- title: sectionOrder[i].title,
- icon: sectionOrder[i].icon,
- priority: sectionOrder[i].priority,
- items: [],
- collapsed: false,
- flatStartIndex: 0
- }
- }
-
- for (var i = 0; i < scoredItems.length; i++) {
- var scoredItem = scoredItems[i]
- var item = scoredItem.item
- var sectionId = item.section || "apps"
-
- if (sections[sectionId] && sections[sectionId].items.length < limit) {
- sections[sectionId].items.push(item)
- } else if (sections["apps"] && sections["apps"].items.length < limit) {
- sections["apps"].items.push(item)
- }
- }
-
- for (var i = 0; i < sectionOrder.length; i++) {
- var section = sections[sectionOrder[i].id]
- if (section && section.items.length > 0) {
- if (sortAlphabetically && section.id === "apps") {
- section.items.sort(function (a, b) {
- return (a.name || "").localeCompare(b.name || "")
- })
- }
- result.push(section)
- }
- }
-
- return result
-}
-
-function flattenSections(sections) {
- var flat = []
- flat._sectionBounds = null
- var bounds = {}
-
- for (var i = 0; i < sections.length; i++) {
- var section = sections[i]
-
- flat.push({
- isHeader: true,
- section: section,
- sectionId: section.id,
- sectionIndex: i
- })
-
- var itemStart = flat.length
- section.flatStartIndex = itemStart
-
- if (!section.collapsed) {
- for (var j = 0; j < section.items.length; j++) {
- flat.push({
- isHeader: false,
- item: section.items[j],
- sectionId: section.id,
- sectionIndex: i,
- indexInSection: j
- })
- }
- }
-
- var itemEnd = flat.length - 1
- var itemCount = flat.length - itemStart
- if (itemCount > 0) {
- bounds[section.id] = {
- start: itemStart,
- end: itemEnd,
- count: itemCount
- }
- }
- }
-
- flat._sectionBounds = bounds
- return flat
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml
deleted file mode 100644
index aba4c2f..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml
+++ /dev/null
@@ -1,114 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import qs.Common
-
-Item {
- id: root
-
- property var section: null
- property var controller: null
- property string viewMode: "list"
- property int gridColumns: 4
- property int startIndex: 0
-
- signal itemClicked(int flatIndex)
- signal itemRightClicked(int flatIndex, var item, real mouseX, real mouseY)
-
- height: headerItem.height + (section?.collapsed ? 0 : contentLoader.height + Theme.spacingXS)
- width: parent?.width ?? 200
-
- SectionHeader {
- id: headerItem
- width: parent.width
- section: root.section
- controller: root.controller
- viewMode: root.viewMode
- canChangeViewMode: root.controller?.canChangeSectionViewMode(root.section?.id) ?? true
-
- onViewModeToggled: {
- if (root.controller && root.section) {
- var newMode = root.viewMode === "list" ? "grid" : "list";
- root.controller.setSectionViewMode(root.section.id, newMode);
- }
- }
- }
-
- Loader {
- id: contentLoader
- anchors.top: headerItem.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingXS
- active: !root.section?.collapsed
- visible: active
-
- sourceComponent: root.viewMode === "grid" ? gridComponent : listComponent
-
- Component {
- id: listComponent
-
- Column {
- spacing: 2
- width: contentLoader.width
-
- Repeater {
- model: ScriptModel {
- values: root.section?.items ?? []
- objectProp: "id"
- }
-
- ResultItem {
- required property var modelData
- required property int index
-
- width: parent?.width ?? 200
- item: modelData
- isSelected: (root.startIndex + index) === root.controller?.selectedFlatIndex
- controller: root.controller
- flatIndex: root.startIndex + index
-
- onClicked: root.itemClicked(root.startIndex + index)
- onRightClicked: (mouseX, mouseY) => {
- root.itemRightClicked(root.startIndex + index, modelData, mouseX, mouseY);
- }
- }
- }
- }
- }
-
- Component {
- id: gridComponent
-
- Flow {
- width: contentLoader.width
- spacing: 4
-
- Repeater {
- model: ScriptModel {
- values: root.section?.items ?? []
- objectProp: "id"
- }
-
- GridItem {
- required property var modelData
- required property int index
-
- width: Math.floor(contentLoader.width / root.gridColumns)
- height: width + 24
- item: modelData
- isSelected: (root.startIndex + index) === root.controller?.selectedFlatIndex
- controller: root.controller
- flatIndex: root.startIndex + index
-
- onClicked: root.itemClicked(root.startIndex + index)
- onRightClicked: (mouseX, mouseY) => {
- root.itemRightClicked(root.startIndex + index, modelData, mouseX, mouseY);
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml
deleted file mode 100644
index ee366c7..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml
+++ /dev/null
@@ -1,340 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import QtQuick.Controls
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var section: null
- property var controller: null
- property string viewMode: "list"
- property bool canChangeViewMode: true
- property bool canCollapse: true
- property bool isSticky: false
-
- signal viewModeToggled
-
- width: parent?.width ?? 200
- height: 32
- color: isSticky ? "transparent" : (hoverArea.containsMouse ? Theme.surfaceHover : "transparent")
- radius: Theme.cornerRadius
-
- MouseArea {
- id: hoverArea
- anchors.fill: parent
- hoverEnabled: true
- acceptedButtons: Qt.NoButton
- }
-
- Row {
- id: leftContent
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingXS
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- // Whether the apps category picker should replace the plain title
- readonly property bool hasAppCategories: root.section?.id === "apps" && (root.controller?.appCategories?.length ?? 0) > 0
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- // Hide section icon when the category chip already shows one
- visible: !leftContent.hasAppCategories
- name: root.section?.icon ?? "folder"
- size: 16
- color: Theme.surfaceVariantText
- }
-
- // Plain title — hidden when the category chip is shown
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- visible: !leftContent.hasAppCategories
- text: root.section?.title ?? ""
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceVariantText
- }
-
- // Compact inline category chip — only visible on the apps section
- Item {
- id: categoryChip
- visible: leftContent.hasAppCategories
- anchors.verticalCenter: parent.verticalCenter
- // Size to content with a fixed-min width so it doesn't jump around
- width: chipRow.implicitWidth + Theme.spacingM * 2
- height: 24
-
- readonly property string currentCategory: root.controller?.appCategory || (root.controller?.appCategories?.length > 0 ? root.controller.appCategories[0] : "")
- readonly property var iconMap: {
- const cats = root.controller?.appCategories ?? [];
- const m = {};
- cats.forEach(c => { m[c] = AppSearchService.getCategoryIcon(c); });
- return m;
- }
-
- Rectangle {
- anchors.fill: parent
- radius: Theme.cornerRadius
- color: chipArea.containsMouse || categoryPopup.visible ? Theme.surfaceContainerHigh : "transparent"
- border.color: categoryPopup.visible ? Theme.primary : Theme.outlineMedium
- border.width: categoryPopup.visible ? 2 : 1
- }
-
- Row {
- id: chipRow
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: categoryChip.iconMap[categoryChip.currentCategory] ?? "apps"
- size: 14
- color: Theme.surfaceText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: categoryChip.currentCategory
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- }
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: categoryPopup.visible ? "expand_less" : "expand_more"
- size: 14
- color: Theme.surfaceVariantText
- }
- }
-
- MouseArea {
- id: chipArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (categoryPopup.visible) {
- categoryPopup.close();
- } else {
- const pos = categoryChip.mapToItem(Overlay.overlay, 0, 0);
- categoryPopup.x = pos.x;
- categoryPopup.y = pos.y + categoryChip.height + 4;
- categoryPopup.open();
- }
- }
- }
-
- Popup {
- id: categoryPopup
- parent: Overlay.overlay
- width: Math.max(categoryChip.width, 180)
- padding: 0
- modal: true
- dim: false
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
-
- background: Rectangle { color: "transparent" }
-
- contentItem: Rectangle {
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
- border.color: Theme.primary
- border.width: 2
-
- ElevationShadow {
- anchors.fill: parent
- z: -1
- level: Theme.elevationLevel2
- fallbackOffset: 4
- targetRadius: parent.radius
- targetColor: parent.color
- borderColor: parent.border.color
- borderWidth: parent.border.width
- shadowEnabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled
- }
-
- ListView {
- id: categoryList
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- model: root.controller?.appCategories ?? []
- spacing: 2
- clip: true
- interactive: contentHeight > height
- implicitHeight: contentHeight
-
- delegate: Rectangle {
- id: catDelegate
- required property string modelData
- required property int index
- width: categoryList.width
- height: 32
- radius: Theme.cornerRadius
- readonly property bool isCurrent: categoryChip.currentCategory === modelData
- color: isCurrent ? Theme.primaryHover : catArea.containsMouse ? Theme.primaryHoverLight : "transparent"
-
- Row {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: Theme.spacingS
- spacing: Theme.spacingS
-
- DankIcon {
- anchors.verticalCenter: parent.verticalCenter
- name: categoryChip.iconMap[catDelegate.modelData] ?? "apps"
- size: 16
- color: catDelegate.isCurrent ? Theme.primary : Theme.surfaceText
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: catDelegate.modelData
- font.pixelSize: Theme.fontSizeMedium
- color: catDelegate.isCurrent ? Theme.primary : Theme.surfaceText
- font.weight: catDelegate.isCurrent ? Font.Medium : Font.Normal
- }
- }
-
- MouseArea {
- id: catArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (root.controller)
- root.controller.setAppCategory(catDelegate.modelData);
- categoryPopup.close();
- }
- }
- }
- }
- }
-
- // Size to list content, cap at 10 visible items
- height: Math.min((root.controller?.appCategories?.length ?? 0) * 34, 10 * 34) + Theme.spacingS * 2 + 4
- }
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: root.section?.items?.length ?? 0
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.outlineButton
- }
- }
-
- Row {
- id: rightContent
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingXS
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- Row {
- id: viewModeRow
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
- visible: root.canChangeViewMode && !root.section?.collapsed
-
- Repeater {
- model: [
- {
- mode: "list",
- icon: "view_list"
- },
- {
- mode: "grid",
- icon: "grid_view"
- },
- {
- mode: "tile",
- icon: "view_module"
- }
- ]
-
- Rectangle {
- required property var modelData
- required property int index
-
- width: 20
- height: 20
- radius: 4
- color: root.viewMode === modelData.mode ? Theme.primaryHover : modeArea.containsMouse ? Theme.surfaceHover : "transparent"
-
- DankIcon {
- anchors.centerIn: parent
- name: parent.modelData.icon
- size: 14
- color: root.viewMode === parent.modelData.mode ? Theme.primary : Theme.surfaceVariantText
- }
-
- MouseArea {
- id: modeArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (root.viewMode !== parent.modelData.mode && root.controller && root.section) {
- root.controller.setSectionViewMode(root.section.id, parent.modelData.mode);
- }
- }
- }
- }
- }
- }
-
- Item {
- id: collapseButton
- width: root.canCollapse ? 24 : 0
- height: 24
- visible: root.canCollapse
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: root.section?.collapsed ? "expand_more" : "expand_less"
- size: 16
- color: collapseArea.containsMouse ? Theme.primary : Theme.surfaceVariantText
- }
-
- MouseArea {
- id: collapseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (root.controller && root.section) {
- root.controller.toggleSection(root.section.id);
- }
- }
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- anchors.rightMargin: rightContent.width + Theme.spacingS
- cursorShape: root.canCollapse ? Qt.PointingHandCursor : Qt.ArrowCursor
- enabled: root.canCollapse
- onClicked: {
- if (root.canCollapse && root.controller && root.section) {
- root.controller.toggleSection(root.section.id);
- }
- }
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: 1
- color: Theme.outlineMedium
- visible: root.isSticky
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml
deleted file mode 100644
index 0b48802..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml
+++ /dev/null
@@ -1,199 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell.Wayland
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var item: null
- property bool isSelected: false
- property bool isHovered: itemArea.containsMouse
- property var controller: null
- property int flatIndex: -1
-
- signal clicked
- signal rightClicked(real mouseX, real mouseY)
-
- radius: Theme.cornerRadius
- color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent"
- border.width: isSelected ? 2 : 0
- border.color: Theme.primary
-
- readonly property string toplevelId: item?.data?.toplevelId ?? ""
- readonly property var waylandToplevel: {
- if (!toplevelId || !item?.pluginId)
- return null;
- const pluginInstance = PluginService.pluginInstances[item.pluginId];
- if (!pluginInstance?.getToplevelById)
- return null;
- return pluginInstance.getToplevelById(toplevelId);
- }
- readonly property bool hasScreencopy: waylandToplevel !== null
-
- readonly property string iconValue: {
- if (!item)
- return "";
- if (hasScreencopy)
- return "";
- var data = item.data;
- if (data?.imageUrl)
- return "image:" + data.imageUrl;
- if (data?.imagePath)
- return "image:" + data.imagePath;
- if (data?.path && isImageFile(data.path))
- return "image:" + data.path;
- switch (item.iconType) {
- case "material":
- case "nerd":
- return "material:" + (item.icon || "image");
- case "unicode":
- return "unicode:" + (item.icon || "");
- case "composite":
- return item.iconFull || "";
- case "image":
- default:
- return item.icon || "";
- }
- }
-
- function isImageFile(path) {
- if (!path)
- return false;
- var ext = path.split('.').pop().toLowerCase();
- return ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "jxl", "avif", "heif", "exr"].indexOf(ext) >= 0;
- }
-
- DankRipple {
- id: rippleLayer
- rippleColor: Theme.surfaceText
- cornerRadius: root.radius
- }
-
- Item {
- anchors.fill: parent
- anchors.margins: 4
-
- Rectangle {
- id: imageContainer
- anchors.fill: parent
- radius: Theme.cornerRadius - 2
- color: Theme.surfaceContainerHigh
- clip: true
-
- ScreencopyView {
- id: screencopyView
- anchors.fill: parent
- captureSource: root.waylandToplevel
- live: root.hasScreencopy
- visible: root.hasScreencopy
-
- Rectangle {
- anchors.fill: parent
- color: root.isHovered ? Theme.withAlpha(Theme.surfaceVariant, 0.2) : "transparent"
- }
- }
-
- AppIconRenderer {
- anchors.fill: parent
- iconValue: root.iconValue
- iconSize: Math.min(parent.width, parent.height)
- fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
- materialIconSizeAdjustment: iconSize * 0.3
- visible: !root.hasScreencopy
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: labelText.implicitHeight + Theme.spacingS * 2
- color: Theme.withAlpha(Theme.surfaceContainer, 0.85)
- visible: root.item?.name?.length > 0
-
- Text {
- id: labelText
- anchors.fill: parent
- anchors.margins: Theme.spacingXS
- text: root.item?._hName ?? root.item?.name ?? ""
- textFormat: root.item?._hRich ? Text.RichText : Text.PlainText
- font.pixelSize: Theme.fontSizeSmall
- font.family: Theme.fontFamily
- color: Theme.surfaceText
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- }
- }
-
- Rectangle {
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.margins: Theme.spacingXS
- width: 20
- height: 20
- radius: 10
- color: Theme.primary
- visible: root.isSelected
-
- DankIcon {
- anchors.centerIn: parent
- name: "check"
- size: 14
- color: Theme.primaryText
- }
- }
-
- Rectangle {
- id: attributionBadge
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.margins: Theme.spacingXS
- width: root.hasScreencopy ? 28 : 40
- height: root.hasScreencopy ? 28 : 16
- radius: root.hasScreencopy ? 14 : 4
- color: root.hasScreencopy ? Theme.surfaceContainer : "transparent"
- visible: attributionImage.status === Image.Ready
- opacity: 0.95
-
- Image {
- id: attributionImage
- anchors.fill: parent
- anchors.margins: root.hasScreencopy ? 4 : 0
- fillMode: Image.PreserveAspectFit
- source: root.item?.data?.attribution || ""
- mipmap: true
- }
- }
- }
- }
-
- MouseArea {
- id: itemArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onPressed: mouse => {
- if (mouse.button === Qt.LeftButton)
- rippleLayer.trigger(mouse.x, mouse.y);
- }
- onClicked: mouse => {
- if (mouse.button === Qt.RightButton) {
- var scenePos = mapToItem(null, mouse.x, mouse.y);
- root.rightClicked(scenePos.x, scenePos.y);
- return;
- }
- root.clicked();
- }
-
- onPositionChanged: {
- if (root.controller)
- root.controller.keyboardNavigationActive = false;
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml
deleted file mode 100644
index f8a97de..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml
+++ /dev/null
@@ -1,212 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modals.Common
-import qs.Widgets
-
-DankModal {
- id: root
-
- property string outputName: ""
- property var changes: []
- property int countdown: 10
-
- signal confirmed
- signal reverted
-
- shouldBeVisible: false
- allowStacking: true
- modalWidth: 420
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 200
-
- Timer {
- id: countdownTimer
- interval: 1000
- repeat: true
- running: root.shouldBeVisible
- onTriggered: {
- root.countdown--;
- if (root.countdown <= 0) {
- root.reverted();
- root.close();
- }
- }
- }
-
- onOpened: {
- countdown = 10;
- countdownTimer.start();
- }
-
- onDialogClosed: {
- countdownTimer.stop();
- }
-
- onBackgroundClicked: {
- root.reverted();
- root.close();
- }
-
- content: Component {
- FocusScope {
- id: confirmContent
-
- anchors.fill: parent
- focus: true
- implicitHeight: mainColumn.implicitHeight
-
- Keys.onEscapePressed: event => {
- root.reverted();
- root.close();
- event.accepted = true;
- }
-
- Keys.onReturnPressed: event => {
- root.confirmed();
- root.close();
- event.accepted = true;
- }
-
- Column {
- id: mainColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- StyledText {
- text: I18n.tr("Confirm Display Changes")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- Rectangle {
- width: parent.width
- height: 70
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHighest
-
- StyledText {
- anchors.centerIn: parent
- text: root.countdown + "s"
- font.pixelSize: Theme.fontSizeXLarge * 1.5
- color: Theme.primary
- font.weight: Font.Bold
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
- visible: root.changes.length > 0
-
- Repeater {
- model: root.changes
-
- StyledText {
- required property var modelData
- text: modelData
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
- }
- }
-
- Item {
- width: parent.width
- height: 36
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- Rectangle {
- width: Math.max(70, revertText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: revertArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: revertText
-
- anchors.centerIn: parent
- text: I18n.tr("Revert")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: revertArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- root.reverted();
- root.close();
- }
- }
- }
-
- Rectangle {
- width: Math.max(80, confirmText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: confirmArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- id: confirmText
-
- anchors.centerIn: parent
- text: I18n.tr("Keep Changes")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: confirmArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- root.confirmed();
- root.close();
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
-
- DankActionButton {
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: {
- root.reverted();
- root.close();
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml
deleted file mode 100644
index 8b96742..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml
+++ /dev/null
@@ -1,920 +0,0 @@
-import Qt.labs.folderlistmodel
-import QtCore
-import QtQuick
-import QtQuick.Controls
-import qs.Common
-import qs.Widgets
-
-FocusScope {
- id: root
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property string homeDir: StandardPaths.writableLocation(StandardPaths.HomeLocation)
- property string docsDir: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
- property string musicDir: StandardPaths.writableLocation(StandardPaths.MusicLocation)
- property string videosDir: StandardPaths.writableLocation(StandardPaths.MoviesLocation)
- property string picsDir: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
- property string downloadDir: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
- property string desktopDir: StandardPaths.writableLocation(StandardPaths.DesktopLocation)
- property string currentPath: ""
- property var fileExtensions: ["*.*"]
- property alias filterExtensions: root.fileExtensions
- property string browserTitle: "Select File"
- property string browserIcon: "folder_open"
- property string browserType: "generic"
- property bool showHiddenFiles: false
- property int selectedIndex: -1
- property bool keyboardNavigationActive: false
- property bool backButtonFocused: false
- property bool saveMode: false
- property string defaultFileName: ""
- property int keyboardSelectionIndex: -1
- property bool keyboardSelectionRequested: false
- property bool showKeyboardHints: false
- property bool showFileInfo: false
- property string selectedFilePath: ""
- property string selectedFileName: ""
- property bool selectedFileIsDir: false
- property bool showOverwriteConfirmation: false
- property string pendingFilePath: ""
- property bool showSidebar: true
- property string viewMode: "grid"
- property string sortBy: "name"
- property bool sortAscending: true
- property int iconSizeIndex: 1
- property var iconSizes: [80, 120, 160, 200]
- property bool pathEditMode: false
- property bool pathInputHasFocus: false
- property int actualGridColumns: 5
- property bool _initialized: false
- property bool closeOnEscape: true
- property var windowControls: null
-
- signal fileSelected(string path)
- signal closeRequested
-
- function encodeFileUrl(path) {
- if (!path)
- return "";
- return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
- }
-
- function initialize() {
- loadSettings();
- currentPath = getLastPath();
- _initialized = true;
- }
-
- function reset() {
- currentPath = getLastPath();
- selectedIndex = -1;
- keyboardNavigationActive = false;
- backButtonFocused = false;
- }
-
- function loadSettings() {
- const type = browserType || "default";
- const settings = CacheData.fileBrowserSettings[type];
- const isImageBrowser = ["wallpaper", "profile"].includes(browserType);
-
- if (settings) {
- viewMode = settings.viewMode || (isImageBrowser ? "grid" : "list");
- sortBy = settings.sortBy || "name";
- sortAscending = settings.sortAscending !== undefined ? settings.sortAscending : true;
- iconSizeIndex = settings.iconSizeIndex !== undefined ? settings.iconSizeIndex : 1;
- showSidebar = settings.showSidebar !== undefined ? settings.showSidebar : true;
- } else {
- viewMode = isImageBrowser ? "grid" : "list";
- }
- }
-
- function saveSettings() {
- if (!_initialized)
- return;
- const type = browserType || "default";
- let settings = CacheData.fileBrowserSettings;
- if (!settings[type]) {
- settings[type] = {};
- }
- settings[type].viewMode = viewMode;
- settings[type].sortBy = sortBy;
- settings[type].sortAscending = sortAscending;
- settings[type].iconSizeIndex = iconSizeIndex;
- settings[type].showSidebar = showSidebar;
- settings[type].lastPath = currentPath;
- CacheData.fileBrowserSettings = settings;
-
- if (browserType === "wallpaper") {
- CacheData.wallpaperLastPath = currentPath;
- } else if (browserType === "profile") {
- CacheData.profileLastPath = currentPath;
- }
-
- CacheData.saveCache();
- }
-
- onViewModeChanged: saveSettings()
- onSortByChanged: saveSettings()
- onSortAscendingChanged: saveSettings()
- onIconSizeIndexChanged: saveSettings()
- onShowSidebarChanged: saveSettings()
-
- function isImageFile(fileName) {
- if (!fileName)
- return false;
- const ext = fileName.toLowerCase().split('.').pop();
- return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext);
- }
-
- function getLastPath() {
- const type = browserType || "default";
- const settings = CacheData.fileBrowserSettings[type];
- const lastPath = settings?.lastPath || "";
- return (lastPath && lastPath !== "") ? lastPath : homeDir;
- }
-
- function saveLastPath(path) {
- const type = browserType || "default";
- let settings = CacheData.fileBrowserSettings;
- if (!settings[type]) {
- settings[type] = {};
- }
- settings[type].lastPath = path;
- CacheData.fileBrowserSettings = settings;
- CacheData.saveCache();
-
- if (browserType === "wallpaper") {
- CacheData.wallpaperLastPath = path;
- } else if (browserType === "profile") {
- CacheData.profileLastPath = path;
- }
- }
-
- function setSelectedFileData(path, name, isDir) {
- selectedFilePath = path;
- selectedFileName = name;
- selectedFileIsDir = isDir;
- }
-
- function navigateUp() {
- const path = currentPath;
- if (path === homeDir)
- return;
- const lastSlash = path.lastIndexOf('/');
- if (lastSlash <= 0)
- return;
- const newPath = path.substring(0, lastSlash);
- if (newPath.length < homeDir.length) {
- currentPath = homeDir;
- saveLastPath(homeDir);
- } else {
- currentPath = newPath;
- saveLastPath(newPath);
- }
- }
-
- function navigateTo(path) {
- currentPath = path;
- saveLastPath(path);
- selectedIndex = -1;
- backButtonFocused = false;
- }
-
- function keyboardFileSelection(index) {
- if (index < 0)
- return;
- keyboardSelectionTimer.targetIndex = index;
- keyboardSelectionTimer.start();
- }
-
- function executeKeyboardSelection(index) {
- keyboardSelectionIndex = index;
- keyboardSelectionRequested = true;
- }
-
- function handleSaveFile(filePath) {
- var normalizedPath = filePath;
- if (!normalizedPath.startsWith("file://")) {
- normalizedPath = encodeFileUrl(filePath);
- }
-
- var exists = false;
- var fileName = filePath.split('/').pop();
-
- for (var i = 0; i < folderModel.count; i++) {
- if (folderModel.get(i, "fileName") === fileName && !folderModel.get(i, "fileIsDir")) {
- exists = true;
- break;
- }
- }
-
- if (exists) {
- pendingFilePath = normalizedPath;
- showOverwriteConfirmation = true;
- } else {
- fileSelected(normalizedPath);
- closeRequested();
- }
- }
-
- onCurrentPathChanged: {
- selectedFilePath = "";
- selectedFileName = "";
- selectedFileIsDir = false;
- saveSettings();
- }
-
- onSelectedIndexChanged: {
- if (selectedIndex >= 0 && folderModel && selectedIndex < folderModel.count) {
- selectedFilePath = "";
- selectedFileName = "";
- selectedFileIsDir = false;
- }
- }
-
- property var steamPaths: [StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.steam/steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.local/share/Steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/snap/steam/common/.local/share/Steam/steamapps/workshop/content/431960"]
-
- property var quickAccessLocations: [
- {
- "name": I18n.tr("Home"),
- "path": homeDir,
- "icon": "home"
- },
- {
- "name": I18n.tr("Documents"),
- "path": docsDir,
- "icon": "description"
- },
- {
- "name": I18n.tr("Downloads"),
- "path": downloadDir,
- "icon": "download"
- },
- {
- "name": I18n.tr("Pictures"),
- "path": picsDir,
- "icon": "image"
- },
- {
- "name": I18n.tr("Music"),
- "path": musicDir,
- "icon": "music_note"
- },
- {
- "name": I18n.tr("Videos"),
- "path": videosDir,
- "icon": "movie"
- },
- {
- "name": I18n.tr("Desktop"),
- "path": desktopDir,
- "icon": "computer"
- }
- ]
-
- FolderListModel {
- id: folderModel
-
- showDirsFirst: true
- showDotAndDotDot: false
- showHidden: root.showHiddenFiles
- caseSensitive: false
- nameFilters: fileExtensions
- showFiles: true
- showDirs: true
- folder: encodeFileUrl(currentPath || homeDir)
- sortField: {
- switch (sortBy) {
- case "name":
- return FolderListModel.Name;
- case "size":
- return FolderListModel.Size;
- case "modified":
- return FolderListModel.Time;
- case "type":
- return FolderListModel.Type;
- default:
- return FolderListModel.Name;
- }
- }
- sortReversed: !sortAscending
- }
-
- QtObject {
- id: keyboardController
-
- property int totalItems: folderModel.count
- property int gridColumns: viewMode === "list" ? 1 : Math.max(1, actualGridColumns)
-
- function handleKey(event) {
- if (event.key === Qt.Key_Escape && root.closeOnEscape) {
- closeRequested();
- event.accepted = true;
- return;
- }
- if (event.key === Qt.Key_F10) {
- showKeyboardHints = !showKeyboardHints;
- event.accepted = true;
- return;
- }
- if (event.key === Qt.Key_F1 || event.key === Qt.Key_I) {
- showFileInfo = !showFileInfo;
- event.accepted = true;
- return;
- }
- if ((event.modifiers & Qt.AltModifier && event.key === Qt.Key_Left) || event.key === Qt.Key_Backspace) {
- if (currentPath !== homeDir) {
- navigateUp();
- event.accepted = true;
- }
- return;
- }
- if (!keyboardNavigationActive) {
- const isInitKey = event.key === Qt.Key_Tab || event.key === Qt.Key_Down || event.key === Qt.Key_Right || (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) || (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) || (event.key === Qt.Key_L && event.modifiers & Qt.ControlModifier);
-
- if (isInitKey) {
- keyboardNavigationActive = true;
- if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- } else {
- backButtonFocused = false;
- selectedIndex = 0;
- }
- event.accepted = true;
- }
- return;
- }
- switch (event.key) {
- case Qt.Key_Tab:
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = 0;
- } else if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- } else {
- selectedIndex = 0;
- }
- event.accepted = true;
- break;
- case Qt.Key_Backtab:
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = totalItems - 1;
- } else if (selectedIndex > 0) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- } else {
- selectedIndex = totalItems - 1;
- }
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = 0;
- } else if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (event.modifiers & Qt.ControlModifier) {
- if (selectedIndex > 0) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- if (selectedIndex > 0) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_H:
- if (event.modifiers & Qt.ControlModifier) {
- if (!backButtonFocused && selectedIndex > 0) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_L:
- if (event.modifiers & Qt.ControlModifier) {
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = 0;
- } else if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- }
- event.accepted = true;
- }
- break;
- case Qt.Key_Left:
- if (pathInputHasFocus)
- return;
- if (backButtonFocused)
- return;
- if (selectedIndex > 0) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- }
- event.accepted = true;
- break;
- case Qt.Key_Right:
- if (pathInputHasFocus)
- return;
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = 0;
- } else if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- }
- event.accepted = true;
- break;
- case Qt.Key_Up:
- if (backButtonFocused) {
- backButtonFocused = false;
- if (gridColumns === 1) {
- selectedIndex = 0;
- } else {
- var col = selectedIndex % gridColumns;
- selectedIndex = Math.min(col, totalItems - 1);
- }
- } else if (selectedIndex >= gridColumns) {
- selectedIndex -= gridColumns;
- } else if (selectedIndex > 0 && gridColumns === 1) {
- selectedIndex--;
- } else if (currentPath !== homeDir) {
- backButtonFocused = true;
- selectedIndex = -1;
- }
- event.accepted = true;
- break;
- case Qt.Key_Down:
- if (backButtonFocused) {
- backButtonFocused = false;
- selectedIndex = 0;
- } else if (gridColumns === 1) {
- if (selectedIndex < totalItems - 1) {
- selectedIndex++;
- }
- } else {
- var newIndex = selectedIndex + gridColumns;
- if (newIndex < totalItems) {
- selectedIndex = newIndex;
- } else {
- var lastRowStart = Math.floor((totalItems - 1) / gridColumns) * gridColumns;
- var col = selectedIndex % gridColumns;
- var targetIndex = lastRowStart + col;
- if (targetIndex < totalItems && targetIndex > selectedIndex) {
- selectedIndex = targetIndex;
- }
- }
- }
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- case Qt.Key_Space:
- if (backButtonFocused) {
- navigateUp();
- } else if (selectedIndex >= 0 && selectedIndex < totalItems) {
- root.keyboardFileSelection(selectedIndex);
- }
- event.accepted = true;
- break;
- }
- }
- }
-
- Timer {
- id: keyboardSelectionTimer
-
- property int targetIndex: -1
-
- interval: 1
- onTriggered: {
- executeKeyboardSelection(targetIndex);
- }
- }
-
- focus: true
-
- Keys.onPressed: event => {
- keyboardController.handleKey(event);
- }
-
- Column {
- anchors.fill: parent
- spacing: 0
-
- Item {
- width: parent.width
- height: 48
-
- MouseArea {
- anchors.fill: parent
- onPressed: if (windowControls)
- windowControls.tryStartMove()
- onDoubleClicked: if (windowControls)
- windowControls.tryToggleMaximize()
- }
-
- Row {
- spacing: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingL
-
- DankIcon {
- name: browserIcon
- size: Theme.iconSizeLarge
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: browserTitle
- font.pixelSize: Theme.fontSizeXLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingS
-
- DankActionButton {
- circular: false
- iconName: showHiddenFiles ? "visibility_off" : "visibility"
- iconSize: Theme.iconSize - 4
- iconColor: showHiddenFiles ? Theme.primary : Theme.surfaceText
- onClicked: showHiddenFiles = !showHiddenFiles
- }
-
- DankActionButton {
- circular: false
- iconName: viewMode === "grid" ? "view_list" : "grid_view"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: viewMode = viewMode === "grid" ? "list" : "grid"
- }
-
- DankActionButton {
- circular: false
- iconName: iconSizeIndex === 0 ? "photo_size_select_small" : iconSizeIndex === 1 ? "photo_size_select_large" : iconSizeIndex === 2 ? "photo_size_select_actual" : "zoom_in"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- visible: viewMode === "grid"
- onClicked: iconSizeIndex = (iconSizeIndex + 1) % iconSizes.length
- }
-
- DankActionButton {
- circular: false
- iconName: "info"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.showKeyboardHints = !root.showKeyboardHints
- }
-
- DankActionButton {
- visible: windowControls?.supported ?? false
- circular: false
- iconName: windowControls?.targetWindow?.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: if (windowControls)
- windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- circular: false
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.closeRequested()
- }
- }
- }
-
- StyledRect {
- width: parent.width
- height: 1
- color: Theme.outline
- }
-
- Item {
- width: parent.width
- height: parent.height - 49
-
- Row {
- anchors.fill: parent
- spacing: 0
-
- Row {
- width: showSidebar ? 201 : 0
- height: parent.height
- spacing: 0
- visible: showSidebar
-
- FileBrowserSidebar {
- height: parent.height
- quickAccessLocations: root.quickAccessLocations
- currentPath: root.currentPath
- onLocationSelected: path => navigateTo(path)
- }
-
- StyledRect {
- width: 1
- height: parent.height
- color: Theme.outline
- }
- }
-
- Column {
- width: parent.width - (showSidebar ? 201 : 0)
- height: parent.height
- spacing: 0
-
- FileBrowserNavigation {
- width: parent.width
- currentPath: root.currentPath
- homeDir: root.homeDir
- backButtonFocused: root.backButtonFocused
- keyboardNavigationActive: root.keyboardNavigationActive
- showSidebar: root.showSidebar
- pathEditMode: root.pathEditMode
- onNavigateUp: root.navigateUp()
- onNavigateTo: path => root.navigateTo(path)
- onPathInputFocusChanged: hasFocus => {
- root.pathInputHasFocus = hasFocus;
- if (hasFocus) {
- root.pathEditMode = true;
- }
- }
- }
-
- StyledRect {
- width: parent.width
- height: 1
- color: Theme.outline
- }
-
- Item {
- id: gridContainer
- width: parent.width
- height: parent.height - 41
- clip: true
-
- property real gridCellWidth: iconSizes[iconSizeIndex] + 24
- property real gridCellHeight: iconSizes[iconSizeIndex] + 56
- property real availableGridWidth: width - Theme.spacingM * 2
- property int gridColumns: Math.max(1, Math.floor(availableGridWidth / gridCellWidth))
- property real gridLeftMargin: Theme.spacingM + Math.max(0, (availableGridWidth - (gridColumns * gridCellWidth)) / 2)
-
- onGridColumnsChanged: {
- root.actualGridColumns = gridColumns;
- }
- Component.onCompleted: {
- root.actualGridColumns = gridColumns;
- }
-
- DankGridView {
- id: fileGrid
- anchors.fill: parent
- anchors.leftMargin: gridContainer.gridLeftMargin
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingS
- anchors.bottomMargin: Theme.spacingS
- visible: viewMode === "grid"
- cellWidth: gridContainer.gridCellWidth
- cellHeight: gridContainer.gridCellHeight
- cacheBuffer: 260
- model: folderModel
- currentIndex: selectedIndex
- onCurrentIndexChanged: {
- if (keyboardNavigationActive && currentIndex >= 0)
- positionViewAtIndex(currentIndex, GridView.Contain);
- }
-
- ScrollBar.vertical: DankScrollbar {
- id: gridScrollbar
- }
-
- ScrollBar.horizontal: DankScrollbar {
- policy: ScrollBar.AlwaysOff
- }
-
- delegate: FileBrowserGridDelegate {
- iconSizes: root.iconSizes
- iconSizeIndex: root.iconSizeIndex
- selectedIndex: root.selectedIndex
- keyboardNavigationActive: root.keyboardNavigationActive
- onItemClicked: (index, path, name, isDir) => {
- selectedIndex = index;
- setSelectedFileData(path, name, isDir);
- if (isDir) {
- navigateTo(path);
- } else {
- fileSelected(path);
- root.closeRequested();
- }
- }
- onItemSelected: (index, path, name, isDir) => {
- setSelectedFileData(path, name, isDir);
- }
-
- Connections {
- function onKeyboardSelectionRequestedChanged() {
- if (root.keyboardSelectionRequested && root.keyboardSelectionIndex === index) {
- root.keyboardSelectionRequested = false;
- selectedIndex = index;
- setSelectedFileData(filePath, fileName, fileIsDir);
- if (fileIsDir) {
- navigateTo(filePath);
- } else {
- fileSelected(filePath);
- root.closeRequested();
- }
- }
- }
-
- target: root
- }
- }
- }
-
- DankListView {
- id: fileList
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.topMargin: Theme.spacingS
- anchors.bottomMargin: Theme.spacingS
- visible: viewMode === "list"
- spacing: 2
- model: folderModel
- currentIndex: selectedIndex
- onCurrentIndexChanged: {
- if (keyboardNavigationActive && currentIndex >= 0)
- positionViewAtIndex(currentIndex, ListView.Contain);
- }
-
- ScrollBar.vertical: DankScrollbar {
- id: listScrollbar
- }
-
- delegate: FileBrowserListDelegate {
- width: fileList.width
- selectedIndex: root.selectedIndex
- keyboardNavigationActive: root.keyboardNavigationActive
- onItemClicked: (index, path, name, isDir) => {
- selectedIndex = index;
- setSelectedFileData(path, name, isDir);
- if (isDir) {
- navigateTo(path);
- } else {
- fileSelected(path);
- root.closeRequested();
- }
- }
- onItemSelected: (index, path, name, isDir) => {
- setSelectedFileData(path, name, isDir);
- }
-
- Connections {
- function onKeyboardSelectionRequestedChanged() {
- if (root.keyboardSelectionRequested && root.keyboardSelectionIndex === index) {
- root.keyboardSelectionRequested = false;
- selectedIndex = index;
- setSelectedFileData(filePath, fileName, fileIsDir);
- if (fileIsDir) {
- navigateTo(filePath);
- } else {
- fileSelected(filePath);
- root.closeRequested();
- }
- }
- }
-
- target: root
- }
- }
- }
- }
- }
- }
-
- FileBrowserSaveRow {
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- saveMode: root.saveMode
- defaultFileName: root.defaultFileName
- currentPath: root.currentPath
- onSaveRequested: filePath => handleSaveFile(filePath)
- }
-
- KeyboardHints {
- id: keyboardHints
-
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- showHints: root.showKeyboardHints
- }
-
- FileInfo {
- id: fileInfo
-
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- width: 300
- showFileInfo: root.showFileInfo
- selectedIndex: root.selectedIndex
- sourceFolderModel: folderModel
- currentPath: root.currentPath
- currentFileName: root.selectedFileName
- currentFileIsDir: root.selectedFileIsDir
- currentFileExtension: {
- if (root.selectedFileIsDir || !root.selectedFileName)
- return "";
-
- var lastDot = root.selectedFileName.lastIndexOf('.');
- return lastDot > 0 ? root.selectedFileName.substring(lastDot + 1).toLowerCase() : "";
- }
- }
-
- FileBrowserSortMenu {
- id: sortMenu
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.topMargin: 120
- anchors.rightMargin: Theme.spacingL
- sortBy: root.sortBy
- sortAscending: root.sortAscending
- onSortBySelected: value => {
- root.sortBy = value;
- }
- onSortOrderSelected: ascending => {
- root.sortAscending = ascending;
- }
- }
- }
-
- FileBrowserOverwriteDialog {
- anchors.fill: parent
- showDialog: showOverwriteConfirmation
- pendingFilePath: root.pendingFilePath
- onConfirmed: filePath => {
- showOverwriteConfirmation = false;
- fileSelected(filePath);
- pendingFilePath = "";
- Qt.callLater(() => root.closeRequested());
- }
- onCancelled: {
- showOverwriteConfirmation = false;
- pendingFilePath = "";
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml
deleted file mode 100644
index effa9bd..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml
+++ /dev/null
@@ -1,253 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import qs.Common
-import qs.Widgets
-
-StyledRect {
- id: delegateRoot
-
- required property bool fileIsDir
- required property string filePath
- required property string fileName
- required property int index
-
- property bool weMode: false
- property var iconSizes: [80, 120, 160, 200]
- property int iconSizeIndex: 1
- property int selectedIndex: -1
- property bool keyboardNavigationActive: false
-
- signal itemClicked(int index, string path, string name, bool isDir)
- signal itemSelected(int index, string path, string name, bool isDir)
-
- function getFileExtension(fileName) {
- const parts = fileName.split('.');
- if (parts.length > 1) {
- return parts[parts.length - 1].toLowerCase();
- }
- return "";
- }
-
- function determineFileType(fileName) {
- const ext = getFileExtension(fileName);
-
- const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico", "jxl", "avif", "heif", "exr"];
- if (imageExts.includes(ext)) {
- return "image";
- }
-
- const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"];
- if (videoExts.includes(ext)) {
- return "video";
- }
-
- const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"];
- if (audioExts.includes(ext)) {
- return "audio";
- }
-
- const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"];
- if (codeExts.includes(ext)) {
- return "code";
- }
-
- const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"];
- if (docExts.includes(ext)) {
- return "document";
- }
-
- const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"];
- if (archiveExts.includes(ext)) {
- return "archive";
- }
-
- if (!ext || fileName.indexOf('.') === -1) {
- return "binary";
- }
-
- return "file";
- }
-
- function isImageFile(fileName) {
- if (!fileName) {
- return false;
- }
- return determineFileType(fileName) === "image";
- }
-
- function isVideoFile(fileName) {
- if (!fileName) {
- return false;
- }
- return determineFileType(fileName) === "video";
- }
-
- property bool isImage: isImageFile(delegateRoot.fileName)
- property bool isVideo: isVideoFile(delegateRoot.fileName)
-
- property string _xdgCacheHome: Paths.strip(Paths.xdgCache)
- property string _thumbnailSize: iconSizeIndex >= 2 ? "x-large" : "large"
- property int _thumbnailPx: iconSizeIndex >= 2 ? 512 : 256
- property string videoThumbnailPath: {
- if (!delegateRoot.fileIsDir && isVideo) {
- const hash = Qt.md5("file://" + delegateRoot.filePath);
- return _xdgCacheHome + "/thumbnails/" + _thumbnailSize + "/" + hash + ".png";
- }
- return "";
- }
-
- property string _videoThumb: ""
-
- onVideoThumbnailPathChanged: {
- _videoThumb = "";
- if (!videoThumbnailPath)
- return;
- const thumbPath = videoThumbnailPath;
- const thumbDir = _xdgCacheHome + "/thumbnails/" + _thumbnailSize;
- const size = _thumbnailPx;
- const fp = delegateRoot.filePath;
- Paths.mkdir(thumbDir);
- Proc.runCommand(null, ["test", "-f", thumbPath], function(output, exitCode) {
- if (exitCode === 0) {
- _videoThumb = thumbPath;
- } else {
- Proc.runCommand(null, ["ffmpegthumbnailer", "-i", fp, "-o", thumbPath, "-s", String(size), "-f"], function(output, exitCode) {
- if (exitCode === 0)
- _videoThumb = thumbPath;
- });
- }
- });
- }
-
- function getIconForFile(fileName) {
- const lowerName = fileName.toLowerCase();
- if (lowerName.startsWith("dockerfile")) {
- return "docker";
- }
- const ext = fileName.split('.').pop();
- return ext || "";
- }
-
- width: weMode ? 245 : iconSizes[iconSizeIndex] + 16
- height: weMode ? 205 : iconSizes[iconSizeIndex] + 48
- radius: Theme.cornerRadius
- color: {
- if (keyboardNavigationActive && delegateRoot.index === selectedIndex)
- return Theme.surfacePressed;
-
- return mouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent";
- }
- border.color: keyboardNavigationActive && delegateRoot.index === selectedIndex ? Theme.primary : "transparent"
- border.width: (keyboardNavigationActive && delegateRoot.index === selectedIndex) ? 2 : 0
-
- Component.onCompleted: {
- if (keyboardNavigationActive && delegateRoot.index === selectedIndex)
- itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
- }
-
- onSelectedIndexChanged: {
- if (keyboardNavigationActive && selectedIndex === delegateRoot.index)
- itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
- }
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- Item {
- width: weMode ? 225 : (iconSizes[iconSizeIndex] - 8)
- height: weMode ? 165 : (iconSizes[iconSizeIndex] - 8)
- anchors.horizontalCenter: parent.horizontalCenter
-
- Image {
- id: gridPreviewImage
- anchors.fill: parent
- anchors.margins: 2
- property var weExtensions: [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".tga", ".jxl", ".avif", ".heif", ".exr"]
- property int weExtIndex: 0
- property string imagePath: {
- if (weMode && delegateRoot.fileIsDir)
- return delegateRoot.filePath + "/preview" + weExtensions[weExtIndex];
- if (!delegateRoot.fileIsDir && isImage)
- return delegateRoot.filePath;
- if (_videoThumb)
- return _videoThumb;
- return "";
- }
- source: imagePath ? "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/') : ""
- onStatusChanged: {
- if (weMode && delegateRoot.fileIsDir && status === Image.Error) {
- if (weExtIndex < weExtensions.length - 1) {
- weExtIndex++;
- } else {
- imagePath = "";
- }
- }
- }
- fillMode: Image.PreserveAspectCrop
- sourceSize.width: weMode ? 225 : iconSizes[iconSizeIndex]
- sourceSize.height: weMode ? 225 : iconSizes[iconSizeIndex]
- asynchronous: true
- visible: false
- }
-
- MultiEffect {
- anchors.fill: parent
- anchors.margins: 2
- source: gridPreviewImage
- maskEnabled: true
- maskSource: gridImageMask
- visible: gridPreviewImage.status === Image.Ready && ((!delegateRoot.fileIsDir && (isImage || isVideo)) || (weMode && delegateRoot.fileIsDir))
- maskThresholdMin: 0.5
- maskSpreadAtMin: 1
- }
-
- Item {
- id: gridImageMask
- anchors.fill: parent
- anchors.margins: 2
- layer.enabled: true
- layer.smooth: true
- visible: false
-
- Rectangle {
- anchors.fill: parent
- radius: Theme.cornerRadius
- color: "black"
- antialiasing: true
- }
- }
-
- DankNFIcon {
- anchors.centerIn: parent
- name: delegateRoot.fileIsDir ? "folder" : getIconForFile(delegateRoot.fileName)
- size: iconSizes[iconSizeIndex] * 0.45
- color: delegateRoot.fileIsDir ? Theme.primary : Theme.surfaceText
- visible: (!delegateRoot.fileIsDir && !isImage && !(isVideo && gridPreviewImage.status === Image.Ready)) || (delegateRoot.fileIsDir && !weMode)
- }
- }
-
- StyledText {
- text: delegateRoot.fileName || ""
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- width: delegateRoot.width - Theme.spacingM
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignHCenter
- anchors.horizontalCenter: parent.horizontalCenter
- maximumLineCount: 2
- wrapMode: Text.Wrap
- }
- }
-
- MouseArea {
- id: mouseArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- itemClicked(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml
deleted file mode 100644
index 2f452b4..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml
+++ /dev/null
@@ -1,258 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import qs.Common
-import qs.Widgets
-
-StyledRect {
- id: listDelegateRoot
-
- required property bool fileIsDir
- required property string filePath
- required property string fileName
- required property int index
- required property var fileModified
- required property int fileSize
-
- property int selectedIndex: -1
- property bool keyboardNavigationActive: false
-
- signal itemClicked(int index, string path, string name, bool isDir)
- signal itemSelected(int index, string path, string name, bool isDir)
-
- function getFileExtension(fileName) {
- const parts = fileName.split('.');
- if (parts.length > 1) {
- return parts[parts.length - 1].toLowerCase();
- }
- return "";
- }
-
- function determineFileType(fileName) {
- const ext = getFileExtension(fileName);
-
- const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico", "jxl", "avif", "heif", "exr"];
- if (imageExts.includes(ext)) {
- return "image";
- }
-
- const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"];
- if (videoExts.includes(ext)) {
- return "video";
- }
-
- const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"];
- if (audioExts.includes(ext)) {
- return "audio";
- }
-
- const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"];
- if (codeExts.includes(ext)) {
- return "code";
- }
-
- const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"];
- if (docExts.includes(ext)) {
- return "document";
- }
-
- const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"];
- if (archiveExts.includes(ext)) {
- return "archive";
- }
-
- if (!ext || fileName.indexOf('.') === -1) {
- return "binary";
- }
-
- return "file";
- }
-
- function isImageFile(fileName) {
- if (!fileName) {
- return false;
- }
- return determineFileType(fileName) === "image";
- }
-
- function isVideoFile(fileName) {
- if (!fileName) {
- return false;
- }
- return determineFileType(fileName) === "video";
- }
-
- property bool isImage: isImageFile(listDelegateRoot.fileName)
- property bool isVideo: isVideoFile(listDelegateRoot.fileName)
-
- property string _xdgCacheHome: Paths.strip(Paths.xdgCache)
- property string videoThumbnailPath: {
- if (!listDelegateRoot.fileIsDir && isVideo) {
- const hash = Qt.md5("file://" + listDelegateRoot.filePath);
- return _xdgCacheHome + "/thumbnails/normal/" + hash + ".png";
- }
- return "";
- }
-
- property string _videoThumb: ""
-
- onVideoThumbnailPathChanged: {
- _videoThumb = "";
- if (!videoThumbnailPath)
- return;
- const thumbPath = videoThumbnailPath;
- const fp = listDelegateRoot.filePath;
- Paths.mkdir(_xdgCacheHome + "/thumbnails/normal");
- Proc.runCommand(null, ["test", "-f", thumbPath], function(output, exitCode) {
- if (exitCode === 0) {
- _videoThumb = thumbPath;
- } else {
- Proc.runCommand(null, ["ffmpegthumbnailer", "-i", fp, "-o", thumbPath, "-s", "128", "-f"], function(output, exitCode) {
- if (exitCode === 0)
- _videoThumb = thumbPath;
- });
- }
- });
- }
-
- function getIconForFile(fileName) {
- const lowerName = fileName.toLowerCase();
- if (lowerName.startsWith("dockerfile")) {
- return "docker";
- }
- const ext = fileName.split('.').pop();
- return ext || "";
- }
-
- function formatFileSize(size) {
- if (size < 1024)
- return size + " B";
- if (size < 1024 * 1024)
- return (size / 1024).toFixed(1) + " KB";
- if (size < 1024 * 1024 * 1024)
- return (size / (1024 * 1024)).toFixed(1) + " MB";
- return (size / (1024 * 1024 * 1024)).toFixed(1) + " GB";
- }
-
- height: 44
- radius: Theme.cornerRadius
- color: {
- if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex)
- return Theme.surfacePressed;
- return listMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent";
- }
- border.color: keyboardNavigationActive && listDelegateRoot.index === selectedIndex ? Theme.primary : "transparent"
- border.width: (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) ? 2 : 0
-
- Component.onCompleted: {
- if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex)
- itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
- }
-
- onSelectedIndexChanged: {
- if (keyboardNavigationActive && selectedIndex === listDelegateRoot.index)
- itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
- }
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: Theme.spacingS
- spacing: Theme.spacingS
-
- Item {
- width: 28
- height: 28
- anchors.verticalCenter: parent.verticalCenter
-
- Image {
- id: listPreviewImage
- anchors.fill: parent
- property string imagePath: {
- if (!listDelegateRoot.fileIsDir && isImage)
- return listDelegateRoot.filePath;
- if (_videoThumb)
- return _videoThumb;
- return "";
- }
- source: imagePath ? "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/') : ""
- fillMode: Image.PreserveAspectCrop
- sourceSize.width: 32
- sourceSize.height: 32
- asynchronous: true
- visible: false
- }
-
- MultiEffect {
- anchors.fill: parent
- source: listPreviewImage
- maskEnabled: true
- maskSource: listImageMask
- visible: listPreviewImage.status === Image.Ready && !listDelegateRoot.fileIsDir && (isImage || isVideo)
- maskThresholdMin: 0.5
- maskSpreadAtMin: 1
- }
-
- Item {
- id: listImageMask
- anchors.fill: parent
- layer.enabled: true
- layer.smooth: true
- visible: false
-
- Rectangle {
- anchors.fill: parent
- radius: Theme.cornerRadius
- color: "black"
- antialiasing: true
- }
- }
-
- DankNFIcon {
- anchors.centerIn: parent
- name: listDelegateRoot.fileIsDir ? "folder" : getIconForFile(listDelegateRoot.fileName)
- size: Theme.iconSize - 2
- color: listDelegateRoot.fileIsDir ? Theme.primary : Theme.surfaceText
- visible: listDelegateRoot.fileIsDir || (!isImage && !(isVideo && listPreviewImage.status === Image.Ready))
- }
- }
-
- StyledText {
- text: listDelegateRoot.fileName || ""
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width - 280
- elide: Text.ElideRight
- anchors.verticalCenter: parent.verticalCenter
- maximumLineCount: 1
- clip: true
- }
-
- StyledText {
- text: listDelegateRoot.fileIsDir ? "" : formatFileSize(listDelegateRoot.fileSize)
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: 70
- horizontalAlignment: Text.AlignRight
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: Qt.formatDateTime(listDelegateRoot.fileModified, "MMM d, yyyy h:mm AP")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: 140
- horizontalAlignment: Text.AlignRight
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: listMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- itemClicked(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml
deleted file mode 100644
index c7686ca..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml
+++ /dev/null
@@ -1,97 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Widgets
-
-FloatingWindow {
- id: fileBrowserModal
-
- property bool disablePopupTransparency: true
- property string browserTitle: "Select File"
- property string browserIcon: "folder_open"
- property string browserType: "generic"
- property var fileExtensions: ["*.*"]
- property alias filterExtensions: fileBrowserModal.fileExtensions
- property bool showHiddenFiles: false
- property bool saveMode: false
- property string defaultFileName: ""
- property var parentModal: null
- property bool shouldHaveFocus: visible
- property bool allowFocusOverride: false
- property bool shouldBeVisible: visible
- property bool allowStacking: true
-
- signal fileSelected(string path)
- signal dialogClosed
-
- function open() {
- visible = true;
- }
-
- function close() {
- visible = false;
- }
-
- objectName: "fileBrowserModal"
- title: "Files - " + browserTitle
- minimumSize: Qt.size(500, 400)
- implicitWidth: 800
- implicitHeight: 600
- color: Theme.surfaceContainer
- visible: false
-
- onVisibleChanged: {
- if (visible) {
- if (parentModal && "shouldHaveFocus" in parentModal) {
- parentModal.shouldHaveFocus = false;
- parentModal.allowFocusOverride = true;
- }
- Qt.callLater(() => {
- if (content) {
- content.reset();
- content.forceActiveFocus();
- }
- });
- } else {
- if (parentModal && "allowFocusOverride" in parentModal) {
- parentModal.allowFocusOverride = false;
- parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
- }
- dialogClosed();
- }
- }
-
- Loader {
- id: contentLoader
- anchors.fill: parent
- active: fileBrowserModal.visible
- sourceComponent: FileBrowserContent {
- id: content
- anchors.fill: parent
- focus: true
- closeOnEscape: false
- windowControls: fileBrowserModal.windowControlsRef
-
- browserTitle: fileBrowserModal.browserTitle
- browserIcon: fileBrowserModal.browserIcon
- browserType: fileBrowserModal.browserType
- fileExtensions: fileBrowserModal.fileExtensions
- showHiddenFiles: fileBrowserModal.showHiddenFiles
- saveMode: fileBrowserModal.saveMode
- defaultFileName: fileBrowserModal.defaultFileName
-
- Component.onCompleted: initialize()
-
- onFileSelected: path => fileBrowserModal.fileSelected(path)
- onCloseRequested: fileBrowserModal.close()
- }
- }
-
- property alias content: contentLoader.item
- property alias windowControlsRef: windowControls
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: fileBrowserModal
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml
deleted file mode 100644
index 61ce7b6..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml
+++ /dev/null
@@ -1,130 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Row {
- id: navigation
-
- property string currentPath: ""
- property string homeDir: ""
- property bool backButtonFocused: false
- property bool keyboardNavigationActive: false
- property bool showSidebar: true
- property bool pathEditMode: false
- property bool pathInputHasFocus: false
-
- signal navigateUp()
- signal navigateTo(string path)
- signal pathInputFocusChanged(bool hasFocus)
-
- height: 40
- leftPadding: Theme.spacingM
- rightPadding: Theme.spacingM
- spacing: Theme.spacingS
-
- StyledRect {
- width: 32
- height: 32
- radius: Theme.cornerRadius
- color: (backButtonMouseArea.containsMouse || (backButtonFocused && keyboardNavigationActive)) && currentPath !== homeDir ? Theme.surfaceVariant : "transparent"
- opacity: currentPath !== homeDir ? 1 : 0
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: "arrow_back"
- size: Theme.iconSizeSmall
- color: Theme.surfaceText
- }
-
- MouseArea {
- id: backButtonMouseArea
-
- anchors.fill: parent
- hoverEnabled: currentPath !== homeDir
- cursorShape: currentPath !== homeDir ? Qt.PointingHandCursor : Qt.ArrowCursor
- enabled: currentPath !== homeDir
- onClicked: navigation.navigateUp()
- }
- }
-
- Item {
- width: Math.max(0, (parent?.width ?? 0) - 40 - Theme.spacingS - (showSidebar ? 0 : 80))
- height: 32
- anchors.verticalCenter: parent.verticalCenter
-
- StyledRect {
- anchors.fill: parent
- radius: Theme.cornerRadius
- color: pathEditMode ? Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) : "transparent"
- border.color: pathEditMode ? Theme.primary : "transparent"
- border.width: pathEditMode ? 1 : 0
- visible: !pathEditMode
-
- StyledText {
- id: pathDisplay
- text: currentPath.replace("file://", "")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: Theme.spacingS
- elide: Text.ElideMiddle
- verticalAlignment: Text.AlignVCenter
- maximumLineCount: 1
- wrapMode: Text.NoWrap
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.IBeamCursor
- onClicked: {
- pathEditMode = true
- pathInput.text = currentPath.replace("file://", "")
- Qt.callLater(() => pathInput.forceActiveFocus())
- }
- }
- }
-
- DankTextField {
- id: pathInput
- anchors.fill: parent
- visible: pathEditMode
- topPadding: Theme.spacingXS
- bottomPadding: Theme.spacingXS
- onAccepted: {
- const newPath = text.trim()
- if (newPath !== "") {
- navigation.navigateTo(newPath)
- }
- pathEditMode = false
- }
- Keys.onEscapePressed: {
- pathEditMode = false
- }
- Keys.onDownPressed: {
- pathEditMode = false
- }
- onActiveFocusChanged: {
- navigation.pathInputFocusChanged(activeFocus)
- if (!activeFocus && pathEditMode) {
- pathEditMode = false
- }
- }
- }
- }
-
- Row {
- spacing: Theme.spacingXS
- visible: !showSidebar
- anchors.verticalCenter: parent.verticalCenter
-
- DankActionButton {
- circular: false
- iconName: "sort"
- iconSize: Theme.iconSize - 6
- iconColor: Theme.surfaceText
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml
deleted file mode 100644
index a664be5..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml
+++ /dev/null
@@ -1,127 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Item {
- id: overwriteDialog
-
- property bool showDialog: false
- property string pendingFilePath: ""
-
- signal confirmed(string filePath)
- signal cancelled()
-
- visible: showDialog
- focus: showDialog
-
- Keys.onEscapePressed: {
- cancelled()
- }
-
- Keys.onReturnPressed: {
- confirmed(pendingFilePath)
- }
-
- Rectangle {
- anchors.fill: parent
- color: Theme.shadowStrong
- opacity: 0.8
-
- MouseArea {
- anchors.fill: parent
- onClicked: {
- cancelled()
- }
- }
- }
-
- StyledRect {
- anchors.centerIn: parent
- width: 400
- height: 160
- color: Theme.surfaceContainer
- radius: Theme.cornerRadius
- border.color: Theme.outlineMedium
- border.width: 1
-
- Column {
- anchors.centerIn: parent
- width: parent.width - Theme.spacingL * 2
- spacing: Theme.spacingM
-
- StyledText {
- text: I18n.tr("File Already Exists")
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: I18n.tr("A file with this name already exists. Do you want to overwrite it?")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- }
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- StyledRect {
- width: 80
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceVariantHover : Theme.surfaceVariant
- border.color: Theme.outline
- border.width: 1
-
- StyledText {
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- cancelled()
- }
- }
- }
-
- StyledRect {
- width: 90
- height: 36
- radius: Theme.cornerRadius
- color: overwriteArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- anchors.centerIn: parent
- text: I18n.tr("Overwrite")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: overwriteArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- confirmed(pendingFilePath)
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml
deleted file mode 100644
index 6360c7f..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml
+++ /dev/null
@@ -1,74 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Row {
- id: saveRow
-
- property bool saveMode: false
- property string defaultFileName: ""
- property string currentPath: ""
-
- signal saveRequested(string filePath)
-
- height: saveMode ? 40 : 0
- visible: saveMode
- spacing: Theme.spacingM
-
- DankTextField {
- id: fileNameInput
-
- width: parent.width - saveButton.width - Theme.spacingM
- height: 40
- text: defaultFileName
- placeholderText: I18n.tr("Enter filename...")
- ignoreLeftRightKeys: false
- focus: saveMode
- topPadding: Theme.spacingS
- bottomPadding: Theme.spacingS
- Component.onCompleted: {
- if (saveMode)
- Qt.callLater(() => {
- forceActiveFocus()
- })
- }
- onAccepted: {
- if (text.trim() !== "") {
- var basePath = currentPath.replace(/^file:\/\//, '')
- var fullPath = basePath + "/" + text.trim()
- fullPath = fullPath.replace(/\/+/g, '/')
- saveRequested(fullPath)
- }
- }
- }
-
- StyledRect {
- id: saveButton
-
- width: 80
- height: 40
- color: fileNameInput.text.trim() !== "" ? Theme.primary : Theme.surfaceVariant
- radius: Theme.cornerRadius
-
- StyledText {
- anchors.centerIn: parent
- text: I18n.tr("Save")
- color: fileNameInput.text.trim() !== "" ? Theme.primaryText : Theme.surfaceVariantText
- font.pixelSize: Theme.fontSizeMedium
- }
-
- StateLayer {
- stateColor: Theme.primary
- cornerRadius: Theme.cornerRadius
- enabled: fileNameInput.text.trim() !== ""
- onClicked: {
- if (fileNameInput.text.trim() !== "") {
- var basePath = currentPath.replace(/^file:\/\//, '')
- var fullPath = basePath + "/" + fileNameInput.text.trim()
- fullPath = fullPath.replace(/\/+/g, '/')
- saveRequested(fullPath)
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml
deleted file mode 100644
index bc02b3e..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml
+++ /dev/null
@@ -1,70 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-StyledRect {
- id: sidebar
-
- property var quickAccessLocations: []
- property string currentPath: ""
- signal locationSelected(string path)
-
- width: 200
- color: Theme.surface
- clip: true
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- spacing: 4
-
- StyledText {
- text: I18n.tr("Quick Access")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- leftPadding: Theme.spacingS
- bottomPadding: Theme.spacingXS
- }
-
- Repeater {
- model: quickAccessLocations
-
- StyledRect {
- width: parent?.width ?? 0
- height: 38
- radius: Theme.cornerRadius
- color: quickAccessMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : (currentPath === modelData?.path ? Theme.surfacePressed : "transparent")
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- spacing: Theme.spacingS
-
- DankIcon {
- name: modelData?.icon ?? ""
- size: Theme.iconSize - 2
- color: currentPath === modelData?.path ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: modelData?.name ?? ""
- font.pixelSize: Theme.fontSizeMedium
- color: currentPath === modelData?.path ? Theme.primary : Theme.surfaceText
- font.weight: currentPath === modelData?.path ? Font.Medium : Font.Normal
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: quickAccessMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: locationSelected(modelData?.path ?? "")
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml
deleted file mode 100644
index e1886f9..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml
+++ /dev/null
@@ -1,183 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-StyledRect {
- id: sortMenu
-
- property string sortBy: "name"
- property bool sortAscending: true
-
- signal sortBySelected(string value)
- signal sortOrderSelected(bool ascending)
-
- width: 200
- height: sortColumn.height + Theme.spacingM * 2
- color: Theme.surfaceContainer
- radius: Theme.cornerRadius
- border.color: Theme.outlineMedium
- border.width: 1
- visible: false
- z: 100
-
- Column {
- id: sortColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingXS
-
- StyledText {
- text: "Sort By"
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- }
-
- Repeater {
- model: [{
- "name": "Name",
- "value": "name"
- }, {
- "name": "Size",
- "value": "size"
- }, {
- "name": "Modified",
- "value": "modified"
- }, {
- "name": "Type",
- "value": "type"
- }]
-
- StyledRect {
- width: sortColumn?.width ?? 0
- height: 32
- radius: Theme.cornerRadius
- color: sortMouseArea.containsMouse ? Theme.surfaceVariant : (sortBy === modelData?.value ? Theme.surfacePressed : "transparent")
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- spacing: Theme.spacingS
-
- DankIcon {
- name: sortBy === modelData?.value ? "check" : ""
- size: Theme.iconSizeSmall
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- visible: sortBy === modelData?.value
- }
-
- StyledText {
- text: modelData?.name ?? ""
- font.pixelSize: Theme.fontSizeMedium
- color: sortBy === modelData?.value ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: sortMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- sortMenu.sortBySelected(modelData?.value ?? "name")
- sortMenu.visible = false
- }
- }
- }
- }
-
- StyledRect {
- width: sortColumn.width
- height: 1
- color: Theme.outline
- }
-
- StyledText {
- text: "Order"
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- font.weight: Font.Medium
- topPadding: Theme.spacingXS
- }
-
- StyledRect {
- width: sortColumn?.width ?? 0
- height: 32
- radius: Theme.cornerRadius
- color: ascMouseArea.containsMouse ? Theme.surfaceVariant : (sortAscending ? Theme.surfacePressed : "transparent")
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- spacing: Theme.spacingS
-
- DankIcon {
- name: "arrow_upward"
- size: Theme.iconSizeSmall
- color: sortAscending ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: "Ascending"
- font.pixelSize: Theme.fontSizeMedium
- color: sortAscending ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: ascMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- sortMenu.sortOrderSelected(true)
- sortMenu.visible = false
- }
- }
- }
-
- StyledRect {
- width: sortColumn?.width ?? 0
- height: 32
- radius: Theme.cornerRadius
- color: descMouseArea.containsMouse ? Theme.surfaceVariant : (!sortAscending ? Theme.surfacePressed : "transparent")
-
- Row {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- spacing: Theme.spacingS
-
- DankIcon {
- name: "arrow_downward"
- size: Theme.iconSizeSmall
- color: !sortAscending ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: "Descending"
- font.pixelSize: Theme.fontSizeMedium
- color: !sortAscending ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: descMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- sortMenu.sortOrderSelected(false)
- sortMenu.visible = false
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml
deleted file mode 100644
index 25b8d5a..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml
+++ /dev/null
@@ -1,66 +0,0 @@
-import QtQuick
-import Quickshell.Wayland
-import qs.Common
-import qs.Modals.Common
-
-DankModal {
- id: fileBrowserSurfaceModal
-
- property string browserTitle: "Select File"
- property string browserIcon: "folder_open"
- property string browserType: "generic"
- property var fileExtensions: ["*.*"]
- property alias filterExtensions: fileBrowserSurfaceModal.fileExtensions
- property bool showHiddenFiles: false
- property bool saveMode: false
- property string defaultFileName: ""
- property var parentPopout: null
-
- signal fileSelected(string path)
-
- layerNamespace: "dms:filebrowser"
- modalWidth: 800
- modalHeight: 600
- backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- closeOnEscapeKey: true
- closeOnBackgroundClick: true
- allowStacking: true
- keepPopoutsOpen: true
-
- onBackgroundClicked: close()
-
- onOpened: {
- if (parentPopout) {
- parentPopout.customKeyboardFocus = WlrKeyboardFocus.None;
- }
- Qt.callLater(() => {
- if (contentLoader.item) {
- contentLoader.item.reset();
- contentLoader.item.forceActiveFocus();
- }
- });
- }
-
- onDialogClosed: {
- if (parentPopout) {
- parentPopout.customKeyboardFocus = null;
- }
- }
-
- content: FileBrowserContent {
- focus: true
-
- browserTitle: fileBrowserSurfaceModal.browserTitle
- browserIcon: fileBrowserSurfaceModal.browserIcon
- browserType: fileBrowserSurfaceModal.browserType
- fileExtensions: fileBrowserSurfaceModal.fileExtensions
- showHiddenFiles: fileBrowserSurfaceModal.showHiddenFiles
- saveMode: fileBrowserSurfaceModal.saveMode
- defaultFileName: fileBrowserSurfaceModal.defaultFileName
-
- Component.onCompleted: initialize()
-
- onFileSelected: path => fileBrowserSurfaceModal.fileSelected(path)
- onCloseRequested: fileBrowserSurfaceModal.close()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml
deleted file mode 100644
index c41f039..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml
+++ /dev/null
@@ -1,237 +0,0 @@
-import QtQuick
-import QtCore
-import Quickshell.Io
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property bool showFileInfo: false
- property int selectedIndex: -1
- property var sourceFolderModel: null
- property string currentPath: ""
-
- height: 200
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95)
- border.color: Theme.secondary
- border.width: 2
- opacity: showFileInfo ? 1 : 0
- z: 100
-
- onShowFileInfoChanged: {
- if (showFileInfo && currentFileName && currentPath) {
- const fullPath = currentPath + "/" + currentFileName
- fileStatProcess.selectedFilePath = fullPath
- fileStatProcess.running = true
- }
- }
-
- Process {
- id: fileStatProcess
- command: ["stat", "-c", "%y|%A|%s|%n", selectedFilePath]
- property string selectedFilePath: ""
- property var fileStats: null
- running: false
-
- stdout: StdioCollector {
- onStreamFinished: {
- if (text && text.trim()) {
- const parts = text.trim().split('|')
- if (parts.length >= 4) {
- fileStatProcess.fileStats = {
- "modifiedTime": parts[0],
- "permissions": parts[1],
- "size": parseInt(parts[2]) || 0,
- "fullPath": parts[3]
- }
- }
- }
- }
- }
-
- onExited: function (exitCode) {}
- }
-
- property string currentFileName: ""
- property bool currentFileIsDir: false
- property string currentFileExtension: ""
-
- onCurrentFileNameChanged: {
- if (showFileInfo && currentFileName && currentPath) {
- const fullPath = currentPath + "/" + currentFileName
- if (fullPath !== fileStatProcess.selectedFilePath) {
- fileStatProcess.selectedFilePath = fullPath
- fileStatProcess.running = true
- }
- }
- }
-
- function updateFileInfo(filePath, fileName, isDirectory) {
- if (filePath && filePath !== fileStatProcess.selectedFilePath) {
- fileStatProcess.selectedFilePath = filePath
- currentFileName = fileName || ""
- currentFileIsDir = isDirectory || false
-
- let ext = ""
- if (!isDirectory && fileName) {
- const lastDot = fileName.lastIndexOf('.')
- if (lastDot > 0) {
- ext = fileName.substring(lastDot + 1).toLowerCase()
- }
- }
- currentFileExtension = ext
-
- if (showFileInfo) {
- fileStatProcess.running = true
- }
- }
- }
-
- readonly property var currentFileDisplayData: {
- if (selectedIndex < 0 || !sourceFolderModel) {
- return {
- "exists": false,
- "name": "No selection",
- "type": "",
- "size": "",
- "modified": "",
- "permissions": "",
- "extension": "",
- "position": "N/A"
- }
- }
-
- const hasValidFile = currentFileName !== ""
- return {
- "exists": hasValidFile,
- "name": hasValidFile ? currentFileName : "Loading...",
- "type": currentFileIsDir ? "Directory" : "File",
- "size": fileStatProcess.fileStats ? formatFileSize(fileStatProcess.fileStats.size) : "Calculating...",
- "modified": fileStatProcess.fileStats ? formatDateTime(fileStatProcess.fileStats.modifiedTime) : "Loading...",
- "permissions": fileStatProcess.fileStats ? fileStatProcess.fileStats.permissions : "Loading...",
- "extension": currentFileExtension,
- "position": sourceFolderModel ? ((selectedIndex + 1) + " of " + sourceFolderModel.count) : "N/A"
- }
- }
-
- Column {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingXS
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- DankIcon {
- name: "info"
- size: Theme.iconSize
- color: Theme.secondary
- }
-
- StyledText {
- text: I18n.tr("File Information")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: currentFileDisplayData.name
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width
- elide: Text.ElideMiddle
- wrapMode: Text.NoWrap
- font.weight: Font.Medium
- }
-
- StyledText {
- text: currentFileDisplayData.type + (currentFileDisplayData.extension ? " (." + currentFileDisplayData.extension + ")" : "")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: parent.width
- }
-
- StyledText {
- text: currentFileDisplayData.size
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: parent.width
- visible: currentFileDisplayData.exists && !currentFileIsDir
- }
-
- StyledText {
- text: currentFileDisplayData.modified
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: parent.width
- elide: Text.ElideRight
- visible: currentFileDisplayData.exists
- }
-
- StyledText {
- text: currentFileDisplayData.permissions
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- visible: currentFileDisplayData.exists
- }
-
- StyledText {
- text: currentFileDisplayData.position
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: parent.width
- }
- }
- }
-
- StyledText {
- text: I18n.tr("F1/I: Toggle • F10: Help")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingM
- horizontalAlignment: Text.AlignHCenter
- }
-
- function formatFileSize(bytes) {
- if (bytes === 0 || !bytes) {
- return "0 B"
- }
- const k = 1024
- const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
- const i = Math.floor(Math.log(bytes) / Math.log(k))
- return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
- }
-
- function formatDateTime(dateTimeString) {
- if (!dateTimeString) {
- return "Unknown"
- }
- const parts = dateTimeString.split(' ')
- if (parts.length >= 2) {
- return parts[0] + " " + parts[1].split('.')[0]
- }
- return dateTimeString
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml
deleted file mode 100644
index 1910810..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml
+++ /dev/null
@@ -1,50 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property bool showHints: false
-
- height: 80
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95)
- border.color: Theme.primary
- border.width: 2
- opacity: showHints ? 1 : 0
- z: 100
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingS
- spacing: 2
-
- StyledText {
- text: I18n.tr("Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- width: parent.width
- wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- }
-
- StyledText {
- text: I18n.tr("Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- width: parent.width
- wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml
deleted file mode 100644
index 8a5ca00..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml
+++ /dev/null
@@ -1,492 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- property var greeterRoot: parent ? parent.greeterRoot : null
-
- readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2)
- readonly property real sectionIconSize: Theme.iconSizeSmall + 2
- readonly property real keybindRowHeight: Math.round(Theme.fontSizeMedium * 2)
- readonly property real keyBadgeHeight: Math.round(Theme.fontSizeSmall * 1.83)
-
- readonly property var featureNames: ({
- "spotlight": "App Launcher",
- "clipboard": "Clipboard",
- "processlist": "Task Manager",
- "settings": "Settings",
- "notifications": "Notifications",
- "notepad": "Notepad",
- "hotkeys": "Keybinds",
- "lock": "Lock Screen",
- "dankdash": "Dashboard"
- })
-
- function getFeatureDesc(action) {
- const match = action.match(/dms\s+ipc\s+call\s+(\w+)/);
- if (match && featureNames[match[1]])
- return featureNames[match[1]];
- return null;
- }
-
- readonly property var dmsKeybinds: {
- if (!greeterRoot || !greeterRoot.cheatsheetLoaded || !greeterRoot.cheatsheetData || !greeterRoot.cheatsheetData.binds)
- return [];
- const seen = new Set();
- const binds = [];
- const allBinds = greeterRoot.cheatsheetData.binds;
- for (const category in allBinds) {
- const categoryBinds = allBinds[category];
- for (let i = 0; i < categoryBinds.length; i++) {
- const bind = categoryBinds[i];
- if (!bind.key || !bind.action)
- continue;
- if (!bind.action.includes("dms"))
- continue;
- if (!(bind.action.includes("spawn") || bind.action.includes("exec")))
- continue;
- const feature = getFeatureDesc(bind.action);
- if (!feature)
- continue;
- if (seen.has(feature))
- continue;
- seen.add(feature);
- binds.push({
- key: bind.key,
- desc: feature
- });
- }
- }
- return binds;
- }
-
- readonly property bool hasKeybinds: dmsKeybinds.length > 0
-
- DankFlickable {
- anchors.fill: parent
- clip: true
- contentHeight: mainColumn.height + Theme.spacingL * 2
- contentWidth: width
-
- Column {
- id: mainColumn
- anchors.horizontalCenter: parent.horizontalCenter
- width: Math.min(640, parent.width - Theme.spacingXL * 2)
- topPadding: Theme.spacingL
- spacing: Theme.spacingL
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: root.headerIconContainerSize
- height: root.headerIconContainerSize
- radius: Math.round(root.headerIconContainerSize * 0.29)
- color: Theme.withAlpha(Theme.success, 0.15)
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: "check_circle"
- size: Theme.iconSize + 4
- color: Theme.success
- }
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
-
- StyledText {
- text: I18n.tr("You're All Set!", "greeter completion page title")
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
-
- StyledText {
- text: I18n.tr("DankMaterialShell is ready to use", "greeter completion page subtitle")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- }
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
- visible: root.hasKeybinds
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- DankIcon {
- name: "keyboard"
- size: root.sectionIconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("DMS Shortcuts", "greeter keybinds section header")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- id: keybindsRect
- width: parent.width
- height: keybindsGrid.height + Theme.spacingM * 2
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
-
- readonly property bool useTwoColumns: width > 500
- readonly property int columnCount: useTwoColumns ? 2 : 1
- readonly property real itemWidth: useTwoColumns ? (width - Theme.spacingM * 3) / 2 : width - Theme.spacingM * 2
- property real maxKeyWidth: 0
-
- Grid {
- id: keybindsGrid
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- columns: keybindsRect.columnCount
- rowSpacing: Theme.spacingS
- columnSpacing: Theme.spacingM
-
- Repeater {
- model: root.dmsKeybinds
-
- Row {
- width: keybindsRect.itemWidth
- height: root.keybindRowHeight
- spacing: Theme.spacingS
-
- Item {
- width: keybindsRect.maxKeyWidth
- height: parent.height
-
- Row {
- id: keysRow
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- property real naturalWidth: {
- let w = 0;
- for (let i = 0; i < children.length; i++) {
- if (children[i].visible)
- w += children[i].width + (i > 0 ? Theme.spacingXS : 0);
- }
- return w;
- }
-
- Component.onCompleted: {
- Qt.callLater(() => {
- if (naturalWidth > keybindsRect.maxKeyWidth)
- keybindsRect.maxKeyWidth = naturalWidth;
- });
- }
-
- Repeater {
- model: (modelData.key || "").split("+")
-
- Rectangle {
- width: singleKeyText.implicitWidth + Theme.spacingM
- height: root.keyBadgeHeight
- radius: Theme.spacingXS
- color: Theme.surfaceContainerHighest
- border.width: 1
- border.color: Theme.outline
-
- StyledText {
- id: singleKeyText
- anchors.centerIn: parent
- color: Theme.secondary
- text: modelData
- font.pixelSize: Theme.fontSizeSmall - 1
- font.weight: Font.Medium
- isMonospace: true
- }
- }
- }
- }
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- width: parent.width - keybindsRect.maxKeyWidth - Theme.spacingS
- text: modelData.desc || ""
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- elide: Text.ElideRight
- }
- }
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: noKeybindsColumn.height + Theme.spacingM * 2
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
- visible: !root.hasKeybinds
-
- Column {
- id: noKeybindsColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingS
-
- Row {
- spacing: Theme.spacingS
-
- DankIcon {
- name: "keyboard"
- size: root.sectionIconSize
- color: Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("No DMS shortcuts configured", "greeter no keybinds message")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- width: parent.width
- height: Math.round(Theme.fontSizeMedium * 2.85)
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHighest
-
- Rectangle {
- anchors.fill: parent
- radius: parent.radius
- color: Theme.primary
- opacity: noKeybindsLinkMouse.containsMouse ? 0.12 : 0
- }
-
- Row {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- DankIcon {
- name: "menu_book"
- size: root.sectionIconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Configure Keybinds", "greeter configure keybinds link")
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- DankIcon {
- name: "open_in_new"
- size: Theme.iconSizeSmall - 2
- color: Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: noKeybindsLinkMouse
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- let url = "https://danklinux.com/docs/dankmaterialshell/keybinds-ipc";
- if (CompositorService.isNiri)
- url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings";
- else if (CompositorService.isHyprland)
- url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-1";
- else if (CompositorService.isDwl)
- url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-2";
- Qt.openUrlExternally(url);
- }
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.3
- visible: root.hasKeybinds
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- DankIcon {
- name: "settings"
- size: root.sectionIconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Configure", "greeter settings section header")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Grid {
- width: parent.width
- columns: 2
- rowSpacing: Theme.spacingS
- columnSpacing: Theme.spacingS
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "display_settings"
- title: I18n.tr("Displays", "greeter settings link")
- description: I18n.tr("Resolution, position, scale", "greeter displays description")
- onClicked: PopoutService.openSettingsWithTab("display_config")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "wallpaper"
- title: I18n.tr("Wallpaper", "greeter settings link")
- description: I18n.tr("Background image", "greeter wallpaper description")
- onClicked: PopoutService.openSettingsWithTab("wallpaper")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "format_paint"
- title: I18n.tr("Theme & Colors", "greeter settings link")
- description: I18n.tr("Dynamic colors, presets", "greeter theme description")
- onClicked: PopoutService.openSettingsWithTab("theme")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "notifications"
- title: I18n.tr("Notifications", "greeter settings link")
- description: I18n.tr("Popup behavior, position", "greeter notifications description")
- onClicked: PopoutService.openSettingsWithTab("notifications")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "toolbar"
- title: I18n.tr("DankBar", "greeter settings link")
- description: I18n.tr("Widgets, layout, style", "greeter dankbar description")
- onClicked: PopoutService.openSettingsWithTab("dankbar_settings")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "keyboard"
- title: I18n.tr("Keybinds", "greeter settings link")
- description: I18n.tr("niri shortcuts config", "greeter keybinds niri description")
- visible: KeybindsService.available
- onClicked: PopoutService.openSettingsWithTab("keybinds")
- }
-
- GreeterSettingsCard {
- width: (parent.width - Theme.spacingS) / 2
- iconName: "dock_to_bottom"
- title: I18n.tr("Dock", "greeter settings link")
- description: I18n.tr("Position, pinned apps", "greeter dock description")
- visible: !KeybindsService.available
- onClicked: PopoutService.openSettingsWithTab("dock")
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.3
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingS
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- DankIcon {
- name: "explore"
- size: root.sectionIconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Explore", "greeter explore section header")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- GreeterQuickLink {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "menu_book"
- title: I18n.tr("Docs", "greeter documentation link")
- isExternal: true
- onClicked: Qt.openUrlExternally("https://danklinux.com/docs")
- }
-
- GreeterQuickLink {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "extension"
- title: I18n.tr("Plugins", "greeter plugins link")
- isExternal: true
- onClicked: Qt.openUrlExternally("https://danklinux.com/plugins")
- }
-
- GreeterQuickLink {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "palette"
- title: I18n.tr("Themes", "greeter themes link")
- isExternal: true
- onClicked: Qt.openUrlExternally("https://danklinux.com/plugins?tab=themes")
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml
deleted file mode 100644
index 288cd58..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml
+++ /dev/null
@@ -1,427 +0,0 @@
-import QtQuick
-import Quickshell.Io
-import qs.Common
-import qs.Widgets
-
-Item {
- id: root
-
- property bool isRunning: false
- property bool hasRun: false
- property var doctorResults: null
- property int errorCount: 0
- property int warningCount: 0
- property int okCount: 0
- property int infoCount: 0
- property string selectedFilter: "error"
-
- readonly property real loadingContainerSize: Math.round(Theme.iconSize * 5)
- readonly property real pulseRingSize: Math.round(Theme.iconSize * 3.3)
- readonly property real centerIconContainerSize: Math.round(Theme.iconSize * 2.67)
- readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2)
-
- readonly property var filteredResults: {
- if (!doctorResults?.results)
- return [];
- return doctorResults.results.filter(r => r.status === selectedFilter);
- }
-
- function runDoctor() {
- hasRun = false;
- isRunning = true;
- doctorProcess.running = true;
- }
-
- Component.onCompleted: runDoctor()
-
- Item {
- id: loadingView
- anchors.fill: parent
- visible: root.isRunning
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingXL
-
- Item {
- width: root.loadingContainerSize
- height: root.loadingContainerSize
- anchors.horizontalCenter: parent.horizontalCenter
-
- Rectangle {
- id: pulseRing1
- anchors.centerIn: parent
- width: root.pulseRingSize
- height: root.pulseRingSize
- radius: root.pulseRingSize / 2
- color: "transparent"
- border.width: Math.round(Theme.spacingXS * 0.75)
- border.color: Theme.primary
- opacity: 0
-
- SequentialAnimation on opacity {
- running: root.isRunning
- loops: Animation.Infinite
- NumberAnimation {
- from: 0.8
- to: 0
- duration: 1500
- easing.type: Easing.OutQuad
- }
- }
-
- SequentialAnimation on scale {
- running: root.isRunning
- loops: Animation.Infinite
- NumberAnimation {
- from: 0.5
- to: 1.5
- duration: 1500
- easing.type: Easing.OutQuad
- }
- }
- }
-
- Rectangle {
- id: pulseRing2
- anchors.centerIn: parent
- width: root.pulseRingSize
- height: root.pulseRingSize
- radius: root.pulseRingSize / 2
- color: "transparent"
- border.width: Math.round(Theme.spacingXS * 0.75)
- border.color: Theme.secondary
- opacity: 0
-
- SequentialAnimation on opacity {
- running: root.isRunning
- loops: Animation.Infinite
- NumberAnimation {
- from: 0.8
- to: 0
- duration: 1500
- easing.type: Easing.OutQuad
- }
- }
-
- SequentialAnimation on scale {
- running: root.isRunning
- loops: Animation.Infinite
- NumberAnimation {
- from: 0.3
- to: 1.3
- duration: 1500
- easing.type: Easing.OutQuad
- }
- }
- }
-
- Rectangle {
- anchors.centerIn: parent
- width: root.centerIconContainerSize
- height: root.centerIconContainerSize
- radius: root.centerIconContainerSize / 2
- color: Theme.primaryContainer
-
- DankIcon {
- anchors.centerIn: parent
- name: "vital_signs"
- size: Theme.iconSizeLarge
- color: Theme.primary
- }
-
- SequentialAnimation on scale {
- running: root.isRunning
- loops: Animation.Infinite
- NumberAnimation {
- from: 1
- to: 1.1
- duration: 750
- easing.type: Easing.InOutQuad
- }
- NumberAnimation {
- from: 1.1
- to: 1
- duration: 750
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
-
- Column {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingS
-
- StyledText {
- text: I18n.tr("System Check", "greeter doctor page title")
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Bold
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: I18n.tr("Analyzing configuration...", "greeter doctor page loading text")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- }
- }
-
- Item {
- id: resultsView
- anchors.fill: parent
- visible: root.hasRun && !root.isRunning
- opacity: (root.hasRun && !root.isRunning) ? 1 : 0
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.emphasizedEasing
- }
- }
-
- Column {
- id: headerSection
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingL
- anchors.leftMargin: Theme.spacingXL
- anchors.rightMargin: Theme.spacingXL
- spacing: Theme.spacingL
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: root.headerIconContainerSize
- height: root.headerIconContainerSize
- radius: Math.round(root.headerIconContainerSize * 0.29)
- color: root.errorCount > 0 ? Theme.errorContainer : Theme.primaryContainer
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: root.errorCount > 0 ? "warning" : "check_circle"
- size: Theme.iconSize + 4
- color: root.errorCount > 0 ? Theme.error : Theme.primary
- }
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
-
- StyledText {
- text: I18n.tr("System Check", "greeter doctor page title")
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
-
- StyledText {
- text: {
- if (root.errorCount === 0)
- return I18n.tr("All checks passed", "greeter doctor page success");
- return root.errorCount === 1
- ? I18n.tr("%1 issue found", "greeter doctor page error count").arg(root.errorCount)
- : I18n.tr("%1 issues found", "greeter doctor page error count").arg(root.errorCount);
- }
- font.pixelSize: Theme.fontSizeMedium
- color: root.errorCount > 0 ? Theme.error : Theme.surfaceVariantText
- }
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- GreeterStatusCard {
- width: (parent.width - Theme.spacingS * 3) / 4
- count: root.errorCount
- label: I18n.tr("Errors", "greeter doctor page status card")
- iconName: "error"
- iconColor: Theme.error
- bgColor: Theme.errorContainer || Theme.withAlpha(Theme.error, 0.15)
- selected: root.selectedFilter === "error"
- onClicked: root.selectedFilter = "error"
- }
-
- GreeterStatusCard {
- width: (parent.width - Theme.spacingS * 3) / 4
- count: root.warningCount
- label: I18n.tr("Warnings", "greeter doctor page status card")
- iconName: "warning"
- iconColor: Theme.warning
- bgColor: Theme.withAlpha(Theme.warning, 0.15)
- selected: root.selectedFilter === "warn"
- onClicked: root.selectedFilter = "warn"
- }
-
- GreeterStatusCard {
- width: (parent.width - Theme.spacingS * 3) / 4
- count: root.infoCount
- label: I18n.tr("Info", "greeter doctor page status card")
- iconName: "info"
- iconColor: Theme.secondary
- bgColor: Theme.withAlpha(Theme.secondary, 0.15)
- selected: root.selectedFilter === "info"
- onClicked: root.selectedFilter = "info"
- }
-
- GreeterStatusCard {
- width: (parent.width - Theme.spacingS * 3) / 4
- count: root.okCount
- label: I18n.tr("OK", "greeter doctor page status card")
- iconName: "check_circle"
- iconColor: Theme.success
- bgColor: Theme.withAlpha(Theme.success, 0.15)
- selected: root.selectedFilter === "ok"
- onClicked: root.selectedFilter = "ok"
- }
- }
- }
-
- Rectangle {
- id: resultsContainer
- anchors.top: headerSection.bottom
- anchors.bottom: footerSection.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingL
- anchors.bottomMargin: Theme.spacingM
- anchors.leftMargin: Theme.spacingXL
- anchors.rightMargin: Theme.spacingXL
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
- clip: true
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingS
- visible: root.filteredResults.length === 0
-
- DankIcon {
- name: {
- switch (root.selectedFilter) {
- case "error":
- return "check_circle";
- case "warn":
- return "thumb_up";
- case "info":
- return "info";
- default:
- return "verified";
- }
- }
- size: Math.round(Theme.iconSize * 1.67)
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: {
- switch (root.selectedFilter) {
- case "error":
- return I18n.tr("No errors", "greeter doctor page empty state");
- case "warn":
- return I18n.tr("No warnings", "greeter doctor page empty state");
- case "info":
- return I18n.tr("No info items", "greeter doctor page empty state");
- default:
- return I18n.tr("No checks passed", "greeter doctor page empty state");
- }
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
-
- DankFlickable {
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- clip: true
- contentHeight: resultsColumn.height
- contentWidth: width
- visible: root.filteredResults.length > 0
-
- Column {
- id: resultsColumn
- width: parent.width
- spacing: Theme.spacingS
-
- Repeater {
- model: root.filteredResults
-
- GreeterDoctorResultItem {
- width: resultsColumn.width
- resultData: modelData
- }
- }
- }
- }
- }
-
- Row {
- id: footerSection
- anchors.bottom: parent.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottomMargin: Theme.spacingL
- spacing: Theme.spacingM
-
- DankButton {
- text: I18n.tr("Run Again", "greeter doctor page button")
- iconName: "refresh"
- backgroundColor: Theme.surfaceContainerHighest
- textColor: Theme.surfaceText
- onClicked: root.runDoctor()
- }
- }
- }
-
- Process {
- id: doctorProcess
- command: ["dms", "doctor", "--json"]
- running: false
-
- stdout: StdioCollector {
- onStreamFinished: {
- root.isRunning = false;
- root.hasRun = true;
- try {
- root.doctorResults = JSON.parse(text);
- if (root.doctorResults?.summary) {
- root.errorCount = root.doctorResults.summary.errors || 0;
- root.warningCount = root.doctorResults.summary.warnings || 0;
- root.okCount = root.doctorResults.summary.ok || 0;
- root.infoCount = root.doctorResults.summary.info || 0;
- }
- if (root.errorCount > 0)
- root.selectedFilter = "error";
- else if (root.warningCount > 0)
- root.selectedFilter = "warn";
- else if (root.infoCount > 0)
- root.selectedFilter = "info";
- else
- root.selectedFilter = "ok";
- } catch (e) {
- console.error("GreeterDoctorPage: Failed to parse doctor output:", e);
- }
- }
- }
-
- onExited: exitCode => {
- if (exitCode !== 0) {
- root.isRunning = false;
- root.hasRun = true;
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml
deleted file mode 100644
index b15969a..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml
+++ /dev/null
@@ -1,109 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var resultData: null
-
- readonly property string status: resultData?.status || "ok"
- readonly property string statusIcon: {
- switch (status) {
- case "error":
- return "error";
- case "warn":
- return "warning";
- case "info":
- return "info";
- default:
- return "check_circle";
- }
- }
- readonly property color statusColor: {
- switch (status) {
- case "error":
- return Theme.error;
- case "warn":
- return Theme.warning;
- case "info":
- return Theme.secondary;
- default:
- return Theme.success;
- }
- }
-
- height: Math.round(Theme.fontSizeMedium * 3.4)
- radius: Theme.cornerRadius
- color: Theme.withAlpha(statusColor, 0.08)
-
- DankIcon {
- id: statusIcon
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- name: root.statusIcon
- size: Theme.iconSize - 4
- color: root.statusColor
- }
-
- Column {
- anchors.left: statusIcon.right
- anchors.leftMargin: Theme.spacingS
- anchors.right: categoryChip.visible ? categoryChip.left : (urlButton.visible ? urlButton.left : parent.right)
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- spacing: 1
-
- StyledText {
- width: parent.width
- text: root.resultData?.name || ""
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- elide: Text.ElideRight
- }
-
- StyledText {
- width: parent.width
- text: root.resultData?.message || ""
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- elide: Text.ElideRight
- visible: text.length > 0
- }
- }
-
- Rectangle {
- id: categoryChip
- anchors.right: urlButton.visible ? urlButton.left : parent.right
- anchors.rightMargin: urlButton.visible ? Theme.spacingXS : Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- height: Math.round(Theme.fontSizeSmall * 1.67)
- width: categoryText.implicitWidth + Theme.spacingS
- radius: Theme.spacingXS
- color: Theme.surfaceContainerHighest
- visible: !!(root.resultData?.category)
-
- StyledText {
- id: categoryText
- anchors.centerIn: parent
- text: root.resultData?.category || ""
- font.pixelSize: Theme.fontSizeSmall - 2
- color: Theme.surfaceVariantText
- }
- }
-
- DankActionButton {
- id: urlButton
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- iconName: "open_in_new"
- iconSize: Theme.iconSize - 6
- buttonSize: 24
- visible: !!(root.resultData?.url)
- tooltipText: root.resultData?.url || ""
- onClicked: Qt.openUrlExternally(root.resultData.url)
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml
deleted file mode 100644
index a5bf4f4..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml
+++ /dev/null
@@ -1,74 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property string iconName: ""
- property string title: ""
- property string description: ""
-
- signal clicked
-
- readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.5)
-
- height: Math.round(Theme.fontSizeMedium * 6.4)
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.fill: parent
- radius: parent.radius
- color: Theme.primary
- opacity: mouseArea.containsMouse ? 0.12 : 0
- }
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- Rectangle {
- width: root.iconContainerSize
- height: root.iconContainerSize
- radius: Math.round(root.iconContainerSize * 0.28)
- color: Theme.primaryContainer
- anchors.horizontalCenter: parent.horizontalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: root.iconName
- size: Theme.iconSize - 4
- color: Theme.primary
- }
- }
-
- Column {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: 2
-
- StyledText {
- text: root.title
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: root.description
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.clicked()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml
deleted file mode 100644
index 973dab2..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml
+++ /dev/null
@@ -1,333 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- property int currentPage: 0
- readonly property int totalPages: 3
- readonly property var pageComponents: [welcomePage, doctorPage, completePage]
-
- property var cheatsheetData: ({})
- property bool cheatsheetLoaded: false
-
- readonly property int modalWidth: 720
- readonly property int modalHeight: screen ? Math.min(760, screen.height - 80) : 760
-
- signal greeterCompleted
-
- Component.onCompleted: Qt.callLater(loadCheatsheet)
-
- function loadCheatsheet() {
- const provider = KeybindsService.cheatsheetProvider;
- if (KeybindsService.cheatsheetAvailable && provider && !cheatsheetLoaded) {
- cheatsheetProcess.command = ["dms", "keybinds", "show", provider];
- cheatsheetProcess.running = true;
- }
- }
-
- Connections {
- target: KeybindsService
- function onCheatsheetAvailableChanged() {
- if (KeybindsService.cheatsheetAvailable && !root.cheatsheetLoaded)
- loadCheatsheet();
- }
- }
-
- function getKeybind(actionPattern) {
- if (!cheatsheetLoaded || !cheatsheetData.binds)
- return "";
- for (const category in cheatsheetData.binds) {
- const binds = cheatsheetData.binds[category];
- for (let i = 0; i < binds.length; i++) {
- const bind = binds[i];
- if (bind.action && bind.action.includes(actionPattern))
- return bind.key || "";
- }
- }
- return "";
- }
-
- function show() {
- currentPage = FirstLaunchService.requestedStartPage || 0;
- visible = true;
- }
-
- function showAtPage(page) {
- currentPage = page;
- visible = true;
- }
-
- function nextPage() {
- if (currentPage < totalPages - 1)
- currentPage++;
- }
-
- function prevPage() {
- if (currentPage > 0)
- currentPage--;
- }
-
- function finish() {
- FirstLaunchService.markFirstLaunchComplete();
- greeterCompleted();
- visible = false;
- }
-
- function skip() {
- FirstLaunchService.markFirstLaunchComplete();
- greeterCompleted();
- visible = false;
- }
-
- objectName: "greeterModal"
- title: I18n.tr("Welcome", "greeter modal window title")
- minimumSize: Qt.size(modalWidth, modalHeight)
- maximumSize: Qt.size(modalWidth, modalHeight)
- color: Theme.surfaceContainer
- visible: false
-
- Process {
- id: cheatsheetProcess
- running: false
-
- stdout: StdioCollector {
- onStreamFinished: {
- const trimmed = text.trim();
- if (trimmed.length === 0)
- return;
- try {
- root.cheatsheetData = JSON.parse(trimmed);
- root.cheatsheetLoaded = true;
- } catch (e) {
- console.warn("Greeter: Failed to parse cheatsheet:", e);
- }
- }
- }
- }
-
- FocusScope {
- id: contentFocusScope
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- root.skip();
- event.accepted = true;
- }
-
- Keys.onPressed: event => {
- switch (event.key) {
- case Qt.Key_Return:
- case Qt.Key_Enter:
- if (root.currentPage < root.totalPages - 1)
- root.nextPage();
- else
- root.finish();
- event.accepted = true;
- break;
- case Qt.Key_Left:
- if (root.currentPage > 0)
- root.prevPage();
- event.accepted = true;
- break;
- case Qt.Key_Right:
- if (root.currentPage < root.totalPages - 1)
- root.nextPage();
- event.accepted = true;
- break;
- }
- }
-
- MouseArea {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- height: headerRow.height + Theme.spacingM
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- Item {
- id: headerRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- height: Math.round(Theme.fontSizeMedium * 2.85)
-
- Rectangle {
- id: pageIndicatorContainer
- readonly property real indicatorHeight: Math.round(Theme.fontSizeMedium * 2)
-
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- width: pageIndicatorRow.width + Theme.spacingM * 2
- height: indicatorHeight
- radius: indicatorHeight / 2
- color: Theme.surfaceContainerHigh
-
- Row {
- id: pageIndicatorRow
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- Repeater {
- model: root.totalPages
-
- Rectangle {
- required property int index
- property bool isActive: index === root.currentPage
- readonly property real dotSize: Math.round(Theme.spacingS * 1.3)
-
- width: isActive ? dotSize * 3 : dotSize
- height: dotSize
- radius: dotSize / 2
- color: isActive ? Theme.primary : Theme.surfaceTextAlpha
- anchors.verticalCenter: parent.verticalCenter
-
- Behavior on width {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.emphasizedEasing
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- }
- }
- }
- }
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported && windowControls.canMaximize
- iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.skip()
-
- DankTooltip {
- text: I18n.tr("Skip setup", "greeter skip button tooltip")
- }
- }
- }
- }
-
- Item {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: headerRow.bottom
- anchors.bottom: footerRow.top
- anchors.topMargin: Theme.spacingS
-
- Loader {
- id: pageLoader
- anchors.fill: parent
- sourceComponent: root.pageComponents[root.currentPage]
-
- property var greeterRoot: root
- }
- }
-
- Rectangle {
- id: footerRow
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- height: Math.round(Theme.fontSizeMedium * 4.5)
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.top: parent.top
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.5
- }
-
- Row {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingL
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankButton {
- visible: root.currentPage < root.totalPages - 1
- text: I18n.tr("Skip", "greeter skip button")
- backgroundColor: "transparent"
- textColor: Theme.surfaceVariantText
- onClicked: root.skip()
- }
-
- DankButton {
- visible: root.currentPage > 0
- text: I18n.tr("Back", "greeter back button")
- iconName: "arrow_back"
- backgroundColor: Theme.surfaceContainerHighest
- textColor: Theme.surfaceText
- onClicked: root.prevPage()
- }
-
- DankButton {
- visible: root.currentPage < root.totalPages - 1
- enabled: !(root.currentPage === 1 && pageLoader.item && pageLoader.item.isRunning)
- text: root.currentPage === 0 ? I18n.tr("Get Started", "greeter first page button") : I18n.tr("Next", "greeter next button")
- iconName: "arrow_forward"
- backgroundColor: Theme.primary
- textColor: Theme.primaryText
- onClicked: root.nextPage()
- }
-
- DankButton {
- visible: root.currentPage === root.totalPages - 1
- text: I18n.tr("Finish", "greeter finish button")
- iconName: "check"
- backgroundColor: Theme.primary
- textColor: Theme.primaryText
- onClicked: root.finish()
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-
- Component {
- id: welcomePage
- GreeterWelcomePage {}
- }
-
- Component {
- id: doctorPage
- GreeterDoctorPage {}
- }
-
- Component {
- id: completePage
- GreeterCompletePage {}
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml
deleted file mode 100644
index d064275..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml
+++ /dev/null
@@ -1,60 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property string iconName: ""
- property string title: ""
- property bool isExternal: false
-
- signal clicked
-
- height: Math.round(Theme.fontSizeMedium * 3.1)
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.fill: parent
- radius: parent.radius
- color: Theme.primary
- opacity: mouseArea.containsMouse ? 0.12 : 0
- }
-
- Row {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- DankIcon {
- name: root.iconName
- size: Theme.iconSizeSmall + 2
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: root.title
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- DankIcon {
- visible: root.isExternal
- name: "open_in_new"
- size: Theme.iconSizeSmall - 2
- color: Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.clicked()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml
deleted file mode 100644
index 85e6b1c..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml
+++ /dev/null
@@ -1,78 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property string iconName: ""
- property string title: ""
- property string description: ""
-
- signal clicked
-
- readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.5)
-
- height: Math.round(Theme.fontSizeMedium * 4.5)
- radius: Theme.cornerRadius
- color: Theme.surfaceContainerHigh
-
- Rectangle {
- anchors.fill: parent
- radius: parent.radius
- color: Theme.primary
- opacity: mouseArea.containsMouse ? 0.12 : 0
- }
-
- Row {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingM
-
- Rectangle {
- width: root.iconContainerSize
- height: root.iconContainerSize
- radius: Math.round(root.iconContainerSize * 0.28)
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: root.iconName
- size: Theme.iconSize - 4
- color: Theme.primaryText
- }
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
- width: parent.width - root.iconContainerSize - Theme.spacingM
-
- StyledText {
- text: root.title
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- StyledText {
- text: root.description
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Theme.surfaceVariantText
- width: parent.width
- elide: Text.ElideRight
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.clicked()
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml
deleted file mode 100644
index af0d5d6..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml
+++ /dev/null
@@ -1,75 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property int count: 0
- property string label: ""
- property string iconName: ""
- property color iconColor: Theme.surfaceText
- property color bgColor: Theme.surfaceContainerHigh
- property bool selected: false
-
- signal clicked
-
- height: Math.round(Theme.fontSizeMedium * 5)
- radius: Theme.cornerRadius
- color: bgColor
- border.width: selected ? 2 : 0
- border.color: selected ? iconColor : "transparent"
- scale: mouseArea.pressed ? 0.97 : 1
-
- Behavior on scale {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.emphasizedEasing
- }
- }
-
- Behavior on border.width {
- NumberAnimation {
- duration: Theme.shortDuration
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: root.clicked()
- }
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- Row {
- anchors.horizontalCenter: parent.horizontalCenter
- spacing: Theme.spacingS
-
- DankIcon {
- name: root.iconName
- size: Theme.iconSize - 4
- color: root.iconColor
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: root.count.toString()
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Bold
- color: root.iconColor
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- StyledText {
- text: root.label
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml
deleted file mode 100644
index fcb4fc5..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml
+++ /dev/null
@@ -1,165 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import Quickshell
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- readonly property real logoSize: Math.round(Theme.iconSize * 5.3)
-
- Column {
- id: mainColumn
- anchors.centerIn: parent
- width: Math.min(Math.round(Theme.fontSizeMedium * 43), parent.width - Theme.spacingXL * 2)
- spacing: Theme.spacingXL
-
- Column {
- width: parent.width
- spacing: Theme.spacingM
-
- Image {
- width: root.logoSize
- height: width * (569.94629 / 506.50931)
- anchors.horizontalCenter: parent.horizontalCenter
- fillMode: Image.PreserveAspectFit
- smooth: true
- mipmap: true
- asynchronous: true
- source: "file://" + Theme.shellDir + "/assets/danklogonormal.svg"
- layer.enabled: true
- layer.smooth: true
- layer.mipmap: true
- layer.effect: MultiEffect {
- saturation: 0
- colorization: 1
- colorizationColor: Theme.primary
- }
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Welcome to DankMaterialShell", "greeter welcome page title")
- font.pixelSize: Theme.fontSizeXLarge + 4
- font.weight: Font.Bold
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: I18n.tr("A modern desktop shell for Wayland compositors", "greeter welcome page tagline")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outlineMedium
- opacity: 0.3
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingM
-
- StyledText {
- text: I18n.tr("Features", "greeter welcome page section header")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- Grid {
- width: parent.width
- columns: 3
- rowSpacing: Theme.spacingS
- columnSpacing: Theme.spacingS
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "auto_awesome"
- title: I18n.tr("Dynamic Theming", "greeter feature card title")
- description: I18n.tr("Colors from wallpaper", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("theme")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "format_paint"
- title: I18n.tr("App Theming", "greeter feature card title")
- description: I18n.tr("GTK, Qt, IDEs, more", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("theme")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "download"
- title: I18n.tr("Theme Registry", "greeter feature card title")
- description: I18n.tr("Community themes", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("theme")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "view_carousel"
- title: I18n.tr("DankBar", "greeter feature card title")
- description: I18n.tr("Modular widget bar", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("dankbar_settings")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "extension"
- title: I18n.tr("Plugins", "greeter feature card title")
- description: I18n.tr("Extensible architecture", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("plugins")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "layers"
- title: I18n.tr("Multi-Monitor", "greeter feature card title")
- description: I18n.tr("Per-screen config", "greeter feature card description")
- onClicked: {
- const hasDisplayConfig = CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl;
- PopoutService.openSettingsWithTab(hasDisplayConfig ? "display_config" : "display_widgets");
- }
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "nightlight"
- title: I18n.tr("Display Control", "greeter feature card title")
- description: I18n.tr("Night mode & gamma", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("display_gamma")
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "tune"
- title: I18n.tr("Control Center", "greeter feature card title")
- description: I18n.tr("Quick system toggles", "greeter feature card description")
- // This is doing an IPC since its just easier and lazier to access the bar ref
- onClicked: Quickshell.execDetached(["dms", "ipc", "call", "control-center", "open"])
- }
-
- GreeterFeatureCard {
- width: (parent.width - Theme.spacingS * 2) / 3
- iconName: "lock"
- title: I18n.tr("Lock Screen", "greeter feature card title")
- description: I18n.tr("Security & privacy", "greeter feature card description")
- onClicked: PopoutService.openSettingsWithTab("lock_screen")
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml
deleted file mode 100644
index e1d6765..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml
+++ /dev/null
@@ -1,347 +0,0 @@
-import QtQml
-import QtQuick
-import QtQuick.Layouts
-import Quickshell.Hyprland
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:keybinds"
- useOverlayLayer: true
- property real scrollStep: 60
- property var activeFlickable: null
- property real _maxW: Math.min(Screen.width * 0.92, 1200)
- property real _maxH: Math.min(Screen.height * 0.92, 900)
- modalWidth: _maxW
- modalHeight: _maxH
- onBackgroundClicked: close()
- onOpened: {
- Qt.callLater(() => {
- modalFocusScope.forceActiveFocus();
- if (contentLoader.item?.searchField)
- contentLoader.item.searchField.forceActiveFocus();
- });
- if (!Object.keys(KeybindsService.cheatsheet).length && KeybindsService.cheatsheetAvailable)
- KeybindsService.loadCheatsheet();
- }
-
- HyprlandFocusGrab {
- windows: [root.contentWindow]
- active: root.useHyprlandFocusGrab && root.shouldHaveFocus
- }
-
- function scrollDown() {
- if (!root.activeFlickable)
- return;
- let newY = root.activeFlickable.contentY + scrollStep;
- newY = Math.min(newY, root.activeFlickable.contentHeight - root.activeFlickable.height);
- root.activeFlickable.contentY = newY;
- }
-
- function scrollUp() {
- if (!root.activeFlickable)
- return;
- let newY = root.activeFlickable.contentY - root.scrollStep;
- newY = Math.max(0, newY);
- root.activeFlickable.contentY = newY;
- }
-
- modalFocusScope.Keys.onPressed: event => {
- if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
- scrollDown();
- event.accepted = true;
- } else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
- scrollUp();
- event.accepted = true;
- } else if (event.key === Qt.Key_Down) {
- scrollDown();
- event.accepted = true;
- } else if (event.key === Qt.Key_Up) {
- scrollUp();
- event.accepted = true;
- }
- }
-
- content: Component {
- Item {
- anchors.fill: parent
- property alias searchField: searchField
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- spacing: Theme.spacingL
-
- RowLayout {
- width: parent.width
-
- StyledText {
- Layout.alignment: Qt.AlignLeft
- text: KeybindsService.cheatsheet.title || i18n("Keybinds")
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Bold
- color: Theme.primary
- }
-
- DankTextField {
- id: searchField
- Layout.alignment: Qt.AlignRight
- leftIconName: "search"
- keyForwardTargets: [root.modalFocusScope]
- onTextEdited: searchDebounce.restart()
- Keys.onEscapePressed: event => {
- root.close();
- event.accepted = true;
- }
- }
- }
-
- Timer {
- id: searchDebounce
- interval: 50
- repeat: false
- onTriggered: {
- mainFlickable.categories = mainFlickable.generateCategories(searchField.text);
- }
- }
-
- DankFlickable {
- id: mainFlickable
- width: parent.width
- height: parent.height - parent.spacing - 40
- contentWidth: rowLayout.implicitWidth
- contentHeight: rowLayout.implicitHeight
- clip: true
-
- Component.onCompleted: root.activeFlickable = mainFlickable
-
- property var rawBinds: KeybindsService.cheatsheet.binds || {}
-
- function generateCategories(query) {
- const lowerQuery = query ? query.toLowerCase().trim() : "";
- const lowerQueryWords = query.split(/\s+/);
- const processed = {};
-
- for (const cat in rawBinds) {
- const binds = rawBinds[cat];
- const catLower = cat.toLowerCase();
- const subcats = {};
- let hasSubcats = false;
- for (let i = 0; i < binds.length; i++) {
- const bind = binds[i];
- const keyLower = bind.key.toLowerCase();
- const descLower = bind.desc.toLowerCase();
- const actionLower = bind.action.toLowerCase();
-
- if (bind.hideOnOverlay)
- continue;
- let shouldContinue = false;
- for (let j = 0; j < lowerQueryWords.length; j++) {
- const word = lowerQueryWords[j];
- if (!(
- word.length === 0 ||
- keyLower.includes(word) ||
- descLower.includes(word) ||
- catLower.includes(word) ||
- actionLower.includes(word)
- )) {
- shouldContinue = true;
- break;
- }
- }
- if (shouldContinue)
- continue;
-
- if (bind.subcat) {
- hasSubcats = true;
- if (!subcats[bind.subcat])
- subcats[bind.subcat] = [];
- subcats[bind.subcat].push(bind);
- } else {
- if (!subcats["_root"])
- subcats["_root"] = [];
- subcats["_root"].push(bind);
- }
- }
-
- if (Object.keys(subcats).length === 0)
- continue;
-
- processed[cat] = {
- hasSubcats: hasSubcats,
- subcats: subcats,
- subcatKeys: Object.keys(subcats)
- };
- }
-
- return processed;
- }
-
- property var categories: generateCategories("");
-
- function estimateCategoryHeight(catName) {
- const catData = categories[catName];
- if (!catData)
- return 0;
- let bindCount = 0;
- for (const key of catData.subcatKeys) {
- bindCount += catData.subcats[key]?.length || 0;
- if (key !== "_root")
- bindCount += 1;
- }
- return 40 + bindCount * 28;
- }
-
- property var categoryKeys: Object.keys(categories);
-
- function distributeCategories(cols) {
- const columns = [];
- const heights = [];
- for (let i = 0; i < cols; i++) {
- columns.push([]);
- heights.push(0);
- }
- const sorted = [...categoryKeys].sort((a, b) => estimateCategoryHeight(b) - estimateCategoryHeight(a));
- for (const cat of sorted) {
- let minIdx = 0;
- for (let i = 1; i < cols; i++) {
- if (heights[i] < heights[minIdx])
- minIdx = i;
- }
- columns[minIdx].push(cat);
- heights[minIdx] += estimateCategoryHeight(cat);
- }
- return columns;
- }
-
- Row {
- id: rowLayout
- width: mainFlickable.width
- spacing: Theme.spacingM
-
- property int numColumns: Math.max(1, Math.min(3, Math.floor(width / 350)))
- property var columnCategories: mainFlickable.distributeCategories(numColumns)
-
- Repeater {
- model: rowLayout.numColumns
-
- Column {
- id: masonryColumn
- width: (rowLayout.width - rowLayout.spacing * (rowLayout.numColumns - 1)) / rowLayout.numColumns
- spacing: Theme.spacingXL
-
- Repeater {
- model: rowLayout.columnCategories[index] || []
-
- Column {
- id: categoryColumn
- width: parent.width
- spacing: Theme.spacingXS
-
- property string catName: modelData
- property var catData: mainFlickable.categories[catName]
-
- StyledText {
- text: categoryColumn.catName
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Bold
- color: Theme.primary
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.primary
- opacity: 0.3
- }
-
- Item {
- width: 1
- height: Theme.spacingXS
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingM
-
- Repeater {
- model: categoryColumn.catData?.subcatKeys || []
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- property string subcatName: modelData
- property var subcatBinds: categoryColumn.catData?.subcats?.[subcatName] || []
-
- StyledText {
- visible: parent.subcatName !== "_root"
- text: parent.subcatName
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.DemiBold
- color: Theme.primary
- opacity: 0.7
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- Repeater {
- model: parent.parent.subcatBinds
-
- Item {
- width: parent.width
- height: 24
-
- StyledRect {
- id: keyBadge
- width: Math.min(keyText.implicitWidth + 12, 160)
- height: 22
- radius: 4
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- id: keyText
- anchors.centerIn: parent
- color: Theme.secondary
- text: (modelData.key || "").replace(/\+/g, " + ")
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- isMonospace: true
- elide: Text.ElideRight
- width: Math.min(implicitWidth, 148)
- }
- }
-
- StyledText {
- anchors.left: parent.left
- anchors.leftMargin: 170
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- text: modelData.desc || modelData.action || ""
- font.pixelSize: Theme.fontSizeSmall
- opacity: 0.9
- elide: Text.ElideRight
- wrapMode: Text.NoWrap
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml
deleted file mode 100644
index 9d19388..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml
+++ /dev/null
@@ -1,633 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Quickshell.Hyprland
-import Quickshell.Io
-import Quickshell
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: muxModal
-
- layerNamespace: "dms:mux"
-
- property int selectedIndex: -1
- property string searchText: ""
- property var filteredSessions: []
-
- function updateFilteredSessions() {
- var filtered = []
- var lowerSearch = searchText.trim().toLowerCase()
- for (var i = 0; i < MuxService.sessions.length; i++) {
- var session = MuxService.sessions[i]
- if (lowerSearch.length > 0 && !session.name.toLowerCase().includes(lowerSearch))
- continue
- filtered.push(session)
- }
- filteredSessions = filtered
-
- if (selectedIndex >= filteredSessions.length) {
- selectedIndex = Math.max(0, filteredSessions.length - 1)
- }
- }
-
- onSearchTextChanged: updateFilteredSessions()
-
- Connections {
- target: MuxService
- function onSessionsChanged() {
- updateFilteredSessions()
- }
- }
-
- HyprlandFocusGrab {
- id: grab
- windows: [muxModal.contentWindow]
- active: CompositorService.isHyprland && muxModal.shouldHaveFocus
- }
-
- function toggle() {
- if (shouldBeVisible) {
- hide()
- } else {
- show()
- }
- }
-
- function show() {
- open()
- selectedIndex = -1
- searchText = ""
- MuxService.refreshSessions()
- shouldHaveFocus = true
-
- Qt.callLater(() => {
- if (muxPanel && muxPanel.searchField) {
- muxPanel.searchField.forceActiveFocus();
- }
- })
- }
-
- function hide() {
- close()
- selectedIndex = -1
- searchText = ""
- }
-
- function attachToSession(name) {
- MuxService.attachToSession(name)
- hide()
- }
-
- function renameSession(name) {
- inputModal.showWithOptions({
- title: I18n.tr("Rename Session"),
- message: I18n.tr("Enter a new name for session \"%1\"").arg(name),
- initialText: name,
- onConfirm: function (newName) {
- MuxService.renameSession(name, newName)
- }
- })
- }
-
- function killSession(name) {
- confirmModal.showWithOptions({
- title: I18n.tr("Kill Session"),
- message: I18n.tr("Are you sure you want to kill session \"%1\"?").arg(name),
- confirmText: I18n.tr("Kill"),
- confirmColor: Theme.primary,
- onConfirm: function () {
- MuxService.killSession(name)
- }
- })
- }
-
- function createNewSession() {
- inputModal.showWithOptions({
- title: I18n.tr("New Session"),
- message: I18n.tr("Please write a name for your new %1 session").arg(MuxService.displayName),
- onConfirm: function (name) {
- MuxService.createSession(name)
- hide()
- }
- })
- }
-
- function selectNext() {
- selectedIndex = Math.min(selectedIndex + 1, filteredSessions.length - 1)
- }
-
- function selectPrevious() {
- selectedIndex = Math.max(selectedIndex - 1, -1)
- }
-
- function activateSelected() {
- if (selectedIndex === -1) {
- createNewSession()
- } else if (selectedIndex >= 0 && selectedIndex < filteredSessions.length) {
- attachToSession(filteredSessions[selectedIndex].name)
- }
- }
-
- visible: false
- modalWidth: 600
- modalHeight: 600
- backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- cornerRadius: Theme.cornerRadius
- borderColor: Theme.outlineMedium
- borderWidth: 1
- enableShadow: true
- keepContentLoaded: true
-
- onBackgroundClicked: hide()
-
- Timer {
- interval: 3000
- running: muxModal.shouldBeVisible
- repeat: true
- onTriggered: MuxService.refreshSessions()
- }
-
- IpcHandler {
- function open(): string {
- muxModal.show()
- return "MUX_OPEN_SUCCESS"
- }
-
- function close(): string {
- muxModal.hide()
- return "MUX_CLOSE_SUCCESS"
- }
-
- function toggle(): string {
- muxModal.toggle()
- return "MUX_TOGGLE_SUCCESS"
- }
-
- target: "mux"
- }
-
- // Backwards compatibility
- IpcHandler {
- function open(): string {
- muxModal.show()
- return "TMUX_OPEN_SUCCESS"
- }
-
- function close(): string {
- muxModal.hide()
- return "TMUX_CLOSE_SUCCESS"
- }
-
- function toggle(): string {
- muxModal.toggle()
- return "TMUX_TOGGLE_SUCCESS"
- }
-
- target: "tmux"
- }
-
- InputModal {
- id: inputModal
- onShouldBeVisibleChanged: {
- if (shouldBeVisible) {
- muxModal.shouldHaveFocus = false;
- muxModal.contentWindow.visible = false;
- return;
- }
- if (muxModal.shouldBeVisible) {
- muxModal.contentWindow.visible = true;
- }
- Qt.callLater(function () {
- if (!muxModal.shouldBeVisible) {
- return;
- }
- muxModal.shouldHaveFocus = true;
- muxModal.modalFocusScope.forceActiveFocus();
- if (muxPanel.searchField) {
- muxPanel.searchField.forceActiveFocus();
- }
- });
- }
- }
-
- ConfirmModal {
- id: confirmModal
- onShouldBeVisibleChanged: {
- if (shouldBeVisible) {
- muxModal.shouldHaveFocus = false;
- muxModal.contentWindow.visible = false;
- return;
- }
- if (muxModal.shouldBeVisible) {
- muxModal.contentWindow.visible = true;
- }
- Qt.callLater(function () {
- if (!muxModal.shouldBeVisible) {
- return;
- }
- muxModal.shouldHaveFocus = true;
- muxModal.modalFocusScope.forceActiveFocus();
- if (muxPanel.searchField) {
- muxPanel.searchField.forceActiveFocus();
- }
- });
- }
- }
-
- directContent: Item {
- id: muxPanel
-
- clip: false
-
- property alias searchField: searchField
-
- Keys.onPressed: event => {
- if ((event.key === Qt.Key_J && (event.modifiers & Qt.ControlModifier)) ||
- (event.key === Qt.Key_Down)) {
- selectNext()
- event.accepted = true
- } else if ((event.key === Qt.Key_K && (event.modifiers & Qt.ControlModifier)) ||
- (event.key === Qt.Key_Up)) {
- selectPrevious()
- event.accepted = true
- } else if (event.key === Qt.Key_N && (event.modifiers & Qt.ControlModifier)) {
- createNewSession()
- event.accepted = true
- } else if (event.key === Qt.Key_R && (event.modifiers & Qt.ControlModifier)) {
- if (MuxService.supportsRename && selectedIndex >= 0 && selectedIndex < filteredSessions.length) {
- renameSession(filteredSessions[selectedIndex].name)
- }
- event.accepted = true
- } else if (event.key === Qt.Key_D && (event.modifiers & Qt.ControlModifier)) {
- if (selectedIndex >= 0 && selectedIndex < filteredSessions.length) {
- killSession(filteredSessions[selectedIndex].name)
- }
- event.accepted = true
- } else if (event.key === Qt.Key_Escape) {
- hide()
- event.accepted = true
- } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
- activateSelected()
- event.accepted = true
- }
- }
-
- Column {
- width: parent.width - Theme.spacingM * 2
- height: parent.height - Theme.spacingM * 2
- x: Theme.spacingM
- y: Theme.spacingM
- spacing: Theme.spacingS
-
- // Header
- Item {
- width: parent.width
- height: 40
-
- StyledText {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("%1 Sessions").arg(MuxService.displayName)
- font.pixelSize: Theme.fontSizeLarge + 4
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
-
- StyledText {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- text: {
- const total = MuxService.sessions.length;
- const filtered = muxModal.filteredSessions.length;
- const activePart = total === 1
- ? I18n.tr("%1 active session").arg(total)
- : I18n.tr("%1 active sessions").arg(total);
- const filteredPart = filtered === 1
- ? I18n.tr("%1 filtered").arg(filtered)
- : I18n.tr("%1 filtered").arg(filtered);
- return activePart + ", " + filteredPart;
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- }
- }
-
- // Search field
- DankTextField {
- id: searchField
-
- width: parent.width
- height: 48
- cornerRadius: Theme.cornerRadius
- backgroundColor: Theme.surfaceContainerHigh
- normalBorderColor: Theme.outlineMedium
- focusedBorderColor: Theme.primary
- leftIconName: "search"
- leftIconSize: Theme.iconSize
- leftIconColor: Theme.surfaceVariantText
- leftIconFocusedColor: Theme.primary
- showClearButton: true
- font.pixelSize: Theme.fontSizeMedium
- placeholderText: I18n.tr("Search sessions...")
- keyForwardTargets: [muxPanel]
-
- onTextEdited: {
- muxModal.searchText = text
- muxModal.selectedIndex = 0
- }
- }
-
- // New Session Button
- Rectangle {
- width: parent.width
- height: 56
- radius: Theme.cornerRadius
- color: muxModal.selectedIndex === -1 ? Theme.primaryContainer :
- (newMouse.containsMouse ? Theme.surfaceContainerHigh : Theme.surfaceContainer)
-
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- Rectangle {
- Layout.preferredWidth: 40
- Layout.preferredHeight: 40
- radius: 20
- color: Theme.primaryContainer
-
- DankIcon {
- anchors.centerIn: parent
- name: "add"
- size: Theme.iconSize
- color: Theme.primary
- }
- }
-
- Column {
- Layout.fillWidth: true
- spacing: 2
-
- StyledText {
- text: I18n.tr("New Session")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- StyledText {
- text: I18n.tr("Create a new %1 session (n)").arg(MuxService.displayName)
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
- }
- }
-
- MouseArea {
- id: newMouse
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: muxModal.createNewSession()
- }
- }
-
- // Sessions List
- Rectangle {
- width: parent.width
- height: parent.height - 88 - 48 - shortcutsBar.height - Theme.spacingS * 3
- radius: Theme.cornerRadius
- color: "transparent"
-
- ScrollView {
- anchors.fill: parent
- clip: true
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- Repeater {
- model: ScriptModel {
- values: muxModal.filteredSessions
- }
-
- delegate: Rectangle {
- required property var modelData
- required property int index
-
- width: parent.width
- height: 64
- radius: Theme.cornerRadius
- color: muxModal.selectedIndex === index ? Theme.primaryContainer :
- (sessionMouse.containsMouse ? Theme.surfaceContainerHigh : "transparent")
-
- MouseArea {
- id: sessionMouse
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: muxModal.attachToSession(modelData.name)
- }
-
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- // Avatar
- Rectangle {
- Layout.preferredWidth: 40
- Layout.preferredHeight: 40
- radius: 20
- color: modelData.attached ? Theme.primaryContainer : Theme.surfaceContainerHigh
-
- StyledText {
- anchors.centerIn: parent
- text: modelData.name.charAt(0).toUpperCase()
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Bold
- color: modelData.attached ? Theme.primary : Theme.surfaceText
- }
- }
-
- // Info
- Column {
- Layout.fillWidth: true
- spacing: 2
-
- StyledText {
- text: modelData.name
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- elide: Text.ElideRight
- }
-
- StyledText {
- text: {
- var parts = []
- if (modelData.windows !== "N/A")
- parts.push(modelData.windows === 1
- ? I18n.tr("%1 window").arg(modelData.windows)
- : I18n.tr("%1 windows").arg(modelData.windows))
- parts.push(modelData.attached ? I18n.tr("attached") : I18n.tr("detached"))
- return parts.join(" \u2022 ")
- }
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
- }
-
- // Rename button (tmux only)
- Rectangle {
- Layout.preferredWidth: 36
- Layout.preferredHeight: 36
- radius: 18
- visible: MuxService.supportsRename
- color: renameMouse.containsMouse ? Theme.surfaceContainerHighest : "transparent"
-
- DankIcon {
- anchors.centerIn: parent
- name: "edit"
- size: Theme.iconSizeSmall
- color: renameMouse.containsMouse ? Theme.primary : Theme.surfaceVariantText
- }
-
- MouseArea {
- id: renameMouse
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: muxModal.renameSession(modelData.name)
- }
- }
-
- // Delete button
- Rectangle {
- Layout.preferredWidth: 36
- Layout.preferredHeight: 36
- radius: 18
- color: deleteMouse.containsMouse ? Theme.errorContainer : "transparent"
-
- DankIcon {
- anchors.centerIn: parent
- name: "delete"
- size: Theme.iconSizeSmall
- color: deleteMouse.containsMouse ? Theme.error : Theme.surfaceVariantText
- }
-
- MouseArea {
- id: deleteMouse
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- muxModal.killSession(modelData.name)
- }
- }
- }
- }
- }
- }
-
- // Empty state
- Item {
- width: parent.width
- height: muxModal.filteredSessions.length === 0 ? 200 : 0
- visible: muxModal.filteredSessions.length === 0
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingM
-
- DankIcon {
- name: muxModal.searchText.length > 0 ? "search_off" : "terminal"
- size: 48
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: muxModal.searchText.length > 0 ? I18n.tr("No sessions found") : I18n.tr("No active %1 sessions").arg(MuxService.displayName)
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: muxModal.searchText.length > 0 ? I18n.tr("Try a different search") : I18n.tr("Press 'n' or click 'New Session' to create one")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- }
- }
- }
- }
-
- // Shortcuts bar
- Row {
- id: shortcutsBar
- width: parent.width
- spacing: Theme.spacingM
- bottomPadding: Theme.spacingS
-
- Repeater {
- model: {
- var shortcuts = [
- { key: "↑↓", label: I18n.tr("Navigate") },
- { key: "↵", label: I18n.tr("Attach") },
- { key: "^N", label: I18n.tr("New") },
- { key: "^D", label: I18n.tr("Kill") },
- { key: "Esc", label: I18n.tr("Close") }
- ]
- if (MuxService.supportsRename)
- shortcuts.splice(3, 0, { key: "^R", label: I18n.tr("Rename") })
- return shortcuts
- }
-
- delegate: Row {
- required property var modelData
- spacing: 4
-
- Rectangle {
- width: keyText.width + Theme.spacingS
- height: keyText.height + 4
- radius: 4
- color: Theme.surfaceContainerHighest
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- id: keyText
- anchors.centerIn: parent
- text: modelData.key
- font.pixelSize: Theme.fontSizeSmall - 1
- font.weight: Font.Medium
- color: Theme.surfaceVariantText
- }
- }
-
- StyledText {
- text: modelData.label
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml
deleted file mode 100644
index 79dbada..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml
+++ /dev/null
@@ -1,155 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:network-info"
-
- keepPopoutsOpen: true
-
- property bool networkInfoModalVisible: false
- property string networkSSID: ""
- property var networkData: null
-
- function showNetworkInfo(ssid, data) {
- networkSSID = ssid;
- networkData = data;
- networkInfoModalVisible = true;
- open();
- NetworkService.fetchNetworkInfo(ssid);
- }
-
- function hideDialog() {
- networkInfoModalVisible = false;
- close();
- networkSSID = "";
- networkData = null;
- }
-
- visible: networkInfoModalVisible
- modalWidth: 600
- modalHeight: 500
- enableShadow: true
- onBackgroundClicked: hideDialog()
- onVisibleChanged: {
- if (!visible) {
- networkSSID = "";
- networkData = null;
- }
- }
-
- content: Component {
- Item {
- anchors.fill: parent
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- spacing: Theme.spacingL
-
- Row {
- width: parent.width
-
- Column {
- width: parent.width - 40
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Network Information")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: I18n.tr("Details for \"%1\"").arg(networkSSID)
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- elide: Text.ElideRight
- }
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.hideDialog()
- }
- }
-
- Rectangle {
- id: detailsRect
-
- width: parent.width
- height: parent.height - 140
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: Theme.outlineStrong
- border.width: 1
- clip: true
-
- DankFlickable {
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- contentHeight: detailsText.contentHeight
-
- StyledText {
- id: detailsText
-
- width: parent.width
- text: NetworkService.networkInfoDetails && NetworkService.networkInfoDetails.replace(/\\n/g, '\n') || I18n.tr("No information available")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- wrapMode: Text.WordWrap
- }
- }
- }
-
- Item {
- width: parent.width
- height: 40
-
- Rectangle {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- width: Math.max(70, closeText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: closeArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- id: closeText
-
- anchors.centerIn: parent
- text: I18n.tr("Close")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: closeArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.hideDialog()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml
deleted file mode 100644
index 4b42fdc..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml
+++ /dev/null
@@ -1,155 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:network-info-wired"
-
- keepPopoutsOpen: true
-
- property bool networkWiredInfoModalVisible: false
- property string networkID: ""
- property var networkData: null
-
- function showNetworkInfo(id, data) {
- networkID = id;
- networkData = data;
- networkWiredInfoModalVisible = true;
- open();
- NetworkService.fetchWiredNetworkInfo(data.uuid);
- }
-
- function hideDialog() {
- networkWiredInfoModalVisible = false;
- close();
- networkID = "";
- networkData = null;
- }
-
- visible: networkWiredInfoModalVisible
- modalWidth: 600
- modalHeight: 500
- enableShadow: true
- onBackgroundClicked: hideDialog()
- onVisibleChanged: {
- if (!visible) {
- networkID = "";
- networkData = null;
- }
- }
-
- content: Component {
- Item {
- anchors.fill: parent
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- spacing: Theme.spacingL
-
- Row {
- width: parent.width
-
- Column {
- width: parent.width - 40
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Network Information")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: I18n.tr("Details for \"%1\"").arg(networkSSID)
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- elide: Text.ElideRight
- }
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.hideDialog()
- }
- }
-
- Rectangle {
- id: detailsRect
-
- width: parent.width
- height: parent.height - 140
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: Theme.outlineStrong
- border.width: 1
- clip: true
-
- DankFlickable {
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- contentHeight: detailsText.contentHeight
-
- StyledText {
- id: detailsText
-
- width: parent.width
- text: NetworkService.networkWiredInfoDetails && NetworkService.networkWiredInfoDetails.replace(/\\n/g, '\n') || I18n.tr("No information available")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- wrapMode: Text.WordWrap
- }
- }
- }
-
- Item {
- width: parent.width
- height: 40
-
- Rectangle {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- width: Math.max(70, closeText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: closeArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- id: closeText
-
- anchors.centerIn: parent
- text: I18n.tr("Close")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: closeArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: root.hideDialog()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml
deleted file mode 100644
index 8653344..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml
+++ /dev/null
@@ -1,225 +0,0 @@
-import QtQuick
-import Quickshell.Hyprland
-import Quickshell.Io
-import qs.Common
-import qs.Modals.Common
-import qs.Modules.Notifications.Center
-import qs.Services
-
-DankModal {
- id: notificationModal
-
- layerNamespace: "dms:notification-center-modal"
-
- HyprlandFocusGrab {
- windows: [notificationModal.contentWindow]
- active: notificationModal.useHyprlandFocusGrab && notificationModal.shouldHaveFocus
- }
-
- property bool notificationModalOpen: false
- property var notificationListRef: null
- property var historyListRef: null
- property int currentTab: 0
-
- property var notificationHeaderRef: null
-
- function show() {
- notificationModalOpen = true;
- currentTab = 0;
- NotificationService.onOverlayOpen();
- open();
- modalKeyboardController.reset();
- if (modalKeyboardController && notificationListRef) {
- modalKeyboardController.listView = notificationListRef;
- modalKeyboardController.rebuildFlatNavigation();
-
- Qt.callLater(() => {
- modalKeyboardController.keyboardNavigationActive = true;
- modalKeyboardController.selectedFlatIndex = 0;
- modalKeyboardController.updateSelectedIdFromIndex();
- if (notificationListRef) {
- notificationListRef.keyboardActive = true;
- notificationListRef.currentIndex = 0;
- }
- modalKeyboardController.selectionVersion++;
- modalKeyboardController.ensureVisible();
- });
- }
- }
-
- function hide() {
- notificationModalOpen = false;
- NotificationService.onOverlayClose();
- close();
- modalKeyboardController.reset();
- }
-
- function toggle() {
- if (shouldBeVisible) {
- hide();
- } else {
- show();
- }
- }
-
- function clearAll() {
- NotificationService.clearAllNotifications();
- }
-
- function dismissAllPopups() {
- NotificationService.dismissAllPopups();
- }
-
- modalWidth: Math.min(500, screenWidth - 48)
- modalHeight: Math.min(700, screenHeight * 0.85)
- backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
- visible: false
- onBackgroundClicked: hide()
- onOpened: () => {
- Qt.callLater(() => modalFocusScope.forceActiveFocus());
- }
- onShouldBeVisibleChanged: shouldBeVisible => {
- if (!shouldBeVisible) {
- notificationModalOpen = false;
- modalKeyboardController.reset();
- NotificationService.onOverlayClose();
- }
- }
- modalFocusScope.Keys.onPressed: event => {
- if (event.key === Qt.Key_Escape) {
- hide();
- event.accepted = true;
- return;
- }
-
- if (event.key === Qt.Key_Left) {
- if (notificationHeaderRef && notificationHeaderRef.currentTab > 0) {
- notificationHeaderRef.currentTab = 0;
- event.accepted = true;
- }
- return;
- }
- if (event.key === Qt.Key_Right) {
- if (notificationHeaderRef && notificationHeaderRef.currentTab === 0 && SettingsData.notificationHistoryEnabled) {
- notificationHeaderRef.currentTab = 1;
- event.accepted = true;
- }
- return;
- }
-
- if (currentTab === 1 && historyListRef) {
- historyListRef.handleKey(event);
- return;
- }
- modalKeyboardController.handleKey(event);
- }
-
- NotificationKeyboardController {
- id: modalKeyboardController
-
- listView: null
- isOpen: notificationModal.notificationModalOpen
- onClose: () => notificationModal.hide()
- }
-
- IpcHandler {
- function open(): string {
- notificationModal.show();
- return "NOTIFICATION_MODAL_OPEN_SUCCESS";
- }
-
- function close(): string {
- notificationModal.hide();
- return "NOTIFICATION_MODAL_CLOSE_SUCCESS";
- }
-
- function toggle(): string {
- notificationModal.toggle();
- return "NOTIFICATION_MODAL_TOGGLE_SUCCESS";
- }
-
- function toggleDoNotDisturb(): string {
- SessionData.setDoNotDisturb(!SessionData.doNotDisturb);
-
- return "NOTIFICATION_MODAL_TOGGLE_DND_SUCCESS";
- }
-
- function getDoNotDisturb(): bool {
- return SessionData.doNotDisturb;
- }
-
- function clearAll(): string {
- notificationModal.clearAll();
- return "NOTIFICATION_MODAL_CLEAR_ALL_SUCCESS";
- }
-
- function dismissAllPopups(): string {
- notificationModal.dismissAllPopups();
- return "NOTIFICATION_MODAL_DISMISS_ALL_POPUPS_SUCCESS";
- }
-
- target: "notifications"
- }
-
- content: Component {
- Item {
- id: notificationKeyHandler
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- anchors.fill: parent
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- spacing: Theme.spacingM
-
- NotificationHeader {
- id: notificationHeader
- keyboardController: modalKeyboardController
- onCurrentTabChanged: notificationModal.currentTab = currentTab
- Component.onCompleted: notificationModal.notificationHeaderRef = notificationHeader
- }
-
- NotificationSettings {
- id: notificationSettings
- expanded: notificationHeader.showSettings
- }
-
- KeyboardNavigatedNotificationList {
- id: notificationList
- width: parent.width
- height: parent.height - y
- visible: notificationHeader.currentTab === 0
- keyboardController: modalKeyboardController
- Component.onCompleted: {
- notificationModal.notificationListRef = notificationList;
- if (modalKeyboardController) {
- modalKeyboardController.listView = notificationList;
- modalKeyboardController.rebuildFlatNavigation();
- }
- }
- }
-
- HistoryNotificationList {
- id: historyList
- width: parent.width
- height: parent.height - y
- visible: notificationHeader.currentTab === 1
- Component.onCompleted: notificationModal.historyListRef = historyList
- }
- }
-
- NotificationKeyboardHints {
- id: keyboardHints
-
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- showHints: notificationHeader.currentTab === 0 ? modalKeyboardController.showKeyboardHints : historyList.showKeyboardHints
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml
deleted file mode 100644
index 21ddf8f..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml
+++ /dev/null
@@ -1,412 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- property string passwordInput: ""
- property var currentFlow: PolkitService.agent?.flow
- property bool isLoading: false
- property bool awaitingFprintForPassword: false
- readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
-
- property string polkitEtcPamText: ""
- property string polkitLibPamText: ""
- property string systemAuthPamText: ""
- property string commonAuthPamText: ""
- property string passwordAuthPamText: ""
- readonly property bool polkitPamHasFprint: {
- const polkitText = polkitEtcPamText !== "" ? polkitEtcPamText : polkitLibPamText;
- if (!polkitText)
- return false;
- return pamModuleEnabled(polkitText, "pam_fprintd") || (polkitText.includes("system-auth") && pamModuleEnabled(systemAuthPamText, "pam_fprintd")) || (polkitText.includes("common-auth") && pamModuleEnabled(commonAuthPamText, "pam_fprintd")) || (polkitText.includes("password-auth") && pamModuleEnabled(passwordAuthPamText, "pam_fprintd"));
- }
-
- function stripPamComment(line) {
- if (!line)
- return "";
- const trimmed = line.trim();
- if (!trimmed || trimmed.startsWith("#"))
- return "";
- const hashIdx = trimmed.indexOf("#");
- if (hashIdx >= 0)
- return trimmed.substring(0, hashIdx).trim();
- return trimmed;
- }
-
- function pamModuleEnabled(pamText, moduleName) {
- if (!pamText || !moduleName)
- return false;
- const lines = pamText.split(/\r?\n/);
- for (let i = 0; i < lines.length; i++) {
- const line = stripPamComment(lines[i]);
- if (line && line.includes(moduleName))
- return true;
- }
- return false;
- }
-
- function focusPasswordField() {
- passwordField.forceActiveFocus();
- }
-
- function show() {
- passwordInput = "";
- isLoading = false;
- awaitingFprintForPassword = false;
- visible = true;
- Qt.callLater(focusPasswordField);
- }
-
- function hide() {
- visible = false;
- }
-
- function _commitSubmit() {
- isLoading = true;
- awaitingFprintForPassword = false;
- currentFlow.submit(passwordInput);
- passwordInput = "";
- }
-
- function submitAuth() {
- if (!currentFlow || isLoading)
- return;
- if (!currentFlow.isResponseRequired) {
- awaitingFprintForPassword = true;
- return;
- }
- _commitSubmit();
- }
-
- function cancelAuth() {
- if (isLoading)
- return;
- awaitingFprintForPassword = false;
- if (currentFlow) {
- currentFlow.cancelAuthenticationRequest();
- return;
- }
- hide();
- }
-
- objectName: "polkitAuthModal"
- title: I18n.tr("Authentication")
- minimumSize: Qt.size(460, 220)
- maximumSize: Qt.size(460, 220)
- color: Theme.surfaceContainer
- visible: false
-
- onVisibleChanged: {
- if (visible) {
- Qt.callLater(focusPasswordField);
- return;
- }
- passwordInput = "";
- isLoading = false;
- awaitingFprintForPassword = false;
- }
-
- Connections {
- target: PolkitService.agent
- enabled: PolkitService.polkitAvailable
-
- function onAuthenticationRequestStarted() {
- show();
- }
-
- function onIsActiveChanged() {
- if (!(PolkitService.agent?.isActive ?? false))
- hide();
- }
- }
-
- Connections {
- target: currentFlow
- enabled: currentFlow !== null
-
- function onIsResponseRequiredChanged() {
- if (!currentFlow.isResponseRequired)
- return;
- if (awaitingFprintForPassword && passwordInput !== "") {
- _commitSubmit();
- return;
- }
- awaitingFprintForPassword = false;
- isLoading = false;
- passwordInput = "";
- passwordField.forceActiveFocus();
- }
-
- function onAuthenticationSucceeded() {
- hide();
- }
-
- function onAuthenticationFailed() {
- isLoading = false;
- }
-
- function onAuthenticationRequestCancelled() {
- hide();
- }
- }
-
- FileView {
- path: "/etc/pam.d/polkit-1"
- printErrors: false
- onLoaded: root.polkitEtcPamText = text()
- onLoadFailed: root.polkitEtcPamText = ""
- }
-
- FileView {
- path: "/usr/lib/pam.d/polkit-1"
- printErrors: false
- onLoaded: root.polkitLibPamText = text()
- onLoadFailed: root.polkitLibPamText = ""
- }
-
- FileView {
- path: "/etc/pam.d/system-auth"
- printErrors: false
- onLoaded: root.systemAuthPamText = text()
- onLoadFailed: root.systemAuthPamText = ""
- }
-
- FileView {
- path: "/etc/pam.d/common-auth"
- printErrors: false
- onLoaded: root.commonAuthPamText = text()
- onLoadFailed: root.commonAuthPamText = ""
- }
-
- FileView {
- path: "/etc/pam.d/password-auth"
- printErrors: false
- onLoaded: root.passwordAuthPamText = text()
- onLoadFailed: root.passwordAuthPamText = ""
- }
-
- FocusScope {
- id: contentFocusScope
-
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- cancelAuth();
- event.accepted = true;
- }
-
- Item {
- id: headerSection
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- height: Math.max(titleColumn.implicitHeight, windowButtonRow.implicitHeight)
-
- MouseArea {
- anchors.fill: parent
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- Column {
- id: titleColumn
- anchors.left: parent.left
- anchors.right: windowButtonRow.left
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Authentication Required")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: currentFlow?.message ?? ""
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- wrapMode: Text.Wrap
- maximumLineCount: 2
- elide: Text.ElideRight
- visible: text !== ""
- }
-
- StyledText {
- text: currentFlow?.supplementaryMessage ?? ""
- font.pixelSize: Theme.fontSizeSmall
- color: (currentFlow?.supplementaryIsError ?? false) ? Theme.error : Theme.surfaceTextMedium
- width: parent.width
- wrapMode: Text.Wrap
- maximumLineCount: 2
- elide: Text.ElideRight
- opacity: (currentFlow?.supplementaryIsError ?? false) ? 1 : 0.8
- visible: text !== ""
- }
- }
-
- Row {
- id: windowButtonRow
- anchors.right: parent.right
- anchors.top: parent.top
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported && windowControls.canMaximize
- iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- enabled: !isLoading
- opacity: enabled ? 1 : 0.5
- onClicked: cancelAuth()
- }
- }
- }
-
- Column {
- id: bottomSection
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingS
-
- StyledText {
- text: currentFlow?.inputPrompt ?? ""
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- width: parent.width
- visible: text !== ""
- }
-
- DankTextField {
- id: passwordField
-
- width: parent.width
- height: inputFieldHeight
- backgroundColor: Theme.surfaceHover
- normalBorderColor: Theme.outlineStrong
- focusedBorderColor: Theme.primary
- borderWidth: 1
- focusedBorderWidth: 2
- leftIconName: polkitPamHasFprint ? "fingerprint" : ""
- leftIconSize: 20
- leftIconColor: Theme.primary
- leftIconFocusedColor: Theme.primary
- opacity: isLoading ? 0.5 : 1
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: passwordInput
- showPasswordToggle: !(currentFlow?.responseVisible ?? false)
- echoMode: (currentFlow?.responseVisible ?? false) || passwordVisible ? TextInput.Normal : TextInput.Password
- placeholderText: ""
- enabled: !isLoading
- onTextEdited: passwordInput = text
- onAccepted: submitAuth()
- }
-
- StyledText {
- text: I18n.tr("Authentication failed, please try again")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.error
- width: parent.width
- visible: currentFlow?.failed ?? false
- }
-
- Item {
- width: parent.width
- height: 36
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
- enabled: !isLoading
- opacity: enabled ? 1 : 0.5
-
- StyledText {
- id: cancelText
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- enabled: parent.enabled
- onClicked: cancelAuth()
- }
- }
-
- Rectangle {
- width: Math.max(80, authText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: authArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
- enabled: !isLoading
- opacity: enabled ? 1 : 0.5
-
- StyledText {
- id: authText
- anchors.centerIn: parent
- text: I18n.tr("Authenticate")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: authArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- enabled: parent.enabled
- onClicked: submitAuth()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml
deleted file mode 100644
index c59037f..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml
+++ /dev/null
@@ -1,809 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import Quickshell
-import Quickshell.Hyprland
-import qs.Common
-import qs.Modals.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
-
- layerNamespace: "dms:power-menu"
- keepPopoutsOpen: true
-
- HyprlandFocusGrab {
- windows: [root.contentWindow]
- active: root.useHyprlandFocusGrab && root.shouldHaveFocus
- }
-
- property int selectedIndex: 0
- property int selectedRow: 0
- property int selectedCol: 0
- property rect parentBounds: Qt.rect(0, 0, 0, 0)
- property var parentScreen: null
- property var visibleActions: []
- property int gridColumns: 3
- property int gridRows: 2
-
- property string holdAction: ""
- property int holdActionIndex: -1
- property real holdProgress: 0
- property bool showHoldHint: false
-
- readonly property bool needsConfirmation: SettingsData.powerActionConfirm
- readonly property int holdDurationMs: SettingsData.powerActionHoldDuration * 1000
-
- signal powerActionRequested(string action, string title, string message)
- signal lockRequested
-
- function actionNeedsConfirm(action) {
- return action !== "lock" && action !== "restart";
- }
-
- function startHold(action, actionIndex) {
- if (!needsConfirmation || !actionNeedsConfirm(action)) {
- executeAction(action);
- return;
- }
- holdAction = action;
- holdActionIndex = actionIndex;
- holdProgress = 0;
- showHoldHint = false;
- holdTimer.start();
- }
-
- function cancelHold() {
- if (holdAction === "")
- return;
- const wasHolding = holdProgress > 0;
- holdTimer.stop();
- if (wasHolding && holdProgress < 1) {
- showHoldHint = true;
- hintTimer.restart();
- }
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- }
-
- function completeHold() {
- if (holdProgress < 1) {
- cancelHold();
- return;
- }
- const action = holdAction;
- holdTimer.stop();
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- executeAction(action);
- }
-
- function executeAction(action) {
- if (action === "lock") {
- close();
- lockRequested();
- return;
- }
- if (action === "restart") {
- close();
- Quickshell.execDetached(["dms", "restart"]);
- return;
- }
- close();
- root.powerActionRequested(action, "", "");
- }
-
- Timer {
- id: holdTimer
- interval: 16
- repeat: true
- onTriggered: {
- root.holdProgress = Math.min(1, root.holdProgress + (interval / root.holdDurationMs));
- if (root.holdProgress >= 1) {
- stop();
- root.completeHold();
- }
- }
- }
-
- Timer {
- id: hintTimer
- interval: 2000
- onTriggered: root.showHoldHint = false
- }
-
- function openCentered() {
- parentBounds = Qt.rect(0, 0, 0, 0);
- parentScreen = null;
- open();
- }
-
- function openFromControlCenter(bounds, targetScreen) {
- parentBounds = bounds;
- parentScreen = targetScreen;
- open();
- }
-
- function updateVisibleActions() {
- const allActions = SettingsData.powerMenuActions || ["reboot", "logout", "poweroff", "lock", "suspend", "restart"];
- visibleActions = allActions.filter(action => {
- if (action === "hibernate" && !SessionService.hibernateSupported)
- return false;
- return true;
- });
-
- if (!SettingsData.powerMenuGridLayout)
- return;
- const count = visibleActions.length;
- if (count === 0) {
- gridColumns = 1;
- gridRows = 1;
- return;
- }
-
- if (count <= 3) {
- gridColumns = 1;
- gridRows = count;
- return;
- }
-
- if (count === 4) {
- gridColumns = 2;
- gridRows = 2;
- return;
- }
-
- gridColumns = 3;
- gridRows = Math.ceil(count / 3);
- }
-
- function getDefaultActionIndex() {
- const defaultAction = SettingsData.powerMenuDefaultAction || "logout";
- const index = visibleActions.indexOf(defaultAction);
- return index >= 0 ? index : 0;
- }
-
- function getActionAtIndex(index) {
- if (index < 0 || index >= visibleActions.length)
- return "";
- return visibleActions[index];
- }
-
- function getActionData(action) {
- switch (action) {
- case "reboot":
- return {
- "icon": "restart_alt",
- "label": I18n.tr("Reboot"),
- "key": "R"
- };
- case "logout":
- return {
- "icon": "logout",
- "label": I18n.tr("Log Out"),
- "key": "X"
- };
- case "poweroff":
- return {
- "icon": "power_settings_new",
- "label": I18n.tr("Power Off"),
- "key": "P"
- };
- case "lock":
- return {
- "icon": "lock",
- "label": I18n.tr("Lock"),
- "key": "L"
- };
- case "suspend":
- return {
- "icon": "bedtime",
- "label": I18n.tr("Suspend"),
- "key": "S"
- };
- case "hibernate":
- return {
- "icon": "ac_unit",
- "label": I18n.tr("Hibernate"),
- "key": "H"
- };
- case "restart":
- return {
- "icon": "refresh",
- "label": I18n.tr("Restart DMS"),
- "key": "D"
- };
- default:
- return {
- "icon": "help",
- "label": action,
- "key": "?"
- };
- }
- }
-
- function selectOption(action, actionIndex) {
- startHold(action, actionIndex !== undefined ? actionIndex : -1);
- }
-
- shouldBeVisible: false
- modalWidth: SettingsData.powerMenuGridLayout ? Math.min(550, gridColumns * 180 + Theme.spacingS * (gridColumns - 1) + Theme.spacingL * 2) : 400
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight : 300
- enableShadow: true
- targetScreen: parentScreen
- positioning: parentBounds.width > 0 ? "custom" : "center"
- customPosition: {
- if (parentBounds.width > 0) {
- const effectiveBarThickness = Math.max(26 + (SettingsData.barConfigs[0]?.innerPadding ?? 4) * 0.6 + (SettingsData.barConfigs[0]?.innerPadding ?? 4) + 4, Theme.barHeight - 4 - (8 - (SettingsData.barConfigs[0]?.innerPadding ?? 4)));
- const barExclusionZone = effectiveBarThickness + (SettingsData.barConfigs[0]?.spacing ?? 4) + (SettingsData.barConfigs[0]?.bottomGap ?? 0);
- const screenW = parentScreen?.width ?? 1920;
- const screenH = parentScreen?.height ?? 1080;
- const margin = Theme.spacingL;
-
- let targetX = parentBounds.x + (parentBounds.width - modalWidth) / 2;
- let targetY = parentBounds.y + (parentBounds.height - modalHeight) / 2;
-
- const minY = (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top) === SettingsData.Position.Top ? barExclusionZone + margin : margin;
- const maxY = (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top) === SettingsData.Position.Bottom ? screenH - modalHeight - barExclusionZone - margin : screenH - modalHeight - margin;
-
- targetY = Math.max(minY, Math.min(maxY, targetY));
-
- return Qt.point(targetX, targetY);
- }
- return Qt.point(0, 0);
- }
- onBackgroundClicked: () => {
- cancelHold();
- close();
- }
- onOpened: () => {
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- showHoldHint = false;
- updateVisibleActions();
- const defaultIndex = getDefaultActionIndex();
- if (SettingsData.powerMenuGridLayout) {
- selectedRow = Math.floor(defaultIndex / gridColumns);
- selectedCol = defaultIndex % gridColumns;
- selectedIndex = defaultIndex;
- } else {
- selectedIndex = defaultIndex;
- }
- Qt.callLater(() => modalFocusScope.forceActiveFocus());
- }
- onDialogClosed: () => {
- cancelHold();
- }
- Component.onCompleted: updateVisibleActions()
- modalFocusScope.Keys.onPressed: event => {
- if (event.isAutoRepeat) {
- event.accepted = true;
- return;
- }
- if (SettingsData.powerMenuGridLayout) {
- handleGridNavigation(event, true);
- } else {
- handleListNavigation(event, true);
- }
- }
- modalFocusScope.Keys.onReleased: event => {
- if (event.isAutoRepeat) {
- event.accepted = true;
- return;
- }
- if (SettingsData.powerMenuGridLayout) {
- handleGridNavigation(event, false);
- } else {
- handleListNavigation(event, false);
- }
- }
-
- function handleListNavigation(event, isPressed) {
- if (!isPressed) {
- if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_L || event.key === Qt.Key_S || event.key === Qt.Key_H || event.key === Qt.Key_D || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) {
- cancelHold();
- event.accepted = true;
- }
- return;
- }
-
- switch (event.key) {
- case Qt.Key_Up:
- case Qt.Key_Backtab:
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- break;
- case Qt.Key_Down:
- case Qt.Key_Tab:
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- startHold(getActionAtIndex(selectedIndex), selectedIndex);
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (!(event.modifiers & Qt.ControlModifier)) {
- const idx = visibleActions.indexOf("poweroff");
- startHold("poweroff", idx);
- event.accepted = true;
- } else {
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_R:
- startHold("reboot", visibleActions.indexOf("reboot"));
- event.accepted = true;
- break;
- case Qt.Key_X:
- startHold("logout", visibleActions.indexOf("logout"));
- event.accepted = true;
- break;
- case Qt.Key_L:
- startHold("lock", visibleActions.indexOf("lock"));
- event.accepted = true;
- break;
- case Qt.Key_S:
- startHold("suspend", visibleActions.indexOf("suspend"));
- event.accepted = true;
- break;
- case Qt.Key_H:
- startHold("hibernate", visibleActions.indexOf("hibernate"));
- event.accepted = true;
- break;
- case Qt.Key_D:
- startHold("restart", visibleActions.indexOf("restart"));
- event.accepted = true;
- break;
- }
- }
-
- function handleGridNavigation(event, isPressed) {
- if (!isPressed) {
- if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_L || event.key === Qt.Key_S || event.key === Qt.Key_H || event.key === Qt.Key_D || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) {
- cancelHold();
- event.accepted = true;
- }
- return;
- }
-
- switch (event.key) {
- case Qt.Key_Left:
- selectedCol = (selectedCol - 1 + gridColumns) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Right:
- selectedCol = (selectedCol + 1) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Up:
- case Qt.Key_Backtab:
- selectedRow = (selectedRow - 1 + gridRows) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Down:
- case Qt.Key_Tab:
- selectedRow = (selectedRow + 1) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- startHold(getActionAtIndex(selectedIndex), selectedIndex);
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- selectedCol = (selectedCol + 1) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (!(event.modifiers & Qt.ControlModifier)) {
- const idx = visibleActions.indexOf("poweroff");
- startHold("poweroff", idx);
- event.accepted = true;
- } else {
- selectedCol = (selectedCol - 1 + gridColumns) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- selectedRow = (selectedRow + 1) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- selectedRow = (selectedRow - 1 + gridRows) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_R:
- startHold("reboot", visibleActions.indexOf("reboot"));
- event.accepted = true;
- break;
- case Qt.Key_X:
- startHold("logout", visibleActions.indexOf("logout"));
- event.accepted = true;
- break;
- case Qt.Key_L:
- startHold("lock", visibleActions.indexOf("lock"));
- event.accepted = true;
- break;
- case Qt.Key_S:
- startHold("suspend", visibleActions.indexOf("suspend"));
- event.accepted = true;
- break;
- case Qt.Key_H:
- startHold("hibernate", visibleActions.indexOf("hibernate"));
- event.accepted = true;
- break;
- case Qt.Key_D:
- startHold("restart", visibleActions.indexOf("restart"));
- event.accepted = true;
- break;
- }
- }
-
- content: Component {
- Item {
- anchors.fill: parent
- implicitHeight: (SettingsData.powerMenuGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight) + Theme.spacingL * 2 + (root.needsConfirmation ? hintRow.height + Theme.spacingM : 0)
-
- Grid {
- id: buttonGrid
- visible: SettingsData.powerMenuGridLayout
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.topMargin: Theme.spacingL
- columns: root.gridColumns
- columnSpacing: Theme.spacingS
- rowSpacing: Theme.spacingS
-
- Repeater {
- model: root.visibleActions
-
- Rectangle {
- id: gridButtonRect
- required property int index
- required property string modelData
-
- readonly property var actionData: root.getActionData(modelData)
- readonly property bool isSelected: root.selectedIndex === index
- readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
- readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0
-
- width: (root.modalWidth - Theme.spacingL * 2 - Theme.spacingS * (root.gridColumns - 1)) / root.gridColumns
- height: 100
- radius: Theme.cornerRadius
- color: {
- if (isSelected)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- if (mouseArea.containsMouse)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
- return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
- }
- border.color: isSelected ? Theme.primary : "transparent"
- border.width: isSelected ? 2 : 0
-
- Rectangle {
- id: gridProgressMask
- anchors.fill: parent
- radius: parent.radius
- visible: false
- layer.enabled: true
- }
-
- Item {
- anchors.fill: parent
- visible: gridButtonRect.isHolding
- layer.enabled: gridButtonRect.isHolding
- layer.effect: MultiEffect {
- maskEnabled: true
- maskSource: gridProgressMask
- maskSpreadAtMin: 1
- maskThresholdMin: 0.5
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * root.holdProgress
- color: {
- if (gridButtonRect.modelData === "poweroff")
- return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3);
- if (gridButtonRect.modelData === "reboot")
- return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3);
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
- }
- }
- }
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- DankIcon {
- name: gridButtonRect.actionData.icon
- size: Theme.iconSize + 8
- color: {
- if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) {
- return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: gridButtonRect.actionData.label
- font.pixelSize: Theme.fontSizeMedium
- color: {
- if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) {
- return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- font.weight: Font.Medium
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- Rectangle {
- width: 20
- height: 16
- radius: 4
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
- anchors.horizontalCenter: parent.horizontalCenter
-
- StyledText {
- text: gridButtonRect.actionData.key
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: {
- root.selectedRow = Math.floor(index / root.gridColumns);
- root.selectedCol = index % root.gridColumns;
- root.selectedIndex = index;
- root.startHold(modelData, index);
- }
- onReleased: root.cancelHold()
- onCanceled: root.cancelHold()
- }
- }
- }
- }
-
- Column {
- id: buttonColumn
- visible: !SettingsData.powerMenuGridLayout
- anchors {
- left: parent.left
- right: parent.right
- top: parent.top
- leftMargin: Theme.spacingL
- rightMargin: Theme.spacingL
- topMargin: Theme.spacingL
- }
- spacing: Theme.spacingS
-
- Repeater {
- model: root.visibleActions
-
- Rectangle {
- id: listButtonRect
- required property int index
- required property string modelData
-
- readonly property var actionData: root.getActionData(modelData)
- readonly property bool isSelected: root.selectedIndex === index
- readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
- readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0
-
- width: parent.width
- height: 56
- radius: Theme.cornerRadius
- color: {
- if (isSelected)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- if (listMouseArea.containsMouse)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
- return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
- }
- border.color: isSelected ? Theme.primary : "transparent"
- border.width: isSelected ? 2 : 0
-
- Rectangle {
- id: listProgressMask
- anchors.fill: parent
- radius: parent.radius
- visible: false
- layer.enabled: true
- }
-
- Item {
- anchors.fill: parent
- visible: listButtonRect.isHolding
- layer.enabled: listButtonRect.isHolding
- layer.effect: MultiEffect {
- maskEnabled: true
- maskSource: listProgressMask
- maskSpreadAtMin: 1
- maskThresholdMin: 0.5
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * root.holdProgress
- color: {
- if (listButtonRect.modelData === "poweroff")
- return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3);
- if (listButtonRect.modelData === "reboot")
- return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3);
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
- }
- }
- }
-
- Row {
- anchors {
- left: parent.left
- right: parent.right
- leftMargin: Theme.spacingM
- rightMargin: Theme.spacingM
- verticalCenter: parent.verticalCenter
- }
- spacing: Theme.spacingM
-
- DankIcon {
- name: listButtonRect.actionData.icon
- size: Theme.iconSize + 4
- color: {
- if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) {
- return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: listButtonRect.actionData.label
- font.pixelSize: Theme.fontSizeMedium
- color: {
- if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) {
- return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- width: 28
- height: 20
- radius: 4
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
- anchors {
- right: parent.right
- rightMargin: Theme.spacingM
- verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: listButtonRect.actionData.key
- font.pixelSize: Theme.fontSizeSmall
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
- }
-
- MouseArea {
- id: listMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: {
- root.selectedIndex = index;
- root.startHold(modelData, index);
- }
- onReleased: root.cancelHold()
- onCanceled: root.cancelHold()
- }
- }
- }
- }
-
- Row {
- id: hintRow
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- anchors.bottomMargin: Theme.spacingS
- spacing: Theme.spacingXS
- visible: root.needsConfirmation
- opacity: root.showHoldHint ? 1 : 0.5
-
- Behavior on opacity {
- NumberAnimation {
- duration: 150
- }
- }
-
- DankIcon {
- name: root.showHoldHint ? "warning" : "touch_app"
- size: Theme.fontSizeSmall
- color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- readonly property real totalMs: SettingsData.powerActionHoldDuration * 1000
- readonly property int remainingMs: Math.ceil(totalMs * (1 - root.holdProgress))
- text: {
- if (root.showHoldHint)
- return I18n.tr("Hold longer to confirm");
- if (root.holdProgress > 0) {
- if (totalMs < 1000)
- return I18n.tr("Hold to confirm (%1 ms)").arg(remainingMs);
- return I18n.tr("Hold to confirm (%1s)").arg(Math.ceil(remainingMs / 1000));
- }
- if (totalMs < 1000)
- return I18n.tr("Hold to confirm (%1 ms)").arg(totalMs);
- return I18n.tr("Hold to confirm (%1s)").arg(SettingsData.powerActionHoldDuration);
- }
- font.pixelSize: Theme.fontSizeSmall
- color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml
deleted file mode 100644
index 8cfc705..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml
+++ /dev/null
@@ -1,609 +0,0 @@
-import QtQuick
-import QtQuick.Layouts
-import Quickshell
-import Quickshell.Wayland
-import qs.Common
-import qs.Modules.ProcessList
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: processListModal
-
- property bool disablePopupTransparency: true
- property int currentTab: 0
- property string searchText: ""
- property string expandedPid: ""
- property string processFilter: "all"
- property bool shouldHaveFocus: visible
- property alias shouldBeVisible: processListModal.visible
-
- signal closingModal
-
- function show() {
- if (!DgopService.dgopAvailable) {
- console.warn("ProcessListModal: dgop is not available");
- return;
- }
- visible = true;
- }
-
- function hide() {
- visible = false;
- if (processContextMenu.visible)
- processContextMenu.close();
- }
-
- function toggle() {
- if (!DgopService.dgopAvailable) {
- console.warn("ProcessListModal: dgop is not available");
- return;
- }
- visible = !visible;
- }
-
- function focusOrToggle() {
- if (!DgopService.dgopAvailable) {
- console.warn("ProcessListModal: dgop is not available");
- return;
- }
- if (visible) {
- const modalTitle = I18n.tr("System Monitor", "sysmon window title");
- for (const toplevel of ToplevelManager.toplevels.values) {
- if (toplevel.title !== "System Monitor" && toplevel.title !== modalTitle)
- continue;
- if (toplevel.activated) {
- hide();
- return;
- }
- toplevel.activate();
- return;
- }
- }
- show();
- }
-
- function formatBytes(bytes) {
- if (bytes < 1024)
- return bytes.toFixed(0) + " B/s";
- if (bytes < 1024 * 1024)
- return (bytes / 1024).toFixed(1) + " KB/s";
- if (bytes < 1024 * 1024 * 1024)
- return (bytes / (1024 * 1024)).toFixed(1) + " MB/s";
- return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB/s";
- }
-
- function nextTab() {
- currentTab = (currentTab + 1) % 4;
- }
-
- function previousTab() {
- currentTab = (currentTab - 1 + 4) % 4;
- }
-
- objectName: "processListModal"
- title: I18n.tr("System Monitor", "sysmon window title")
- minimumSize: Qt.size(Math.min(Math.round(Theme.fontSizeMedium * 48), Screen.width), Math.min(Math.round(Theme.fontSizeMedium * 34), Screen.height))
- implicitWidth: Math.round(Theme.fontSizeMedium * 71)
- implicitHeight: Math.round(Theme.fontSizeMedium * 51)
- color: Theme.surfaceContainer
- visible: false
-
- onCurrentTabChanged: {
- if (visible && currentTab === 0 && searchField.visible)
- searchField.forceActiveFocus();
- }
-
- onVisibleChanged: {
- if (!visible) {
- closingModal();
- searchText = "";
- expandedPid = "";
- processFilter = "all";
- processFilterGroup.currentIndex = 0;
- if (processesTabLoader.item)
- processesTabLoader.item.reset();
- DgopService.removeRef(["cpu", "memory", "network", "disk", "system"]);
- } else {
- DgopService.addRef(["cpu", "memory", "network", "disk", "system"]);
- Qt.callLater(() => {
- if (currentTab === 0 && searchField.visible)
- searchField.forceActiveFocus();
- else if (contentFocusScope)
- contentFocusScope.forceActiveFocus();
- });
- }
- }
-
- ProcessContextMenu {
- id: processContextMenu
- parentFocusItem: contentFocusScope
- onProcessKilled: {
- if (processesTabLoader.item)
- processesTabLoader.item.forceRefresh(3);
- }
- }
-
- FocusScope {
- id: contentFocusScope
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- anchors.fill: parent
- focus: true
-
- Keys.onPressed: event => {
- if (processContextMenu.visible)
- return;
-
- switch (event.key) {
- case Qt.Key_1:
- currentTab = 0;
- event.accepted = true;
- return;
- case Qt.Key_2:
- currentTab = 1;
- event.accepted = true;
- return;
- case Qt.Key_3:
- currentTab = 2;
- event.accepted = true;
- return;
- case Qt.Key_4:
- currentTab = 3;
- event.accepted = true;
- return;
- case Qt.Key_Tab:
- nextTab();
- event.accepted = true;
- return;
- case Qt.Key_Backtab:
- previousTab();
- event.accepted = true;
- return;
- case Qt.Key_Escape:
- if (searchText.length > 0) {
- searchText = "";
- event.accepted = true;
- return;
- }
- if (currentTab === 0 && processesTabLoader.item?.keyboardNavigationActive) {
- processesTabLoader.item.reset();
- event.accepted = true;
- return;
- }
- hide();
- event.accepted = true;
- return;
- case Qt.Key_F:
- if (event.modifiers & Qt.ControlModifier) {
- searchField.forceActiveFocus();
- event.accepted = true;
- return;
- }
- break;
- }
-
- if (currentTab === 0 && processesTabLoader.item)
- processesTabLoader.item.handleKey(event);
- }
-
- Rectangle {
- anchors.centerIn: parent
- width: 400
- height: 200
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1)
- border.color: Theme.error
- border.width: 2
- visible: !DgopService.dgopAvailable
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingL
-
- DankIcon {
- name: "error"
- size: 48
- color: Theme.error
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: I18n.tr("System Monitor Unavailable")
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Bold
- color: Theme.error
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: I18n.tr("The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature.", "dgop unavailable error message")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- anchors.horizontalCenter: parent.horizontalCenter
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
- }
- }
-
- ColumnLayout {
- anchors.fill: parent
- spacing: 0
- visible: DgopService.dgopAvailable
-
- Item {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.4)
-
- MouseArea {
- anchors.fill: parent
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- Row {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingL
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: "analytics"
- size: Theme.iconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("System Monitor")
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Medium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported
- circular: false
- iconName: processListModal.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- circular: false
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: processListModal.hide()
- }
- }
- }
-
- RowLayout {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.7)
- Layout.leftMargin: Theme.spacingL
- Layout.rightMargin: Theme.spacingL
- spacing: Theme.spacingM
-
- Row {
- spacing: 2
-
- Repeater {
- model: [
- {
- text: I18n.tr("Processes"),
- icon: "list_alt"
- },
- {
- text: I18n.tr("Performance"),
- icon: "analytics"
- },
- {
- text: I18n.tr("Disks"),
- icon: "storage"
- },
- {
- text: I18n.tr("System"),
- icon: "computer"
- }
- ]
-
- Rectangle {
- width: tabRowContent.implicitWidth + Theme.spacingM * 2
- height: Math.round(Theme.fontSizeMedium * 3.1)
- radius: Theme.cornerRadius
- color: currentTab === index ? Theme.primaryPressed : (tabMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent")
- border.color: currentTab === index ? Theme.primary : "transparent"
- border.width: currentTab === index ? 1 : 0
-
- Row {
- id: tabRowContent
- anchors.centerIn: parent
- spacing: Theme.spacingXS
-
- DankIcon {
- name: modelData.icon
- size: Theme.iconSize - 2
- color: currentTab === index ? Theme.primary : Theme.surfaceText
- opacity: currentTab === index ? 1 : 0.7
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: modelData.text
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: currentTab === index ? Theme.primary : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: tabMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: currentTab = index
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- }
- }
- }
- }
- }
-
- Item {
- Layout.fillWidth: true
- }
-
- DankButtonGroup {
- id: processFilterGroup
- model: [I18n.tr("All"), I18n.tr("User"), I18n.tr("System")]
- currentIndex: 0
- checkEnabled: false
- buttonHeight: Math.round(Theme.fontSizeSmall * 2.6)
- minButtonWidth: 0
- buttonPadding: Theme.spacingS
- textSize: Theme.fontSizeSmall
- visible: currentTab === 0
- onSelectionChanged: (index, selected) => {
- if (!selected)
- return;
- currentIndex = index;
- switch (index) {
- case 0:
- processListModal.processFilter = "all";
- return;
- case 1:
- processListModal.processFilter = "user";
- return;
- case 2:
- processListModal.processFilter = "system";
- return;
- }
- }
- }
-
- DankTextField {
- id: searchField
- Layout.fillWidth: true
- Layout.maximumWidth: Math.round(Theme.fontSizeMedium * 18)
- Layout.minimumWidth: Theme.fontSizeMedium * 4
- Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 2.8)
- placeholderText: I18n.tr("Search processes...", "process search placeholder")
- leftIconName: "search"
- showClearButton: true
- text: searchText
- visible: currentTab === 0
- onTextChanged: searchText = text
- ignoreUpDownKeys: true
- keyForwardTargets: [contentFocusScope]
- }
- }
-
- Rectangle {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.margins: Theme.spacingL
- Layout.topMargin: Theme.spacingM
- radius: Theme.cornerRadius
- color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- border.color: Theme.outlineLight
- border.width: 1
- clip: true
-
- Loader {
- id: processesTabLoader
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- active: processListModal.visible && currentTab === 0
- visible: currentTab === 0
- sourceComponent: ProcessesView {
- searchText: processListModal.searchText
- expandedPid: processListModal.expandedPid
- processFilter: processListModal.processFilter
- contextMenu: processContextMenu
- onExpandedPidChanged: processListModal.expandedPid = expandedPid
- }
- }
-
- Loader {
- id: performanceTabLoader
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- active: processListModal.visible && currentTab === 1
- visible: currentTab === 1
- sourceComponent: PerformanceView {}
- }
-
- Loader {
- id: disksTabLoader
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- active: processListModal.visible && currentTab === 2
- visible: currentTab === 2
- sourceComponent: DisksView {}
- }
-
- Loader {
- id: systemTabLoader
- anchors.fill: parent
- anchors.margins: Theme.spacingS
- active: processListModal.visible && currentTab === 3
- visible: currentTab === 3
- sourceComponent: SystemView {}
- }
- }
-
- Rectangle {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.round(Theme.fontSizeSmall * 2.7)
- Layout.leftMargin: Theme.spacingL
- Layout.rightMargin: Theme.spacingL
- Layout.bottomMargin: Theme.spacingM
- color: "transparent"
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingL
-
- Row {
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Processes:", "process count label in footer")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
-
- StyledText {
- text: DgopService.processCount.toString()
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
- }
-
- Row {
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Uptime:", "uptime label in footer")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
-
- StyledText {
- text: DgopService.shortUptime || "--"
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Bold
- color: Theme.surfaceText
- }
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingL
-
- Row {
- spacing: Theme.spacingXS
-
- DankIcon {
- name: "swap_horiz"
- size: 14
- color: Theme.info
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: "↓" + formatBytes(DgopService.networkRxRate) + " ↑" + formatBytes(DgopService.networkTxRate)
- font.pixelSize: Theme.fontSizeSmall
- font.family: SettingsData.monoFontFamily
- color: Theme.surfaceText
- }
- }
-
- Row {
- spacing: Theme.spacingXS
-
- DankIcon {
- name: "storage"
- size: 14
- color: Theme.warning
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: "↓" + formatBytes(DgopService.diskReadRate) + " ↑" + formatBytes(DgopService.diskWriteRate)
- font.pixelSize: Theme.fontSizeSmall
- font.family: SettingsData.monoFontFamily
- color: Theme.surfaceText
- }
- }
-
- Row {
- spacing: Theme.spacingXS
-
- DankIcon {
- name: "memory"
- size: 14
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: DgopService.cpuUsage.toFixed(1) + "%"
- font.pixelSize: Theme.fontSizeSmall
- font.family: SettingsData.monoFontFamily
- font.weight: Font.Bold
- color: DgopService.cpuUsage > 80 ? Theme.error : Theme.surfaceText
- }
- }
-
- Row {
- spacing: Theme.spacingXS
-
- DankIcon {
- name: "sd_card"
- size: 14
- color: Theme.secondary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: DgopService.formatSystemMemory(DgopService.usedMemoryKB) + " / " + DgopService.formatSystemMemory(DgopService.totalMemoryKB)
- font.pixelSize: Theme.fontSizeSmall
- font.family: SettingsData.monoFontFamily
- font.weight: Font.Bold
- color: DgopService.memoryUsage > 90 ? Theme.error : Theme.surfaceText
- }
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: processListModal
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml
deleted file mode 100644
index 29b4961..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml
+++ /dev/null
@@ -1,144 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property var parentModal: null
-
- width: parent.width - Theme.spacingS * 2
- height: 110
- radius: Theme.cornerRadius
- color: "transparent"
- border.width: 0
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- Item {
- id: profileImageContainer
-
- width: 80
- height: 80
- anchors.verticalCenter: parent.verticalCenter
-
- DankCircularImage {
- id: profileImage
-
- anchors.fill: parent
- imageSource: {
- if (PortalService.profileImage === "") {
- return "";
- }
- if (PortalService.profileImage.startsWith("/")) {
- return "file://" + PortalService.profileImage;
- }
- return PortalService.profileImage;
- }
- fallbackIcon: "person"
- }
-
- Rectangle {
- anchors.fill: parent
- radius: width / 2
- color: Qt.rgba(0, 0, 0, 0.7)
- visible: profileMouseArea.containsMouse
-
- Row {
- anchors.centerIn: parent
- spacing: 4
-
- Rectangle {
- width: 28
- height: 28
- radius: 14
- color: Qt.rgba(255, 255, 255, 0.9)
-
- DankIcon {
- anchors.centerIn: parent
- name: "edit"
- size: 16
- color: "black"
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: () => {
- if (root.parentModal) {
- root.parentModal.allowFocusOverride = true;
- root.parentModal.shouldHaveFocus = false;
- root.parentModal.openProfileBrowser();
- }
- }
- }
- }
-
- Rectangle {
- width: 28
- height: 28
- radius: 14
- color: Qt.rgba(255, 255, 255, 0.9)
- visible: profileImage.hasImage
-
- DankIcon {
- anchors.centerIn: parent
- name: "close"
- size: 16
- color: "black"
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: () => {
- return PortalService.setProfileImage("");
- }
- }
- }
- }
- }
-
- MouseArea {
- id: profileMouseArea
-
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- propagateComposedEvents: true
- acceptedButtons: Qt.NoButton
- }
- }
-
- Column {
- width: 120
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- StyledText {
- text: UserInfoService.fullName || "User"
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Medium
- color: Theme.surfaceText
- elide: Text.ElideRight
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- StyledText {
- text: DgopService.hostname || "DMS"
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceVariantText
- elide: Text.ElideRight
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml
deleted file mode 100644
index 34cd51a..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml
+++ /dev/null
@@ -1,522 +0,0 @@
-import QtQuick
-import qs.Common
-import qs.Modules.Settings
-
-FocusScope {
- id: root
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property int currentIndex: 0
- property var parentModal: null
-
- focus: true
-
- Rectangle {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingS
- anchors.rightMargin: (parentModal && parentModal.isCompactMode) ? Theme.spacingS : (32 + Theme.spacingS)
- anchors.bottomMargin: 0
- anchors.topMargin: 0
- color: "transparent"
-
- Loader {
- id: wallpaperLoader
- anchors.fill: parent
- active: root.currentIndex === 0
- visible: active
- focus: active
-
- sourceComponent: Component {
- WallpaperTab {
- parentModal: root.parentModal
- }
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: timeWeatherLoader
- anchors.fill: parent
- active: root.currentIndex === 1
- visible: active
- focus: active
-
- sourceComponent: TimeWeatherTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: keybindsLoader
- anchors.fill: parent
- active: root.currentIndex === 2
- visible: active
- focus: active
-
- sourceComponent: KeybindsTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: topBarLoader
- anchors.fill: parent
- active: root.currentIndex === 3
- visible: active
- focus: active
-
- sourceComponent: DankBarTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: workspacesLoader
- anchors.fill: parent
- active: root.currentIndex === 4
- visible: active
- focus: active
-
- sourceComponent: WorkspacesTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: dockLoader
- anchors.fill: parent
- active: root.currentIndex === 5
- visible: active
- focus: active
-
- sourceComponent: Component {
- DockTab {}
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: displayConfigLoader
- anchors.fill: parent
- active: root.currentIndex === 24
- visible: active
- focus: active
-
- sourceComponent: DisplayConfigTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: gammaControlLoader
- anchors.fill: parent
- active: root.currentIndex === 25
- visible: active
- focus: active
-
- sourceComponent: GammaControlTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: displayWidgetsLoader
- anchors.fill: parent
- active: root.currentIndex === 26
- visible: active
- focus: active
-
- sourceComponent: DisplayWidgetsTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: networkLoader
- anchors.fill: parent
- active: root.currentIndex === 7
- visible: active
- focus: active
-
- sourceComponent: NetworkTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: printerLoader
- anchors.fill: parent
- active: root.currentIndex === 8
- visible: active
- focus: active
-
- sourceComponent: PrinterTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: launcherLoader
- anchors.fill: parent
- active: root.currentIndex === 9
- visible: active
- focus: active
-
- sourceComponent: LauncherTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: themeColorsLoader
- anchors.fill: parent
- active: root.currentIndex === 10
- visible: active
- focus: active
-
- sourceComponent: ThemeColorsTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: lockScreenLoader
- anchors.fill: parent
- active: root.currentIndex === 11
- visible: active
- focus: active
-
- sourceComponent: LockScreenTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: greeterLoader
- anchors.fill: parent
- active: root.currentIndex === 31
- visible: active
- focus: active
-
- sourceComponent: GreeterTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: pluginsLoader
- anchors.fill: parent
- active: root.currentIndex === 12
- visible: active
- focus: active
-
- sourceComponent: PluginsTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: aboutLoader
- anchors.fill: parent
- active: root.currentIndex === 13
- visible: active
- focus: active
-
- sourceComponent: AboutTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: typographyMotionLoader
- anchors.fill: parent
- active: root.currentIndex === 14
- visible: active
- focus: active
-
- sourceComponent: TypographyMotionTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: soundsLoader
- anchors.fill: parent
- active: root.currentIndex === 15
- visible: active
- focus: active
-
- sourceComponent: SoundsTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: mediaPlayerLoader
- anchors.fill: parent
- active: root.currentIndex === 16
- visible: active
- focus: active
-
- sourceComponent: MediaPlayerTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: notificationsLoader
- anchors.fill: parent
- active: root.currentIndex === 17
- visible: active
- focus: active
-
- sourceComponent: NotificationsTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: osdLoader
- anchors.fill: parent
- active: root.currentIndex === 18
- visible: active
- focus: active
-
- sourceComponent: OSDTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: runningAppsLoader
- anchors.fill: parent
- active: root.currentIndex === 19
- visible: active
- focus: active
-
- sourceComponent: RunningAppsTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: systemUpdaterLoader
- anchors.fill: parent
- active: root.currentIndex === 20
- visible: active
- focus: active
-
- sourceComponent: SystemUpdaterTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: powerSleepLoader
- anchors.fill: parent
- active: root.currentIndex === 21
- visible: active
- focus: active
-
- sourceComponent: PowerSleepTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: widgetsLoader
- anchors.fill: parent
- active: root.currentIndex === 22
- visible: active
- focus: active
-
- sourceComponent: WidgetsTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: clipboardLoader
- anchors.fill: parent
- active: root.currentIndex === 23
- visible: active
- focus: active
-
- sourceComponent: ClipboardTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: desktopWidgetsLoader
- anchors.fill: parent
- active: root.currentIndex === 27
- visible: active
- focus: active
-
- sourceComponent: DesktopWidgetsTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: windowRulesLoader
- anchors.fill: parent
- active: root.currentIndex === 28
- visible: active
- focus: active
-
- sourceComponent: WindowRulesTab {
- parentModal: root.parentModal
- }
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: audioLoader
- anchors.fill: parent
- active: root.currentIndex === 29
- visible: active
- focus: active
-
- sourceComponent: AudioTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: localeLoader
- anchors.fill: parent
- active: root.currentIndex === 30
- visible: active
- focus: active
-
- sourceComponent: LocaleTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
-
- Loader {
- id: muxLoader
- anchors.fill: parent
- active: root.currentIndex === 32
- visible: active
- focus: active
-
- sourceComponent: MuxTab {}
-
- onActiveChanged: {
- if (active && item)
- Qt.callLater(() => item.forceActiveFocus());
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml
deleted file mode 100644
index 9ce9153..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml
+++ /dev/null
@@ -1,382 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Modals.FileBrowser
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: settingsModal
-
- property bool disablePopupTransparency: true
- property var profileBrowser: profileBrowserLoader.item
- property var wallpaperBrowser: wallpaperBrowserLoader.item
-
- function openProfileBrowser(allowStacking) {
- profileBrowserLoader.active = true;
- if (!profileBrowserLoader.item)
- return;
- if (allowStacking !== undefined)
- profileBrowserLoader.item.allowStacking = allowStacking;
- profileBrowserLoader.item.open();
- }
-
- function openWallpaperBrowser(allowStacking) {
- wallpaperBrowserLoader.active = true;
- if (!wallpaperBrowserLoader.item)
- return;
- if (allowStacking !== undefined)
- wallpaperBrowserLoader.item.allowStacking = allowStacking;
- wallpaperBrowserLoader.item.open();
- }
- property alias sidebar: sidebar
- property int currentTabIndex: 0
- property bool shouldHaveFocus: visible
- property bool allowFocusOverride: false
- property alias shouldBeVisible: settingsModal.visible
- property bool isCompactMode: width < 700
- property bool menuVisible: !isCompactMode
- property bool enableAnimations: true
-
- signal closingModal
-
- function show() {
- visible = true;
- }
-
- function hide() {
- visible = false;
- }
-
- function toggle() {
- visible = !visible;
- }
-
- function showWithTab(tabIndex: int) {
- if (tabIndex >= 0) {
- currentTabIndex = tabIndex;
- sidebar.autoExpandForTab(tabIndex);
- }
- visible = true;
- }
-
- function showWithTabName(tabName: string) {
- var idx = sidebar.resolveTabIndex(tabName);
- if (idx >= 0) {
- currentTabIndex = idx;
- sidebar.autoExpandForTab(idx);
- }
- visible = true;
- }
-
- function resolveTabIndex(tabName: string): int {
- return sidebar.resolveTabIndex(tabName);
- }
-
- function toggleMenu() {
- enableAnimations = true;
- menuVisible = !menuVisible;
- }
-
- objectName: "settingsModal"
- title: I18n.tr("Settings", "settings window title")
- minimumSize: Qt.size(500, 400)
- implicitWidth: 900
- implicitHeight: screen ? Math.min(940, screen.height - 100) : 940
- color: Theme.surfaceContainer
- visible: false
-
- onIsCompactModeChanged: {
- enableAnimations = false;
- if (!isCompactMode) {
- menuVisible = true;
- }
- Qt.callLater(() => {
- enableAnimations = true;
- });
- }
-
- onVisibleChanged: {
- if (!visible) {
- closingModal();
- } else {
- Qt.callLater(() => {
- sidebar.focusSearch();
- });
- }
- }
-
- Loader {
- active: settingsModal.visible
- sourceComponent: Component {
- Ref {
- service: CupsService
- }
- }
- }
-
- LazyLoader {
- id: profileBrowserLoader
- active: false
-
- FileBrowserModal {
- id: profileBrowserItem
-
- allowStacking: true
- parentModal: settingsModal
- browserTitle: I18n.tr("Select Profile Image", "profile image file browser title")
- browserIcon: "person"
- browserType: "profile"
- showHiddenFiles: true
- fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif", "*.exr"]
- onFileSelected: path => {
- PortalService.setProfileImage(path);
- close();
- }
- onDialogClosed: () => {
- allowStacking = true;
- }
- }
- }
-
- LazyLoader {
- id: wallpaperBrowserLoader
- active: false
-
- FileBrowserModal {
- id: wallpaperBrowserItem
-
- allowStacking: true
- parentModal: settingsModal
- browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title")
- browserIcon: "wallpaper"
- browserType: "wallpaper"
- showHiddenFiles: true
- fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif", "*.exr"]
- onFileSelected: path => {
- SessionData.setWallpaper(path);
- close();
- }
- onDialogClosed: () => {
- allowStacking = true;
- }
- }
- }
-
- FocusScope {
- id: contentFocusScope
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- anchors.fill: parent
- focus: true
-
- Column {
- anchors.fill: parent
- spacing: 0
-
- Item {
- width: parent.width
- height: 48
- z: 10
-
- MouseArea {
- anchors.fill: parent
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- Rectangle {
- anchors.fill: parent
- color: Theme.surfaceContainer
- opacity: 0.5
- }
-
- Row {
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingL
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankActionButton {
- visible: settingsModal.isCompactMode
- circular: false
- iconName: "menu"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- onClicked: () => {
- settingsModal.toggleMenu();
- }
- }
-
- DankIcon {
- name: "settings"
- size: Theme.iconSize
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Settings")
- font.pixelSize: Theme.fontSizeXLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Row {
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.top: parent.top
- anchors.topMargin: Theme.spacingM
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported
- circular: false
- iconName: settingsModal.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- circular: false
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: settingsModal.hide()
- }
- }
- }
-
- Rectangle {
- id: readOnlyBanner
-
- property bool showBanner: (SettingsData._isReadOnly && SettingsData._hasUnsavedChanges) || (SessionData._isReadOnly && SessionData._hasUnsavedChanges)
-
- width: parent.width
- height: showBanner ? bannerContent.implicitHeight + Theme.spacingM * 2 : 0
- color: Theme.surfaceContainerHigh
- visible: showBanner
- clip: true
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Row {
- id: bannerContent
-
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Theme.spacingL
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingM
-
- DankIcon {
- name: "info"
- size: Theme.iconSize
- color: Theme.warning
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- id: bannerText
-
- text: I18n.tr("Settings are read-only. Changes will not persist.", "read-only settings warning for NixOS home-manager users")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- width: Math.max(100, parent.width - (copySettingsButton.visible ? copySettingsButton.width + Theme.spacingM : 0) - (copySessionButton.visible ? copySessionButton.width + Theme.spacingM : 0) - Theme.spacingM * 2 - Theme.iconSize)
- wrapMode: Text.WordWrap
- }
-
- DankButton {
- id: copySettingsButton
-
- visible: SettingsData._isReadOnly && SettingsData._hasUnsavedChanges
- text: "settings.json"
- iconName: "content_copy"
- backgroundColor: Theme.primary
- textColor: Theme.primaryText
- buttonHeight: 32
- horizontalPadding: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- onClicked: {
- Quickshell.execDetached(["dms", "cl", "copy", SettingsData.getCurrentSettingsJson()]);
- ToastService.showInfo(I18n.tr("Copied to clipboard"));
- }
- }
-
- DankButton {
- id: copySessionButton
-
- visible: SessionData._isReadOnly && SessionData._hasUnsavedChanges
- text: "session.json"
- iconName: "content_copy"
- backgroundColor: Theme.primary
- textColor: Theme.primaryText
- buttonHeight: 32
- horizontalPadding: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- onClicked: {
- Quickshell.execDetached(["dms", "cl", "copy", SessionData.getCurrentSessionJson()]);
- ToastService.showInfo(I18n.tr("Copied to clipboard"));
- }
- }
- }
- }
-
- Item {
- width: parent.width
- height: parent.height - 48 - readOnlyBanner.height
- clip: true
-
- SettingsSidebar {
- id: sidebar
-
- anchors.left: parent.left
- width: settingsModal.isCompactMode ? parent.width : sidebar.implicitWidth
- visible: settingsModal.isCompactMode ? settingsModal.menuVisible : true
- parentModal: settingsModal
- currentIndex: settingsModal.currentTabIndex
- onTabChangeRequested: tabIndex => {
- settingsModal.currentTabIndex = tabIndex;
- if (settingsModal.isCompactMode) {
- settingsModal.enableAnimations = true;
- settingsModal.menuVisible = false;
- }
- }
- }
-
- Item {
- anchors.left: settingsModal.isCompactMode ? (settingsModal.menuVisible ? sidebar.right : parent.left) : sidebar.right
- anchors.right: parent.right
- height: parent.height
- clip: true
-
- SettingsContent {
- id: content
-
- anchors.fill: parent
- parentModal: settingsModal
- currentIndex: settingsModal.currentTabIndex
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: settingsModal
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml
deleted file mode 100644
index 092881c..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml
+++ /dev/null
@@ -1,1023 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Modals.Settings
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- property int currentIndex: 0
- property var parentModal: null
-
- signal tabChangeRequested(int tabIndex)
- property string _expandedIds: ","
- property string _collapsedIds: ","
- property string _autoExpandedIds: ","
- property bool searchActive: searchField.text.length > 0
- property int searchSelectedIndex: 0
- property int keyboardHighlightIndex: -1
-
- function focusSearch() {
- searchField.forceActiveFocus();
- }
-
- function highlightNext() {
- var flatItems = getFlatNavigableItems();
- if (flatItems.length === 0)
- return;
- var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex);
- if (currentPos === -1) {
- currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
- }
- var nextPos = (currentPos + 1) % flatItems.length;
- keyboardHighlightIndex = flatItems[nextPos].tabIndex;
- autoExpandForTab(keyboardHighlightIndex);
- }
-
- function highlightPrevious() {
- var flatItems = getFlatNavigableItems();
- if (flatItems.length === 0)
- return;
- var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex);
- if (currentPos === -1) {
- currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
- }
- var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
- keyboardHighlightIndex = flatItems[prevPos].tabIndex;
- autoExpandForTab(keyboardHighlightIndex);
- }
-
- function selectHighlighted() {
- if (keyboardHighlightIndex < 0)
- return;
- var oldIndex = currentIndex;
- var newIndex = keyboardHighlightIndex;
- tabChangeRequested(newIndex);
- autoCollapseIfNeeded(oldIndex, newIndex);
- keyboardHighlightIndex = -1;
- Qt.callLater(searchField.forceActiveFocus);
- }
-
- readonly property var categoryStructure: [
- {
- "id": "personalization",
- "text": I18n.tr("Personalization"),
- "icon": "palette",
- "children": [
- {
- "id": "wallpaper",
- "text": I18n.tr("Wallpaper"),
- "icon": "wallpaper",
- "tabIndex": 0
- },
- {
- "id": "theme",
- "text": I18n.tr("Theme & Colors"),
- "icon": "format_paint",
- "tabIndex": 10
- },
- {
- "id": "typography",
- "text": I18n.tr("Typography & Motion"),
- "icon": "text_fields",
- "tabIndex": 14
- },
- {
- "id": "time_weather",
- "text": I18n.tr("Time & Weather"),
- "icon": "schedule",
- "tabIndex": 1
- },
- {
- "id": "sounds",
- "text": I18n.tr("Sounds"),
- "icon": "volume_up",
- "tabIndex": 15,
- "soundsOnly": true
- }
- ]
- },
- {
- "id": "dankbar",
- "text": I18n.tr("Dank Bar"),
- "icon": "toolbar",
- "children": [
- {
- "id": "dankbar_settings",
- "text": I18n.tr("Settings"),
- "icon": "tune",
- "tabIndex": 3
- },
- {
- "id": "dankbar_widgets",
- "text": I18n.tr("Widgets"),
- "icon": "widgets",
- "tabIndex": 22
- }
- ]
- },
- {
- "id": "workspaces_widgets",
- "text": I18n.tr("Workspaces & Widgets"),
- "icon": "dashboard",
- "collapsedByDefault": true,
- "children": [
- {
- "id": "workspaces",
- "text": I18n.tr("Workspaces"),
- "icon": "view_module",
- "tabIndex": 4
- },
- {
- "id": "media_player",
- "text": I18n.tr("Media Player"),
- "icon": "music_note",
- "tabIndex": 16
- },
- {
- "id": "notifications",
- "text": I18n.tr("Notifications"),
- "icon": "notifications",
- "tabIndex": 17
- },
- {
- "id": "osd",
- "text": I18n.tr("On-screen Displays"),
- "icon": "tune",
- "tabIndex": 18
- },
- {
- "id": "running_apps",
- "text": I18n.tr("Running Apps"),
- "icon": "app_registration",
- "tabIndex": 19,
- "hyprlandNiriOnly": true
- },
- {
- "id": "updater",
- "text": I18n.tr("System Updater"),
- "icon": "refresh",
- "tabIndex": 20
- },
- {
- "id": "desktop_widgets",
- "text": I18n.tr("Desktop Widgets"),
- "icon": "widgets",
- "tabIndex": 27
- }
- ]
- },
- {
- "id": "dock_launcher",
- "text": I18n.tr("Dock & Launcher"),
- "icon": "apps",
- "collapsedByDefault": true,
- "children": [
- {
- "id": "dock",
- "text": I18n.tr("Dock"),
- "icon": "dock_to_bottom",
- "tabIndex": 5
- },
- {
- "id": "launcher",
- "text": I18n.tr("Launcher"),
- "icon": "grid_view",
- "tabIndex": 9
- }
- ]
- },
- {
- "id": "keybinds",
- "text": I18n.tr("Keyboard Shortcuts"),
- "icon": "keyboard",
- "tabIndex": 2,
- "shortcutsOnly": true
- },
- {
- "id": "displays",
- "text": I18n.tr("Displays"),
- "icon": "monitor",
- "collapsedByDefault": true,
- "children": [
- {
- "id": "display_config",
- "text": I18n.tr("Configuration"),
- "icon": "display_settings",
- "tabIndex": 24
- },
- {
- "id": "display_gamma",
- "text": I18n.tr("Gamma Control"),
- "icon": "brightness_6",
- "tabIndex": 25
- },
- {
- "id": "display_widgets",
- "text": I18n.tr("Widgets", "settings_displays"),
- "icon": "widgets",
- "tabIndex": 26
- }
- ]
- },
- {
- "id": "network",
- "text": I18n.tr("Network"),
- "icon": "wifi",
- "tabIndex": 7,
- "dmsOnly": true
- },
- {
- "id": "system",
- "text": I18n.tr("System"),
- "icon": "memory",
- "collapsedByDefault": true,
- "children": [
- {
- "id": "audio",
- "text": I18n.tr("Audio"),
- "icon": "headphones",
- "tabIndex": 29
- },
- {
- "id": "locale",
- "text": I18n.tr("Locale"),
- "icon": "language",
- "tabIndex": 30
- },
- {
- "id": "clipboard",
- "text": I18n.tr("Clipboard"),
- "icon": "content_paste",
- "tabIndex": 23,
- "clipboardOnly": true
- },
- {
- "id": "printers",
- "text": I18n.tr("Printers"),
- "icon": "print",
- "tabIndex": 8,
- "cupsOnly": true
- },
- {
- "id": "multiplexers",
- "text": I18n.tr("Multiplexers"),
- "icon": "terminal",
- "tabIndex": 32
- },
- {
- "id": "window_rules",
- "text": I18n.tr("Window Rules"),
- "icon": "select_window",
- "tabIndex": 28,
- "niriOnly": true
- }
- ]
- },
- {
- "id": "power_security",
- "text": I18n.tr("Power & Security"),
- "icon": "security",
- "collapsedByDefault": true,
- "children": [
- {
- "id": "lock_screen",
- "text": I18n.tr("Lock Screen"),
- "icon": "lock",
- "tabIndex": 11
- },
- {
- "id": "greeter",
- "text": I18n.tr("Greeter"),
- "icon": "login",
- "tabIndex": 31
- },
- {
- "id": "power_sleep",
- "text": I18n.tr("Power & Sleep"),
- "icon": "power_settings_new",
- "tabIndex": 21
- }
- ]
- },
- {
- "id": "plugins",
- "text": I18n.tr("Plugins"),
- "icon": "extension",
- "tabIndex": 12
- },
- {
- "id": "separator",
- "separator": true
- },
- {
- "id": "about",
- "text": I18n.tr("About"),
- "icon": "info",
- "tabIndex": 13
- }
- ]
-
- function isItemVisible(item) {
- if (item.dmsOnly && NetworkService.usingLegacy)
- return false;
- if (item.cupsOnly && !CupsService.cupsAvailable)
- return false;
- if (item.shortcutsOnly && !KeybindsService.available)
- return false;
- if (item.soundsOnly && !AudioService.soundsAvailable)
- return false;
- if (item.hyprlandNiriOnly && !CompositorService.isNiri && !CompositorService.isHyprland)
- return false;
- if (item.niriOnly && !CompositorService.isNiri)
- return false;
- if (item.clipboardOnly && (!DMSService.isConnected || DMSService.apiVersion < 23))
- return false;
- return true;
- }
-
- function hasVisibleChildren(category) {
- if (!category.children)
- return false;
- return category.children.some(child => isItemVisible(child));
- }
-
- function isCategoryVisible(category) {
- if (category.separator)
- return true;
- if (!isItemVisible(category))
- return false;
- if (category.children && !hasVisibleChildren(category))
- return false;
- return true;
- }
-
- function _setExpanded(id, expanded) {
- var marker = "," + id + ",";
- if (expanded) {
- if (_expandedIds.indexOf(marker) < 0)
- _expandedIds = _expandedIds + id + ",";
- _collapsedIds = _collapsedIds.replace(marker, ",");
- } else {
- _expandedIds = _expandedIds.replace(marker, ",");
- if (_collapsedIds.indexOf(marker) < 0)
- _collapsedIds = _collapsedIds + id + ",";
- }
- SessionData.setSettingsSidebarState(_expandedIds, _collapsedIds);
- }
-
- function _setAutoExpanded(id, value) {
- var marker = "," + id + ",";
- if (value) {
- if (_autoExpandedIds.indexOf(marker) < 0)
- _autoExpandedIds = _autoExpandedIds + id + ",";
- } else {
- _autoExpandedIds = _autoExpandedIds.replace(marker, ",");
- }
- }
-
- function _isAutoExpanded(id) {
- return _autoExpandedIds.indexOf("," + id + ",") >= 0;
- }
-
- function toggleCategory(categoryId) {
- _setExpanded(categoryId, !isCategoryExpanded(categoryId));
- _setAutoExpanded(categoryId, false);
- }
-
- function isCategoryExpanded(categoryId) {
- if (_collapsedIds.indexOf("," + categoryId + ",") >= 0)
- return false;
- if (_expandedIds.indexOf("," + categoryId + ",") >= 0)
- return true;
- var category = categoryStructure.find(cat => cat.id === categoryId);
- if (category && category.collapsedByDefault)
- return false;
- return true;
- }
-
- function isChildActive(category) {
- if (!category.children)
- return false;
- return category.children.some(child => child.tabIndex === currentIndex);
- }
-
- function findParentCategory(tabIndex) {
- for (var i = 0; i < categoryStructure.length; i++) {
- var cat = categoryStructure[i];
- if (cat.children) {
- for (var j = 0; j < cat.children.length; j++) {
- if (cat.children[j].tabIndex === tabIndex) {
- return cat;
- }
- }
- }
- }
- return null;
- }
-
- function autoExpandForTab(tabIndex) {
- var parent = findParentCategory(tabIndex);
- if (!parent)
- return;
-
- if (!isCategoryExpanded(parent.id)) {
- _setExpanded(parent.id, true);
- _setAutoExpanded(parent.id, true);
- }
- }
-
- function autoCollapseIfNeeded(oldTabIndex, newTabIndex) {
- var oldParent = findParentCategory(oldTabIndex);
- var newParent = findParentCategory(newTabIndex);
-
- if (oldParent && oldParent !== newParent && _isAutoExpanded(oldParent.id)) {
- _setExpanded(oldParent.id, false);
- _setAutoExpanded(oldParent.id, false);
- }
- }
-
- function navigateNext() {
- var flatItems = getFlatNavigableItems();
- var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
- var oldIndex = currentIndex;
- var newIndex;
- if (currentPos === -1) {
- newIndex = flatItems[0]?.tabIndex ?? 0;
- } else {
- var nextPos = (currentPos + 1) % flatItems.length;
- newIndex = flatItems[nextPos].tabIndex;
- }
- tabChangeRequested(newIndex);
- autoCollapseIfNeeded(oldIndex, newIndex);
- autoExpandForTab(newIndex);
- }
-
- function navigatePrevious() {
- var flatItems = getFlatNavigableItems();
- var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
- var oldIndex = currentIndex;
- var newIndex;
- if (currentPos === -1) {
- newIndex = flatItems[0]?.tabIndex ?? 0;
- } else {
- var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
- newIndex = flatItems[prevPos].tabIndex;
- }
- tabChangeRequested(newIndex);
- autoCollapseIfNeeded(oldIndex, newIndex);
- autoExpandForTab(newIndex);
- }
-
- function getFlatNavigableItems() {
- var items = [];
- for (var i = 0; i < categoryStructure.length; i++) {
- var cat = categoryStructure[i];
- if (cat.separator || !isCategoryVisible(cat))
- continue;
-
- if (cat.tabIndex !== undefined && !cat.children) {
- items.push(cat);
- }
-
- if (cat.children) {
- for (var j = 0; j < cat.children.length; j++) {
- var child = cat.children[j];
- if (isItemVisible(child)) {
- items.push(child);
- }
- }
- }
- }
- return items;
- }
-
- function resolveTabIndex(name: string): int {
- if (!name)
- return -1;
-
- var normalized = name.toLowerCase().replace(/[_\-\s]/g, "");
-
- for (var i = 0; i < categoryStructure.length; i++) {
- var cat = categoryStructure[i];
- if (cat.separator)
- continue;
-
- var catId = (cat.id || "").toLowerCase().replace(/[_\-\s]/g, "");
- if (catId === normalized) {
- if (cat.tabIndex !== undefined)
- return cat.tabIndex;
- if (cat.children && cat.children.length > 0)
- return cat.children[0].tabIndex;
- }
-
- if (cat.children) {
- for (var j = 0; j < cat.children.length; j++) {
- var child = cat.children[j];
- var childId = (child.id || "").toLowerCase().replace(/[_\-\s]/g, "");
- if (childId === normalized)
- return child.tabIndex;
- }
- }
- }
- return -1;
- }
-
- property real __maxTextWidth: Math.max(__m1.advanceWidth, __m2.advanceWidth, __m3.advanceWidth, __m4.advanceWidth, __m5.advanceWidth, __m6.advanceWidth)
- property real __calculatedWidth: Math.max(270, __maxTextWidth + Theme.iconSize * 2 + Theme.spacingM * 4 + Theme.spacingS * 2)
-
- implicitWidth: __calculatedWidth
- width: __calculatedWidth
- height: parent.height
- color: Theme.surfaceContainer
- radius: Theme.cornerRadius
-
- Component.onCompleted: {
- root._expandedIds = SessionData.settingsSidebarExpandedIds;
- root._collapsedIds = SessionData.settingsSidebarCollapsedIds;
- }
-
- StyledTextMetrics {
- id: __m1
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Workspaces & Widgets")
- }
- StyledTextMetrics {
- id: __m2
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Typography & Motion")
- }
- StyledTextMetrics {
- id: __m3
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Keyboard Shortcuts")
- }
- StyledTextMetrics {
- id: __m4
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Power & Security")
- }
- StyledTextMetrics {
- id: __m5
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Dock & Launcher")
- }
- StyledTextMetrics {
- id: __m6
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- text: I18n.tr("Personalization")
- }
-
- function selectSearchResult(result) {
- if (!result)
- return;
- if (result.section) {
- SettingsSearchService.navigateToSection(result.section);
- }
- var oldIndex = root.currentIndex;
- tabChangeRequested(result.tabIndex);
- autoCollapseIfNeeded(oldIndex, result.tabIndex);
- autoExpandForTab(result.tabIndex);
- searchField.text = "";
- SettingsSearchService.clear();
- searchSelectedIndex = 0;
- keyboardHighlightIndex = -1;
- Qt.callLater(searchField.forceActiveFocus);
- }
-
- function navigateSearchResults(delta) {
- if (SettingsSearchService.results.length === 0)
- return;
- searchSelectedIndex = Math.max(0, Math.min(searchSelectedIndex + delta, SettingsSearchService.results.length - 1));
- }
-
- DankFlickable {
- anchors.fill: parent
- clip: true
- contentHeight: sidebarColumn.height
-
- Column {
- id: sidebarColumn
- width: parent.width
- leftPadding: Theme.spacingS
- rightPadding: Theme.spacingS
- bottomPadding: Theme.spacingL
- topPadding: Theme.spacingM + 2
- spacing: 2
-
- ProfileSection {
- width: parent.width - parent.leftPadding - parent.rightPadding
- parentModal: root.parentModal
- }
-
- Rectangle {
- width: parent.width - parent.leftPadding - parent.rightPadding
- height: 1
- color: Theme.outline
- opacity: 0.2
- }
-
- Item {
- width: parent.width - parent.leftPadding - parent.rightPadding
- height: Theme.spacingXS
- }
-
- DankTextField {
- id: searchField
- width: parent.width - parent.leftPadding - parent.rightPadding
- placeholderText: I18n.tr("Search...")
- normalBorderColor: Theme.outlineMedium
- focusedBorderColor: Theme.primary
- leftIconName: "search"
- leftIconSize: Theme.iconSize - 4
- showClearButton: text.length > 0
- usePopupTransparency: false
- onTextChanged: {
- SettingsSearchService.search(text);
- root.searchSelectedIndex = 0;
- }
- keyForwardTargets: [keyHandler]
-
- Item {
- id: keyHandler
- function navNext() {
- if (root.searchActive) {
- root.navigateSearchResults(1);
- } else {
- root.highlightNext();
- }
- }
- function navPrev() {
- if (root.searchActive) {
- root.navigateSearchResults(-1);
- } else {
- root.highlightPrevious();
- }
- }
- function navSelect() {
- if (root.searchActive && SettingsSearchService.results.length > 0) {
- root.selectSearchResult(SettingsSearchService.results[root.searchSelectedIndex]);
- } else if (root.keyboardHighlightIndex >= 0) {
- root.selectHighlighted();
- }
- }
- Keys.onDownPressed: event => {
- navNext();
- event.accepted = true;
- }
- Keys.onUpPressed: event => {
- navPrev();
- event.accepted = true;
- }
- Keys.onTabPressed: event => {
- navNext();
- event.accepted = true;
- }
- Keys.onBacktabPressed: event => {
- navPrev();
- event.accepted = true;
- }
- Keys.onReturnPressed: event => {
- navSelect();
- event.accepted = true;
- }
- Keys.onEscapePressed: event => {
- if (root.searchActive) {
- searchField.text = "";
- SettingsSearchService.clear();
- } else {
- root.keyboardHighlightIndex = -1;
- }
- event.accepted = true;
- }
- }
- }
-
- Column {
- id: searchResultsColumn
- width: parent.width - parent.leftPadding - parent.rightPadding
- spacing: 2
- visible: root.searchActive
-
- Item {
- width: parent.width
- height: Theme.spacingS
- }
-
- Repeater {
- model: ScriptModel {
- values: SettingsSearchService.results
- }
-
- Rectangle {
- id: resultDelegate
- required property int index
- required property var modelData
-
- width: searchResultsColumn.width
- height: resultContent.height + Theme.spacingM * 2
- radius: Theme.cornerRadius
- color: {
- if (root.searchSelectedIndex === index)
- return Theme.buttonBg;
- if (resultMouseArea.containsMouse)
- return Theme.surfaceHover;
- return "transparent";
- }
-
- DankRipple {
- id: resultRipple
- rippleColor: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
- cornerRadius: resultDelegate.radius
- }
-
- Row {
- id: resultContent
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: resultDelegate.modelData.icon || "settings"
- size: Theme.iconSize - 2
- color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Column {
- width: parent.width - Theme.iconSize - Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: 2
-
- StyledText {
- text: resultDelegate.modelData.label
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
- width: parent.width
- wrapMode: Text.Wrap
- horizontalAlignment: Text.AlignLeft
- }
-
- StyledText {
- text: resultDelegate.modelData.category
- font.pixelSize: Theme.fontSizeSmall - 1
- color: root.searchSelectedIndex === resultDelegate.index ? Theme.withAlpha(Theme.buttonText, 0.7) : Theme.surfaceVariantText
- width: parent.width
- wrapMode: Text.Wrap
- horizontalAlignment: Text.AlignLeft
- }
- }
- }
-
- MouseArea {
- id: resultMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => resultRipple.trigger(mouse.x, mouse.y)
- onClicked: root.selectSearchResult(resultDelegate.modelData)
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
-
- StyledText {
- width: parent.width
- text: I18n.tr("No matches")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- horizontalAlignment: Text.AlignHCenter
- visible: searchField.text.length > 0 && SettingsSearchService.results.length === 0
- topPadding: Theme.spacingM
- }
- }
-
- Item {
- width: parent.width - parent.leftPadding - parent.rightPadding
- height: Theme.spacingXS
- visible: !root.searchActive
- }
-
- Repeater {
- model: root.categoryStructure
-
- delegate: Column {
- id: categoryDelegate
- required property int index
- required property var modelData
-
- width: parent.width - parent.leftPadding - parent.rightPadding
- visible: !root.searchActive && root.isCategoryVisible(modelData)
- spacing: 2
-
- Rectangle {
- width: parent.width
- height: 1
- color: Theme.outline
- opacity: 0.15
- visible: categoryDelegate.modelData.separator === true
- }
-
- Item {
- width: parent.width
- height: Theme.spacingS
- visible: categoryDelegate.modelData.separator === true
- }
-
- Rectangle {
- id: categoryRow
- width: parent.width
- height: Math.max(Theme.iconSize, Theme.fontSizeMedium) + Theme.spacingS * 2
- radius: Theme.cornerRadius
- visible: categoryDelegate.modelData.separator !== true
-
- readonly property bool hasTab: categoryDelegate.modelData.tabIndex !== undefined && !categoryDelegate.modelData.children
- readonly property bool isActive: hasTab && root.currentIndex === categoryDelegate.modelData.tabIndex
- readonly property bool isHighlighted: hasTab && root.keyboardHighlightIndex === categoryDelegate.modelData.tabIndex
-
- color: {
- if (isActive)
- return Theme.buttonBg;
- if (isHighlighted)
- return Theme.buttonHover;
- if (categoryMouseArea.containsMouse)
- return Theme.surfaceHover;
- return "transparent";
- }
-
- DankRipple {
- id: categoryRipple
- rippleColor: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
- cornerRadius: categoryRow.radius
- }
-
- Row {
- id: categoryRowContent
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: categoryDelegate.modelData.icon || ""
- size: Theme.iconSize - 2
- color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: categoryDelegate.modelData.text || ""
- font.pixelSize: Theme.fontSizeMedium
- font.weight: (categoryRow.isActive || root.isChildActive(categoryDelegate.modelData)) ? Font.Medium : Font.Normal
- color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- DankIcon {
- id: expandIcon
- name: root.isCategoryExpanded(categoryDelegate.modelData.id) ? "expand_less" : "expand_more"
- size: Theme.iconSize - 4
- color: Theme.surfaceVariantText
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- visible: categoryDelegate.modelData.children !== undefined && categoryDelegate.modelData.children.length > 0
- }
-
- MouseArea {
- id: categoryMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => categoryRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- root.keyboardHighlightIndex = -1;
- if (categoryDelegate.modelData.children) {
- root.toggleCategory(categoryDelegate.modelData.id);
- } else if (categoryDelegate.modelData.tabIndex !== undefined) {
- root.tabChangeRequested(categoryDelegate.modelData.tabIndex);
- }
- Qt.callLater(searchField.forceActiveFocus);
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- Column {
- id: childrenColumn
- width: parent.width
- spacing: 2
- visible: categoryDelegate.modelData.children !== undefined && root.isCategoryExpanded(categoryDelegate.modelData.id)
- clip: true
-
- Repeater {
- model: categoryDelegate.modelData.children || []
-
- delegate: Rectangle {
- id: childDelegate
- required property int index
- required property var modelData
-
- readonly property bool isActive: root.currentIndex === modelData.tabIndex
- readonly property bool isHighlighted: root.keyboardHighlightIndex === modelData.tabIndex
-
- width: childrenColumn.width
- height: Math.max(Theme.iconSize - 4, Theme.fontSizeSmall + 1) + Theme.spacingS * 2
- radius: Theme.cornerRadius
- visible: root.isItemVisible(modelData)
- color: {
- if (isActive)
- return Theme.buttonBg;
- if (isHighlighted)
- return Theme.buttonHover;
- if (childMouseArea.containsMouse)
- return Theme.surfaceHover;
- return "transparent";
- }
-
- DankRipple {
- id: childRipple
- rippleColor: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
- cornerRadius: childDelegate.radius
- }
-
- Row {
- id: childRowContent
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingL + Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: childDelegate.modelData.icon || ""
- size: Theme.iconSize - 4
- color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceVariantText
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: childDelegate.modelData.text || ""
- font.pixelSize: Theme.fontSizeSmall + 1
- font.weight: childDelegate.isActive ? Font.Medium : Font.Normal
- color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- MouseArea {
- id: childMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: mouse => childRipple.trigger(mouse.x, mouse.y)
- onClicked: {
- root.keyboardHighlightIndex = -1;
- root.tabChangeRequested(childDelegate.modelData.tabIndex);
- Qt.callLater(searchField.forceActiveFocus);
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml
deleted file mode 100644
index 92689f2..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml
+++ /dev/null
@@ -1,764 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- property string wifiPasswordSSID: ""
- property string wifiPasswordInput: ""
- property string wifiUsernameInput: ""
- property bool requiresEnterprise: false
- property bool isHiddenNetwork: false
-
- property string wifiAnonymousIdentityInput: ""
- property string wifiDomainInput: ""
-
- property bool isPromptMode: false
- property string promptToken: ""
- property string promptReason: ""
- property var promptFields: []
- property string promptSetting: ""
-
- property bool isVpnPrompt: false
- property string connectionName: ""
- property string vpnServiceType: ""
- property string connectionType: ""
- property var fieldsInfo: []
- property var secretValues: ({})
-
- readonly property bool showUsernameField: requiresEnterprise && !isVpnPrompt && fieldsInfo.length === 0
- readonly property bool showPasswordField: fieldsInfo.length === 0
- readonly property bool showAnonField: requiresEnterprise && !isVpnPrompt
- readonly property bool showDomainField: requiresEnterprise && !isVpnPrompt
- readonly property bool showSavePasswordCheckbox: (isVpnPrompt || fieldsInfo.length > 0) && promptReason !== "pkcs11"
-
- readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
- readonly property int inputFieldWithSpacing: inputFieldHeight + Theme.spacingM
- readonly property int checkboxRowHeight: Theme.fontSizeMedium + Theme.spacingS
- readonly property int headerHeight: Theme.fontSizeLarge + Theme.fontSizeMedium + Theme.spacingM * 2
- readonly property int buttonRowHeight: 36 + Theme.spacingM
-
- property int calculatedHeight: {
- let h = headerHeight + buttonRowHeight + Theme.spacingL * 2;
- h += fieldsInfo.length * inputFieldWithSpacing;
- if (isHiddenNetwork)
- h += inputFieldWithSpacing;
- if (showUsernameField)
- h += inputFieldWithSpacing;
- if (showPasswordField)
- h += inputFieldWithSpacing;
- if (showAnonField)
- h += inputFieldWithSpacing;
- if (showDomainField)
- h += inputFieldWithSpacing;
- if (showSavePasswordCheckbox)
- h += checkboxRowHeight;
- return h;
- }
-
- function focusFirstField() {
- if (fieldsInfo.length > 0) {
- if (dynamicFieldsRepeater.count > 0) {
- const firstItem = dynamicFieldsRepeater.itemAt(0);
- if (firstItem)
- firstItem.children[0].forceActiveFocus();
- }
- return;
- }
- if (isHiddenNetwork) {
- ssidInput.forceActiveFocus();
- return;
- }
- if (requiresEnterprise && !isVpnPrompt) {
- usernameInput.forceActiveFocus();
- return;
- }
- passwordInput.forceActiveFocus();
- }
-
- function show(ssid) {
- wifiPasswordSSID = ssid;
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
- isPromptMode = false;
- isHiddenNetwork = false;
- promptToken = "";
- promptReason = "";
- promptFields = [];
- promptSetting = "";
- isVpnPrompt = false;
- connectionName = "";
- vpnServiceType = "";
- connectionType = "";
- fieldsInfo = [];
- secretValues = {};
-
- const network = NetworkService.wifiNetworks.find(n => n.ssid === ssid);
- requiresEnterprise = network?.enterprise || false;
-
- visible = true;
- Qt.callLater(focusFirstField);
- }
-
- function showHidden() {
- wifiPasswordSSID = "";
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
- isPromptMode = false;
- isHiddenNetwork = true;
- promptToken = "";
- promptReason = "";
- promptFields = [];
- promptSetting = "";
- isVpnPrompt = false;
- connectionName = "";
- vpnServiceType = "";
- connectionType = "";
- fieldsInfo = [];
- secretValues = {};
- requiresEnterprise = false;
-
- visible = true;
- Qt.callLater(focusFirstField);
- }
-
- function showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fInfo) {
- isPromptMode = true;
- promptToken = token;
- promptReason = reason;
- promptFields = fields || [];
- promptSetting = setting || "802-11-wireless-security";
- connectionType = connType || "802-11-wireless";
- connectionName = connName || ssid || "";
- vpnServiceType = vpnService || "";
- fieldsInfo = fInfo || [];
- secretValues = {};
-
- isVpnPrompt = (connectionType === "vpn" || connectionType === "wireguard");
- wifiPasswordSSID = isVpnPrompt ? connectionName : ssid;
-
- requiresEnterprise = setting === "802-1x";
-
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
-
- visible = true;
- Qt.callLater(() => {
- if (reason === "wrong-password" && fieldsInfo.length === 0) {
- passwordInput.text = "";
- }
- focusFirstField();
- });
- }
-
- function hide() {
- visible = false;
- }
-
- function getFieldLabel(fieldName) {
- switch (fieldName) {
- case "username":
- case "identity":
- return I18n.tr("Username");
- case "password":
- return I18n.tr("Password");
- case "cert-pass":
- case "certpass":
- return I18n.tr("Certificate Password");
- case "private-key-password":
- return I18n.tr("Private Key Password");
- case "pin":
- case "key_pass":
- return I18n.tr("PIN");
- case "psk":
- return I18n.tr("Password");
- case "anonymous-identity":
- return I18n.tr("Anonymous Identity");
- default:
- return fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/-/g, " ");
- }
- }
-
- function submitCredentialsAndClose() {
- if (fieldsInfo.length > 0) {
- NetworkService.submitCredentials(promptToken, secretValues, savePasswordCheckbox.checked);
- hide();
- secretValues = {};
- return;
- }
-
- if (isPromptMode) {
- const secrets = {};
- if (isVpnPrompt) {
- if (passwordInput.text)
- secrets["password"] = passwordInput.text;
- } else if (promptSetting === "802-11-wireless-security") {
- secrets["psk"] = passwordInput.text;
- } else if (promptSetting === "802-1x") {
- if (usernameInput.text)
- secrets["identity"] = usernameInput.text;
- if (passwordInput.text)
- secrets["password"] = passwordInput.text;
- if (wifiAnonymousIdentityInput)
- secrets["anonymous-identity"] = wifiAnonymousIdentityInput;
- }
- NetworkService.submitCredentials(promptToken, secrets, savePasswordCheckbox.checked);
- } else {
- const ssid = isHiddenNetwork ? ssidInput.text : wifiPasswordSSID;
- const username = requiresEnterprise ? usernameInput.text : "";
- NetworkService.connectToWifi(ssid, passwordInput.text, username, wifiAnonymousIdentityInput, wifiDomainInput, isHiddenNetwork);
- }
-
- hide();
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
- passwordInput.text = "";
- if (requiresEnterprise)
- usernameInput.text = "";
- if (isHiddenNetwork)
- ssidInput.text = "";
- }
-
- function clearAndClose() {
- if (isPromptMode)
- NetworkService.cancelCredentials(promptToken);
- hide();
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
- secretValues = {};
- }
-
- objectName: "wifiPasswordModal"
- title: {
- if (promptReason === "pkcs11")
- return I18n.tr("Smartcard PIN");
- if (isVpnPrompt)
- return I18n.tr("VPN Password");
- if (isHiddenNetwork)
- return I18n.tr("Hidden Network");
- return I18n.tr("Wi-Fi Password");
- }
- minimumSize: Qt.size(420, calculatedHeight)
- maximumSize: Qt.size(420, calculatedHeight)
- color: Theme.surfaceContainer
- visible: false
-
- onVisibleChanged: {
- if (visible) {
- Qt.callLater(focusFirstField);
- return;
- }
- wifiPasswordInput = "";
- wifiUsernameInput = "";
- wifiAnonymousIdentityInput = "";
- wifiDomainInput = "";
- secretValues = {};
- passwordInput.text = "";
- usernameInput.text = "";
- anonInput.text = "";
- domainMatchInput.text = "";
- ssidInput.text = "";
- for (var i = 0; i < dynamicFieldsRepeater.count; i++) {
- const item = dynamicFieldsRepeater.itemAt(i);
- if (item?.children[0])
- item.children[0].text = "";
- }
- }
-
- Connections {
- target: NetworkService
-
- function onPasswordDialogShouldReopenChanged() {
- if (!NetworkService.passwordDialogShouldReopen || NetworkService.connectingSSID === "")
- return;
- wifiPasswordSSID = NetworkService.connectingSSID;
- wifiPasswordInput = "";
- visible = true;
- NetworkService.passwordDialogShouldReopen = false;
- }
- }
-
- FocusScope {
- id: contentFocusScope
-
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- clearAndClose();
- event.accepted = true;
- }
-
- Column {
- id: contentCol
- anchors.centerIn: parent
- width: parent.width - Theme.spacingL * 2
- spacing: Theme.spacingM
-
- Item {
- width: contentCol.width
- height: Math.max(headerCol.height, buttonRow.height)
-
- MouseArea {
- anchors.left: parent.left
- anchors.right: buttonRow.left
- anchors.rightMargin: Theme.spacingM
- height: headerCol.height
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
-
- Column {
- id: headerCol
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: {
- if (promptReason === "pkcs11")
- return I18n.tr("Smartcard Authentication");
- if (isVpnPrompt)
- return I18n.tr("Connect to VPN");
- if (isHiddenNetwork)
- return I18n.tr("Connect to Hidden Network");
- return I18n.tr("Connect to Wi-Fi");
- }
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- Column {
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: {
- if (promptReason === "pkcs11")
- return I18n.tr("Enter PIN for ") + wifiPasswordSSID;
- if (fieldsInfo.length > 0)
- return I18n.tr("Enter credentials for ") + wifiPasswordSSID;
- if (isVpnPrompt)
- return I18n.tr("Enter password for ") + wifiPasswordSSID;
- if (isHiddenNetwork)
- return I18n.tr("Enter network name and password");
- const prefix = requiresEnterprise ? I18n.tr("Enter credentials for ") : I18n.tr("Enter password for ");
- return prefix + wifiPasswordSSID;
- }
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- elide: Text.ElideRight
- }
-
- StyledText {
- visible: isPromptMode && promptReason === "wrong-password"
- text: I18n.tr("Incorrect password")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.error
- width: parent.width
- }
- }
- }
- }
-
- Row {
- id: buttonRow
- anchors.right: parent.right
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported && windowControls.canMaximize
- iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: clearAndClose()
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: ssidInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: ssidInput.activeFocus ? 2 : 1
- visible: isHiddenNetwork
-
- MouseArea {
- anchors.fill: parent
- onClicked: ssidInput.forceActiveFocus()
- }
-
- DankTextField {
- id: ssidInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- placeholderText: I18n.tr("Network Name (SSID)")
- backgroundColor: "transparent"
- enabled: root.visible
- keyNavigationTab: passwordInput
- onAccepted: passwordInput.forceActiveFocus()
- }
- }
-
- Repeater {
- id: dynamicFieldsRepeater
- model: fieldsInfo
-
- delegate: Rectangle {
- required property var modelData
- required property int index
-
- width: contentCol.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: fieldInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: fieldInput.activeFocus ? 2 : 1
-
- DankTextField {
- id: fieldInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- showPasswordToggle: modelData.isSecret
- echoMode: modelData.isSecret && !passwordVisible ? TextInput.Password : TextInput.Normal
- placeholderText: getFieldLabel(modelData.name)
- backgroundColor: "transparent"
- enabled: root.visible
-
- Keys.onTabPressed: event => {
- if (index < fieldsInfo.length - 1) {
- const nextItem = dynamicFieldsRepeater.itemAt(index + 1);
- if (nextItem)
- nextItem.children[0].forceActiveFocus();
- } else {
- const firstItem = dynamicFieldsRepeater.itemAt(0);
- if (firstItem)
- firstItem.children[0].forceActiveFocus();
- }
- event.accepted = true;
- }
-
- Keys.onBacktabPressed: event => {
- if (index > 0) {
- const prevItem = dynamicFieldsRepeater.itemAt(index - 1);
- if (prevItem)
- prevItem.children[0].forceActiveFocus();
- } else {
- const lastItem = dynamicFieldsRepeater.itemAt(fieldsInfo.length - 1);
- if (lastItem)
- lastItem.children[0].forceActiveFocus();
- }
- event.accepted = true;
- }
-
- onTextEdited: {
- let updated = Object.assign({}, root.secretValues);
- updated[modelData.name] = text;
- root.secretValues = updated;
- }
-
- onAccepted: {
- if (index < fieldsInfo.length - 1) {
- const nextItem = dynamicFieldsRepeater.itemAt(index + 1);
- if (nextItem)
- nextItem.children[0].forceActiveFocus();
- return;
- }
- submitCredentialsAndClose();
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: usernameInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: usernameInput.activeFocus ? 2 : 1
- visible: showUsernameField
-
- MouseArea {
- anchors.fill: parent
- onClicked: usernameInput.forceActiveFocus()
- }
-
- DankTextField {
- id: usernameInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: wifiUsernameInput
- placeholderText: I18n.tr("Username")
- backgroundColor: "transparent"
- enabled: root.visible
- keyNavigationTab: passwordInput
- keyNavigationBacktab: domainMatchInput
- onTextEdited: wifiUsernameInput = text
- onAccepted: passwordInput.forceActiveFocus()
- }
- }
-
- Rectangle {
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: passwordInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: passwordInput.activeFocus ? 2 : 1
- visible: showPasswordField
-
- MouseArea {
- anchors.fill: parent
- onClicked: passwordInput.forceActiveFocus()
- }
-
- DankTextField {
- id: passwordInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: wifiPasswordInput
- showPasswordToggle: true
- echoMode: passwordVisible ? TextInput.Normal : TextInput.Password
- placeholderText: (requiresEnterprise && !isVpnPrompt) ? I18n.tr("Password") : ""
- backgroundColor: "transparent"
- enabled: root.visible
- keyNavigationTab: (requiresEnterprise && !isVpnPrompt) ? anonInput : null
- keyNavigationBacktab: (requiresEnterprise && !isVpnPrompt) ? usernameInput : null
- onTextEdited: wifiPasswordInput = text
- onAccepted: {
- if (requiresEnterprise && !isVpnPrompt) {
- anonInput.forceActiveFocus();
- return;
- }
- submitCredentialsAndClose();
- }
- }
- }
-
- Rectangle {
- visible: showAnonField
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: anonInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: anonInput.activeFocus ? 2 : 1
-
- MouseArea {
- anchors.fill: parent
- onClicked: anonInput.forceActiveFocus()
- }
-
- DankTextField {
- id: anonInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: wifiAnonymousIdentityInput
- placeholderText: I18n.tr("Anonymous Identity (optional)")
- backgroundColor: "transparent"
- enabled: root.visible
- keyNavigationTab: domainMatchInput
- keyNavigationBacktab: passwordInput
- onTextEdited: wifiAnonymousIdentityInput = text
- onAccepted: domainMatchInput.forceActiveFocus()
- }
- }
-
- Rectangle {
- visible: showDomainField
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: domainMatchInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: domainMatchInput.activeFocus ? 2 : 1
-
- MouseArea {
- anchors.fill: parent
- onClicked: domainMatchInput.forceActiveFocus()
- }
-
- DankTextField {
- id: domainMatchInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- text: wifiDomainInput
- placeholderText: I18n.tr("Domain (optional)")
- backgroundColor: "transparent"
- enabled: root.visible
- keyNavigationTab: usernameInput
- keyNavigationBacktab: anonInput
- onTextEdited: wifiDomainInput = text
- onAccepted: submitCredentialsAndClose()
- }
- }
-
- Row {
- spacing: Theme.spacingS
- visible: showSavePasswordCheckbox
-
- Rectangle {
- id: savePasswordCheckbox
-
- property bool checked: !isVpnPrompt
-
- width: 20
- height: 20
- radius: 4
- color: checked ? Theme.primary : "transparent"
- border.color: checked ? Theme.primary : Theme.outlineButton
- border.width: 2
-
- DankIcon {
- anchors.centerIn: parent
- name: "check"
- size: 12
- color: Theme.background
- visible: parent.checked
- }
-
- MouseArea {
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: savePasswordCheckbox.checked = !savePasswordCheckbox.checked
- }
- }
-
- StyledText {
- text: I18n.tr("Save password")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Item {
- width: parent.width
- height: 40
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: cancelText
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: clearAndClose()
- }
- }
-
- Rectangle {
- width: Math.max(80, connectText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: connectArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
- enabled: {
- if (fieldsInfo.length > 0) {
- for (var i = 0; i < fieldsInfo.length; i++) {
- if (!fieldsInfo[i].isSecret)
- continue;
- const fieldName = fieldsInfo[i].name;
- if (!secretValues[fieldName] || secretValues[fieldName].length === 0)
- return false;
- }
- return true;
- }
- if (isVpnPrompt)
- return passwordInput.text.length > 0;
- if (isHiddenNetwork)
- return ssidInput.text.length > 0;
- return requiresEnterprise ? (usernameInput.text.length > 0 && passwordInput.text.length > 0) : passwordInput.text.length > 0;
- }
- opacity: enabled ? 1 : 0.5
-
- StyledText {
- id: connectText
- anchors.centerIn: parent
- text: I18n.tr("Connect")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: connectArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- enabled: parent.enabled
- onClicked: submitCredentialsAndClose()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml
deleted file mode 100644
index 06ffab7..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml
+++ /dev/null
@@ -1,170 +0,0 @@
-import QtQuick
-import QtQuick.Layouts
-import QtQuick.Effects
-import Quickshell
-import Quickshell.Io
-import qs.Modals.Common
-import qs.Modals.FileBrowser
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-DankModal {
- id: root
- visible: false
- layerNamespace: "dms:wifi-qrcode"
-
- property bool disablePopupTransparency: true
- property string wifiSSID: ""
- property string themedQrCodePath: ""
- property string normalQrCodePath: ""
- modalWidth: 420
- modalHeight: 480
- onBackgroundClicked: hide()
- onOpened: {
- Qt.callLater(() => {
- modalFocusScope.forceActiveFocus();
- contentLoader.item.wifiSSID = wifiSSID;
- contentLoader.item.themedQrCodePath = themedQrCodePath;
- contentLoader.item.saveBrowserLoader = saveBrowserLoader;
- });
- }
-
- function show(ssid) {
- wifiSSID = ssid;
- fetchNetworkQRCode(ssid);
- }
-
- function hide() {
- if (themedQrCodePath !== "") {
- deleteQRCodeFile(themedQrCodePath);
- }
- if (normalQrCodePath !== "") {
- deleteQRCodeFile(normalQrCodePath);
- }
- close();
- }
-
- function fetchNetworkQRCode(ssid) {
- // TODO: Add loading UI?
-
- DMSService.sendRequest("network.qrcode", {
- ssid: ssid
- }, response => {
- if (response.error) {
- ToastService.showError("Failed to fetch network QR code: ", JSON.stringify(response.error));
- } else if (response.result) {
- themedQrCodePath = response.result[0];
- normalQrCodePath = response.result[1];
- open();
- }
- });
- }
-
- function deleteQRCodeFile(path) {
- DMSService.sendRequest("network.delete-qrcode", {
- path: path
- }, response => {
- if (response.error) {
- ToastService.showError(`Failed to remove QR code at ${path}: `, JSON.stringify(response.error));
- }
- })
- }
-
- LazyLoader {
- id: saveBrowserLoader
- active: false
-
- FileBrowserSurfaceModal {
- id: saveBrowser
-
- browserTitle: I18n.tr("Save QR Code")
- browserIcon: "qr_code"
- browserType: "default"
- fileExtensions: ["*.png"]
- allowStacking: true
- saveMode: true
- defaultFileName: `${root.wifiSSID ?? "wifi-qrcode"}.png`
- onFileSelected: path => {
- const cleanPath = decodeURI(path.toString().replace(/^file:\/\//, ''));
- const fileName = cleanPath.split('/').pop();
- const fileUrl = "file://" + cleanPath;
-
- copyQrCodeProcess.exec(["cp", root.normalQrCodePath, cleanPath, "-f"])
- }
-
- Process {
- id: copyQrCodeProcess
- stdout: StdioCollector {
- onStreamFinished: {
- saveBrowser.close();
- }
- }
- }
- }
- }
-
- content: Component {
- Item {
- id: theItem
- property alias themedQrCodePath: qrCodeImg.source
- property var saveBrowserLoader: null
- property string wifiSSID: ""
- anchors.fill: parent
-
- Column {
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- spacing: Theme.spacingL
-
- RowLayout {
- id: modalTitle
- width: parent.width
-
- StyledText {
- text: I18n.tr("WiFi QR code for ") + theItem.wifiSSID
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Bold
- Layout.alignment: Qt.AlignLeft
- }
-
- DankActionButton {
- iconName: "save"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: {
- saveBrowserLoader.active = true;
- if (saveBrowserLoader.item) {
- saveBrowserLoader.item.open();
- }
- }
- Layout.alignment: Qt.AlignRight
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.hide()
- Layout.alignment: Qt.AlignRight
- }
- }
-
- Image {
- id: qrCodeImg
- height: parent.height - parent.spacing - modalTitle.height
- width: height
- anchors.horizontalCenter: parent.horizontalCenter
-
- MultiEffect {
- source: qrCodeImg
- anchors.fill: source
- colorization: 1.0
- colorizationColor: Theme.primary
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml
deleted file mode 100644
index 6c9583a..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml
+++ /dev/null
@@ -1,1184 +0,0 @@
-import QtQuick
-import Quickshell
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- property var editingRule: null
- property bool isEditMode: editingRule !== null
- property bool isNiri: CompositorService.isNiri
- property bool isHyprland: CompositorService.isHyprland
- property bool submitting: false
- property var targetWindow: null
-
- signal ruleSubmitted
-
- readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
- readonly property int sectionSpacing: Theme.spacingL
-
- objectName: "windowRuleModal"
- title: isEditMode ? I18n.tr("Edit Window Rule") : I18n.tr("Create Window Rule")
- minimumSize: Qt.size(500, 600)
- maximumSize: Qt.size(500, 600)
- color: Theme.surfaceContainer
- visible: false
-
- function resetForm() {
- nameInput.text = "";
- appIdInput.text = "";
- titleInput.text = "";
- opacityEnabled.checked = false;
- opacitySlider.value = 100;
- floatingToggle.checked = false;
- maximizedToggle.checked = false;
- maximizedToEdgesToggle.checked = false;
- fullscreenToggle.checked = false;
- openFocusedToggle.checked = false;
- outputInput.text = "";
- workspaceInput.text = "";
- columnWidthInput.text = "";
- windowHeightInput.text = "";
- vrrToggle.checked = false;
- blockOutDropdown.currentValue = "";
- columnDisplayDropdown.currentValue = "";
- scrollFactorEnabled.checked = false;
- scrollFactorSlider.value = 100;
- cornerRadiusEnabled.checked = false;
- cornerRadiusSlider.value = 12;
- clipToGeometryToggle.checked = false;
- tiledStateToggle.checked = false;
- drawBorderBgToggle.checked = false;
- minWidthInput.text = "";
- maxWidthInput.text = "";
- minHeightInput.text = "";
- maxHeightInput.text = "";
- tileToggle.checked = false;
- noFocusToggle.checked = false;
- noBorderToggle.checked = false;
- noShadowToggle.checked = false;
- noDimToggle.checked = false;
- noBlurToggle.checked = false;
- noAnimToggle.checked = false;
- noRoundingToggle.checked = false;
- pinToggle.checked = false;
- opaqueToggle.checked = false;
- sizeInput.text = "";
- moveInput.text = "";
- monitorInput.text = "";
- hyprWorkspaceInput.text = "";
- }
-
- function show(window) {
- editingRule = null;
- targetWindow = window || null;
- resetForm();
- if (targetWindow) {
- nameInput.text = targetWindow.appId || "";
- appIdInput.text = targetWindow.appId ? "^" + targetWindow.appId + "$" : "";
- }
- visible = true;
- Qt.callLater(() => nameInput.forceActiveFocus());
- }
-
- function showEdit(rule) {
- if (!rule) {
- show();
- return;
- }
- editingRule = rule;
- resetForm();
-
- nameInput.text = rule.name || "";
- const match = rule.matchCriteria || {};
- appIdInput.text = match.appId || "";
- titleInput.text = match.title || "";
-
- const actions = rule.actions || {};
- const hasOpacity = actions.opacity !== undefined && actions.opacity !== null;
- opacityEnabled.checked = hasOpacity;
- opacitySlider.value = hasOpacity ? Math.round(actions.opacity * 100) : 100;
-
- floatingToggle.checked = actions.openFloating || false;
- maximizedToggle.checked = actions.openMaximized || false;
- maximizedToEdgesToggle.checked = actions.openMaximizedToEdges || false;
- fullscreenToggle.checked = actions.openFullscreen || false;
-
- openFocusedToggle.checked = actions.openFocused || false;
-
- outputInput.text = actions.openOnOutput || "";
- workspaceInput.text = actions.openOnWorkspace || "";
- columnWidthInput.text = actions.defaultColumnWidth || "";
- windowHeightInput.text = actions.defaultWindowHeight || "";
- vrrToggle.checked = actions.variableRefreshRate || false;
-
- blockOutDropdown.currentValue = actions.blockOutFrom || "";
- columnDisplayDropdown.currentValue = actions.defaultColumnDisplay || "";
-
- const hasScrollFactor = actions.scrollFactor !== undefined && actions.scrollFactor !== null;
- scrollFactorEnabled.checked = hasScrollFactor;
- scrollFactorSlider.value = hasScrollFactor ? Math.round(actions.scrollFactor * 100) : 100;
-
- const hasCornerRadius = actions.cornerRadius !== undefined && actions.cornerRadius !== null;
- cornerRadiusEnabled.checked = hasCornerRadius;
- cornerRadiusSlider.value = hasCornerRadius ? actions.cornerRadius : 12;
-
- clipToGeometryToggle.checked = actions.clipToGeometry || false;
- tiledStateToggle.checked = actions.tiledState || false;
-
- drawBorderBgToggle.checked = actions.drawBorderWithBackground || false;
-
- minWidthInput.text = actions.minWidth !== undefined ? String(actions.minWidth) : "";
- maxWidthInput.text = actions.maxWidth !== undefined ? String(actions.maxWidth) : "";
- minHeightInput.text = actions.minHeight !== undefined ? String(actions.minHeight) : "";
- maxHeightInput.text = actions.maxHeight !== undefined ? String(actions.maxHeight) : "";
-
- tileToggle.checked = actions.tile || false;
- noFocusToggle.checked = actions.nofocus || false;
- noBorderToggle.checked = actions.noborder || false;
- noShadowToggle.checked = actions.noshadow || false;
- noDimToggle.checked = actions.nodim || false;
- noBlurToggle.checked = actions.noblur || false;
- noAnimToggle.checked = actions.noanim || false;
- noRoundingToggle.checked = actions.norounding || false;
- pinToggle.checked = actions.pin || false;
- opaqueToggle.checked = actions.opaque || false;
- sizeInput.text = actions.size || "";
- moveInput.text = actions.move || "";
- monitorInput.text = actions.monitor || "";
- hyprWorkspaceInput.text = actions.workspace || "";
-
- visible = true;
- Qt.callLater(() => nameInput.forceActiveFocus());
- }
-
- function hide() {
- visible = false;
- editingRule = null;
- targetWindow = null;
- }
-
- function submitAndClose() {
- const matchCriteria = {};
- if (appIdInput.text.trim())
- matchCriteria.appId = appIdInput.text.trim();
- if (titleInput.text.trim())
- matchCriteria.title = titleInput.text.trim();
-
- const actions = {};
-
- if (opacityEnabled.checked)
- actions.opacity = opacitySlider.value / 100;
- if (floatingToggle.checked)
- actions.openFloating = true;
- if (maximizedToggle.checked)
- actions.openMaximized = true;
- if (maximizedToEdgesToggle.checked && isNiri)
- actions.openMaximizedToEdges = true;
- if (fullscreenToggle.checked)
- actions.openFullscreen = true;
- if (openFocusedToggle.checked && isNiri)
- actions.openFocused = true;
- if (outputInput.text.trim())
- actions.openOnOutput = outputInput.text.trim();
- if (workspaceInput.text.trim())
- actions.openOnWorkspace = workspaceInput.text.trim();
- if (columnWidthInput.text.trim() && isNiri)
- actions.defaultColumnWidth = columnWidthInput.text.trim();
- if (windowHeightInput.text.trim() && isNiri)
- actions.defaultWindowHeight = windowHeightInput.text.trim();
- if (vrrToggle.checked && isNiri)
- actions.variableRefreshRate = true;
- if (blockOutDropdown.currentValue && isNiri)
- actions.blockOutFrom = blockOutDropdown.currentValue;
- if (columnDisplayDropdown.currentValue && isNiri)
- actions.defaultColumnDisplay = columnDisplayDropdown.currentValue;
- if (scrollFactorEnabled.checked && isNiri)
- actions.scrollFactor = scrollFactorSlider.value / 100;
- if (cornerRadiusEnabled.checked)
- actions.cornerRadius = cornerRadiusSlider.value;
- if (clipToGeometryToggle.checked && isNiri)
- actions.clipToGeometry = true;
- if (tiledStateToggle.checked && isNiri)
- actions.tiledState = true;
- if (drawBorderBgToggle.checked && isNiri)
- actions.drawBorderWithBackground = true;
-
- const minW = parseInt(minWidthInput.text);
- const maxW = parseInt(maxWidthInput.text);
- const minH = parseInt(minHeightInput.text);
- const maxH = parseInt(maxHeightInput.text);
- if (!isNaN(minW))
- actions.minWidth = minW;
- if (!isNaN(maxW))
- actions.maxWidth = maxW;
- if (!isNaN(minH))
- actions.minHeight = minH;
- if (!isNaN(maxH))
- actions.maxHeight = maxH;
-
- if (isHyprland) {
- if (tileToggle.checked)
- actions.tile = true;
- if (noFocusToggle.checked)
- actions.nofocus = true;
- if (noBorderToggle.checked)
- actions.noborder = true;
- if (noShadowToggle.checked)
- actions.noshadow = true;
- if (noDimToggle.checked)
- actions.nodim = true;
- if (noBlurToggle.checked)
- actions.noblur = true;
- if (noAnimToggle.checked)
- actions.noanim = true;
- if (noRoundingToggle.checked)
- actions.norounding = true;
- if (pinToggle.checked)
- actions.pin = true;
- if (opaqueToggle.checked)
- actions.opaque = true;
- if (sizeInput.text.trim())
- actions.size = sizeInput.text.trim();
- if (moveInput.text.trim())
- actions.move = moveInput.text.trim();
- if (monitorInput.text.trim())
- actions.monitor = monitorInput.text.trim();
- if (hyprWorkspaceInput.text.trim())
- actions.workspace = hyprWorkspaceInput.text.trim();
- }
-
- const name = nameInput.text.trim() || matchCriteria.appId || I18n.tr("Rule");
- const compositor = CompositorService.compositor;
-
- const ruleData = {
- name: name,
- matchCriteria: matchCriteria,
- actions: actions,
- enabled: true
- };
-
- submitting = true;
-
- const shouldValidate = CompositorService.isNiri;
-
- if (isEditMode) {
- const ruleJson = JSON.stringify(ruleData);
- Proc.runCommand("update-windowrule", ["dms", "config", "windowrules", "update", compositor, editingRule.id, ruleJson], (output, exitCode) => {
- root.submitting = false;
- if (exitCode !== 0)
- return;
- if (shouldValidate)
- NiriService.validate();
- root.ruleSubmitted();
- root.hide();
- });
- } else {
- const ruleJson = JSON.stringify(ruleData);
- Proc.runCommand("add-windowrule", ["dms", "config", "windowrules", "add", compositor, ruleJson], (output, exitCode) => {
- root.submitting = false;
- if (exitCode !== 0)
- return;
- if (shouldValidate)
- NiriService.validate();
- root.ruleSubmitted();
- root.hide();
- });
- }
- }
-
- onVisibleChanged: {
- if (!visible) {
- editingRule = null;
- targetWindow = null;
- }
- }
-
- component SectionHeader: StyledText {
- property string title
- text: title
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.primary
- topPadding: Theme.spacingM
- bottomPadding: Theme.spacingXS
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- component CheckboxRow: Row {
- property alias checked: checkbox.checked
- property alias label: labelText.text
- property bool indeterminate: false
- spacing: Theme.spacingS
- height: 24
-
- Rectangle {
- id: checkbox
- property bool checked: false
- width: 20
- height: 20
- radius: 4
- color: parent.indeterminate ? Theme.surfaceVariant : (checked ? Theme.primary : "transparent")
- border.color: parent.indeterminate ? Theme.outlineButton : (checked ? Theme.primary : Theme.outlineButton)
- border.width: 2
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- anchors.centerIn: parent
- name: parent.parent.indeterminate ? "remove" : "check"
- size: 12
- color: parent.parent.indeterminate ? Theme.surfaceVariantText : Theme.background
- visible: parent.checked || parent.parent.indeterminate
- }
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (parent.parent.indeterminate) {
- parent.parent.indeterminate = false;
- parent.checked = true;
- } else {
- parent.checked = !parent.checked;
- }
- }
- }
- }
-
- StyledText {
- id: labelText
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceText
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- component InputField: Rectangle {
- id: inputFieldRect
- default property alias contentData: inputFieldRect.data
- property bool hasFocus: false
- width: parent.width
- height: root.inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: hasFocus ? Theme.primary : Theme.outlineStrong
- border.width: hasFocus ? 2 : 1
- }
-
- FocusScope {
- anchors.fill: parent
- focus: true
-
- LayoutMirroring.enabled: I18n.isRtl
- LayoutMirroring.childrenInherit: true
-
- Keys.onEscapePressed: event => {
- hide();
- event.accepted = true;
- }
-
- Item {
- id: header
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- height: Math.max(headerCol.height, closeBtn.height)
-
- MouseArea {
- anchors.left: parent.left
- anchors.right: closeBtn.left
- anchors.rightMargin: Theme.spacingM
- height: headerCol.height
- onPressed: windowControls.tryStartMove()
-
- Column {
- id: headerCol
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: root.isEditMode ? I18n.tr("Edit Window Rule") : I18n.tr("New Window Rule")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- StyledText {
- text: I18n.tr("Configure match criteria and actions")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
- }
- }
-
- DankActionButton {
- id: closeBtn
- anchors.right: parent.right
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: hide()
- }
- }
-
- DankFlickable {
- id: flickable
- anchors.top: header.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: footer.top
- anchors.margins: Theme.spacingL
- anchors.topMargin: Theme.spacingM
- contentWidth: width
- contentHeight: contentCol.implicitHeight
- clip: true
-
- Column {
- id: contentCol
- width: flickable.width - Theme.spacingM
- spacing: Theme.spacingXS
-
- InputField {
- hasFocus: nameInput.activeFocus
- DankTextField {
- id: nameInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: I18n.tr("Rule Name")
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
-
- SectionHeader {
- title: I18n.tr("Match Criteria")
- }
-
- InputField {
- hasFocus: appIdInput.activeFocus
- DankTextField {
- id: appIdInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: isNiri ? I18n.tr("App ID regex (e.g. ^firefox$)") : I18n.tr("Class regex (e.g. ^firefox$)")
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingS
-
- InputField {
- width: addTitleBtn.visible ? parent.width - addTitleBtn.width - Theme.spacingS : parent.width
- hasFocus: titleInput.activeFocus
- DankTextField {
- id: titleInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: I18n.tr("Title regex (optional)")
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
-
- DankActionButton {
- id: addTitleBtn
- width: root.inputFieldHeight
- height: root.inputFieldHeight
- circular: false
- iconName: "add"
- iconSize: 16
- iconColor: Theme.surfaceVariantText
- visible: !root.isEditMode && !!root.targetWindow?.title
- tooltipText: I18n.tr("Add Title")
- tooltipSide: "left"
- onClicked: {
- if (!root.targetWindow?.title)
- return;
- titleInput.text = "^" + root.targetWindow.title + "$";
- }
- }
- }
-
- SectionHeader {
- title: I18n.tr("Window Opening")
- }
-
- Flow {
- width: parent.width
- spacing: Theme.spacingL
-
- CheckboxRow {
- id: floatingToggle
- label: I18n.tr("Float")
- }
- CheckboxRow {
- id: maximizedToggle
- label: I18n.tr("Maximize")
- }
- CheckboxRow {
- id: fullscreenToggle
- label: I18n.tr("Fullscreen")
- }
- CheckboxRow {
- id: maximizedToEdgesToggle
- label: I18n.tr("Max to Edges")
- visible: isNiri
- }
- CheckboxRow {
- id: openFocusedToggle
- label: I18n.tr("Focus")
- visible: isNiri
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: true
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Output")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: outputInput.activeFocus
- DankTextField {
- id: outputInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "HDMI-A-1"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Workspace")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: workspaceInput.activeFocus
- DankTextField {
- id: workspaceInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "chat"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: isNiri
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Column Width")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: columnWidthInput.activeFocus
- DankTextField {
- id: columnWidthInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "800"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Window Height")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: windowHeightInput.activeFocus
- DankTextField {
- id: windowHeightInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "600"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
- }
-
- SectionHeader {
- title: I18n.tr("Dynamic Properties")
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- CheckboxRow {
- id: opacityEnabled
- label: I18n.tr("Opacity")
- anchors.verticalCenter: parent.verticalCenter
- }
-
- DankSlider {
- id: opacitySlider
- width: parent.width - 100
- minimum: 10
- maximum: 100
- value: 100
- enabled: opacityEnabled.checked
- opacity: enabled ? 1 : 0.4
- }
- }
-
- Flow {
- width: parent.width
- spacing: Theme.spacingL
- visible: isNiri
-
- CheckboxRow {
- id: vrrToggle
- label: I18n.tr("VRR On-Demand")
- }
- CheckboxRow {
- id: clipToGeometryToggle
- label: I18n.tr("Clip to Geometry")
- }
- CheckboxRow {
- id: tiledStateToggle
- label: I18n.tr("Tiled State")
- }
- CheckboxRow {
- id: drawBorderBgToggle
- label: I18n.tr("Border with BG")
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: isNiri
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Block Out From")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- DankDropdown {
- id: blockOutDropdown
- width: parent.width
- dropdownWidth: parent.width
- compactMode: true
- options: ["", "screencast", "screen-capture"]
- emptyText: I18n.tr("None")
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Column Display")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- DankDropdown {
- id: columnDisplayDropdown
- width: parent.width
- dropdownWidth: parent.width
- compactMode: true
- options: ["", "tabbed"]
- emptyText: I18n.tr("Normal")
- }
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: isNiri
-
- CheckboxRow {
- id: scrollFactorEnabled
- label: I18n.tr("Scroll Factor")
- anchors.verticalCenter: parent.verticalCenter
- }
-
- DankSlider {
- id: scrollFactorSlider
- width: parent.width - 120
- minimum: 10
- maximum: 200
- value: 100
- enabled: scrollFactorEnabled.checked
- opacity: enabled ? 1 : 0.4
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- CheckboxRow {
- id: cornerRadiusEnabled
- label: I18n.tr("Corner Radius")
- anchors.verticalCenter: parent.verticalCenter
- }
-
- DankSlider {
- id: cornerRadiusSlider
- width: parent.width - 130
- minimum: 0
- maximum: 24
- value: 12
- enabled: cornerRadiusEnabled.checked
- opacity: enabled ? 1 : 0.4
- }
- }
-
- SectionHeader {
- title: I18n.tr("Size Constraints")
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
-
- Column {
- width: (parent.width - Theme.spacingM * 3) / 4
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Min W")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: minWidthInput.activeFocus
- DankTextField {
- id: minWidthInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "px"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM * 3) / 4
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Max W")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: maxWidthInput.activeFocus
- DankTextField {
- id: maxWidthInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "px"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM * 3) / 4
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Min H")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: minHeightInput.activeFocus
- DankTextField {
- id: minHeightInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "px"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM * 3) / 4
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Max H")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: maxHeightInput.activeFocus
- DankTextField {
- id: maxHeightInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "px"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
- }
-
- SectionHeader {
- title: I18n.tr("Hyprland Options")
- visible: isHyprland
- }
-
- Flow {
- width: parent.width
- spacing: Theme.spacingL
- visible: isHyprland
-
- CheckboxRow {
- id: tileToggle
- label: I18n.tr("Tile")
- }
- CheckboxRow {
- id: noFocusToggle
- label: I18n.tr("No Focus")
- }
- CheckboxRow {
- id: noBorderToggle
- label: I18n.tr("No Border")
- }
- CheckboxRow {
- id: noShadowToggle
- label: I18n.tr("No Shadow")
- }
- CheckboxRow {
- id: noDimToggle
- label: I18n.tr("No Dim")
- }
- CheckboxRow {
- id: noBlurToggle
- label: I18n.tr("No Blur")
- }
- CheckboxRow {
- id: noAnimToggle
- label: I18n.tr("No Anim")
- }
- CheckboxRow {
- id: noRoundingToggle
- label: I18n.tr("No Rounding")
- }
- CheckboxRow {
- id: pinToggle
- label: I18n.tr("Pin")
- }
- CheckboxRow {
- id: opaqueToggle
- label: I18n.tr("Opaque")
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: isHyprland
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Size")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: sizeInput.activeFocus
- DankTextField {
- id: sizeInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "800 600"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Move")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: moveInput.activeFocus
- DankTextField {
- id: moveInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "100 100"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingM
- visible: isHyprland
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Monitor")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: monitorInput.activeFocus
- DankTextField {
- id: monitorInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "DP-1"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
-
- Column {
- width: (parent.width - Theme.spacingM) / 2
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Workspace")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- horizontalAlignment: Text.AlignLeft
- }
-
- InputField {
- width: parent.width
- hasFocus: hyprWorkspaceInput.activeFocus
- DankTextField {
- id: hyprWorkspaceInput
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeSmall
- textColor: Theme.surfaceText
- placeholderText: "1"
- backgroundColor: "transparent"
- enabled: root.visible
- }
- }
- }
- }
-
- Item {
- width: 1
- height: Theme.spacingM
- }
- }
- }
-
- Item {
- id: footer
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: Theme.spacingL
- height: 44
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: cancelText
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: hide()
- }
- }
-
- Rectangle {
- width: Math.max(80, createText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: root.submitting ? Theme.surfaceVariant : (createArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary)
-
- StyledText {
- id: createText
- anchors.centerIn: parent
- text: root.submitting ? I18n.tr("Saving...") : (root.isEditMode ? I18n.tr("Update") : I18n.tr("Create"))
- font.pixelSize: Theme.fontSizeMedium
- color: root.submitting ? Theme.surfaceVariantText : Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: createArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: root.submitting ? Qt.ArrowCursor : Qt.PointingHandCursor
- enabled: !root.submitting
- onClicked: submitAndClose()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml
deleted file mode 100644
index 6519ac3..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml
+++ /dev/null
@@ -1,230 +0,0 @@
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-FloatingWindow {
- id: root
-
- property bool disablePopupTransparency: true
- readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
-
- objectName: "workspaceRenameModal"
- title: I18n.tr("Rename Workspace")
- minimumSize: Qt.size(400, 160)
- maximumSize: Qt.size(400, 160)
- color: Theme.surfaceContainer
- visible: false
-
- function show(name) {
- nameInput.text = name;
- visible = true;
- Qt.callLater(() => nameInput.forceActiveFocus());
- }
-
- function hide() {
- visible = false;
- }
-
- function submitAndClose() {
- renameWorkspace(nameInput.text);
- hide();
- }
-
- function renameWorkspace(name) {
- if (CompositorService.isNiri) {
- NiriService.renameWorkspace(name);
- } else if (CompositorService.isHyprland) {
- HyprlandService.renameWorkspace(name);
- } else {
- console.warn("WorkspaceRenameModal: rename not supported for this compositor");
- }
- }
-
- onVisibleChanged: {
- if (visible) {
- Qt.callLater(() => nameInput.forceActiveFocus());
- return;
- }
- nameInput.text = "";
- }
-
- FocusScope {
- id: contentFocusScope
-
- anchors.fill: parent
- focus: true
-
- Keys.onEscapePressed: event => {
- hide();
- event.accepted = true;
- }
-
- Column {
- id: contentCol
- anchors.centerIn: parent
- width: parent.width - Theme.spacingL * 2
- spacing: Theme.spacingM
-
- Item {
- width: contentCol.width
- height: Math.max(headerText.height, buttonRow.height)
-
- MouseArea {
- anchors.left: parent.left
- anchors.right: buttonRow.left
- anchors.rightMargin: Theme.spacingM
- height: parent.height
- onPressed: windowControls.tryStartMove()
- onDoubleClicked: windowControls.tryToggleMaximize()
- }
-
- StyledText {
- id: headerText
- text: I18n.tr("Enter a new name for this workspace")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- anchors.verticalCenter: parent.verticalCenter
- width: parent.width - buttonRow.width - Theme.spacingM
- }
-
- Row {
- id: buttonRow
- anchors.right: parent.right
- spacing: Theme.spacingXS
-
- DankActionButton {
- visible: windowControls.supported && windowControls.canMaximize
- iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: windowControls.tryToggleMaximize()
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: hide()
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: inputFieldHeight
- radius: Theme.cornerRadius
- color: Theme.surfaceHover
- border.color: nameInput.activeFocus ? Theme.primary : Theme.outlineStrong
- border.width: nameInput.activeFocus ? 2 : 1
-
- MouseArea {
- anchors.fill: parent
- onClicked: nameInput.forceActiveFocus()
- }
-
- DankTextField {
- id: nameInput
-
- anchors.fill: parent
- font.pixelSize: Theme.fontSizeMedium
- textColor: Theme.surfaceText
- placeholderText: I18n.tr("Workspace name")
- backgroundColor: "transparent"
- enabled: root.visible
- onAccepted: submitAndClose()
- }
- }
-
- Item {
- width: parent.width
- height: 40
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: cancelText
- anchors.centerIn: parent
- text: I18n.tr("Cancel")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: cancelArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: hide()
- }
- }
-
- Rectangle {
- width: Math.max(80, renameText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: renameArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- id: renameText
- anchors.centerIn: parent
- text: I18n.tr("Rename")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: renameArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: submitAndClose()
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
- }
-
- FloatingWindowControls {
- id: windowControls
- targetWindow: root
- }
-
- IpcHandler {
- target: "workspace-rename"
-
- function open(): string {
- const ws = NiriService.workspaces[NiriService.focusedWorkspaceId];
- show(ws?.name || "");
- return "WORKSPACE_RENAME_MODAL_OPENED";
- }
-
- function close(): string {
- hide();
- return "WORKSPACE_RENAME_MODAL_CLOSED";
- }
- }
-}