* fix(frame): make connected mode honor the settings it overrides Several frame-mode behaviors contradicted what the settings UI shows: - Frame -> Blur gated blur for every shell surface in connected mode, including the Settings window, polkit, context menus, OSDs and toasts. WindowBlur now defaults to Background blur; only surfaces painted with the frame color (connected popouts, slideouts, Control Center) follow Frame -> Blur, and frame-owned surfaces are blurred by the frame as before. - The notepad slideout painted its own fill at the notepad transparency. On screens where the frame owns connected chrome it now claims a frame surface (new connected_arc slot 5), so the frame paints it flush with the cutout, with fillets, and follows the slide. - Notification popups painted a card surface on top of the frame body, stacking fills. That layer is transparent when the frame paints it. - Connected mode stripped shadow, border and corner styling from every bar, including bars on displays without a frame, and hid the rows. Styling is now stripped and restored per bar based on whether it covers a frame display, re-checked on screen, frame display and display-name-mode changes. - Auto popup gaps and Gap size were hidden in separate mode although they still apply there; they now hide only in connected mode. - The launcher style picker was hidden in connected mode while Island still overrode the connected launcher. Connected mode now always uses the connected launcher; the picker shows Full, disabled, with a note linking to the Bar layout picker. - The frame shadow ignored Shadows -> Apply to -> Bars. * fix(frame): address review feedback on connected mode - Skip bar style reconciliation while the screen list is empty, so a hotplug doesn't restore and re-strip every bar. - Replace the 16 copies of the connector blur anchor and cutout in FrameWindow with a ConnectorBlurRegion inline component. - Let connected mode use the island launcher again now that the island can sit in any bar. The picker offers Full and Island there and hides Spotlight, which opens the full launcher in that mode anyway; the note and the SettingsControlledBy bar target are dropped. * frame: address review findings on connected mode --------- Co-authored-by: purian23 <[email protected]>
DMS Quickshell Interface
QML-based desktop shell interface for DankMaterialShell providing panels, widgets, and overlays.
See root README for project overview and installation.
Architecture
Modular QML Structure
Modules/- UI components (panels, widgets, overlays)Services/- System integration singletons (audio, network, bluetooth)Widgets/- Reusable UI controlsCommon/- Shared resources and themes
Technology Stack
- Quickshell - QML-based shell framework
- Qt/QtQuick - UI rendering and controls
- Material Design 3 - Design system and theming
Development
Run the shell:
quickshell -p quickshell/
Code formatting:
qmlfmt -t 4 -i 4 -b 250 -w path/to/file.qml
make lint-qml # Run from repo root; requires quickshell/.qmlls.ini (generated by `qs -p quickshell/`)
# Uses Qt 6 qmllint. Override path with QMLLINT=/path/to/qmllint if needed.
# Auto-detects `qmllint6`, Fedora's `qmllint-qt6`, `/usr/lib/qt6/bin/qmllint`, then `qmllint`.
Components
Panels & Bars
Modules/TopBar/- Multi-monitor status bars with workspace switchingModules/DBar/- Customizable widget bar with plugin supportModules/Dock/- Application dock with window management
System Controls
Modules/ControlCenter/- WiFi, Bluetooth, audio, display settingsModules/Notifications/- Notification center with popups
Overlays
Modules/Spotlight/- Application and file launcherModules/Overview/- Workspace overviewModules/Lock/- Screen lock system
Utilities
Modules/ProcessList/- System monitoring and process managementModules/Calendar/- Calendar widget with event syncModules/Weather/- Weather display
Services
Singletons providing system integration:
Media & Audio
AudioService- PipeWire/PulseAudio volume and device controlMprisController- Media player integration
Network
NetworkService- NetworkManager WiFi controlBluetoothService- BlueZ Bluetooth management
Display
DisplayService- Brightness control and night modeWallpaperService- Wallpaper management and effects
System
BatteryService- Battery status and power profilesIdleService- Idle detection and inhibit locksClipboardService- Clipboard history with imagesDgopService- System metrics (CPU, RAM, GPU)
Integration
NiriService- Niri workspace integrationHyprlandService- Hyprland workspace integrationPluginService- Plugin discovery and lifecycle
Widgets
Reusable Material Design 3 components in Widgets/:
DankIcon- Icon component with Material fontDankSlider- Enhanced slider with animationsDankToggle- Toggle switch componentDankTabBar- Tab bar implementationDankGridView- Grid layout with adaptive columnsDankListView- Scrollable list viewDankTextField- Text input with validationDDropdown- Dropdown selectionDPopout- Base for overlay componentsStateLayer- Material interaction states
Theming
Dynamic Color Schemes
Wallpaper-based theming using matugen:
import qs.Common
Rectangle {
color: Theme.container
border.color: Theme.outline
}
Theme singleton provides Material Design 3 color system, spacing, fonts, and elevation.
Application Themes
Templates in scripts/templates/ generate themes for:
- GTK 3/4
- Qt5/Qt6
- Alacritty, Kitty, Ghostty, Foot, Wezterm terminals
- Neovim
- VSCode/VSCodium
- Firefox
Multi-Monitor Support
Per-monitor panel instances using Quickshell Variants:
Variants {
model: Quickshell.screens
PanelWindow {
screen: modelData
// Per-screen configuration
}
}
Workspace switchers adapt to compositor (Niri/Hyprland).
Plugin System
External plugins in ~/.config/DankMaterialShell/plugins/:
Widget plugins - UI components in DankBar Daemon plugins - Background processes without UI
Plugin manifest (plugin.json):
{
"id": "pluginId",
"name": "Plugin Name",
"version": "1.0.0",
"type": "widget",
"component": "./Widget.qml",
"settings": "./Settings.qml",
"permissions": ["settings_read", "settings_write"]
}
Plugins access pluginService for persistent data:
pluginService.savePluginData("pluginId", "key", value)
pluginService.loadPluginData("pluginId", "key", defaultValue)
IPC Integration
Backend IPC socket communication:
import Quickshell.Io
Process {
command: ["dms", "ipc", "call", "spotlight", "toggle"]
running: true
}
Common IPC commands exposed through services for reactive property bindings.
Code Conventions
Component Structure:
import QtQuick
import Quickshell
import qs.Common
import qs.Services
Item {
id: root
property type name: value
signal customSignal(type param)
Component { /* children */ }
}
Services (Singletons):
import QtQuick
import Quickshell
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property bool featureAvailable: false
property type currentValue: defaultValue
function performAction(param) { /* implementation */ }
}
Guidelines:
- Use
Theme.propertyNamefor consistent styling - Bind directly to service properties for reactivity
- Use
DankIconfor all icons - Implement feature detection and graceful degradation
- 4-space indentation, no unnecessary comments
Translation
Internationalization using POEditor:
export POEDITOR_API_TOKEN="token"
export POEDITOR_PROJECT_ID="id"
python3 scripts/i18nsync.py sync
Pre-commit hook checks translation sync status.
License
MIT License - See LICENSE for details.