Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/shell.qml

Raw
//@ pragma IconTheme Papirus
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Widgets
import Quickshell.Services.UPower

ShellRoot {
    id: shell

    // Connector name of the monitor that hosts the interactive nuguland
    // surfaces (bar, OSD, toasts). Set e.g. "DP-1" to pin them; left empty it
    // falls back to the first connected screen. The wallpaper stays on every
    // screen; interactive security prompts stay on the primary screen.
    property string primaryOutput: ""
    readonly property var primaryScreens: {
        const screens = Quickshell.screens;
        const want = String(shell.primaryOutput || "");
        for (let i = 0; i < screens.length; i++)
            if (want.length === 0 || String(screens[i].name) === want)
                return [screens[i]];

        return [];
    }
    readonly property string primaryScreenName: primaryScreens.length > 0 ? String(primaryScreens[0].name) : ""

    // Bar orientation: "horizontal" (top edge, default) or "vertical" (left
    // edge). Injected into the Bar and the SurfaceManager so layout and popout
    // geometry share one source of truth.
    property string orientation: "horizontal"

    // Layer-shell surfaces size from anchors/implicitWidth only at map time, so
    // flipping orientation at runtime needs a remap: drop the bar then re-show
    // it a frame later to pick up the new thickness and anchored edges.
    property bool barRemap: true

    Timer {
        id: barRemapTimer

        interval: 60
        onTriggered: shell.barRemap = true
    }

    Format {
        id: format
    }

    Theme {
        id: nuguTheme

        lowPowerMode: power.lowPowerMode()
    }

    Time {
        id: time
    }

    CalDav {
        id: caldav
    }

    Niri {
        id: niri
    }

    Resources {
        id: resources

        // DI (never singletons inside the service): UPower/PowerProfiles singletons
        // for battery health + throttling, and the existing Brightness instance.
        upower: UPower
        powerProfiles: PowerProfiles
        brightnessService: brightness
    }

    Notifications {
        id: notifications
    }

    Tray {
        id: tray
    }

    Clipboard {
        id: clipboard
        surfaces: surfaceManager
        niriService: niri
    }

    Vault {
        id: vault

        clipboardService: clipboard
        panelOpen: surfaceManager.popoutOpen && surfaceManager.popoutName === "vault"
    }

    Connections {
        target: lock

        function onLogicalLockedChanged() {
            if (lock.logicalLocked)
                vault.lock();
        }
    }

    Launcher {
        id: launcher
    }

    Osd {
        id: osd
    }

    Media {
        id: media

        osdService: osd
        audioService: audio
    }

    Audio {
        id: audio

        osdService: osd
    }

    Brightness {
        id: brightness

        osdService: osd
        niriService: niri
    }

    Idle {
        id: idle
    }

    Privilege {
        id: privilege
    }

    Lock {
        id: lock

        theme: nuguTheme
        timeService: time
        mediaService: media
        notificationService: notifications
        powerService: power
    }

    Network {
        id: network
    }

    Bluetooth {
        id: bluetooth
    }

    Power {
        id: power

        lockService: lock
        niriService: niri
    }

    Screenshots {
        id: screenshots

        niriService: niri
        osdService: osd
    }

    SurfaceManager {
        id: surfaceManager

        niriService: niri
        powerService: power
        mediaService: media
        trayService: tray
    }

    Noko {
        id: noko
    }

    Usage {
        id: usage
    }

    Diagnostics {
        id: diagnosticsService

        surfaces: surfaceManager
        screens: Quickshell.screens
        niriService: niri
        audioService: audio
        networkService: network
        vaultService: vault
        nokoService: noko
    }

    Variants {
        model: Quickshell.screens

        delegate: Component {
            PanelWindow {
                required property var modelData

                objectName: "osdOverlaySurface"
                screen: modelData
                // primary monitor only — no value showing the OSD once per screen.
                visible: osd.visibleState && modelData.name === shell.primaryScreenName
                implicitWidth: 316
                implicitHeight: osdCard.implicitHeight + 64
                color: "transparent"
                exclusionMode: ExclusionMode.Ignore
                WlrLayershell.layer: WlrLayer.Overlay
                WlrLayershell.namespace: "nuguland-osd"
                WlrLayershell.keyboardFocus: WlrKeyboardFocus.None

                anchors {
                    top: true
                    right: true
                }

                // Mirrors the notification card's visual language (backdrop
                // alpha, radius, IconImage, IBM Plex, accent) but stays a
                // glance-only meter — no close/actions/body. The mask is left
                // empty on purpose: the OSD is non-interactive, so the surface
                // must pass clicks through (the inverse of the toast mask).
                Rectangle {
                    id: osdCard

                    readonly property var indicator: osd.valueIndicator(osd.currentEvent, osd.currentValue)
                    readonly property string roleColor: osd.currentRole === "error" ? nuguTheme.error : (osd.currentRole === "warning" ? nuguTheme.warning : nuguTheme.ui.accent)
                    readonly property bool hasBar: indicator.progressBar && indicator.progressBar.visible
                    readonly property bool isError: osd.currentRole === "error"
                    readonly property string resolvedIcon: Quickshell.iconPath(String(osd.iconName(osd.currentEvent, osd.currentValue)), true)

                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.top: parent.top
                    anchors.topMargin: 56
                    anchors.rightMargin: 24
                    anchors.leftMargin: 8
                    anchors.bottomMargin: 8
                    implicitHeight: osdRow.implicitHeight + 24
                    radius: 14
                    color: nuguTheme.withAlpha(nuguTheme.ui.backdrop, 0.92)
                    opacity: osd.visibleState ? 1 : 0

                    // left accent strip, like the notification card's urgency bar
                    Rectangle {
                        anchors.left: parent.left
                        anchors.top: parent.top
                        anchors.bottom: parent.bottom
                        width: 3
                        radius: 2
                        color: osdCard.roleColor
                    }

                    Row {
                        id: osdRow
                        anchors.left: parent.left
                        anchors.right: parent.right
                        anchors.leftMargin: 14
                        anchors.rightMargin: 14
                        anchors.verticalCenter: parent.verticalCenter
                        spacing: 12

                        Rectangle {
                            anchors.verticalCenter: parent.verticalCenter
                            width: 40
                            height: 40
                            radius: 12
                            color: nuguTheme.withAlpha(osdCard.roleColor, 0.18)

                            IconImage {
                                anchors.centerIn: parent
                                width: 24
                                height: 24
                                source: osdCard.resolvedIcon
                                visible: source.toString().length > 0
                            }
                        }

                        Column {
                            width: parent.width - 40 - parent.spacing
                            anchors.verticalCenter: parent.verticalCenter
                            spacing: 7

                            Row {
                                width: parent.width
                                spacing: 8

                                Text {
                                    id: osdLabel
                                    color: nuguTheme.content.normal
                                    font.family: "IBM Plex Sans"
                                    font.pixelSize: 14
                                    font.bold: true
                                    text: String(osdCard.indicator.displayLabel || "OSD")
                                    width: parent.width - osdValue.width - parent.spacing
                                    elide: Text.ElideRight
                                }

                                Text {
                                    id: osdValue
                                    anchors.baseline: osdLabel.baseline
                                    color: osdCard.hasBar ? osdCard.roleColor : nuguTheme.ui.normal
                                    font.family: "IBM Plex Mono"
                                    font.pixelSize: osdCard.hasBar ? 14 : 13
                                    font.bold: osdCard.hasBar
                                    text: osdCard.isError ? "" : String(osdCard.indicator.displayValue || "")
                                }
                            }

                            // hero meter for volume/brightness/microphone levels
                            Rectangle {
                                width: parent.width
                                height: osdCard.hasBar ? 5 : 0
                                visible: osdCard.hasBar
                                radius: 2.5
                                color: nuguTheme.withAlpha(nuguTheme.ui.minor, 0.28)

                                Rectangle {
                                    anchors.left: parent.left
                                    anchors.top: parent.top
                                    anchors.bottom: parent.bottom
                                    width: parent.width * Math.max(0, Math.min(1, osdCard.indicator.normalizedValue || 0))
                                    radius: parent.radius
                                    color: osdCard.roleColor
                                    Behavior on width {
                                        NumberAnimation {
                                            duration: nuguTheme.lowPowerMode ? 0 : 160
                                            easing.type: Easing.OutCubic
                                        }
                                    }
                                }
                            }

                            // error payload reads in the body line
                            Text {
                                visible: osdCard.isError
                                color: nuguTheme.error
                                font.family: "IBM Plex Sans"
                                font.pixelSize: 12
                                text: osd.currentValue
                                width: parent.width
                                wrapMode: Text.WordWrap
                                maximumLineCount: 2
                                elide: Text.ElideRight
                            }
                        }
                    }

                    Behavior on opacity {
                        NumberAnimation {
                            duration: nuguTheme.lowPowerMode ? 0 : 120
                            easing.type: Easing.OutCubic
                        }
                    }
                }

                mask: Region {}
            }
        }
    }

    Variants {
        model: Quickshell.screens

        delegate: Component {
            PanelWindow {
                id: nokoOverlayWindow

                required property var modelData

                objectName: "nokoFocusOverlaySurface"
                screen: modelData
                visible: (noko.overlayState || "").length > 0 && String(modelData.name || "") === String(niri.focusedOutputName || shell.primaryScreenName)
                implicitWidth: 1
                implicitHeight: 1
                color: "transparent"
                exclusionMode: ExclusionMode.Ignore
                WlrLayershell.layer: WlrLayer.Overlay
                WlrLayershell.namespace: "nuguland-noko-overlay"
                WlrLayershell.keyboardFocus: WlrKeyboardFocus.None

                anchors {
                    top: true
                    left: true
                    right: true
                    bottom: true
                }

                NokoFocusOverlay {
                    anchors.fill: parent
                    theme: nuguTheme
                    nokoService: noko
                    niriService: niri
                    barHeight: nokoOverlayWindow.modelData.name === shell.primaryScreenName ? surfaceManager.barHeight : 0
                    orientation: shell.orientation
                }

                mask: Region {}
            }
        }
    }

    Variants {
        model: Quickshell.screens

        delegate: Component {
            PanelWindow {
                id: toastSurface

                required property var modelData

                readonly property var toasts: notifications.activeToastRows()

                objectName: "notificationToastSurface"
                screen: modelData
                // primary monitor only, so a toast shows once, not once per screen.
                visible: toastSurface.toasts.length > 0 && modelData.name === shell.primaryScreenName
                implicitWidth: 404
                implicitHeight: Math.max(1, toastColumn.implicitHeight + 64)
                color: "transparent"
                exclusionMode: ExclusionMode.Ignore
                WlrLayershell.layer: WlrLayer.Overlay
                WlrLayershell.namespace: "nuguland-toast"
                WlrLayershell.keyboardFocus: WlrKeyboardFocus.None

                anchors {
                    top: true
                    right: true
                }
                Column {
                    id: toastColumn
                    anchors.top: parent.top
                    anchors.right: parent.right
                    anchors.topMargin: 56
                    anchors.rightMargin: 24
                    anchors.leftMargin: 8
                    anchors.bottomMargin: 8
                    width: parent.width - 32
                    spacing: 8

                    Repeater {
                        model: toastSurface.toasts
                        // Wrap in a plain Item: Qt6 does NOT inject an array
                        // model's modelData into a required property on an
                        // external-component (NotificationCard) delegate root —
                        // the wrapper takes the injection and passes it down
                        // explicitly. (Same fix used for the popup in Task 3.)
                        delegate: Item {
                            id: toastWrap
                            required property var modelData
                            width: toastColumn.width
                            implicitHeight: toastCard.implicitHeight
                            height: implicitHeight
                            NotificationCard {
                                id: toastCard
                                width: parent.width
                                theme: nuguTheme
                                modelData: toastWrap.modelData
                                compact: true
                                onDismiss: id => notifications.dismissToast(id)
                                onInvokeAction: (id, actionId) => notifications.runAction(id, actionId)
                            }
                            // Dismiss + drain derive from the service-stamped
                            // absolute expiresAt, not a fresh interval, so a
                            // Repeater rebuild (any other toast added/removed)
                            // resumes the countdown rather than restarting it.
                            readonly property real toastTotal: toastWrap.modelData.timeoutMs || 0
                            readonly property real toastExpiry: toastWrap.modelData.expiresAt || 0
                            readonly property real toastRemaining: Math.max(0, toastExpiry - Date.now())
                            readonly property int toastProgress: toastWrap.modelData.value !== undefined ? Number(toastWrap.modelData.value) : -1
                            readonly property bool toastHasProgress: toastProgress >= 0

                            // Progress toasts persist until complete (no drain
                            // dismissal); plain toasts auto-dismiss at expiry.
                            Timer {
                                running: toastWrap.toastExpiry > 0 && !toastWrap.toastHasProgress
                                interval: Math.max(1, toastWrap.toastRemaining)
                                repeat: false
                                onTriggered: notifications.dismissToast(String(toastWrap.modelData.id))
                            }
                            // Progress complete: auto-dismiss shortly after 100%.
                            Timer {
                                running: toastWrap.toastHasProgress && toastWrap.toastProgress >= 100
                                interval: 1500
                                repeat: false
                                onTriggered: notifications.dismissToast(String(toastWrap.modelData.id))
                            }
                            // bottom bar: content progress when the toast carries
                            // a value hint, otherwise the auto-dismiss drain.
                            Rectangle {
                                visible: toastWrap.toastHasProgress
                                anchors.left: toastCard.left
                                anchors.bottom: toastCard.bottom
                                anchors.leftMargin: 12
                                anchors.bottomMargin: 4
                                height: 2
                                radius: 1
                                color: nuguTheme ? nuguTheme.ui.accent : "transparent"
                                width: (toastCard.width - 24) * Math.max(0, Math.min(100, toastWrap.toastProgress)) / 100
                                Behavior on width {
                                    NumberAnimation {
                                        duration: nuguTheme && nuguTheme.lowPowerMode ? 0 : 200
                                    }
                                }
                            }
                            Rectangle {
                                visible: toastWrap.toastExpiry > 0 && !toastWrap.toastHasProgress
                                anchors.left: toastCard.left
                                anchors.bottom: toastCard.bottom
                                anchors.leftMargin: 12
                                anchors.bottomMargin: 4
                                height: 2
                                radius: 1
                                color: nuguTheme ? nuguTheme.withAlpha(nuguTheme.ui.accent, 0.55) : "transparent"
                                width: (toastCard.width - 24) * (toastWrap.toastTotal > 0 ? toastWrap.toastRemaining / toastWrap.toastTotal : 1)
                                NumberAnimation on width {
                                    running: toastWrap.toastExpiry > 0 && !toastWrap.toastHasProgress && !(nuguTheme && nuguTheme.lowPowerMode)
                                    to: 0
                                    duration: Math.max(1, toastWrap.toastRemaining)
                                }
                            }
                        }
                    }
                }

                // Accept input only over the toast cards (click to dismiss);
                // the transparent margins stay click-through to apps below.
                mask: Region {
                    item: toastColumn
                }
            }
        }
    }

    Variants {
        model: shell.primaryScreens

        delegate: Component {
            PanelWindow {
                required property var modelData

                objectName: "privilegeSecuritySurface"
                screen: modelData
                visible: privilege.active || privilege.error.length > 0 || privilege.confirming
                color: "transparent"
                exclusionMode: ExclusionMode.Ignore
                WlrLayershell.layer: WlrLayer.Overlay
                WlrLayershell.namespace: "nuguland-privilege"
                WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive

                anchors {
                    top: true
                    bottom: true
                    left: true
                    right: true
                }

                onVisibleChanged: if (visible)
                    Qt.callLater(privilegeSurface.focusSecret)

                PrivilegeSurface {
                    id: privilegeSurface

                    anchors.fill: parent
                    theme: nuguTheme
                    privilegeService: privilege
                }
            }
        }
    }

    Variants {
        model: Quickshell.screens

        delegate: Component {
            AuroraBackdrop {
                required property var modelData

                screen: modelData
                resourceService: resources
                lowPowerMode: power.lowPowerMode()
            }
        }
    }

    Variants {
        model: shell.barRemap ? shell.primaryScreens : []

        delegate: Component {
            Bar {
                required property var modelData

                // primary monitor only; the bar consolidates every output's
                // workspaces into per-output trays (see Bar.qml workspaceStrip).
                screen: modelData
                theme: nuguTheme
                niriService: niri
                timeService: time
                resourceService: resources
                notificationService: notifications
                trayService: tray
                mediaService: media
                clipboardService: clipboard
                vaultService: vault
                launcherService: launcher
                audioService: audio
                brightnessService: brightness
                networkService: network
                bluetoothService: bluetooth
                powerService: power
                privilegeService: privilege
                idleService: idle
                lockService: lock
                nokoService: noko
                surfaces: surfaceManager
                usageService: usage
                caldavService: caldav
                formatService: format
                orientation: shell.orientation
            }
        }
    }

    IpcHandler {
        target: "noko"

        function state(): string {
            return noko.stateJson();
        }

        function refresh(): string {
            return noko.refresh();
        }

        function install(): string {
            return noko.install();
        }

        function update(): string {
            return noko.update();
        }

        function checkUpdates(): string {
            return noko.checkUpdates();
        }

        function trigger(): string {
            return noko.trigger();
        }

        function start(): string {
            return noko.startCapture();
        }

        function stop(): string {
            return noko.stopCapture();
        }

        function transcribe(seconds: int): string {
            return noko.transcribe(seconds);
        }

        function listening(): string {
            return noko.beginListening();
        }

        function transcribing(): string {
            return noko.beginTranscribing();
        }

        function finish(): string {
            return noko.finish();
        }
    }

    IpcHandler {
        function increase() {
            return audio.increase();
        }

        function decrease() {
            return audio.decrease();
        }

        function muteOutput() {
            return audio.muteOutput();
        }

        function muteInput() {
            return audio.muteInput();
        }

        function route(action: string): string {
            return audio.route(action);
        }

        target: "volume"
    }

    IpcHandler {
        function next() {
            return media.action("next");
        }

        function previous() {
            return media.action("previous");
        }

        function playPause() {
            return media.action("playPause");
        }

        function stop() {
            return media.action("stop");
        }

        function shuffle() {
            return media.action("shuffle");
        }

        function repeat() {
            return media.action("repeat");
        }

        function route(action: string): string {
            return media.action(action);
        }

        target: "media"
    }

    IpcHandler {
        function increase(): string {
            return brightness.increase();
        }

        function decrease(): string {
            return brightness.decrease();
        }

        target: "brightness"
    }

    IpcHandler {
        function usageState(): string {
            return usage.stateJson();
        }

        function record(name: string): string {
            return usage.record(name);
        }

        target: "usage"
    }

    IpcHandler {
        target: "caldav"
        function state(): string {
            return caldav.stateJson();
        }
        function selfTest(): string {
            return caldav.selfTest();
        }
        function refresh(): string {
            caldav.refresh();
            return caldav.stateJson();
        }
    }

    IpcHandler {
        target: "system"
        function state(): string {
            return resources.stateJson();
        }
        function selfTest(): string {
            return resources.selfTest();
        }
    }

    IpcHandler {
        target: "clipboard"
        function selfTest(): string {
            return clipboard.selfTest();
        }
    }

    IpcHandler {
        target: "vault"

        function state(): string {
            return vault.stateJson();
        }

        function open(): string {
            vault.prepareOpen(niri.focusedAppId);
            return surfaceManager.openRegisteredPopout("vault", niri.focusedOutputName);
        }

        function lock(): string {
            vault.lock();
            return vault.stateJson();
        }

        function sync(): string {
            vault.sync();
            return vault.stateJson();
        }
    }

    IpcHandler {
        function ping(): string {
            return "nuguland";
        }

        function diagnostics(): string {
            return diagnosticsService.snapshot();
        }

        function niriState(): string {
            return niri.stateJson();
        }

        function niriSelfTest(): string {
            return JSON.stringify(niri.selfTest());
        }

        function setOrientation(mode: string): string {
            const want = String(mode);
            if (want === "toggle")
                shell.orientation = shell.orientation === "vertical" ? "horizontal" : "vertical";
            else if (want === "horizontal" || want === "vertical")
                shell.orientation = want;

            shell.barRemap = false;
            barRemapTimer.restart();
            return shell.orientation;
        }

        function abbreviateSelfTest(): string {
            return JSON.stringify(format.abbreviateSelfTest());
        }

        function reloadTheme() {
            nuguTheme.reload();
            return nuguTheme.mode;
        }

        function screenshotScreen(path: string): string {
            niri.screenshotScreen(path);
            return path;
        }

        function windowRuleMetadata(): string {
            return niri.windowRuleMetadata();
        }

        function windowCardAction(kind: string): string {
            return niri.windowCardAction(kind);
        }

        function openWindow(): string {
            return surfaceManager.openRegisteredPopout("window");
        }

        function timeState(): string {
            return time.stateJson();
        }

        function timeStateAt(iso: string): string {
            return time.stateAt(iso);
        }

        function timeRelative(fromIso: string, toIso: string): string {
            return time.relative(fromIso, toIso);
        }

        function timeCalendar(year: int, month: int, selectedDay: int): string {
            return time.calendar(year, month, selectedDay);
        }

        function openClock(): string {
            return surfaceManager.openRegisteredPopout("clock");
        }

        function systemWidgetState(): string {
            return resources.systemWidgetState();
        }

        function openSystem(): string {
            return surfaceManager.openRegisteredPopout("system");
        }

        function notificationWidgetState(attention: bool, active: bool): string {
            return notifications.widgetState(attention, active);
        }

        function notificationsState(): string {
            return notifications.stateJson();
        }

        function notificationsToggleDnd(): string {
            return notifications.toggleDnd();
        }

        function notificationsAction(id: string, actionId: string): string {
            return notifications.runAction(id, actionId);
        }

        function notificationsReply(id: string, text: string): string {
            return notifications.sendReply(id, text);
        }

        function notificationsToggleGroup(appName: string): string {
            return notifications.toggleGroup(appName);
        }

        function notificationsDiscardAll(): string {
            return notifications.discardAllNotifications();
        }

        function notificationsSelfTest(): string {
            return JSON.stringify(notifications.selfTest());
        }

        function notificationsDismissToasts(): string {
            return notifications.dismissToasts();
        }

        function trayWidgetState(attention: bool, active: bool): string {
            return tray.widgetState(attention, active);
        }

        function trayState(): string {
            return tray.stateJson();
        }

        function openTray(): string {
            return surfaceManager.openRegisteredPopout("tray");
        }

        function traySelectItem(id: string): string {
            return tray.selectItem(id);
        }

        function trayMenuExpand(id: string): string {
            return tray.expandSubmenu(id);
        }

        function trayMenuActivate(id: string): string {
            return tray.activateRow(id);
        }

        function trayMenuClose(reason: string): string {
            return tray.closeMenu(reason);
        }

        function launcherSearch(query: string): string {
            return launcher.search(query);
        }

        function launcherState(): string {
            return launcher.stateJson();
        }

        function launcherSelfTest(): string {
            return launcher.selfTest();
        }

        function launcherLaunchRecord(rowJson: string): string {
            return launcher.launchRecord(rowJson);
        }

        function launcherActivate(rowJson: string): string {
            return launcher.activate(rowJson);
        }

        function launcherActivateAction(rowJson: string, index: string): string {
            return launcher.activateAction(rowJson, Number(index));
        }

        function launcherActivateFirst(query: string): string {
            return launcher.activateFirst(query);
        }

        function launcherActivateId(id: string): string {
            return launcher.activateId(id);
        }

        function hotkey(id: string): string {
            return launcher.hotkey(id);
        }

        function openLauncher(): string {
            return surfaceManager.openRegisteredPopout("launcher", niri.focusedOutputName);
        }

        function osdTrigger(event: string, value: string): string {
            return osd.trigger(event, value);
        }

        function osdState(): string {
            return osd.stateJson();
        }

        function osdExpire(): string {
            return osd.expire();
        }

        function clipboardState(): string {
            return clipboard.stateJson();
        }

        function clipboardSearch(query: string): string {
            return clipboard.search(query);
        }

        function clipboardTogglePin(id: string): string {
            return clipboard.togglePin(id);
        }

        function clipboardCopy(id: string): string {
            return clipboard.copy(id);
        }

        function clipboardPaste(id: string): string {
            return clipboard.paste(id);
        }

        function clipboardDelete(id: string): string {
            return clipboard.deleteRow(id);
        }

        function clipboardPrivateMode(enabled: bool): string {
            return clipboard.setPrivateMode(enabled);
        }

        function openClipboard(): string {
            return surfaceManager.openRegisteredPopout("clipboard");
        }

        function openVault(): string {
            vault.prepareOpen(niri.focusedAppId);
            return surfaceManager.openRegisteredPopout("vault", niri.focusedOutputName);
        }

        function mediaState(): string {
            return media.stateJson();
        }

        function openMedia(): string {
            return surfaceManager.openRegisteredPopout("media");
        }

        function mediaAction(kind: string): string {
            return media.action(kind);
        }

        function mediaSeek(position: real): string {
            return media.seek(position);
        }

        function mediaSelect(id: string): string {
            return media.select(id);
        }

        function audioState(): string {
            return audio.stateJson();
        }

        function audioSelfTest(): string {
            return audio.selfTest();
        }

        function openAudio(): string {
            return surfaceManager.openRegisteredPopout("audio");
        }

        function privacyWidgetState(): string {
            return audio.privacyWidgetJson();
        }

        function audioSetVolume(id: string, volume: real): string {
            return audio.setVolume(id, volume);
        }

        function audioToggleMute(id: string): string {
            return audio.toggleMute(id);
        }

        function audioSetDefaultSink(id: string): string {
            return audio.setDefaultSink(id);
        }

        function audioSetDefaultSource(id: string): string {
            return audio.setDefaultSource(id);
        }

        function audioMoveStream(id: string, target: string): string {
            return audio.moveStream(id, target);
        }

        function brightnessState(): string {
            return brightness.stateJson();
        }

        function brightnessSelfTest(): string {
            return brightness.selfTest();
        }

        function openBrightness(): string {
            return surfaceManager.openRegisteredPopout("brightness");
        }

        function brightnessSetLevel(level: string): string {
            return brightness.setLevel(level);
        }

        function brightnessIncrease(): string {
            return brightness.increase();
        }

        function brightnessDecrease(): string {
            return brightness.decrease();
        }

        function idleState(): string {
            return idle.stateJson();
        }

        function idleToggle(): string {
            return idle.toggle();
        }

        function idleDisable(): string {
            return idle.disable();
        }

        function privilegeState(): string {
            return privilege.stateJson();
        }

        function privilegeSubmit(secret: string): string {
            return privilege.submit(secret);
        }

        function privilegeDeny(): string {
            return privilege.deny();
        }

        function privilegeCancel(): string {
            return privilege.cancel();
        }

        function privilegeFail(message: string): string {
            return privilege.fail(message);
        }

        function privilegeClear(): string {
            return privilege.clear();
        }

        function lockState(): string {
            return lock.stateJson();
        }

        function lockRequest(): string {
            return lock.request();
        }

        function lockType(secret: string): string {
            return lock.typeSecret(secret);
        }

        function lockSubmit(secret: string): string {
            return lock.submit(secret);
        }

        function lockCancel(): string {
            return lock.cancel();
        }

        function networkState(): string {
            return network.stateJson();
        }

        function networkSelfTest(): string {
            return network.selfTest();
        }

        function networkWidgetState(): string {
            const state = JSON.parse(network.stateJson());
            state.barLabel = "network";
            state.shader.values = [resources.networkRxLevel(), resources.networkTxLevel(), state.compact.signal / 100, state.wifi.enabled ? 1 : 0];
            state.shader.history = resources.shaderHistoryObject(resources.networkHistorySamples);
            state.rates = {
                "rxRate": resources.networkRxRate,
                "txRate": resources.networkTxRate,
                "rxLevel": resources.networkRxLevel(),
                "txLevel": resources.networkTxLevel()
            };
            return JSON.stringify(state);
        }

        function networkScan() {
            return network.scan();
        }

        function networkSelect(id: string): string {
            return network.select(id);
        }

        function networkToggleWifi(enabled: bool): string {
            return network.toggleWifi(enabled);
        }

        function networkForget(id: string): string {
            return network.forget(id);
        }

        function networkCheckConnectivity() {
            return network.checkConnectivity();
        }

        function bluetoothState(): string {
            return bluetooth.stateJson();
        }

        function bluetoothScan(): string {
            return bluetooth.scan();
        }

        function bluetoothToggle(enabled: bool): string {
            return bluetooth.toggle(enabled);
        }

        function bluetoothDeviceAction(kind: string, id: string): string {
            return bluetooth.deviceAction(kind, id);
        }

        function powerState(): string {
            return power.stateJson();
        }

        function openPower(): string {
            return surfaceManager.openRegisteredPopout("power");
        }

        function openNetwork(): string {
            return surfaceManager.openRegisteredPopout("connectivity");
        }

        function powerSelfTest(): string {
            return power.selfTest();
        }

        function powerSessionAction(kind: string): string {
            return power.sessionAction(kind);
        }

        function powerConfirmAction(kind: string): string {
            return power.confirmAction(kind);
        }

        function powerCancelAction(): string {
            return power.cancelAction();
        }

        function screenshotsState(): string {
            return screenshots.stateJson();
        }

        function screenshotsBeginSelection(x: real, y: real): string {
            return screenshots.beginSelection(x, y);
        }

        function screenshotsUpdateSelection(x: real, y: real): string {
            return screenshots.updateSelection(x, y);
        }

        function screenshotsCompleteSelection(path: string): string {
            return screenshots.completeSelection(path);
        }

        function screenshotsCancelSelection(): string {
            return screenshots.cancelSelection();
        }

        function screenshotsCapture(kind: string, path: string): string {
            return screenshots.capture(kind, path);
        }

        function screenshotsPickColor(): string {
            return screenshots.pickColor();
        }

        function screenshotsRecordAction(kind: string, id: string): string {
            return screenshots.recordAction(kind, id);
        }

        function screenshotsClear(): string {
            return screenshots.clear();
        }

        function openScreenshots(): string {
            return surfaceManager.openRegisteredPopout("screenshots");
        }

        function registeredAnchors(): string {
            return surfaceManager.registeredAnchors();
        }

        function popoutContentCatalog(): string {
            return surfaceManager.popoutContentCatalog();
        }

        function setPopoutScreen(width: int, height: int): string {
            return surfaceManager.setPopoutScreen(width, height);
        }

        function openPopout(name: string, anchor: string): string {
            return surfaceManager.openPopout(name, anchor);
        }

        function openRegisteredPopout(name: string): string {
            return surfaceManager.openRegisteredPopout(name);
        }

        function openNotifications(): string {
            return surfaceManager.openRegisteredPopout("notifications");
        }

        function hoverRegisteredPopout(name: string): string {
            return surfaceManager.hoverRegisteredPopout(name);
        }

        function closePopout(): string {
            return surfaceManager.closePopout("");
        }

        function popoutInteraction(kind: string): string {
            return surfaceManager.popoutInteraction(kind);
        }

        function popoutState(): string {
            return surfaceManager.popoutState();
        }

        function hideAll() {
            surfaceManager.closePopout("hideAll");
            return "ok";
        }

        target: "nuguland"
    }
}