summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/PLUGINS/LauncherExample/README.md
blob: db34b83262e91122abcd4d8278dab8509145ac75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# LauncherExample Plugin

A demonstration plugin that showcases the DMS launcher plugin system capabilities.

## Purpose

This plugin serves as a comprehensive example for developers creating launcher plugins for DMS. It demonstrates:

- **Plugin Structure**: Proper manifest, launcher, and settings components
- **Trigger System**: Customizable trigger strings for plugin activation (including empty triggers)
- **Item Management**: Providing searchable items to the launcher
- **Action Execution**: Handling different types of actions (toast, copy, script)
- **Settings Integration**: Configurable plugin settings with persistence

## Features

### Example Items
- **Test Items 1-3**: Demonstrate toast notifications
- **Copy Action**: Shows clipboard integration
- **Script Action**: Demonstrates command execution

### Trigger System
- **Default Trigger**: `#` (configurable in settings)
- **Empty Trigger Option**: Items can always be visible without needing a trigger
- **Usage**: Type `#` in launcher to filter to this plugin (when trigger is set)
- **Search**: Type `# test` to search within plugin items

### Action Types
- `toast:message` - Shows toast notification
- `copy:text` - Copies text to clipboard
- `script:command` - Executes shell command (demo only)

## File Structure

```
PLUGINS/LauncherExample/
├── plugin.json                    # Plugin manifest
├── LauncherExampleLauncher.qml    # Main launcher component
├── LauncherExampleSettings.qml    # Settings interface
└── README.md                      # This documentation
```

## Installation

1. **Plugin Directory**: Copy to `~/.config/DankMaterialShell/plugins/LauncherExample`
2. **Enable Plugin**: Settings → Plugins → Enable "LauncherExample"
3. **Configure**: Set custom trigger in plugin settings if desired

## Usage

### With Trigger (Default)
1. Open launcher (Ctrl+Space or launcher button)
2. Type `#` to activate plugin trigger
3. Browse available items or add search terms
4. Press Enter to execute selected item

### Without Trigger (Empty Trigger Mode)
1. Enable "No trigger (always show)" in plugin settings
2. Open launcher - plugin items are always visible
3. Search works normally with plugin items included
4. Press Enter to execute selected item

### Search Examples
- `#` - Show all plugin items (with trigger enabled)
- `# test` - Show items matching "test"
- `# copy` - Show items matching "copy"
- `test` - Show all items matching "test" (with empty trigger enabled)

## Developer Guide

### Plugin Contract

**Launcher Component Requirements**:
```qml
// Required properties
property var pluginService: null
property string trigger: "#"

// Required signals
signal itemsChanged()

// Required functions
function getItems(query): array
function executeItem(item): void

// Optional functions (for Shift+Enter paste support)
function getPasteText(item): string|null
function getPasteArgs(item): array|null
```

**Item Structure**:
```javascript
{
    name: "Item Name",           // Display name
    icon: "icon_name",           // Icon (optional, see Icon Types below)
    comment: "Description",      // Subtitle text
    action: "type:data",         // Action to execute
    categories: ["PluginName"]   // Category array
}
```

**Icon Types**:

The `icon` field supports four formats:

1. **Material Design Icons** - Use `material:` prefix:
   ```javascript
   icon: "material:lightbulb"  // Material Symbols Rounded font
   ```
   Examples: `material:star`, `material:favorite`, `material:settings`

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`

4. **No Icon** - Omit the `icon` field entirely:
   ```javascript
   {
       name: "😀  Grinning Face",
       // No icon field
       comment: "Copy emoji",
       action: "copy:😀",
       categories: ["MyPlugin"]
   }
   ```
   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.)
- `data` - Action-specific data

### Settings Integration
```qml
// Save setting
pluginService.savePluginData("pluginId", "key", value)

// Load setting
pluginService.loadPluginData("pluginId", "key", defaultValue)
```

### Trigger Configuration

The trigger can be configured in two ways:

1. **Empty Trigger** (No Trigger Mode):
   - Check "No trigger (always show)" in settings
   - Saves `trigger: ""` and `noTrigger: true`
   - Items always appear in launcher alongside regular apps

2. **Custom Trigger**:
   - Enter any string (e.g., `#`, `!`, `@`, `!ex`)
   - Uncheck "No trigger" checkbox
   - Items only appear when trigger is typed

### Manifest Structure
```json
{
    "id": "launcherExample",
    "name": "LauncherExample",
    "type": "launcher",
    "capabilities": ["launcher"],
    "component": "./LauncherExampleLauncher.qml",
    "settings": "./LauncherExampleSettings.qml",
    "permissions": ["settings_read", "settings_write"]
}
```

Note: The `trigger` field in the manifest is optional and serves as the default trigger value.

## Extending This Plugin

### Adding New Items
```qml
function getItems(query) {
    return [
        {
            name: "My Item",
            icon: "custom_icon",
            comment: "Does something cool",
            action: "custom:action_data",
            categories: ["LauncherExample"]
        }
    ]
}
```

### Adding New Actions
```qml
function executeItem(item) {
    const actionParts = item.action.split(":")
    const actionType = actionParts[0]
    const actionData = actionParts.slice(1).join(":")

    switch (actionType) {
        case "custom":
            handleCustomAction(actionData)
            break
    }
}
```

### Custom Trigger Logic
```qml
Component.onCompleted: {
    if (pluginService) {
        trigger = pluginService.loadPluginData("launcherExample", "trigger", "#")
    }
}

onTriggerChanged: {
    if (pluginService) {
        pluginService.savePluginData("launcherExample", "trigger", trigger)
    }
}
```

## Best Practices

1. **Unique Triggers**: Choose triggers that don't conflict with other plugins
2. **Clear Descriptions**: Write helpful item comments
3. **Error Handling**: Gracefully handle action failures
4. **Performance**: Return results quickly in getItems()
5. **Cleanup**: Destroy temporary objects in executeItem()
6. **Empty Trigger Support**: Consider if your plugin should support empty trigger mode

## Testing

Test the plugin by:
1. Installing and enabling in DMS
2. Testing with trigger enabled
3. Testing with empty trigger (no trigger mode)
4. Trying each action type
5. Testing search functionality
6. Verifying settings persistence

This plugin provides a solid foundation for building more sophisticated launcher plugins with custom functionality!