1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00
Files
DankMaterialShell/quickshell/PLUGINS/POPOUT_SERVICE.md
2025-11-12 17:18:45 -05:00

7.0 KiB

PopoutService for Plugins

Overview

The PopoutService singleton provides plugins with access to all DankMaterialShell popouts and modals. It's automatically injected into plugin widgets and daemons, enabling them to control shell UI elements.

Automatic Injection

The popoutService property is automatically injected into:

  • Widget plugins (loaded in DankBar)
  • Daemon plugins (background services)
  • Plugin settings components

Required: Declare the property in your plugin component:

property var popoutService: null

Note: Without this declaration, the service cannot be injected and you'll see errors like Cannot assign to non-existent property "popoutService"

API Reference

Popouts (DankPopout-based)

Component Open Close Toggle
Control Center openControlCenter() closeControlCenter() toggleControlCenter()
Notification Center openNotificationCenter() closeNotificationCenter() toggleNotificationCenter()
App Drawer openAppDrawer() closeAppDrawer() toggleAppDrawer()
Process List openProcessList() closeProcessList() toggleProcessList()
DankDash openDankDash(tab) closeDankDash() toggleDankDash(tab)
Battery openBattery() closeBattery() toggleBattery()
VPN openVpn() closeVpn() toggleVpn()
System Update openSystemUpdate() closeSystemUpdate() toggleSystemUpdate()

Modals (DankModal-based)

Modal Show Hide Notes
Settings openSettings() closeSettings() Full settings interface
Clipboard History openClipboardHistory() closeClipboardHistory() Cliphist integration
Spotlight openSpotlight() closeSpotlight() Command launcher
Power Menu openPowerMenu() closePowerMenu() Also has togglePowerMenu()
Process List Modal showProcessListModal() hideProcessListModal() Fullscreen version, has toggleProcessListModal()
Color Picker showColorPicker() hideColorPicker() Theme color selection
Notification showNotificationModal() hideNotificationModal() Notification details
WiFi Password showWifiPasswordModal() hideWifiPasswordModal() Network authentication
Network Info showNetworkInfoModal() hideNetworkInfoModal() Network details

Slideouts

Component Open Close Toggle
Notepad openNotepad() closeNotepad() toggleNotepad()

Usage Examples

Simple Widget with Popout Control

import QtQuick
import qs.Common
import qs.Widgets

Rectangle {
    id: root

    property var popoutService: null

    width: 100
    height: 30
    color: Theme.surfaceContainerHigh
    radius: Theme.cornerRadius

    MouseArea {
        anchors.fill: parent
        onClicked: popoutService?.toggleControlCenter()
    }

    StyledText {
        anchors.centerIn: parent
        text: "Settings"
    }
}

Daemon with Event-Driven Popouts

import QtQuick
import qs.Services

Item {
    id: root

    property var popoutService: null

    Connections {
        target: NotificationService

        function onNotificationReceived(notification) {
            if (notification.urgency === "critical") {
                popoutService?.openNotificationCenter()
            }
        }
    }

    Connections {
        target: BatteryService

        function onPercentageChanged() {
            if (BatteryService.percentage < 10 && !BatteryService.isCharging) {
                popoutService?.openBattery()
            }
        }
    }
}

Widget with Multiple Popout Options

import QtQuick
import QtQuick.Controls
import qs.Common

Rectangle {
    property var popoutService: null

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton

        onClicked: (mouse) => {
            if (mouse.button === Qt.RightButton) {
                contextMenu.popup()
            } else {
                popoutService?.toggleControlCenter()
            }
        }
    }

    Menu {
        id: contextMenu

        MenuItem {
            text: "Settings"
            onClicked: popoutService?.openSettings()
        }

        MenuItem {
            text: "Notifications"
            onClicked: popoutService?.toggleNotificationCenter()
        }

        MenuItem {
            text: "Power Menu"
            onClicked: popoutService?.openPowerMenu()
        }
    }
}

Implementation Details

Service Architecture

PopoutService is a singleton that holds references to popout instances:

// Services/PopoutService.qml
Singleton {
    id: root

    property var controlCenterPopout: null
    property var notificationCenterPopout: null
    // ... other popout references

    function toggleControlCenter() {
        controlCenterPopout?.toggle()
    }
    // ... other control functions
}

Reference Assignment

References are assigned in DMSShell.qml when popouts are loaded:

LazyLoader {
    ControlCenterPopout {
        id: controlCenterPopout

        Component.onCompleted: {
            PopoutService.controlCenterPopout = controlCenterPopout
        }
    }
}

Plugin Injection

The service is injected in three locations:

  1. DMSShell.qml (daemon plugins):
Instantiator {
    delegate: Loader {
        onLoaded: {
            if (item) {
                item.popoutService = PopoutService
            }
        }
    }
}
  1. WidgetHost.qml (widget plugins):
onLoaded: {
    if (item.popoutService !== undefined) {
        item.popoutService = PopoutService
    }
}
  1. CenterSection.qml (center widgets):
onLoaded: {
    if (item.popoutService !== undefined) {
        item.popoutService = PopoutService
    }
}
  1. PluginsTab.qml (settings):
onLoaded: {
    if (item && typeof PopoutService !== "undefined") {
        item.popoutService = PopoutService
    }
}

Best Practices

  1. Use Optional Chaining: Always use ?. to handle null cases

    popoutService?.toggleControlCenter()
    
  2. Check Availability: Some popouts may not be available

    if (popoutService && popoutService.controlCenterPopout) {
        popoutService.toggleControlCenter()
    }
    
  3. Lazy Loading: First access may activate lazy loaders - this is normal

  4. Feature Detection: Some popouts require specific features

    if (BatteryService.batteryAvailable) {
        popoutService?.openBattery()
    }
    
  5. User Intent: Only trigger popouts based on user actions or critical events

Example Plugin

See PLUGINS/PopoutControlExample/ for a complete working example that demonstrates:

  • Widget creation with popout controls
  • Menu-based popout selection
  • Proper service usage
  • Error handling

Limitations

  • Popouts are shared across all plugins - avoid conflicts
  • Some popouts may be compositor or feature-dependent
  • Lazy-loaded popouts need activation before use
  • Multi-monitor considerations apply to positioned popouts