diff --git a/Common/AppUsageHistoryData.qml b/Common/AppUsageHistoryData.qml index 9b5fd280..1c65e0f8 100644 --- a/Common/AppUsageHistoryData.qml +++ b/Common/AppUsageHistoryData.qml @@ -12,9 +12,6 @@ Singleton { property var appUsageRanking: {} - readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation) - readonly property string _configDir: _configUrl.startsWith("file://") ? _configUrl.substring(7) : _configUrl - Component.onCompleted: { loadSettings(); } @@ -115,7 +112,7 @@ Singleton { FileView { id: settingsFile - path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/appusage.json" + path: StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/appusage.json" blockLoading: true blockWrites: true watchChanges: true diff --git a/Common/SessionData.qml b/Common/SessionData.qml index ade99341..32e89d42 100644 --- a/Common/SessionData.qml +++ b/Common/SessionData.qml @@ -17,9 +17,6 @@ Singleton { property bool doNotDisturb: false property var pinnedApps: [] - readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation) - readonly property string _configDir: _configUrl.startsWith("file://") ? _configUrl.substring(7) : _configUrl - Component.onCompleted: { loadSettings(); } @@ -115,7 +112,7 @@ Singleton { FileView { id: settingsFile - path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/session.json" + path: StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json" blockLoading: true blockWrites: true watchChanges: true diff --git a/Modules/AppDrawer/AppLauncher.qml b/Modules/AppDrawer/AppLauncher.qml index 1ffaf7a4..280508ab 100644 --- a/Modules/AppDrawer/AppLauncher.qml +++ b/Modules/AppDrawer/AppLauncher.qml @@ -29,7 +29,7 @@ Item { property var categoryIcons: categories.map((category) => { return AppSearchService.getCategoryIcon(category); }) - property var appUsageRanking: AppUsageHistoryData.appUsageRanking + property var appUsageRanking: AppUsageHistoryData.appUsageRanking || {} property alias model: filteredModel property var _watchApplications: AppSearchService.applications diff --git a/Modules/Dock/DockApps.qml b/Modules/Dock/DockApps.qml index a710f219..4d0b5f07 100644 --- a/Modules/Dock/DockApps.qml +++ b/Modules/Dock/DockApps.qml @@ -19,7 +19,7 @@ Item { function movePinnedApp(fromIndex, toIndex) { if (fromIndex === toIndex) return - var currentPinned = [...SessionData.pinnedApps] + var currentPinned = [...(SessionData.pinnedApps || [])] if (fromIndex < 0 || fromIndex >= currentPinned.length || toIndex < 0 || toIndex >= currentPinned.length) return var movedApp = currentPinned.splice(fromIndex, 1)[0] @@ -46,9 +46,10 @@ Item { var items = [] var runningApps = NiriService.getRunningAppIds() - var pinnedApps = [...SessionData.pinnedApps] + var pinnedApps = [...(SessionData.pinnedApps || [])] var addedApps = new Set() + pinnedApps.forEach(appId => { var lowerAppId = appId.toLowerCase() if (!addedApps.has(lowerAppId)) { @@ -64,28 +65,39 @@ Item { }) root.pinnedAppCount = pinnedApps.length var appUsageRanking = AppUsageHistoryData.appUsageRanking || {} - var allUnpinnedApps = [] - - for (var appId in appUsageRanking) { - var lowerAppId = appId.toLowerCase() - if (!addedApps.has(lowerAppId)) { - allUnpinnedApps.push({ - appId: appId, - lastUsed: appUsageRanking[appId].lastUsed || 0, - usageCount: appUsageRanking[appId].usageCount || 0 - }) - } - } - - allUnpinnedApps.sort((a, b) => b.lastUsed - a.lastUsed) var unpinnedApps = [] - var recentToAdd = Math.min(3, allUnpinnedApps.length) - for (var i = 0; i < recentToAdd; i++) { - var appId = allUnpinnedApps[i].appId + var unpinnedAppsSet = new Set() + + // First: Add ALL currently running apps that aren't pinned + runningApps.forEach(appId => { var lowerAppId = appId.toLowerCase() - unpinnedApps.push(appId) - addedApps.add(lowerAppId) + if (!addedApps.has(lowerAppId)) { + unpinnedApps.push(appId) + unpinnedAppsSet.add(lowerAppId) + } + }) + + // Then: Fill remaining slots up to 3 with recently used apps + var remainingSlots = Math.max(0, 3 - unpinnedApps.length) + if (remainingSlots > 0) { + // Sort recent apps by usage + var recentApps = [] + for (var appId in appUsageRanking) { + var lowerAppId = appId.toLowerCase() + if (!addedApps.has(lowerAppId) && !unpinnedAppsSet.has(lowerAppId)) { + recentApps.push({ + appId: appId, + lastUsed: appUsageRanking[appId].lastUsed || 0 + }) + } + } + recentApps.sort((a, b) => b.lastUsed - a.lastUsed) + + var recentToAdd = Math.min(remainingSlots, recentApps.length) + for (var i = 0; i < recentToAdd; i++) { + unpinnedApps.push(recentApps[i].appId) + } } if (pinnedApps.length > 0 && unpinnedApps.length > 0) { items.push({ diff --git a/Modules/Settings/LauncherTab.qml b/Modules/Settings/LauncherTab.qml index 23ac4473..4d721647 100644 --- a/Modules/Settings/LauncherTab.qml +++ b/Modules/Settings/LauncherTab.qml @@ -262,8 +262,8 @@ ScrollView { property var rankedAppsModel: { var apps = []; - for (var appId in AppUsageHistoryData.appUsageRanking) { - var appData = AppUsageHistoryData.appUsageRanking[appId]; + for (var appId in (AppUsageHistoryData.appUsageRanking || {})) { + var appData = (AppUsageHistoryData.appUsageRanking || {})[appId]; apps.push({ "id": appId, "name": appData.name, @@ -320,8 +320,7 @@ ScrollView { hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) anchors.verticalCenter: parent.verticalCenter onClicked: { - AppUsageHistoryData.appUsageRanking = { - }; + AppUsageHistoryData.appUsageRanking = {}; SettingsData.saveSettings(); } } @@ -438,7 +437,7 @@ ScrollView { hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) onClicked: { var currentRanking = Object.assign({ - }, AppUsageHistoryData.appUsageRanking); + }, AppUsageHistoryData.appUsageRanking || {}); delete currentRanking[modelData.id]; AppUsageHistoryData.appUsageRanking = currentRanking; SettingsData.saveSettings();