Possible brightness implementation
This commit is contained in:
parent
867444a29c
commit
2d31e04eaf
4 changed files with 549 additions and 0 deletions
|
|
@ -119,6 +119,10 @@ Variants {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Brightness {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
Clock {
|
Clock {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
|
||||||
63
Modules/Bar/Brightness.qml
Normal file
63
Modules/Bar/Brightness.qml
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Modules.Settings
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: pill.width
|
||||||
|
height: pill.height
|
||||||
|
|
||||||
|
// Used to avoid opening the pill on Quickshell startup
|
||||||
|
property bool firstBrightnessReceived: false
|
||||||
|
|
||||||
|
function getIcon() {
|
||||||
|
if (!BrightnessService.available) {
|
||||||
|
return "brightness_auto"
|
||||||
|
}
|
||||||
|
var brightness = BrightnessService.brightness
|
||||||
|
return brightness <= 0 ? "brightness_1" :
|
||||||
|
brightness < 33 ? "brightness_low" :
|
||||||
|
brightness < 66 ? "brightness_medium" : "brightness_high"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection used to open the pill when brightness changes
|
||||||
|
Connections {
|
||||||
|
target: Brightness
|
||||||
|
function onBrightnessUpdated() {
|
||||||
|
// console.log("[Bar:Brightness] onBrightnessUpdated")
|
||||||
|
if (!firstBrightnessReceived) {
|
||||||
|
// Ignore the first brightness change
|
||||||
|
firstBrightnessReceived = true
|
||||||
|
} else {
|
||||||
|
pill.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NPill {
|
||||||
|
id: pill
|
||||||
|
icon: getIcon()
|
||||||
|
iconCircleColor: Colors.mPrimary
|
||||||
|
collapsedIconColor: Colors.mOnSurface
|
||||||
|
autoHide: true
|
||||||
|
text: Math.round(BrightnessService.brightness) + "%"
|
||||||
|
tooltipText: "Brightness: " + Math.round(BrightnessService.brightness) + "%\nMethod: " + BrightnessService.currentMethod + "\nLeft click for advanced settings.\nScroll up/down to change BrightnessService."
|
||||||
|
|
||||||
|
onWheel: function (angle) {
|
||||||
|
if (!BrightnessService.available) return
|
||||||
|
|
||||||
|
if (angle > 0) {
|
||||||
|
BrightnessService.increaseBrightness(1)
|
||||||
|
} else if (angle < 0) {
|
||||||
|
BrightnessService.decreaseBrightness(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||||
|
settingsPanel.isLoaded = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -273,6 +273,60 @@ NLoader {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Brightness Control
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginMedium * scaling
|
||||||
|
NText {
|
||||||
|
text: "Brightness Control"
|
||||||
|
color: Colors.mSecondary
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: `Brightness: ${Math.round(Brightness.brightness)}%`
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: Style.marginSmall * scaling
|
||||||
|
NIconButton {
|
||||||
|
icon: "brightness_low"
|
||||||
|
fontPointSize: Style.fontSizeLarge * scaling
|
||||||
|
onClicked: {
|
||||||
|
Brightness.decreaseBrightness(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSlider {
|
||||||
|
from: 0
|
||||||
|
to: 100
|
||||||
|
stepSize: 1
|
||||||
|
value: Brightness.brightness
|
||||||
|
implicitWidth: bgRect.width * 0.5
|
||||||
|
onMoved: {
|
||||||
|
Brightness.setBrightnessDebounced(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NIconButton {
|
||||||
|
icon: "brightness_high"
|
||||||
|
fontPointSize: Style.fontSizeLarge * scaling
|
||||||
|
onClicked: {
|
||||||
|
Brightness.increaseBrightness(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: `Method: ${Brightness.currentMethod} | Available: ${Brightness.available}`
|
||||||
|
color: Colors.mOnSurfaceVariant
|
||||||
|
font.pointSize: Style.fontSizeSmall * scaling
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
428
Services/BrightnessService.qml
Normal file
428
Services/BrightnessService.qml
Normal file
|
|
@ -0,0 +1,428 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Public properties
|
||||||
|
property real brightness: 0
|
||||||
|
property real maxBrightness: 100
|
||||||
|
property bool available: false
|
||||||
|
property string currentMethod: ""
|
||||||
|
property var detectedDisplays: []
|
||||||
|
|
||||||
|
// Private properties
|
||||||
|
property var _brightnessMethods: []
|
||||||
|
property var _currentDisplay: null
|
||||||
|
property bool _initialized: false
|
||||||
|
property real _targetBrightness: 0
|
||||||
|
property bool _isSettingBrightness: false
|
||||||
|
|
||||||
|
// Signal when brightness changes
|
||||||
|
signal brightnessUpdated(real newBrightness)
|
||||||
|
signal methodChanged(string newMethod)
|
||||||
|
|
||||||
|
// Initialize the service
|
||||||
|
Component.onCompleted: {
|
||||||
|
initializeBrightness()
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeBrightness() {
|
||||||
|
if (_initialized) return
|
||||||
|
|
||||||
|
console.log("[Brightness] Initializing brightness service...")
|
||||||
|
|
||||||
|
// Start method detection
|
||||||
|
detectMethods()
|
||||||
|
|
||||||
|
_initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function detectMethods() {
|
||||||
|
_brightnessMethods = []
|
||||||
|
|
||||||
|
// Check for brightnessctl
|
||||||
|
brightnessctlProcess.running = true
|
||||||
|
|
||||||
|
// Check for ddcutil
|
||||||
|
ddcutilProcess.running = true
|
||||||
|
|
||||||
|
// Internal backlight is always available if we can access /sys/class/backlight
|
||||||
|
backlightCheck.running = true
|
||||||
|
|
||||||
|
console.log("[Brightness] Starting method detection...")
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMethodsComplete() {
|
||||||
|
// Check if all method detection processes have finished
|
||||||
|
if (!brightnessctlProcess.running && !ddcutilProcess.running && !backlightCheck.running) {
|
||||||
|
console.log("[Brightness] Available methods:", _brightnessMethods)
|
||||||
|
|
||||||
|
// Now detect displays
|
||||||
|
detectDisplays()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process objects for method detection
|
||||||
|
Process {
|
||||||
|
id: brightnessctlProcess
|
||||||
|
command: ["which", "brightnessctl"]
|
||||||
|
running: false
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
_brightnessMethods.push("brightnessctl")
|
||||||
|
console.log("[Brightness] brightnessctl available")
|
||||||
|
}
|
||||||
|
checkMethodsComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: ddcutilProcess
|
||||||
|
command: ["which", "ddcutil"]
|
||||||
|
running: false
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
_brightnessMethods.push("ddcutil")
|
||||||
|
console.log("[Brightness] ddcutil available")
|
||||||
|
}
|
||||||
|
checkMethodsComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: backlightCheck
|
||||||
|
command: ["test", "-d", "/sys/class/backlight"]
|
||||||
|
running: false
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
_brightnessMethods.push("internal")
|
||||||
|
console.log("[Brightness] Internal backlight available")
|
||||||
|
}
|
||||||
|
checkMethodsComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function detectDisplays() {
|
||||||
|
detectedDisplays = []
|
||||||
|
|
||||||
|
// Get internal displays
|
||||||
|
backlightProcess.running = true
|
||||||
|
|
||||||
|
// Get external displays via ddcutil
|
||||||
|
if (_brightnessMethods.indexOf("ddcutil") !== -1) {
|
||||||
|
ddcutilDetectProcess.running = true
|
||||||
|
} else {
|
||||||
|
// If no ddcutil, just check internal displays
|
||||||
|
checkDisplaysComplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[Brightness] Starting display detection...")
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDisplaysComplete() {
|
||||||
|
// Check if all display detection processes have finished
|
||||||
|
var internalFinished = !backlightProcess.running
|
||||||
|
var externalFinished = _brightnessMethods.indexOf("ddcutil") === -1 || !ddcutilDetectProcess.running
|
||||||
|
|
||||||
|
if (internalFinished && externalFinished) {
|
||||||
|
console.log("[Brightness] Detected displays:", detectedDisplays)
|
||||||
|
|
||||||
|
// Set current display to first available
|
||||||
|
if (detectedDisplays.length > 0) {
|
||||||
|
_currentDisplay = detectedDisplays[0]
|
||||||
|
currentMethod = _currentDisplay.method
|
||||||
|
available = true
|
||||||
|
console.log("[Brightness] Using display:", _currentDisplay.name, "method:", currentMethod)
|
||||||
|
|
||||||
|
// Start initial brightness update
|
||||||
|
updateBrightness()
|
||||||
|
} else {
|
||||||
|
console.warn("[Brightness] No displays detected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process objects for display detection
|
||||||
|
Process {
|
||||||
|
id: backlightProcess
|
||||||
|
command: ["ls", "/sys/class/backlight"]
|
||||||
|
running: false
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: function(line) {
|
||||||
|
var trimmedLine = line.replace(/^\s+|\s+$/g, "")
|
||||||
|
if (trimmedLine) {
|
||||||
|
detectedDisplays.push({
|
||||||
|
name: trimmedLine,
|
||||||
|
type: "internal",
|
||||||
|
method: "internal"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
checkDisplaysComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: ddcutilDetectProcess
|
||||||
|
command: ["ddcutil", "detect"]
|
||||||
|
running: false
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: function(line) {
|
||||||
|
console.log("[Brightness] ddcutil detect line:", line)
|
||||||
|
if (line.indexOf("Display") !== -1) {
|
||||||
|
// Simple parsing for Display number
|
||||||
|
var parts = line.split("Display")
|
||||||
|
if (parts.length > 1) {
|
||||||
|
var numberPart = parts[1].replace(/^\s+|\s+$/g, "")
|
||||||
|
var number = numberPart.split(" ")[0]
|
||||||
|
if (number && !isNaN(number)) {
|
||||||
|
detectedDisplays.push({
|
||||||
|
name: "Display " + number,
|
||||||
|
type: "external",
|
||||||
|
method: "ddcutil",
|
||||||
|
index: number
|
||||||
|
})
|
||||||
|
console.log("[Brightness] Added external display:", "Display " + number)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also look for connector information
|
||||||
|
if (line.indexOf("DRM connector:") !== -1) {
|
||||||
|
console.log("[Brightness] Found DRM connector:", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
checkDisplaysComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBrightness() {
|
||||||
|
if (!_currentDisplay) return
|
||||||
|
|
||||||
|
// Prevent multiple simultaneous brightness checks
|
||||||
|
if (brightnessGetProcess.running) {
|
||||||
|
console.log("[Brightness] Brightness check already in progress, skipping...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't update if we're currently setting brightness
|
||||||
|
if (_isSettingBrightness) {
|
||||||
|
console.log("[Brightness] Skipping update while setting brightness...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[Brightness] Updating brightness for display:", _currentDisplay.name)
|
||||||
|
|
||||||
|
// Try the brightness script first
|
||||||
|
if (_currentDisplay.method === "ddcutil" && _currentDisplay.index) {
|
||||||
|
// For ddcutil, try using the display index directly
|
||||||
|
brightnessGetProcess.command = ["ddcutil", "--display", _currentDisplay.index, "getvcp", "10"]
|
||||||
|
} else {
|
||||||
|
// Use the brightness script
|
||||||
|
brightnessGetProcess.command = ["sh", "-c", Quickshell.shellDir + "/Bin/brigthness.sh", "get", _currentDisplay.name]
|
||||||
|
}
|
||||||
|
brightnessGetProcess.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBrightnessDebounced() {
|
||||||
|
// Use debouncing to prevent excessive updates
|
||||||
|
debounceTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBrightness(newBrightness) {
|
||||||
|
if (!_currentDisplay || !available) {
|
||||||
|
console.warn("[Brightness] No display available for brightness control")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp brightness to valid range
|
||||||
|
newBrightness = Math.max(0, Math.min(100, newBrightness))
|
||||||
|
|
||||||
|
// Prevent setting if already setting
|
||||||
|
if (brightnessSetProcess.running) {
|
||||||
|
console.log("[Brightness] Brightness set already in progress, skipping...")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[Brightness] Setting brightness to:", newBrightness, "for display:", _currentDisplay.name)
|
||||||
|
|
||||||
|
// Mark that we're setting brightness
|
||||||
|
_isSettingBrightness = true
|
||||||
|
|
||||||
|
// Try ddcutil directly for external displays
|
||||||
|
if (_currentDisplay.method === "ddcutil" && _currentDisplay.index) {
|
||||||
|
brightnessSetProcess.command = ["ddcutil", "--display", _currentDisplay.index, "setvcp", "10", newBrightness.toString()]
|
||||||
|
} else {
|
||||||
|
// Use the brightness script for internal displays
|
||||||
|
brightnessSetProcess.command = ["sh", "-c", Quickshell.shellDir + "/Bin/brigthness.sh", "set", _currentDisplay.name, newBrightness.toString()]
|
||||||
|
}
|
||||||
|
brightnessSetProcess.running = true
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBrightnessDebounced(newBrightness) {
|
||||||
|
// Store the target brightness for debounced setting
|
||||||
|
_targetBrightness = newBrightness
|
||||||
|
|
||||||
|
// Update UI immediately for responsiveness
|
||||||
|
if (brightness !== newBrightness) {
|
||||||
|
brightness = newBrightness
|
||||||
|
brightnessUpdated(brightness)
|
||||||
|
}
|
||||||
|
|
||||||
|
setDebounceTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process objects for brightness control
|
||||||
|
Process {
|
||||||
|
id: brightnessGetProcess
|
||||||
|
running: false
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: function(line) {
|
||||||
|
var newBrightness = -1
|
||||||
|
|
||||||
|
// Handle ddcutil output format: "current value = X,"
|
||||||
|
if (line.indexOf("current value =") !== -1) {
|
||||||
|
var match = line.match(/current value\s*=\s*(\d+)/)
|
||||||
|
if (match) {
|
||||||
|
newBrightness = parseFloat(match[1])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle direct numeric output
|
||||||
|
newBrightness = parseFloat(line.replace(/^\s+|\s+$/g, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNaN(newBrightness) && newBrightness >= 0) {
|
||||||
|
if (brightness !== newBrightness) {
|
||||||
|
brightness = newBrightness
|
||||||
|
brightnessUpdated(brightness)
|
||||||
|
console.log("[Brightness] Brightness updated to:", brightness)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn("[Brightness] Invalid brightness value:", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
// Only log errors
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
console.warn("[Brightness] Brightness get process failed with code:", exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: brightnessSetProcess
|
||||||
|
running: false
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: function(line) {
|
||||||
|
var result = parseFloat(line.replace(/^\s+|\s+$/g, ""))
|
||||||
|
if (!isNaN(result) && result >= 0) {
|
||||||
|
brightness = result
|
||||||
|
brightnessUpdated(brightness)
|
||||||
|
console.log("[Brightness] Brightness set to:", brightness)
|
||||||
|
} else {
|
||||||
|
console.warn("[Brightness] Failed to set brightness - invalid output:", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: function(exitCode, exitStatus) {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
// If ddcutil succeeded but didn't output a number, refresh the brightness
|
||||||
|
if (_currentDisplay.method === "ddcutil") {
|
||||||
|
// Longer delay to let the display update and avoid conflicts
|
||||||
|
refreshTimer.interval = 1000
|
||||||
|
refreshTimer.start()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn("[Brightness] Set brightness process failed with exit code:", exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the setting flag after a delay
|
||||||
|
settingCompleteTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer to clear the setting flag
|
||||||
|
Timer {
|
||||||
|
id: settingCompleteTimer
|
||||||
|
interval: 800
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
_isSettingBrightness = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer to refresh brightness after setting
|
||||||
|
Timer {
|
||||||
|
id: refreshTimer
|
||||||
|
interval: 500
|
||||||
|
repeat: false
|
||||||
|
onTriggered: updateBrightnessDebounced()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function increaseBrightness(step = 5) {
|
||||||
|
return setBrightnessDebounced(brightness + step)
|
||||||
|
}
|
||||||
|
|
||||||
|
function decreaseBrightness(step = 5) {
|
||||||
|
return setBrightnessDebounced(brightness - step)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDisplay(displayIndex) {
|
||||||
|
if (displayIndex >= 0 && displayIndex < detectedDisplays.length) {
|
||||||
|
_currentDisplay = detectedDisplays[displayIndex]
|
||||||
|
currentMethod = _currentDisplay.method
|
||||||
|
methodChanged(currentMethod)
|
||||||
|
updateBrightness()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayInfo() {
|
||||||
|
return _currentDisplay || null
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAvailableMethods() {
|
||||||
|
return _brightnessMethods
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDetectedDisplays() {
|
||||||
|
return detectedDisplays
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh brightness periodically - but less frequently
|
||||||
|
Timer {
|
||||||
|
interval: 5000 // Update every 5 seconds instead of 2
|
||||||
|
running: available && _initialized
|
||||||
|
repeat: true
|
||||||
|
onTriggered: updateBrightness()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounce timer for UI updates
|
||||||
|
Timer {
|
||||||
|
id: debounceTimer
|
||||||
|
interval: 300
|
||||||
|
repeat: false
|
||||||
|
onTriggered: updateBrightness()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounce timer for setting brightness
|
||||||
|
Timer {
|
||||||
|
id: setDebounceTimer
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: setBrightness(_targetBrightness)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue