mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-30 08:22:51 -05:00
feat: configurable app id substitutions (#1317)
* feat: add configurable app ID substitutions setting * feat: add live icon updates when substitutions change * fix: cursor not showing on headerActions in non-collapsible cards * fix: address PR review feedback - add tags for search index - remove hardcoded height from text fields
This commit is contained in:
@@ -46,22 +46,20 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function moddedAppId(appId: string): string {
|
function moddedAppId(appId: string): string {
|
||||||
if (appId === "Spotify")
|
const subs = SettingsData.appIdSubstitutions || [];
|
||||||
return "spotify";
|
for (let i = 0; i < subs.length; i++) {
|
||||||
if (appId === "beepertexts")
|
const sub = subs[i];
|
||||||
return "beeper";
|
if (sub.type === "exact" && appId === sub.pattern) {
|
||||||
if (appId === "home assistant desktop")
|
return sub.replacement;
|
||||||
return "homeassistant-desktop";
|
} else if (sub.type === "contains" && appId.includes(sub.pattern)) {
|
||||||
if (appId.includes("com.transmissionbt.transmission")) {
|
return sub.replacement;
|
||||||
if (DesktopEntries.heuristicLookup("transmission-gtk"))
|
} else if (sub.type === "regex") {
|
||||||
return "transmission-gtk";
|
const match = appId.match(new RegExp(sub.pattern));
|
||||||
if (DesktopEntries.heuristicLookup("transmission"))
|
if (match) {
|
||||||
return "transmission";
|
return sub.replacement.replace(/\$(\d+)/g, (_, n) => match[n] || "");
|
||||||
return "transmission-gtk";
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const steamMatch = appId.match(/^steam_app_(\d+)$/);
|
|
||||||
if (steamMatch)
|
|
||||||
return `steam_icon_${steamMatch[1]}`;
|
|
||||||
return appId;
|
return appId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const moddedId = moddedAppId(appId);
|
const moddedId = moddedAppId(appId);
|
||||||
if (moddedId.startsWith("steam_icon_")) {
|
if (moddedId !== appId) {
|
||||||
return Quickshell.iconPath(moddedId, true);
|
return Quickshell.iconPath(moddedId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ Singleton {
|
|||||||
property bool keyboardLayoutNameCompactMode: false
|
property bool keyboardLayoutNameCompactMode: false
|
||||||
property bool runningAppsCurrentWorkspace: false
|
property bool runningAppsCurrentWorkspace: false
|
||||||
property bool runningAppsGroupByApp: false
|
property bool runningAppsGroupByApp: false
|
||||||
|
property var appIdSubstitutions: []
|
||||||
property string centeringMode: "index"
|
property string centeringMode: "index"
|
||||||
property string clockDateFormat: ""
|
property string clockDateFormat: ""
|
||||||
property string lockDateFormat: ""
|
property string lockDateFormat: ""
|
||||||
@@ -1842,6 +1843,40 @@ Singleton {
|
|||||||
return workspaceNameIcons[workspaceName] || null;
|
return workspaceNameIcons[workspaceName] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addAppIdSubstitution(pattern, replacement, type) {
|
||||||
|
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||||
|
subs.push({ pattern: pattern, replacement: replacement, type: type });
|
||||||
|
appIdSubstitutions = subs;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAppIdSubstitution(index, pattern, replacement, type) {
|
||||||
|
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||||
|
if (index < 0 || index >= subs.length)
|
||||||
|
return;
|
||||||
|
subs[index] = { pattern: pattern, replacement: replacement, type: type };
|
||||||
|
appIdSubstitutions = subs;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAppIdSubstitution(index) {
|
||||||
|
var subs = JSON.parse(JSON.stringify(appIdSubstitutions));
|
||||||
|
if (index < 0 || index >= subs.length)
|
||||||
|
return;
|
||||||
|
subs.splice(index, 1);
|
||||||
|
appIdSubstitutions = subs;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultAppIdSubstitutions() {
|
||||||
|
return Spec.SPEC.appIdSubstitutions.def;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetAppIdSubstitutions() {
|
||||||
|
appIdSubstitutions = JSON.parse(JSON.stringify(Spec.SPEC.appIdSubstitutions.def));
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
function getRegistryThemeVariant(themeId, defaultVariant) {
|
function getRegistryThemeVariant(themeId, defaultVariant) {
|
||||||
var stored = registryThemeVariants[themeId];
|
var stored = registryThemeVariants[themeId];
|
||||||
if (typeof stored === "string")
|
if (typeof stored === "string")
|
||||||
|
|||||||
@@ -115,6 +115,13 @@ var SPEC = {
|
|||||||
keyboardLayoutNameCompactMode: { def: false },
|
keyboardLayoutNameCompactMode: { def: false },
|
||||||
runningAppsCurrentWorkspace: { def: false },
|
runningAppsCurrentWorkspace: { def: false },
|
||||||
runningAppsGroupByApp: { def: false },
|
runningAppsGroupByApp: { def: false },
|
||||||
|
appIdSubstitutions: { def: [
|
||||||
|
{ pattern: "Spotify", replacement: "spotify", type: "exact" },
|
||||||
|
{ pattern: "beepertexts", replacement: "beeper", type: "exact" },
|
||||||
|
{ pattern: "home assistant desktop", replacement: "homeassistant-desktop", type: "exact" },
|
||||||
|
{ pattern: "com.transmissionbt.transmission", replacement: "transmission-gtk", type: "contains" },
|
||||||
|
{ pattern: "^steam_app_(\\d+)$", replacement: "steam_icon_$1", type: "regex" }
|
||||||
|
]},
|
||||||
centeringMode: { def: "index" },
|
centeringMode: { def: "index" },
|
||||||
clockDateFormat: { def: "" },
|
clockDateFormat: { def: "" },
|
||||||
lockDateFormat: { def: "" },
|
lockDateFormat: { def: "" },
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ BasePill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onAppIdSubstitutionsChanged() {
|
||||||
|
root.updateDesktopEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateDesktopEntry() {
|
function updateDesktopEntry() {
|
||||||
if (activeWindow && activeWindow.appId) {
|
if (activeWindow && activeWindow.appId) {
|
||||||
const moddedId = Paths.moddedAppId(activeWindow.appId);
|
const moddedId = Paths.moddedAppId(activeWindow.appId);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Item {
|
|||||||
|
|
||||||
property int _desktopEntriesUpdateTrigger: 0
|
property int _desktopEntriesUpdateTrigger: 0
|
||||||
property int _toplevelsUpdateTrigger: 0
|
property int _toplevelsUpdateTrigger: 0
|
||||||
|
property int _appIdSubstitutionsTrigger: 0
|
||||||
|
|
||||||
readonly property var sortedToplevels: {
|
readonly property var sortedToplevels: {
|
||||||
_toplevelsUpdateTrigger;
|
_toplevelsUpdateTrigger;
|
||||||
@@ -95,6 +96,13 @@ Item {
|
|||||||
_desktopEntriesUpdateTrigger++;
|
_desktopEntriesUpdateTrigger++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onAppIdSubstitutionsChanged() {
|
||||||
|
_appIdSubstitutionsTrigger++;
|
||||||
|
}
|
||||||
|
}
|
||||||
readonly property var groupedWindows: {
|
readonly property var groupedWindows: {
|
||||||
if (!SettingsData.runningAppsGroupByApp) {
|
if (!SettingsData.runningAppsGroupByApp) {
|
||||||
return [];
|
return [];
|
||||||
@@ -364,6 +372,7 @@ Item {
|
|||||||
height: Theme.barIconSize(root.barThickness)
|
height: Theme.barIconSize(root.barThickness)
|
||||||
source: {
|
source: {
|
||||||
root._desktopEntriesUpdateTrigger;
|
root._desktopEntriesUpdateTrigger;
|
||||||
|
root._appIdSubstitutionsTrigger;
|
||||||
if (!appId)
|
if (!appId)
|
||||||
return "";
|
return "";
|
||||||
const moddedId = Paths.moddedAppId(appId);
|
const moddedId = Paths.moddedAppId(appId);
|
||||||
@@ -596,6 +605,7 @@ Item {
|
|||||||
height: Theme.barIconSize(root.barThickness)
|
height: Theme.barIconSize(root.barThickness)
|
||||||
source: {
|
source: {
|
||||||
root._desktopEntriesUpdateTrigger;
|
root._desktopEntriesUpdateTrigger;
|
||||||
|
root._appIdSubstitutionsTrigger;
|
||||||
if (!appId)
|
if (!appId)
|
||||||
return "";
|
return "";
|
||||||
const moddedId = Paths.moddedAppId(appId);
|
const moddedId = Paths.moddedAppId(appId);
|
||||||
|
|||||||
@@ -265,7 +265,8 @@ Item {
|
|||||||
|
|
||||||
if (!byApp[key]) {
|
if (!byApp[key]) {
|
||||||
const isQuickshell = keyBase === "org.quickshell";
|
const isQuickshell = keyBase === "org.quickshell";
|
||||||
const desktopEntry = DesktopEntries.heuristicLookup(keyBase);
|
const moddedId = Paths.moddedAppId(keyBase);
|
||||||
|
const desktopEntry = DesktopEntries.heuristicLookup(moddedId);
|
||||||
const icon = Paths.getAppIcon(keyBase, desktopEntry);
|
const icon = Paths.getAppIcon(keyBase, desktopEntry);
|
||||||
byApp[key] = {
|
byApp[key] = {
|
||||||
"type": "icon",
|
"type": "icon",
|
||||||
@@ -1367,6 +1368,9 @@ Item {
|
|||||||
function onWorkspaceNameIconsChanged() {
|
function onWorkspaceNameIconsChanged() {
|
||||||
delegateRoot.updateAllData();
|
delegateRoot.updateAllData();
|
||||||
}
|
}
|
||||||
|
function onAppIdSubstitutionsChanged() {
|
||||||
|
delegateRoot.updateAllData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
target: DwlService
|
target: DwlService
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ Item {
|
|||||||
updateDesktopEntry();
|
updateDesktopEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onAppIdSubstitutionsChanged() {
|
||||||
|
updateDesktopEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
property bool isWindowFocused: {
|
property bool isWindowFocused: {
|
||||||
if (!appData) {
|
if (!appData) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -32,6 +32,159 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("runningAppsCurrentWorkspace", checked)
|
onToggled: checked => SettingsData.set("runningAppsCurrentWorkspace", checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
width: parent.width
|
||||||
|
iconName: "find_replace"
|
||||||
|
title: I18n.tr("App ID Substitutions")
|
||||||
|
settingKey: "appIdSubstitutions"
|
||||||
|
tags: ["app", "icon", "substitution", "replacement", "pattern", "window", "class", "regex"]
|
||||||
|
|
||||||
|
headerActions: [
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 36
|
||||||
|
iconName: "restart_alt"
|
||||||
|
iconSize: 20
|
||||||
|
visible: JSON.stringify(SettingsData.appIdSubstitutions) !== JSON.stringify(SettingsData.getDefaultAppIdSubstitutions())
|
||||||
|
backgroundColor: Theme.surfaceContainer
|
||||||
|
iconColor: Theme.surfaceVariantText
|
||||||
|
onClicked: SettingsData.resetAppIdSubstitutions()
|
||||||
|
},
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 36
|
||||||
|
iconName: "add"
|
||||||
|
iconSize: 20
|
||||||
|
backgroundColor: Theme.surfaceContainer
|
||||||
|
iconColor: Theme.primary
|
||||||
|
onClicked: SettingsData.addAppIdSubstitution("", "", "exact")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Map window class names to icon names for proper icon display")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
width: parent.width
|
||||||
|
bottomPadding: Theme.spacingS
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: SettingsData.appIdSubstitutions
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: subItem
|
||||||
|
width: parent.width
|
||||||
|
height: subColumn.implicitHeight + Theme.spacingM
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.withAlpha(Theme.surfaceContainer, 0.5)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: subColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: (parent.width - deleteBtn.width - Theme.spacingS) / 2
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Pattern")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall - 1
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
DankTextField {
|
||||||
|
id: patternField
|
||||||
|
width: parent.width
|
||||||
|
text: modelData.pattern
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
onEditingFinished: SettingsData.updateAppIdSubstitution(index, text, replacementField.text, modelData.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: (parent.width - deleteBtn.width - Theme.spacingS) / 2
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Replacement")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall - 1
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
DankTextField {
|
||||||
|
id: replacementField
|
||||||
|
width: parent.width
|
||||||
|
text: modelData.replacement
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
onEditingFinished: SettingsData.updateAppIdSubstitution(index, patternField.text, text, modelData.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: deleteBtn
|
||||||
|
width: 32
|
||||||
|
height: 40
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: deleteArea.containsMouse ? Theme.withAlpha(Theme.error, 0.2) : "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "delete"
|
||||||
|
size: 18
|
||||||
|
color: deleteArea.containsMouse ? Theme.error : Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: deleteArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: SettingsData.removeAppIdSubstitution(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: 120
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Type")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall - 1
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
|
compactMode: true
|
||||||
|
dropdownWidth: 120
|
||||||
|
currentValue: modelData.type
|
||||||
|
options: ["exact", "contains", "regex"]
|
||||||
|
onValueChanged: value => SettingsData.updateAppIdSubstitution(index, modelData.pattern, modelData.replacement, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ StyledRect {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: headerActionsRow
|
id: headerActionsRow
|
||||||
anchors.right: caretIcon.left
|
anchors.right: root.collapsible ? caretIcon.left : parent.right
|
||||||
anchors.rightMargin: root.collapsible ? Theme.spacingS : 0
|
anchors.rightMargin: root.collapsible ? Theme.spacingS : 0
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
@@ -172,6 +172,7 @@ StyledRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
visible: root.collapsible
|
||||||
anchors.left: caretIcon.left
|
anchors.left: caretIcon.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ Item {
|
|||||||
|
|
||||||
property var iconToWindowRatio: 0.25
|
property var iconToWindowRatio: 0.25
|
||||||
property var iconToWindowRatioCompact: 0.45
|
property var iconToWindowRatioCompact: 0.45
|
||||||
property var entry: DesktopEntries.heuristicLookup(windowData?.class)
|
property var entry: DesktopEntries.heuristicLookup(Paths.moddedAppId(windowData?.class ?? ""))
|
||||||
property var iconPath: Quickshell.iconPath(entry?.icon ?? windowData?.class ?? "application-x-executable", "image-missing")
|
property var iconPath: Paths.getAppIcon(windowData?.class ?? "", entry) || Quickshell.iconPath("application-x-executable", "image-missing")
|
||||||
property bool compactMode: Theme.fontSizeSmall * 4 > targetWindowHeight || Theme.fontSizeSmall * 4 > targetWindowWidth
|
property bool compactMode: Theme.fontSizeSmall * 4 > targetWindowHeight || Theme.fontSizeSmall * 4 > targetWindowWidth
|
||||||
|
|
||||||
x: initX
|
x: initX
|
||||||
|
|||||||
@@ -3153,33 +3153,6 @@
|
|||||||
"icon": "lock",
|
"icon": "lock",
|
||||||
"description": "If the field is hidden, it will appear as soon as a key is pressed."
|
"description": "If the field is hidden, it will appear as soon as a key is pressed."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "lockScreenNotificationMode",
|
|
||||||
"label": "Notification Display",
|
|
||||||
"tabIndex": 11,
|
|
||||||
"category": "Lock Screen",
|
|
||||||
"keywords": [
|
|
||||||
"alert",
|
|
||||||
"control",
|
|
||||||
"display",
|
|
||||||
"information",
|
|
||||||
"lock",
|
|
||||||
"lockscreen",
|
|
||||||
"login",
|
|
||||||
"monitor",
|
|
||||||
"notif",
|
|
||||||
"notification",
|
|
||||||
"notifications",
|
|
||||||
"output",
|
|
||||||
"password",
|
|
||||||
"privacy",
|
|
||||||
"screen",
|
|
||||||
"security",
|
|
||||||
"shown",
|
|
||||||
"what"
|
|
||||||
],
|
|
||||||
"description": "Control what notification information is shown on the lock screen"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "lockScreenShowPasswordField",
|
"section": "lockScreenShowPasswordField",
|
||||||
"label": "Show Password Field",
|
"label": "Show Password Field",
|
||||||
@@ -3915,6 +3888,35 @@
|
|||||||
],
|
],
|
||||||
"description": "Timeout for normal priority notifications"
|
"description": "Timeout for normal priority notifications"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "lockScreenNotificationMode",
|
||||||
|
"label": "Notification Display",
|
||||||
|
"tabIndex": 17,
|
||||||
|
"category": "Notifications",
|
||||||
|
"keywords": [
|
||||||
|
"alert",
|
||||||
|
"alerts",
|
||||||
|
"control",
|
||||||
|
"display",
|
||||||
|
"information",
|
||||||
|
"lock",
|
||||||
|
"lockscreen",
|
||||||
|
"login",
|
||||||
|
"messages",
|
||||||
|
"monitor",
|
||||||
|
"notif",
|
||||||
|
"notification",
|
||||||
|
"notifications",
|
||||||
|
"output",
|
||||||
|
"privacy",
|
||||||
|
"screen",
|
||||||
|
"security",
|
||||||
|
"shown",
|
||||||
|
"toast",
|
||||||
|
"what"
|
||||||
|
],
|
||||||
|
"description": "Control what notification information is shown on the lock screen"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "notificationOverlayEnabled",
|
"section": "notificationOverlayEnabled",
|
||||||
"label": "Notification Overlay",
|
"label": "Notification Overlay",
|
||||||
@@ -4036,6 +4038,29 @@
|
|||||||
"icon": "tune",
|
"icon": "tune",
|
||||||
"description": "Choose where on-screen displays appear on screen"
|
"description": "Choose where on-screen displays appear on screen"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "appIdSubstitutions",
|
||||||
|
"label": "App ID Substitutions",
|
||||||
|
"tabIndex": 19,
|
||||||
|
"category": "Running Apps",
|
||||||
|
"keywords": [
|
||||||
|
"active",
|
||||||
|
"app",
|
||||||
|
"apps",
|
||||||
|
"class",
|
||||||
|
"icon",
|
||||||
|
"pattern",
|
||||||
|
"regex",
|
||||||
|
"replacement",
|
||||||
|
"running",
|
||||||
|
"substitution",
|
||||||
|
"substitutions",
|
||||||
|
"tasks",
|
||||||
|
"window",
|
||||||
|
"windows"
|
||||||
|
],
|
||||||
|
"icon": "find_replace"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "runningApps",
|
"section": "runningApps",
|
||||||
"label": "Running Apps Settings",
|
"label": "Running Apps Settings",
|
||||||
|
|||||||
Reference in New Issue
Block a user