Dropdown Menu
July 14, 2026 · View on GitHub
A DankMaterialShell (DMS) bar plugin that adds a configurable button to the bar which opens a dropdown menu of actions, plugin toggles, popouts, and DMS IPC commands.
Status: beta (v0.7.0)
Screenshots

Features
- One bar button → a menu of anything. Build a dropdown of mixed item types:
- Custom Action — run any shell command.
- Plugin — toggle/open a plugin, Open its popout (works even if the widget isn't on a bar — see below), or run one of its detected IPC actions.
- IPC Command — pick any live
dms ipctarget + function (discovered on demand from your running shell).
- On-demand popouts & actions — "popout" items open the target widget's real popout, and a plugin's IPC actions fire, without that widget taking up bar space. The dropdown instantiates the plugin off-bar so its popout and
IpcHandlerwork, anchored under the dropdown button. Put a widget behind the menu instead of on the bar. - Smart action defaults — a widget plugin defaults to opening its popout; daemons and built-in panels default to toggle/open (the action that actually makes sense for each).
- Per-plugin action detection — opt into scanning a selected plugin for
IpcHandleractions and offer them directly (e.g. a Pomodoro plugin exposes Start Work, Reset, …). - Quick Add chips for common DMS panels (Control Center, Notifications, Clipboard, …) — one click to add, with live "already added" highlighting.
- Smart plugin list — only shows plugins you can actually drive from the menu, and flags ones that are not enabled or not on a bar.
- Full Material icon picker (searchable, all ~4000 symbols) for the button and each item.
- Display modes — show icon, text, or both, per bar pill and per item.
- Multiple dropdowns via variants — each is a separate bar widget.
- Sub-menus — group items into nested, collapsible groups. A sub-menu row expands in place (accordion) with its children indented below, and the popout grows to fit. Edit a group by drilling into it (breadcrumb + back) and reuse the same add/reorder/remove controls. One level of nesting; off-bar popout/IPC hosting works for items inside groups too.
- Drag-to-reorder items by a handle, click-to-edit, and remove; collapsible editor.
Requirements
- DankMaterialShell (quickshell-based) with the plugin system.
dmsCLI onPATH(used for IPC actions).
Install
From the DMS plugin registry (once published)
dms plugins install dropdownMenu
Manual
Clone into your DMS plugins directory:
git clone https://github.com/rdannenbring/dropdown-menu.git \
~/.config/DankMaterialShell/plugins/dropdownMenu
Then enable it in DMS Settings → Plugins, configure a dropdown, and add it to your bar via Bar Settings → Add Widget.
Usage
- Enable the plugin in Settings → Plugins and open its settings.
- Create a dropdown, then click it to edit.
- Add items (Custom Action / Plugin / IPC Command / Sub-menu); use Quick Add for common panels. Click a Sub-menu row to drill in and add items inside it.
- Set the bar pill's icon, label, and display mode.
- Bar Settings → Add Widget to place the dropdown on your bar.
Clicking the dropdown on the bar opens/closes its menu.
Permissions
settings_read, settings_write, process (to run shell/IPC commands).
How it works
Each dropdown is a DMS plugin variant, so multiple dropdowns are independent bar widgets. The bar pill is a PluginComponent; the menu is its popout.
Files
DropdownWidget.qml— the bar pill + popout; dispatches item clicks.DropdownItem.qml— a single menu row.DropdownSettings.qml— the editor (variants, items, IPC discovery, validation).DropdownIconPicker.qml— searchable Material-symbol picker.
Item model (stored in variant data)
action—{ command }, run viaProcess(sh -c).plugin—{ pluginId }, toggled viaPluginService.togglePluginor a built-inPopoutServicetoggle.popout—{ widgetId }, opened on demand: the dropdown instantiates the target plugin's widget off-bar (hidden, zero-size, non-interactive, inside its own bar pill, with full bar context injected) and calls the widget's owntriggerPopout(), so the popout opens anchored under the dropdown button without the widget being placed on a bar. If a copy is on a bar, it falls back toBarWidgetService.triggerWidgetPopout. The off-bar instance runs in the background (timers/fetches) so its popout has data ready.- IPC actions are stored as
actionitems whose command isdms ipc <target> <fn> [args]— reusing the action execution path. submenu—{ label, icon, items: [...] }, a nested group of same-shape items rendered as an inline accordion (one level). The off-bar popout/IPC hosting recurses intoitems, so nested popout/IPC entries work too.
Discovery (opt-in)
- Listing IPC targets/functions runs
dms ipc --helpagainst the running shell — triggered only when you click Load IPC targets / Detect IPC actions, never automatically. It enumerates every liveIpcHandler, which can crash the shell if a plugin registers an un-wireable handler (an upstream quickshellwireDefbug), so the common flows — Custom Action, toggle/open, popout, Sub-menu — never invoke it. Already know the command? Add it as a Custom Action (dms ipc <target> <fn>) to skip discovery. - Per-plugin actions: the selected plugin's QML is grepped for
IpcHandler { target: "…" }and intersected with the live target list, so only working actions are offered.