import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell.Bluetooth import Quickshell.Networking import Quickshell.Services.Pipewire import Quickshell.Services.UPower Item { id: root property var controlCenter property var settings property var theme implicitHeight: pageColumn.implicitHeight ColumnLayout { id: pageColumn width: parent.width spacing: 10 SettingsCard { theme: root.theme title: "Wi-Fi" description: root.controlCenter && root.controlCenter.wifiDevice ? (root.controlCenter.wifiDevice.name || "Available networks") : "Wireless networking unavailable" Layout.fillWidth: true SettingsRow { theme: root.theme label: "Wireless" CCSwitch { theme: root.theme checked: Networking.wifiEnabled enabled: Networking.wifiHardwareEnabled onToggled: Networking.wifiEnabled = checked } } SettingsRow { theme: root.theme label: root.controlCenter && root.controlCenter.wifiDevice && root.controlCenter.wifiDevice.networks.values.find(network => network.connected) ? root.controlCenter.wifiDevice.networks.values.find(network => network.connected).name : "Not connected" CCButton { theme: root.theme text: "Scan" onClicked: { if (root.controlCenter && root.controlCenter.wifiDevice) root.controlCenter.wifiDevice.scannerEnabled = true; } } } Repeater { model: root.controlCenter && root.controlCenter.wifiDevice ? root.controlCenter.wifiDevice.networks : null delegate: SettingsRow { required property var modelData theme: root.theme label: modelData.name CCButton { theme: root.theme text: modelData.connected ? "Disconnect" : "Connect" enabled: !modelData.stateChanging onClicked: modelData.connected ? modelData.disconnect() : root.controlCenter.connectWifi(modelData) } } } SettingsRow { visible: root.controlCenter && root.controlCenter.pendingNetwork !== null theme: root.theme label: "Password" TextField { implicitWidth: 150 palette.base: root.theme.surfaceVariant palette.text: root.theme.text palette.placeholderText: root.theme.mutedText palette.highlight: root.theme.primary placeholderText: "Network password" echoMode: TextInput.Password text: root.controlCenter ? root.controlCenter.wifiPassword : "" onTextChanged: if (root.controlCenter) root.controlCenter.wifiPassword = text onAccepted: if (root.controlCenter) root.controlCenter.submitWifiPassword() } CCButton { theme: root.theme text: "Join" enabled: root.controlCenter && root.controlCenter.wifiPassword.length > 0 onClicked: root.controlCenter.submitWifiPassword() } } } SettingsCard { theme: root.theme title: "Bluetooth" description: root.controlCenter && root.controlCenter.bluetoothAdapter ? "Nearby devices" : "Bluetooth unavailable" Layout.fillWidth: true SettingsRow { theme: root.theme label: "Bluetooth" CCSwitch { theme: root.theme checked: root.controlCenter && root.controlCenter.bluetoothAdapter ? root.controlCenter.bluetoothAdapter.enabled : false enabled: root.controlCenter && root.controlCenter.bluetoothAdapter !== null onToggled: if (root.controlCenter.bluetoothAdapter) root.controlCenter.bluetoothAdapter.enabled = checked } CCButton { theme: root.theme text: root.controlCenter && root.controlCenter.bluetoothAdapter && root.controlCenter.bluetoothAdapter.discovering ? "Stop" : "Scan" enabled: root.controlCenter && root.controlCenter.bluetoothAdapter && root.controlCenter.bluetoothAdapter.enabled onClicked: if (root.controlCenter.bluetoothAdapter) root.controlCenter.bluetoothAdapter.discovering = !root.controlCenter.bluetoothAdapter.discovering } } Repeater { model: root.controlCenter && root.controlCenter.bluetoothAdapter ? root.controlCenter.bluetoothAdapter.devices : null delegate: SettingsRow { required property var modelData theme: root.theme label: modelData.name || modelData.deviceName || "Unknown device" description: modelData.connected ? "Connected" : (modelData.paired ? "Paired" : "Not paired") Label { visible: modelData.batteryAvailable text: Math.round(modelData.battery * 100) + "%" color: root.theme.mutedText } CCButton { theme: root.theme text: modelData.connected ? "Disconnect" : (modelData.paired ? "Connect" : "Pair") onClicked: { if (modelData.connected) modelData.disconnect(); else if (modelData.paired) modelData.connect(); else modelData.pair(); } } } } } SettingsCard { theme: root.theme title: "Audio" description: root.controlCenter && root.controlCenter.audioSink ? (root.controlCenter.audioSink.description || "Default output") : "Audio unavailable" Layout.fillWidth: true SettingsRow { theme: root.theme label: "Output volume" CCButton { theme: root.theme text: root.controlCenter && root.controlCenter.audioSink && root.controlCenter.audioSink.audio && root.controlCenter.audioSink.audio.muted ? "Unmute" : "Mute" enabled: !!(root.controlCenter && root.controlCenter.audioSink && root.controlCenter.audioSink.audio) onClicked: root.controlCenter.audioSink.audio.muted = !root.controlCenter.audioSink.audio.muted } Label { text: root.controlCenter && root.controlCenter.audioSink && root.controlCenter.audioSink.audio ? Math.round(root.controlCenter.audioSink.audio.volume * 100) + "%" : "--" color: root.theme.text } } CCSlider { theme: root.theme Layout.fillWidth: true from: 0 to: 1 value: root.controlCenter && root.controlCenter.audioSink && root.controlCenter.audioSink.audio ? root.controlCenter.audioSink.audio.volume : 0 enabled: !!(root.controlCenter && root.controlCenter.audioSink && root.controlCenter.audioSink.audio) onMoved: if (root.controlCenter.audioSink && root.controlCenter.audioSink.audio) root.controlCenter.audioSink.audio.volume = value } Repeater { model: Pipewire.nodes delegate: SettingsRow { required property var modelData visible: modelData.isSink && !modelData.isStream theme: root.theme label: modelData.description || modelData.name CCButton { theme: root.theme text: modelData === root.controlCenter.audioSink ? "Default" : "Use" enabled: modelData !== root.controlCenter.audioSink onClicked: Pipewire.preferredDefaultAudioSink = modelData } } } } SettingsCard { theme: root.theme title: "Display" description: "Brightness and power profile" Layout.fillWidth: true SettingsRow { theme: root.theme label: "Brightness" description: root.controlCenter && root.controlCenter.brightness > 0 ? root.controlCenter.brightness + "%" : "Unavailable" } CCSlider { theme: root.theme Layout.fillWidth: true from: 1 to: 100 value: root.controlCenter ? root.controlCenter.brightness : 0 enabled: root.controlCenter && root.controlCenter.brightness > 0 onPressedChanged: if (!pressed && root.controlCenter) root.controlCenter.setBrightness(value) } SettingsRow { theme: root.theme label: "Power profile" description: PowerProfile.toString(PowerProfiles.profile) CCButton { theme: root.theme; text: "Saver"; onClicked: PowerProfiles.profile = PowerProfile.PowerSaver } CCButton { theme: root.theme; text: "Balanced"; accent: true; onClicked: PowerProfiles.profile = PowerProfile.Balanced } CCButton { theme: root.theme; text: "Performance"; enabled: PowerProfiles.hasPerformanceProfile; onClicked: PowerProfiles.profile = PowerProfile.Performance } } } } }