mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-30 16:32:50 -05:00
Compare commits
3 Commits
ab071e12aa
...
f762f9ae49
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f762f9ae49 | ||
|
|
4484f6bd61 | ||
|
|
0076c45496 |
@@ -62,6 +62,22 @@ Singleton {
|
||||
property bool _hasUnsavedChanges: false
|
||||
property var _loadedSettingsSnapshot: null
|
||||
property var pluginSettings: ({})
|
||||
property var builtInPluginSettings: ({})
|
||||
|
||||
function getBuiltInPluginSetting(pluginId, key, defaultValue) {
|
||||
if (!builtInPluginSettings[pluginId])
|
||||
return defaultValue;
|
||||
return builtInPluginSettings[pluginId][key] !== undefined ? builtInPluginSettings[pluginId][key] : defaultValue;
|
||||
}
|
||||
|
||||
function setBuiltInPluginSetting(pluginId, key, value) {
|
||||
const updated = JSON.parse(JSON.stringify(builtInPluginSettings));
|
||||
if (!updated[pluginId])
|
||||
updated[pluginId] = {};
|
||||
updated[pluginId][key] = value;
|
||||
builtInPluginSettings = updated;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
property alias dankBarLeftWidgetsModel: leftWidgetsModel
|
||||
property alias dankBarCenterWidgetsModel: centerWidgetsModel
|
||||
|
||||
@@ -382,7 +382,9 @@ var SPEC = {
|
||||
desktopWidgetPositions: { def: {} },
|
||||
desktopWidgetGridSettings: { def: {} },
|
||||
|
||||
desktopWidgetInstances: { def: [] }
|
||||
desktopWidgetInstances: { def: [] },
|
||||
|
||||
builtInPluginSettings: { def: {} }
|
||||
};
|
||||
|
||||
function getValidKeys() {
|
||||
|
||||
@@ -606,6 +606,8 @@ Item {
|
||||
|
||||
active: false
|
||||
|
||||
Component.onCompleted: PopoutService.processListModalLoader = processListModalLoader
|
||||
|
||||
ProcessListModal {
|
||||
id: processListModal
|
||||
|
||||
@@ -658,6 +660,9 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onInstancesChanged: PopoutService.notepadSlideouts = instances
|
||||
Component.onCompleted: PopoutService.notepadSlideouts = instances
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
|
||||
@@ -22,11 +22,8 @@ DankModal {
|
||||
function resetContent() {
|
||||
if (!spotlightContent)
|
||||
return;
|
||||
if (spotlightContent.appLauncher) {
|
||||
spotlightContent.appLauncher.searchQuery = "";
|
||||
spotlightContent.appLauncher.selectedIndex = 0;
|
||||
spotlightContent.appLauncher.setCategory(I18n.tr("All"));
|
||||
}
|
||||
if (spotlightContent.appLauncher)
|
||||
spotlightContent.appLauncher.reset();
|
||||
if (spotlightContent.fileSearchController)
|
||||
spotlightContent.fileSearchController.reset();
|
||||
if (spotlightContent.resetScroll)
|
||||
|
||||
@@ -96,7 +96,11 @@ Item {
|
||||
_updatingFromTrigger = true;
|
||||
selectedCategory = triggerResult.pluginCategory;
|
||||
_updatingFromTrigger = false;
|
||||
if (triggerResult.isBuiltIn) {
|
||||
apps = AppSearchService.getBuiltInLauncherItems(triggerResult.pluginId, triggerResult.query);
|
||||
} else {
|
||||
apps = AppSearchService.getPluginItems(triggerResult.pluginCategory, triggerResult.query);
|
||||
}
|
||||
} else {
|
||||
if (_isTriggered) {
|
||||
_updatingFromTrigger = true;
|
||||
@@ -114,7 +118,11 @@ Item {
|
||||
const items = AppSearchService.getPluginItems(pluginCategory, "");
|
||||
emptyTriggerItems = emptyTriggerItems.concat(items);
|
||||
});
|
||||
// Add Core Apps
|
||||
const builtInEmptyTrigger = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger();
|
||||
builtInEmptyTrigger.forEach(pluginId => {
|
||||
const items = AppSearchService.getBuiltInLauncherItems(pluginId, "");
|
||||
emptyTriggerItems = emptyTriggerItems.concat(items);
|
||||
});
|
||||
const coreItems = AppSearchService.getCoreApps("");
|
||||
apps = AppSearchService.applications.concat(emptyTriggerItems).concat(coreItems);
|
||||
} else {
|
||||
@@ -133,6 +141,11 @@ Item {
|
||||
const items = AppSearchService.getPluginItems(pluginCategory, searchQuery);
|
||||
emptyTriggerItems = emptyTriggerItems.concat(items);
|
||||
});
|
||||
const builtInEmptyTrigger = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger();
|
||||
builtInEmptyTrigger.forEach(pluginId => {
|
||||
const items = AppSearchService.getBuiltInLauncherItems(pluginId, searchQuery);
|
||||
emptyTriggerItems = emptyTriggerItems.concat(items);
|
||||
});
|
||||
|
||||
const coreItems = AppSearchService.getCoreApps(searchQuery);
|
||||
apps = apps.concat(emptyTriggerItems).concat(coreItems);
|
||||
@@ -191,6 +204,7 @@ Item {
|
||||
"categories": app.categories || [],
|
||||
"isPlugin": isPluginItem,
|
||||
"isCore": app.isCore === true,
|
||||
"isBuiltInLauncher": app.isBuiltInLauncher === true,
|
||||
"appIndex": uniqueApps.length - 1
|
||||
});
|
||||
}
|
||||
@@ -240,13 +254,18 @@ Item {
|
||||
}
|
||||
|
||||
function launchApp(appData) {
|
||||
if (!appData || typeof appData.appIndex === "undefined" || appData.appIndex < 0 || appData.appIndex >= _uniqueApps.length) {
|
||||
if (!appData || typeof appData.appIndex === "undefined" || appData.appIndex < 0 || appData.appIndex >= _uniqueApps.length)
|
||||
return;
|
||||
}
|
||||
suppressUpdatesWhileLaunching = true;
|
||||
|
||||
const actualApp = _uniqueApps[appData.appIndex];
|
||||
|
||||
if (appData.isBuiltInLauncher) {
|
||||
AppSearchService.executeBuiltInLauncherItem(actualApp);
|
||||
appLaunched(appData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (appData.isCore) {
|
||||
AppSearchService.executeCoreApp(actualApp);
|
||||
appLaunched(appData);
|
||||
@@ -260,11 +279,20 @@ Item {
|
||||
appLaunched(appData);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
SessionService.launchDesktopEntry(actualApp);
|
||||
appLaunched(appData);
|
||||
AppUsageHistoryData.addAppUsage(actualApp);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
suppressUpdatesWhileLaunching = false;
|
||||
searchQuery = "";
|
||||
selectedIndex = 0;
|
||||
setCategory(I18n.tr("All"));
|
||||
updateFilteredModel();
|
||||
}
|
||||
|
||||
function setCategory(category) {
|
||||
@@ -320,42 +348,50 @@ Item {
|
||||
onTriggered: updateFilteredModel()
|
||||
}
|
||||
|
||||
// Plugin trigger system functions
|
||||
function checkPluginTriggers(query) {
|
||||
if (!query || typeof PluginService === "undefined") {
|
||||
if (!query)
|
||||
return { triggered: false, pluginCategory: "", query: "" };
|
||||
|
||||
const builtInTriggers = AppSearchService.getBuiltInLauncherTriggers();
|
||||
for (const trigger in builtInTriggers) {
|
||||
if (!query.startsWith(trigger))
|
||||
continue;
|
||||
const pluginId = builtInTriggers[trigger];
|
||||
const plugin = AppSearchService.builtInPlugins[pluginId];
|
||||
if (!plugin)
|
||||
continue;
|
||||
return {
|
||||
triggered: false,
|
||||
pluginCategory: "",
|
||||
query: ""
|
||||
triggered: true,
|
||||
pluginId: pluginId,
|
||||
pluginCategory: plugin.name,
|
||||
query: query.substring(trigger.length).trim(),
|
||||
trigger: trigger,
|
||||
isBuiltIn: true
|
||||
};
|
||||
}
|
||||
|
||||
const triggers = PluginService.getAllPluginTriggers();
|
||||
if (typeof PluginService === "undefined")
|
||||
return { triggered: false, pluginCategory: "", query: "" };
|
||||
|
||||
const triggers = PluginService.getAllPluginTriggers();
|
||||
for (const trigger in triggers) {
|
||||
if (query.startsWith(trigger)) {
|
||||
if (!query.startsWith(trigger))
|
||||
continue;
|
||||
const pluginId = triggers[trigger];
|
||||
const plugin = PluginService.getLauncherPlugin(pluginId);
|
||||
|
||||
if (plugin) {
|
||||
const remainingQuery = query.substring(trigger.length).trim();
|
||||
const result = {
|
||||
if (!plugin)
|
||||
continue;
|
||||
return {
|
||||
triggered: true,
|
||||
pluginId: pluginId,
|
||||
pluginCategory: plugin.name || pluginId,
|
||||
query: remainingQuery,
|
||||
trigger: trigger
|
||||
query: query.substring(trigger.length).trim(),
|
||||
trigger: trigger,
|
||||
isBuiltIn: false
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
triggered: false,
|
||||
pluginCategory: "",
|
||||
query: ""
|
||||
};
|
||||
return { triggered: false, pluginCategory: "", query: "" };
|
||||
}
|
||||
|
||||
function getPluginIdForItem(item) {
|
||||
|
||||
@@ -378,6 +378,90 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
id: builtInPluginsCard
|
||||
width: parent.width
|
||||
iconName: "extension"
|
||||
title: "DMS"
|
||||
settingKey: "builtInPlugins"
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Repeater {
|
||||
model: ["dms_settings", "dms_notepad", "dms_sysmon", "dms_settings_search"]
|
||||
|
||||
delegate: Rectangle {
|
||||
id: pluginDelegate
|
||||
required property string modelData
|
||||
required property int index
|
||||
readonly property var plugin: AppSearchService.builtInPlugins[modelData]
|
||||
|
||||
width: parent.width
|
||||
height: 56
|
||||
radius: Theme.cornerRadius
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.3)
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: pluginDelegate.plugin?.cornerIcon ?? "extension"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: pluginDelegate.plugin?.name ?? pluginDelegate.modelData
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: pluginDelegate.plugin?.comment ?? ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankTextField {
|
||||
id: triggerField
|
||||
width: 60
|
||||
visible: pluginDelegate.plugin?.isLauncher === true
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
placeholderText: I18n.tr("Trigger")
|
||||
onTextEdited: SettingsData.setBuiltInPluginSetting(pluginDelegate.modelData, "trigger", text)
|
||||
Component.onCompleted: text = SettingsData.getBuiltInPluginSetting(pluginDelegate.modelData, "trigger", pluginDelegate.plugin?.defaultTrigger ?? "")
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: enableToggle
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.getBuiltInPluginSetting(pluginDelegate.modelData, "enabled", true)
|
||||
onToggled: SettingsData.setBuiltInPluginSetting(pluginDelegate.modelData, "enabled", checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
id: recentAppsCard
|
||||
width: parent.width
|
||||
|
||||
@@ -42,65 +42,180 @@ Singleton {
|
||||
_cachedCategories = null;
|
||||
}
|
||||
|
||||
readonly property var coreApps: [
|
||||
{
|
||||
name: "DMS Settings",
|
||||
icon: Qt.resolvedUrl("../assets/danklogo2.svg"),
|
||||
comment: "Manage DMS configuration",
|
||||
readonly property string dmsLogoPath: Qt.resolvedUrl("../assets/danklogo2.svg")
|
||||
|
||||
readonly property var builtInPlugins: ({
|
||||
"dms_settings": {
|
||||
id: "dms_settings",
|
||||
name: I18n.tr("Settings", "settings window title"),
|
||||
icon: "svg+corner:" + dmsLogoPath + "|settings",
|
||||
cornerIcon: "settings",
|
||||
comment: "DMS",
|
||||
action: "ipc:settings",
|
||||
categories: ["Settings", "System"],
|
||||
isCore: true
|
||||
defaultTrigger: "",
|
||||
isLauncher: false
|
||||
},
|
||||
{
|
||||
name: "DMS Notepad",
|
||||
icon: "material:description",
|
||||
comment: "Quick notes",
|
||||
"dms_notepad": {
|
||||
id: "dms_notepad",
|
||||
name: I18n.tr("Notepad", "Notepad"),
|
||||
icon: "svg+corner:" + dmsLogoPath + "|description",
|
||||
cornerIcon: "description",
|
||||
comment: "DMS",
|
||||
action: "ipc:notepad",
|
||||
categories: ["Office", "Utility"],
|
||||
isCore: true
|
||||
defaultTrigger: "",
|
||||
isLauncher: false
|
||||
},
|
||||
{
|
||||
name: "DMS System Monitor",
|
||||
icon: "material:monitor_heart",
|
||||
comment: "System monitor and process list",
|
||||
"dms_sysmon": {
|
||||
id: "dms_sysmon",
|
||||
name: I18n.tr("System Monitor", "sysmon window title"),
|
||||
icon: "svg+corner:" + dmsLogoPath + "|monitor_heart",
|
||||
cornerIcon: "monitor_heart",
|
||||
comment: "DMS",
|
||||
action: "ipc:processlist",
|
||||
categories: ["System", "Monitor"],
|
||||
isCore: true
|
||||
defaultTrigger: "",
|
||||
isLauncher: false
|
||||
},
|
||||
"dms_settings_search": {
|
||||
id: "dms_settings_search",
|
||||
name: I18n.tr("Settings", "settings window title"),
|
||||
cornerIcon: "search",
|
||||
comment: "DMS",
|
||||
defaultTrigger: "?",
|
||||
isLauncher: true
|
||||
}
|
||||
})
|
||||
|
||||
function getBuiltInPluginTrigger(pluginId) {
|
||||
const plugin = builtInPlugins[pluginId];
|
||||
if (!plugin)
|
||||
return null;
|
||||
return SettingsData.getBuiltInPluginSetting(pluginId, "trigger", plugin.defaultTrigger);
|
||||
}
|
||||
|
||||
readonly property var coreApps: {
|
||||
SettingsData.builtInPluginSettings;
|
||||
const apps = [];
|
||||
for (const pluginId in builtInPlugins) {
|
||||
if (!SettingsData.getBuiltInPluginSetting(pluginId, "enabled", true))
|
||||
continue;
|
||||
const plugin = builtInPlugins[pluginId];
|
||||
if (plugin.isLauncher)
|
||||
continue;
|
||||
apps.push({
|
||||
name: plugin.name,
|
||||
icon: plugin.icon,
|
||||
comment: plugin.comment,
|
||||
action: plugin.action,
|
||||
categories: plugin.categories,
|
||||
isCore: true,
|
||||
builtInPluginId: pluginId
|
||||
});
|
||||
}
|
||||
return apps;
|
||||
}
|
||||
|
||||
function getBuiltInLauncherPlugins() {
|
||||
const result = {};
|
||||
for (const pluginId in builtInPlugins) {
|
||||
const plugin = builtInPlugins[pluginId];
|
||||
if (!plugin.isLauncher)
|
||||
continue;
|
||||
if (!SettingsData.getBuiltInPluginSetting(pluginId, "enabled", true))
|
||||
continue;
|
||||
result[pluginId] = plugin;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getBuiltInLauncherTriggers() {
|
||||
const triggers = {};
|
||||
const launchers = getBuiltInLauncherPlugins();
|
||||
for (const pluginId in launchers) {
|
||||
const trigger = getBuiltInPluginTrigger(pluginId);
|
||||
if (trigger && trigger.trim() !== "")
|
||||
triggers[trigger] = pluginId;
|
||||
}
|
||||
return triggers;
|
||||
}
|
||||
|
||||
function getBuiltInLauncherPluginsWithEmptyTrigger() {
|
||||
const result = [];
|
||||
const launchers = getBuiltInLauncherPlugins();
|
||||
for (const pluginId in launchers) {
|
||||
const trigger = getBuiltInPluginTrigger(pluginId);
|
||||
if (!trigger || trigger.trim() === "")
|
||||
result.push(pluginId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getBuiltInLauncherItems(pluginId, query) {
|
||||
if (pluginId !== "dms_settings_search")
|
||||
return [];
|
||||
|
||||
SettingsSearchService.search(query);
|
||||
const results = SettingsSearchService.results;
|
||||
const items = [];
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const r = results[i];
|
||||
items.push({
|
||||
name: r.label,
|
||||
icon: "material:" + r.icon,
|
||||
comment: r.category,
|
||||
action: "settings_nav:" + r.tabIndex + ":" + r.section,
|
||||
categories: ["Settings"],
|
||||
isCore: true,
|
||||
isBuiltInLauncher: true,
|
||||
builtInPluginId: pluginId
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
function executeBuiltInLauncherItem(item) {
|
||||
if (!item?.action)
|
||||
return false;
|
||||
|
||||
const parts = item.action.split(":");
|
||||
if (parts[0] !== "settings_nav")
|
||||
return false;
|
||||
|
||||
const tabIndex = parseInt(parts[1]);
|
||||
const section = parts.slice(2).join(":");
|
||||
SettingsSearchService.navigateToSection(section);
|
||||
PopoutService.openSettingsWithTabIndex(tabIndex);
|
||||
return true;
|
||||
}
|
||||
]
|
||||
|
||||
function getCoreApps(query) {
|
||||
if (!query || query.length === 0) {
|
||||
if (!query || query.length === 0)
|
||||
return coreApps;
|
||||
}
|
||||
|
||||
const lowerQuery = query.toLowerCase();
|
||||
return coreApps.filter(app => {
|
||||
return app.name.toLowerCase().includes(lowerQuery) || app.comment.toLowerCase().includes(lowerQuery);
|
||||
});
|
||||
return coreApps.filter(app => app.name.toLowerCase().includes(lowerQuery) || app.comment.toLowerCase().includes(lowerQuery));
|
||||
}
|
||||
|
||||
function executeCoreApp(app) {
|
||||
if (!app || !app.action) {
|
||||
if (!app?.action)
|
||||
return false;
|
||||
}
|
||||
|
||||
const actionParts = app.action.split(":");
|
||||
const actionType = actionParts[0];
|
||||
const actionTarget = actionParts[1];
|
||||
const parts = app.action.split(":");
|
||||
if (parts[0] !== "ipc")
|
||||
return false;
|
||||
|
||||
if (actionType === "ipc") {
|
||||
if (actionTarget === "settings") {
|
||||
Quickshell.execDetached(["dms", "ipc", "call", "settings", "toggle"]);
|
||||
switch (parts[1]) {
|
||||
case "settings":
|
||||
PopoutService.focusOrToggleSettings();
|
||||
return true;
|
||||
} else if (actionTarget === "notepad") {
|
||||
Quickshell.execDetached(["dms", "ipc", "call", "notepad", "toggle"]);
|
||||
case "notepad":
|
||||
PopoutService.openNotepad();
|
||||
return true;
|
||||
} else if (actionTarget === "processlist") {
|
||||
Quickshell.execDetached(["dms", "ipc", "call", "processlist", "focusOrToggle"]);
|
||||
case "processlist":
|
||||
PopoutService.showProcessListModal();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ Singleton {
|
||||
property var spotlightModal: null
|
||||
property var powerMenuModal: null
|
||||
property var processListModal: null
|
||||
property var processListModalLoader: null
|
||||
property var colorPickerModal: null
|
||||
property var notificationModal: null
|
||||
property var wifiPasswordModal: null
|
||||
@@ -201,6 +202,7 @@ Singleton {
|
||||
property bool _settingsWantsToggle: false
|
||||
|
||||
property string _settingsPendingTab: ""
|
||||
property int _settingsPendingTabIndex: -1
|
||||
|
||||
function openSettings() {
|
||||
if (settingsModal) {
|
||||
@@ -225,6 +227,19 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
function openSettingsWithTabIndex(tabIndex: int) {
|
||||
if (settingsModal) {
|
||||
settingsModal.showWithTab(tabIndex);
|
||||
return;
|
||||
}
|
||||
if (settingsModalLoader) {
|
||||
_settingsPendingTabIndex = tabIndex;
|
||||
_settingsWantsOpen = true;
|
||||
_settingsWantsToggle = false;
|
||||
settingsModalLoader.activeAsync = true;
|
||||
}
|
||||
}
|
||||
|
||||
function closeSettings() {
|
||||
settingsModal?.close();
|
||||
}
|
||||
@@ -302,7 +317,10 @@ Singleton {
|
||||
function _onSettingsModalLoaded() {
|
||||
if (_settingsWantsOpen) {
|
||||
_settingsWantsOpen = false;
|
||||
if (_settingsPendingTab) {
|
||||
if (_settingsPendingTabIndex >= 0) {
|
||||
settingsModal?.showWithTab(_settingsPendingTabIndex);
|
||||
_settingsPendingTabIndex = -1;
|
||||
} else if (_settingsPendingTab) {
|
||||
settingsModal?.showWithTabName(_settingsPendingTab);
|
||||
_settingsPendingTab = "";
|
||||
} else {
|
||||
@@ -312,7 +330,10 @@ Singleton {
|
||||
}
|
||||
if (_settingsWantsToggle) {
|
||||
_settingsWantsToggle = false;
|
||||
if (_settingsPendingTab) {
|
||||
if (_settingsPendingTabIndex >= 0) {
|
||||
settingsModal.currentTabIndex = _settingsPendingTabIndex;
|
||||
_settingsPendingTabIndex = -1;
|
||||
} else if (_settingsPendingTab) {
|
||||
var idx = settingsModal?.resolveTabIndex(_settingsPendingTab) ?? -1;
|
||||
if (idx >= 0)
|
||||
settingsModal.currentTabIndex = idx;
|
||||
@@ -357,7 +378,12 @@ Singleton {
|
||||
}
|
||||
|
||||
function showProcessListModal() {
|
||||
processListModal?.show();
|
||||
if (processListModal) {
|
||||
processListModal.show();
|
||||
} else if (processListModalLoader) {
|
||||
processListModalLoader.active = true;
|
||||
Qt.callLater(() => processListModal?.show());
|
||||
}
|
||||
}
|
||||
|
||||
function hideProcessListModal() {
|
||||
@@ -365,7 +391,12 @@ Singleton {
|
||||
}
|
||||
|
||||
function toggleProcessListModal() {
|
||||
processListModal?.toggle();
|
||||
if (processListModal) {
|
||||
processListModal.toggle();
|
||||
} else if (processListModalLoader) {
|
||||
processListModalLoader.active = true;
|
||||
Qt.callLater(() => processListModal?.show());
|
||||
}
|
||||
}
|
||||
|
||||
function showColorPicker() {
|
||||
|
||||
@@ -24,9 +24,21 @@ Item {
|
||||
|
||||
readonly property bool isMaterial: iconValue.startsWith("material:")
|
||||
readonly property bool isUnicode: iconValue.startsWith("unicode:")
|
||||
readonly property bool isSvgCorner: iconValue.startsWith("svg+corner:")
|
||||
readonly property bool isSvg: !isSvgCorner && iconValue.startsWith("svg:")
|
||||
readonly property string materialName: isMaterial ? iconValue.substring(9) : ""
|
||||
readonly property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
|
||||
readonly property string iconPath: isMaterial || isUnicode ? "" : Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue)
|
||||
readonly property string svgSource: {
|
||||
if (isSvgCorner) {
|
||||
const parts = iconValue.substring(11).split("|");
|
||||
return parts[0] || "";
|
||||
}
|
||||
if (isSvg)
|
||||
return iconValue.substring(4);
|
||||
return "";
|
||||
}
|
||||
readonly property string svgCornerIcon: isSvgCorner ? (iconValue.substring(11).split("|")[1] || "") : ""
|
||||
readonly property string iconPath: isMaterial || isUnicode || isSvg || isSvgCorner ? "" : Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue)
|
||||
|
||||
visible: iconValue !== undefined && iconValue !== ""
|
||||
|
||||
@@ -46,6 +58,14 @@ Item {
|
||||
visible: root.isUnicode
|
||||
}
|
||||
|
||||
DankSVGIcon {
|
||||
anchors.centerIn: parent
|
||||
source: root.svgSource
|
||||
size: root.iconSize
|
||||
cornerIcon: root.svgCornerIcon
|
||||
visible: root.isSvg || root.isSvgCorner
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: iconImg
|
||||
|
||||
@@ -53,7 +73,7 @@ Item {
|
||||
source: root.iconPath
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
visible: !root.isMaterial && !root.isUnicode && root.iconPath !== "" && status === Image.Ready
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && root.iconPath !== "" && status === Image.Ready
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -64,7 +84,7 @@ Item {
|
||||
anchors.rightMargin: root.fallbackRightMargin
|
||||
anchors.topMargin: root.fallbackTopMargin
|
||||
anchors.bottomMargin: root.fallbackBottomMargin
|
||||
visible: !root.isMaterial && !root.isUnicode && (root.iconPath === "" || iconImg.status !== Image.Ready)
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && (root.iconPath === "" || iconImg.status !== Image.Ready)
|
||||
color: root.fallbackBackgroundColor
|
||||
radius: Theme.cornerRadius
|
||||
border.width: 0
|
||||
|
||||
81
quickshell/Widgets/DankSVGIcon.qml
Normal file
81
quickshell/Widgets/DankSVGIcon.qml
Normal file
@@ -0,0 +1,81 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import Quickshell.Widgets
|
||||
import qs.Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property string source
|
||||
property int size: 24
|
||||
property string cornerIcon: ""
|
||||
property int cornerIconSize: Math.max(10, size * 0.4)
|
||||
property color cornerIconColor: Theme.surfaceText
|
||||
property color cornerIconBackground: Theme.surface
|
||||
property color colorOverride: "transparent"
|
||||
property real brightnessOverride: 0.0
|
||||
property real contrastOverride: 0.0
|
||||
property real saturationOverride: 0.0
|
||||
|
||||
readonly property bool hasCornerIcon: cornerIcon !== ""
|
||||
readonly property bool hasColorOverride: colorOverride.a > 0
|
||||
readonly property bool hasColorEffect: hasColorOverride || brightnessOverride !== 0.0 || contrastOverride !== 0.0 || saturationOverride !== 0.0
|
||||
readonly property string resolvedSource: {
|
||||
if (!source)
|
||||
return "";
|
||||
if (source.startsWith("file://"))
|
||||
return source;
|
||||
if (source.startsWith("/"))
|
||||
return "file://" + source;
|
||||
if (source.startsWith("qrc:"))
|
||||
return source;
|
||||
return source;
|
||||
}
|
||||
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
|
||||
IconImage {
|
||||
id: iconImage
|
||||
anchors.fill: parent
|
||||
source: root.resolvedSource
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous: true
|
||||
implicitSize: root.size * 2
|
||||
backer.sourceSize.width: root.size * 2
|
||||
backer.sourceSize.height: root.size * 2
|
||||
backer.cache: true
|
||||
layer.enabled: root.hasColorEffect
|
||||
layer.smooth: true
|
||||
layer.mipmap: true
|
||||
layer.effect: MultiEffect {
|
||||
saturation: root.saturationOverride
|
||||
colorization: root.hasColorOverride ? 1 : 0
|
||||
colorizationColor: root.colorOverride
|
||||
brightness: root.brightnessOverride
|
||||
contrast: root.contrastOverride
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: root.hasCornerIcon
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.rightMargin: -2
|
||||
anchors.bottomMargin: -2
|
||||
width: root.cornerIconSize + 4
|
||||
height: root.cornerIconSize + 4
|
||||
radius: width / 2
|
||||
color: root.cornerIconBackground
|
||||
border.width: 1
|
||||
border.color: Theme.surfaceLight
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: root.cornerIcon
|
||||
size: root.cornerIconSize
|
||||
color: root.cornerIconColor
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,8 +45,12 @@ apply_gtk4_colors() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$gtk_css" ]; then
|
||||
sed -i '/^@import url.*dank-colors\.css.*);$/d' "$gtk_css"
|
||||
if [ -f "$gtk_css" ] && grep -q '^@import url.*dank-colors\.css.*);$' "$gtk_css"; then
|
||||
echo "GTK4 import already exists"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f "$gtk_css" ] && [ -s "$gtk_css" ]; then
|
||||
sed -i "1i\\$gtk4_import" "$gtk_css"
|
||||
else
|
||||
echo "$gtk4_import" >"$gtk_css"
|
||||
|
||||
Reference in New Issue
Block a user