1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-29 16:02:51 -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 string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0 property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : "" property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon { DankIcon {
anchors.centerIn: parent anchors.centerIn: parent
@@ -102,18 +104,26 @@ Rectangle {
visible: parent.isMaterial visible: parent.isMaterial
} }
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: resultsList.iconSize * 0.8
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage { IconImage {
id: listIconImg id: listIconImg
anchors.fill: parent anchors.fill: parent
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true) source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
asynchronous: true asynchronous: true
visible: !parent.isMaterial && status === Image.Ready visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
visible: !parent.isMaterial && !listIconImg.visible visible: !parent.isMaterial && !parent.isUnicode && !listIconImg.visible
color: Theme.surfaceLight color: Theme.surfaceLight
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 1 border.width: 1
@@ -270,7 +280,9 @@ Rectangle {
property string iconValue: model.icon || "" property string iconValue: model.icon || ""
property bool isMaterial: iconValue.indexOf("material:") === 0 property bool isMaterial: iconValue.indexOf("material:") === 0
property bool isUnicode: iconValue.indexOf("unicode:") === 0
property string materialName: isMaterial ? iconValue.substring(9) : "" property string materialName: isMaterial ? iconValue.substring(9) : ""
property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
DankIcon { DankIcon {
anchors.centerIn: parent anchors.centerIn: parent
@@ -280,19 +292,27 @@ Rectangle {
visible: parent.isMaterial visible: parent.isMaterial
} }
StyledText {
anchors.centerIn: parent
text: parent.unicodeChar
font.pixelSize: parent.iconSize * 0.8
color: Theme.surfaceText
visible: parent.isUnicode
}
IconImage { IconImage {
id: gridIconImg id: gridIconImg
anchors.fill: parent anchors.fill: parent
source: parent.isMaterial ? "" : Quickshell.iconPath(parent.iconValue, true) source: parent.isMaterial || parent.isUnicode ? "" : Quickshell.iconPath(parent.iconValue, true)
smooth: true smooth: true
asynchronous: true asynchronous: true
visible: !parent.isMaterial && status === Image.Ready visible: !parent.isMaterial && !parent.isUnicode && status === Image.Ready
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
visible: !parent.isMaterial && !gridIconImg.visible visible: !parent.isMaterial && !parent.isUnicode && !gridIconImg.visible
color: Theme.surfaceLight color: Theme.surfaceLight
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 1 border.width: 1

View File

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

View File

@@ -45,6 +45,13 @@ Item {
action: "toast:Test Item 3 activated!", action: "toast:Test Item 3 activated!",
categories: ["LauncherExample"] 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", name: "Example Copy Action",
icon: "material:content_copy", icon: "material:content_copy",

View File

@@ -97,7 +97,7 @@ function executeItem(item): void
**Icon Types**: **Icon Types**:
The `icon` field supports three formats: The `icon` field supports four formats:
1. **Material Design Icons** - Use `material:` prefix: 1. **Material Design Icons** - Use `material:` prefix:
```javascript ```javascript
@@ -105,13 +105,19 @@ The `icon` field supports three formats:
``` ```
Examples: `material:star`, `material:favorite`, `material:settings` 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 ```javascript
icon: "firefox" // Uses system icon theme icon: "firefox" // Uses system icon theme
``` ```
Examples: `firefox`, `chrome`, `folder`, `text-editor` Examples: `firefox`, `chrome`, `folder`, `text-editor`
3. **No Icon** - Omit the `icon` field entirely: 4. **No Icon** - Omit the `icon` field entirely:
```javascript ```javascript
{ {
name: "😀 Grinning Face", name: "😀 Grinning Face",
@@ -121,7 +127,7 @@ The `icon` field supports three formats:
categories: ["MyPlugin"] 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: **Action Format**: `type:data` where:
- `type` - Action handler (toast, copy, script, etc.) - `type` - Action handler (toast, copy, script, etc.)

View File

@@ -1228,7 +1228,7 @@ Each item returned by `getItems()` must include:
### Icon Types ### Icon Types
The `icon` field supports three formats: The `icon` field supports four formats:
**1. Material Design Icons** - Use the `material:` prefix: **1. Material Design Icons** - Use the `material:` prefix:
```javascript ```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`) 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 ```javascript
{ {
name: "Firefox", 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` 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 ```javascript
{ {
name: "😀 Grinning Face", name: "😀 Grinning Face",
@@ -1264,7 +1276,7 @@ Uses the user's installed icon theme. Common examples: `firefox`, `chrome`, `fol
categories: ["MyPlugin"] 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 ### Trigger System