1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

feat: allow Launcher plugins to set unicode icons. (#594)

Launcher plugins can now set `icon: "unicode:🍉"`
and the symbol is used as the icon.
This commit is contained in:
Bruno Cesar Rocha
2025-10-31 21:10:00 +00:00
committed by GitHub
parent 1548286083
commit ff3123e387
5 changed files with 85 additions and 20 deletions

View File

@@ -92,7 +92,9 @@ Rectangle {
property string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon {
anchors.centerIn: parent
@@ -102,18 +104,26 @@ Rectangle {
visible: parent.isMaterial
}
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: resultsList.iconSize * 0.8
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage {
id: listIconImg
anchors.fill: parent
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true)
source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
asynchronous: true
visible: !parent.isMaterial && status === Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
}
Rectangle {
anchors.fill: parent
visible: !parent.isMaterial && !listIconImg.visible
visible: !parent.isMaterial && !parent.isUnicode && !listIconImg.visible
color: Theme.surfaceLight
radius: Theme.cornerRadius
border.width: 1
@@ -270,7 +280,9 @@ Rectangle {
property string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon {
anchors.centerIn: parent
@@ -280,19 +292,27 @@ Rectangle {
visible: parent.isMaterial
}
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: parent.iconSize * 0.8
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage {
id: gridIconImg
anchors.fill: parent
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true)
source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
smooth: true
asynchronous: true
visible: !parent.isMaterial && status === Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
}
Rectangle {
anchors.fill: parent
visible: !parent.isMaterial && !gridIconImg.visible
visible: !parent.isMaterial && !parent.isUnicode && !gridIconImg.visible
color: Theme.surfaceLight
radius: Theme.cornerRadius
border.width: 1

View File

@@ -408,7 +408,9 @@ DankPopout {
property string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon {
anchors.centerIn: parent
@@ -418,15 +420,23 @@ DankPopout {
visible: parent.isMaterial
}
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: appList.iconSize * 0.7
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage {
id: listIconImg
anchors.fill: parent
anchors.margins: Theme.spacingXS
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true)
source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
smooth: true
asynchronous: true
visible: !parent.isMaterial && status === Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
}
Rectangle {
@@ -434,7 +444,7 @@ DankPopout {
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.bottomMargin: Theme.spacingM
visible: !parent.isMaterial && listIconImg.status !== Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && listIconImg.status !== Image.Ready
color: Theme.surfaceLight
radius: Theme.cornerRadius
border.width: 0
@@ -597,7 +607,9 @@ DankPopout {
property string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon {
anchors.centerIn: parent
@@ -607,6 +619,14 @@ DankPopout {
visible: parent.isMaterial
}
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: parent.iconSize * 0.8
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage {
id: gridIconImg
@@ -614,10 +634,10 @@ DankPopout {
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.bottomMargin: Theme.spacingS
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true)
source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
smooth: true
asynchronous: true
visible: !parent.isMaterial && status === Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
}
Rectangle {
@@ -625,7 +645,7 @@ DankPopout {
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.bottomMargin: Theme.spacingS
visible: !parent.isMaterial && gridIconImg.status !== Image.Ready
visible: !parent.isMaterial && !parent.isUnicode && gridIconImg.status !== Image.Ready
color: Theme.surfaceLight
radius: Theme.cornerRadius
border.width: 0

View File

@@ -45,6 +45,13 @@ Item {
action: "toast:Test Item 3 activated!",
categories: ["LauncherExample"]
},
{
name: "Unicode Icon Example",
icon: "unicode:🚀",
comment: "Demonstrates unicode/emoji icon support",
action: "toast:Unicode icons work great!",
categories: ["LauncherExample"]
},
{
name: "Example Copy Action",
icon: "material:content_copy",

View File

@@ -97,7 +97,7 @@ function executeItem(item): void
**Icon Types**:
The `icon` field supports three formats:
The `icon` field supports four formats:
1. **Material Design Icons** - Use `material:` prefix:
```javascript
@@ -105,13 +105,19 @@ The `icon` field supports three formats:
```
Examples: `material:star`, `material:favorite`, `material:settings`
2. **Desktop Theme Icons** - Use icon name directly:
2. **Unicode/Emoji Icons** - Use `unicode:` prefix:
```javascript
icon: "unicode:🚀" // Unicode character or emoji
```
Display any Unicode character or emoji as the icon. Examples: `unicode:😀`, `unicode:⚡`, `unicode:🎨`
3. **Desktop Theme Icons** - Use icon name directly:
```javascript
icon: "firefox" // Uses system icon theme
```
Examples: `firefox`, `chrome`, `folder`, `text-editor`
3. **No Icon** - Omit the `icon` field entirely:
4. **No Icon** - Omit the `icon` field entirely:
```javascript
{
name: "😀 Grinning Face",
@@ -121,7 +127,7 @@ The `icon` field supports three formats:
categories: ["MyPlugin"]
}
```
Perfect for emoji pickers or text-only items where the icon area should be hidden
When icon is omitted, the launcher hides the icon area and displays only text
**Action Format**: `type:data` where:
- `type` - Action handler (toast, copy, script, etc.)

View File

@@ -1228,7 +1228,7 @@ Each item returned by `getItems()` must include:
### Icon Types
The `icon` field supports three formats:
The `icon` field supports four formats:
**1. Material Design Icons** - Use the `material:` prefix:
```javascript
@@ -1242,7 +1242,19 @@ The `icon` field supports three formats:
```
Available icons: Any icon from Material Symbols font (e.g., `lightbulb`, `star`, `favorite`, `settings`, `terminal`, `translate`, `sentiment_satisfied`)
**2. Desktop Theme Icons** - Use icon name directly:
**2. Unicode/Emoji Icons** - Use the `unicode:` prefix:
```javascript
{
name: "Grinning Face",
icon: "unicode:😀", // Unicode character or emoji
comment: "Copy emoji to clipboard",
action: "copy:😀",
categories: ["MyPlugin"]
}
```
Display any Unicode character or emoji as the icon. The character is rendered at 70-80% of the icon size with proper theming. Perfect for emoji pickers, symbol selectors, or character libraries.
**3. Desktop Theme Icons** - Use icon name directly:
```javascript
{
name: "Firefox",
@@ -1254,7 +1266,7 @@ Available icons: Any icon from Material Symbols font (e.g., `lightbulb`, `star`,
```
Uses the user's installed icon theme. Common examples: `firefox`, `chrome`, `folder`, `text-editor`
**3. No Icon** - Omit the `icon` field entirely:
**4. No Icon** - Omit the `icon` field entirely:
```javascript
{
name: "😀 Grinning Face",
@@ -1264,7 +1276,7 @@ Uses the user's installed icon theme. Common examples: `firefox`, `chrome`, `fol
categories: ["MyPlugin"]
}
```
When `icon` is omitted, the launcher hides the icon area and displays only the text, giving full width to the item name. Perfect for emoji pickers or text-only items.
When `icon` is omitted, the launcher hides the icon area and displays only the text, giving full width to the item name. Useful when you want emojis or symbols to be part of the item name itself.
### Trigger System