1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-03 20:32:07 -04:00

refactor(icons): centralize icon resolution into Paths.resolveIconPath/resolveIconUrl (#1880)

Supersedes #1878. Rather than duplicating the moddedAppId + file path
substitution pattern inline across 8 files, this introduces two
centralized functions in Paths.qml:

- resolveIconPath(iconName): for Quickshell.iconPath() callsites,
  with DesktopService.resolveIconPath() fallback
- resolveIconUrl(iconName): for image://icon/ URL callsites

All consumer files now use one-line calls. When no substitutions are
configured, moddedAppId() returns the original name unchanged (zero
cost), so this has no impact on users who don't use the feature.

Affected components:
- AppIconRenderer (8 lines → 1)
- NotificationCard, NotificationPopup, HistoryNotificationCard
- DockContextMenu, AppsDockContextMenu
- LauncherContent, LauncherTab (×3)

Co-authored-by: odtgit <odtgit@taliops.com>
This commit is contained in:
odt
2026-03-01 23:31:51 +01:00
committed by bbedward
parent f9b737f543
commit 21750156dc
9 changed files with 39 additions and 22 deletions

View File

@@ -71,15 +71,40 @@ Singleton {
return appId;
}
function resolveIconPath(iconName: string): string {
if (!iconName) return "";
const moddedId = moddedAppId(iconName);
if (moddedId !== iconName) {
if (moddedId.startsWith("~") || moddedId.startsWith("/"))
return toFileUrl(expandTilde(moddedId));
if (moddedId.startsWith("file://"))
return moddedId;
return Quickshell.iconPath(moddedId, true);
}
return Quickshell.iconPath(iconName, true) || DesktopService.resolveIconPath(iconName);
}
function resolveIconUrl(iconName: string): string {
if (!iconName) return "";
const moddedId = moddedAppId(iconName);
if (moddedId !== iconName) {
if (moddedId.startsWith("~") || moddedId.startsWith("/"))
return toFileUrl(expandTilde(moddedId));
if (moddedId.startsWith("file://"))
return moddedId;
return "image://icon/" + moddedId;
}
return "image://icon/" + iconName;
}
function getAppIcon(appId: string, desktopEntry: var): string {
if (appId === "org.quickshell") {
return Qt.resolvedUrl("../assets/danklogo.svg");
}
const moddedId = moddedAppId(appId);
if (moddedId !== appId) {
return Quickshell.iconPath(moddedId, true);
}
if (moddedId !== appId)
return resolveIconPath(appId);
if (desktopEntry && desktopEntry.icon) {
return Quickshell.iconPath(desktopEntry.icon, true);

View File

@@ -643,7 +643,7 @@ FocusScope {
Image {
width: 40
height: 40
source: editingApp?.icon ? "image://icon/" + editingApp.icon : "image://icon/application-x-executable"
source: Paths.resolveIconUrl(editingApp?.icon || "application-x-executable")
sourceSize.width: 40
sourceSize.height: 40
fillMode: Image.PreserveAspectFit

View File

@@ -273,7 +273,7 @@ PanelWindow {
IconImage {
anchors.fill: parent
source: modelData.icon ? Quickshell.iconPath(modelData.icon, true) : ""
source: modelData.icon ? Paths.resolveIconPath(modelData.icon) : ""
smooth: true
asynchronous: true
visible: status === Image.Ready

View File

@@ -329,7 +329,7 @@ PanelWindow {
IconImage {
anchors.fill: parent
source: modelData.icon ? Quickshell.iconPath(modelData.icon, true) : ""
source: modelData.icon ? Paths.resolveIconPath(modelData.icon) : ""
smooth: true
asynchronous: true
visible: status === Image.Ready

View File

@@ -127,7 +127,7 @@ Rectangle {
return appIcon;
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
return "";
return Quickshell.iconPath(appIcon, true);
return Paths.resolveIconPath(appIcon);
}
hasImage: hasNotificationImage

View File

@@ -174,7 +174,7 @@ Rectangle {
return appIcon;
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
return "";
return Quickshell.iconPath(appIcon, true);
return Paths.resolveIconPath(appIcon);
}
hasImage: hasNotificationImage
@@ -508,7 +508,7 @@ Rectangle {
return appIcon;
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
return "";
return Quickshell.iconPath(appIcon, true);
return Paths.resolveIconPath(appIcon);
}
fallbackIcon: {

View File

@@ -484,7 +484,7 @@ PanelWindow {
return appIcon;
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
return "";
return Quickshell.iconPath(appIcon, true);
return Paths.resolveIconPath(appIcon);
}
hasImage: hasNotificationImage

View File

@@ -897,7 +897,7 @@ Item {
Image {
width: 24
height: 24
source: modelData.icon ? "image://icon/" + modelData.icon : "image://icon/application-x-executable"
source: Paths.resolveIconUrl(modelData.icon || "application-x-executable")
sourceSize.width: 24
sourceSize.height: 24
fillMode: Image.PreserveAspectFit
@@ -1008,7 +1008,7 @@ Item {
Image {
width: 24
height: 24
source: modelData.icon ? "image://icon/" + modelData.icon : "image://icon/application-x-executable"
source: Paths.resolveIconUrl(modelData.icon || "application-x-executable")
sourceSize.width: 24
sourceSize.height: 24
fillMode: Image.PreserveAspectFit
@@ -1154,7 +1154,7 @@ Item {
Image {
width: 24
height: 24
source: modelData.icon ? "image://icon/" + modelData.icon : "image://icon/application-x-executable"
source: Paths.resolveIconUrl(modelData.icon || "application-x-executable")
sourceSize.width: 24
sourceSize.height: 24
fillMode: Image.PreserveAspectFit

View File

@@ -49,15 +49,7 @@ Item {
readonly property string iconPath: {
if (hasSpecialPrefix || !iconValue)
return "";
const moddedId = Paths.moddedAppId(iconValue);
if (moddedId !== iconValue) {
if (moddedId.startsWith("~") || moddedId.startsWith("/"))
return Paths.toFileUrl(Paths.expandTilde(moddedId));
if (moddedId.startsWith("file://"))
return moddedId;
return Quickshell.iconPath(moddedId, true);
}
return Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue);
return Paths.resolveIconPath(iconValue);
}
visible: iconValue !== undefined && iconValue !== ""