201 lines
6.5 KiB
QML
201 lines
6.5 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import qs.Common
|
|
import qs.Modules.Plugins
|
|
import qs.Services
|
|
import qs.Widgets
|
|
import "./components"
|
|
|
|
PluginComponent {
|
|
id: root
|
|
|
|
property var popoutService: null
|
|
|
|
readonly property var daemon: (typeof PluginService !== "undefined" && PluginService.pluginInstances) ? PluginService.pluginInstances["gameBar"] : null
|
|
// "focused" follows whichever monitor has focus, "own" sticks to the screen
|
|
// this particular bar instance lives on.
|
|
readonly property string targetMode: String(pluginData.barBrightnessTarget || "focused")
|
|
|
|
property var resolvedScreen: null
|
|
|
|
readonly property string screenName: {
|
|
const screen = root.resolvedScreen || root.parentScreen;
|
|
return (screen && screen.name) ? screen.name : "";
|
|
}
|
|
readonly property string deviceId: root.daemon ? root.daemon.brightnessDeviceForScreen(root.screenName) : ""
|
|
readonly property var device: DisplayService.devices ? (DisplayService.devices.find(d => d.id === root.deviceId) || null) : null
|
|
readonly property bool usable: DisplayService.brightnessAvailable && root.deviceId !== ""
|
|
readonly property int brightness: {
|
|
DisplayService.brightnessVersion;
|
|
return root.deviceId !== "" ? DisplayService.getDeviceBrightness(root.deviceId) : 0;
|
|
}
|
|
readonly property string brightnessIcon: {
|
|
if (!root.usable)
|
|
return "brightness_low";
|
|
if (root.brightness <= 33)
|
|
return "brightness_low";
|
|
if (root.brightness <= 66)
|
|
return "brightness_medium";
|
|
return "brightness_high";
|
|
}
|
|
|
|
function updateScreen() {
|
|
if (root.targetMode === "own") {
|
|
root.resolvedScreen = root.parentScreen;
|
|
return;
|
|
}
|
|
|
|
root.resolvedScreen = CompositorService.getFocusedScreen() || root.parentScreen;
|
|
}
|
|
|
|
// The Control Center pill click follows the shell's own convention for
|
|
// non-boolean widgets (see DisplayProfilesWidget): step through presets.
|
|
readonly property var brightnessPresets: [10, 25, 50, 75, 100]
|
|
|
|
function cyclePreset() {
|
|
if (!root.usable)
|
|
return;
|
|
|
|
const current = root.brightness;
|
|
for (let i = 0; i < root.brightnessPresets.length; i++) {
|
|
if (root.brightnessPresets[i] > current + 1) {
|
|
DisplayService.setBrightness(root.brightnessPresets[i], root.deviceId, false);
|
|
return;
|
|
}
|
|
}
|
|
|
|
DisplayService.setBrightness(root.brightnessPresets[0], root.deviceId, false);
|
|
}
|
|
|
|
function adjust(delta) {
|
|
if (!root.usable)
|
|
return;
|
|
|
|
const next = Math.max(1, Math.min(100, root.brightness + delta));
|
|
DisplayService.setBrightness(next, root.deviceId, false);
|
|
}
|
|
|
|
pluginId: "gameBar"
|
|
pluginService: PluginService
|
|
popoutWidth: 320
|
|
popoutHeight: 150
|
|
|
|
Component.onCompleted: {
|
|
root.updateScreen();
|
|
if (root.daemon)
|
|
root.daemon.ensureBrightnessMap();
|
|
}
|
|
|
|
onTargetModeChanged: root.updateScreen()
|
|
|
|
// Focus usually moves with the active toplevel; the timer covers moves to an
|
|
// empty workspace on another monitor, which raise no toplevel change.
|
|
Connections {
|
|
target: ToplevelManager
|
|
|
|
function onActiveToplevelChanged() {
|
|
root.updateScreen();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
running: root.targetMode === "focused"
|
|
interval: 2000
|
|
repeat: true
|
|
onTriggered: root.updateScreen()
|
|
}
|
|
|
|
horizontalBarPill: Component {
|
|
Item {
|
|
implicitWidth: pillRow.implicitWidth + Theme.spacingS * 2
|
|
height: parent.widgetThickness
|
|
|
|
Row {
|
|
id: pillRow
|
|
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
name: root.brightnessIcon
|
|
size: root.iconSize
|
|
color: root.usable ? Theme.surfaceText : Theme.surfaceVariantText
|
|
}
|
|
|
|
StyledText {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: root.usable ? root.brightness + "%" : "--"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceText
|
|
}
|
|
}
|
|
|
|
WheelHandler {
|
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
onWheel: event => root.adjust(event.angleDelta.y > 0 ? 5 : -5)
|
|
}
|
|
}
|
|
}
|
|
|
|
verticalBarPill: Component {
|
|
Item {
|
|
width: parent.widgetThickness
|
|
implicitHeight: verticalColumn.implicitHeight + Theme.spacingS * 2
|
|
|
|
Column {
|
|
id: verticalColumn
|
|
|
|
anchors.centerIn: parent
|
|
spacing: 0
|
|
|
|
DankIcon {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
name: root.brightnessIcon
|
|
size: root.iconSize
|
|
color: root.usable ? Theme.surfaceText : Theme.surfaceVariantText
|
|
}
|
|
|
|
StyledText {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: root.usable ? root.brightness : "--"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceText
|
|
}
|
|
}
|
|
|
|
WheelHandler {
|
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
|
onWheel: event => root.adjust(event.angleDelta.y > 0 ? 5 : -5)
|
|
}
|
|
}
|
|
}
|
|
|
|
popoutContent: Component {
|
|
PopoutComponent {
|
|
headerText: "Brightness"
|
|
detailsText: root.screenName !== "" ? root.screenName + (root.deviceId !== "" ? " · " + root.deviceId : "") : "No display detected"
|
|
showCloseButton: true
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Theme.spacingS
|
|
|
|
BrightnessControl {
|
|
width: parent.width
|
|
daemon: root.daemon
|
|
screenName: root.screenName
|
|
}
|
|
|
|
StyledText {
|
|
width: parent.width
|
|
text: root.targetMode === "own" ? "Controls this monitor" : "Follows the focused monitor"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|