Decrease gamma when attempting to decrease brightness below 0 (#3122)

This commit is contained in:
Minh
2026-03-24 22:57:53 +01:00
committed by GitHub
17 changed files with 264 additions and 103 deletions
@@ -59,8 +59,8 @@ Item { // Bar content region
implicitWidth: leftSectionRowLayout.implicitWidth
implicitHeight: Appearance.sizes.baseBarHeight
onScrollDown: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05)
onScrollUp: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05)
onScrollDown: Brightness.decreaseBrightness()
onScrollUp: Brightness.increaseBrightness()
onMovedAway: GlobalStates.osdBrightnessOpen = false
onPressed: event => {
if (event.button === Qt.LeftButton)
@@ -70,7 +70,7 @@ Item { // Bar content region
// Visual content
ScrollHint {
reveal: barLeftSideMouseArea.hovered
icon: "light_mode"
icon: Hyprsunset.gamma === 100 ? "light_mode" : "wb_twilight"
tooltipText: Translation.tr("Scroll to change brightness")
side: "left"
anchors.left: parent.left
@@ -25,6 +25,10 @@ Scope {
id: "brightness",
sourceUrl: "indicators/BrightnessIndicator.qml"
},
{
id: "gamma",
sourceUrl: "indicators/GammaIndicator.qml"
},
]
function triggerOsd() {
@@ -52,6 +56,15 @@ Scope {
}
}
Connections {
target: Hyprsunset
function onGammaChangeAttempt() {
root.protectionMessage = "";
root.currentIndicator = "gamma";
root.triggerOsd();
}
}
Connections {
// Listen to volume changes
target: Audio.sink?.audio ?? null
@@ -11,6 +11,8 @@ Item {
required property string name
property bool rotateIcon: false
property bool scaleIcon: false
property alias from: valueProgressBar.from
property alias to: valueProgressBar.to
property real valueIndicatorVerticalPadding: 9
property real valueIndicatorLeftPadding: 10
@@ -9,7 +9,7 @@ OsdValueIndicator {
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
icon: Hyprsunset.active ? "routine" : "light_mode"
icon: Hyprsunset.temperatureActive ? "routine" : "light_mode"
rotateIcon: true
scaleIcon: true
name: Translation.tr("Brightness")
@@ -0,0 +1,14 @@
import qs.services
import QtQuick
import Quickshell
import Quickshell.Hyprland
import qs.modules.ii.onScreenDisplay
OsdValueIndicator {
id: rotateIcon
icon: "wb_twilight"
name: Translation.tr("Gamma")
from: Hyprsunset.gammaLowerLimit / 100
value: Hyprsunset.gamma / 100 ?? 0.5
}
@@ -98,7 +98,7 @@ Scope {
if (!Config.options.sidebar.cornerOpen.valueScroll)
return;
if (cornerWidget.isLeft)
cornerPanelWindow.brightnessMonitor.setBrightness(cornerPanelWindow.brightnessMonitor.brightness - 0.05);
Brightness.decreaseBrightness()
else {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
@@ -109,7 +109,7 @@ Scope {
if (!Config.options.sidebar.cornerOpen.valueScroll)
return;
if (cornerWidget.isLeft)
cornerPanelWindow.brightnessMonitor.setBrightness(cornerPanelWindow.brightnessMonitor.brightness + 0.05);
Brightness.increaseBrightness()
else {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
@@ -40,10 +40,25 @@ Rectangle {
visible: active
active: Config.options.sidebar.quickSliders.showBrightness
sourceComponent: QuickSlider {
materialSymbol: "brightness_6"
value: root.brightnessMonitor.brightness
materialSymbol: "light_mode"
secondaryMaterialSymbol: "wb_twilight"
stopIndicatorValues: Hyprsunset.gamma !== 100 && root.brightnessMonitor?.brightness !== 0 ? [0.3 + root.brightnessMonitor?.brightness * 0.7] : []
value: Hyprsunset.gamma === 100? 0.3 + root.brightnessMonitor?.brightness * 0.7 : Hyprsunset.gamma / 100 * 0.3
tooltipContent: Hyprsunset.gamma === 100 ? `${Math.round(root.brightnessMonitor?.brightness * 100)}%` : `${Translation.tr("Gamma")} ${Hyprsunset.gamma}%`
onMoved: {
root.brightnessMonitor.setBrightness(value)
if (value >= 0.3) {
// 0.3 - 1.0 brightness
root.brightnessMonitor.setBrightness((value - 0.3) / 0.7);
if (Hyprsunset.gamma !== 100) {
Hyprsunset.setGamma(100);
}
} else {
// 0 - 0.3 gamma
if (root.brightnessMonitor.brightness !== 0) {
root.brightnessMonitor.setBrightness(0);
}
Hyprsunset.setGamma(value * 100 / 0.3);
}
}
}
}
@@ -84,16 +99,18 @@ Rectangle {
component QuickSlider: StyledSlider {
id: quickSlider
required property string materialSymbol
property string secondaryMaterialSymbol
configuration: StyledSlider.Configuration.M
stopIndicatorValues: []
dividerValues: secondaryMaterialSymbol.length > 0 ? [secondaryIcon.iconLocation] : []
MaterialSymbol {
id: icon
property bool nearFull: quickSlider.value >= 0.9
anchors {
verticalCenter: parent.verticalCenter
right: nearFull ? quickSlider.handle.right : parent.right
rightMargin: quickSlider.nearFull ? 14 : 8
verticalCenter: quickSlider.verticalCenter
right: nearFull ? quickSlider.handle.right : quickSlider.right
rightMargin: nearFull ? 14 : 8
}
iconSize: 20
color: nearFull ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
@@ -105,7 +122,25 @@ Rectangle {
Behavior on anchors.rightMargin {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
}
MaterialSymbol {
id: secondaryIcon
visible: secondaryMaterialSymbol.length > 0
property real iconLocation: 0.3
property bool nearIcon: iconLocation - quickSlider.value <= 0.1 && iconLocation - quickSlider.value > (quickSlider.handleWidth + 8 - 14) / quickSlider.effectiveDraggingWidth
anchors {
verticalCenter: quickSlider.verticalCenter
right: nearIcon ? quickSlider.handle.right : quickSlider.right
rightMargin: nearIcon ? 14 : (1 - iconLocation) * quickSlider.effectiveDraggingWidth + quickSlider.rightPadding + 8
}
iconSize: 20
color: quickSlider.value >= iconLocation - 0.1 ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
text: secondaryMaterialSymbol
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
}
}
@@ -15,7 +15,7 @@ WindowDialog {
id: root
property var screen: root.QsWindow.window?.screen
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
backgroundHeight: 600
backgroundHeight: 700
WindowDialogTitle {
text: Translation.tr("Eye protection")
@@ -44,9 +44,9 @@ WindowDialog {
iconSize: Appearance.font.pixelSize.larger
buttonIcon: "check"
text: Translation.tr("Enable now")
checked: Hyprsunset.active
checked: Hyprsunset.temperatureActive
onCheckedChanged: {
Hyprsunset.toggle(checked)
Hyprsunset.toggleTemperature(checked)
}
}
@@ -146,6 +146,33 @@ WindowDialog {
id: brightnessColumn
Layout.topMargin: -16
Layout.fillWidth: true
WindowDialogSlider {
anchors {
left: parent.left
right: parent.right
leftMargin: 4
rightMargin: 4
}
value: root.brightnessMonitor.brightness
onMoved: root.brightnessMonitor.setBrightness(value)
}
}
WindowDialogSectionHeader {
text: Translation.tr("Gamma")
}
WindowDialogSeparator {
Layout.topMargin: -22
Layout.leftMargin: 0
Layout.rightMargin: 0
}
Column {
id: gammaColumn
Layout.topMargin: -16
Layout.fillWidth: true
Layout.fillHeight: true
WindowDialogSlider {
@@ -155,9 +182,10 @@ WindowDialog {
leftMargin: 4
rightMargin: 4
}
// text: Translation.tr("Brightness")
value: root.brightnessMonitor.brightness
onMoved: root.brightnessMonitor.setBrightness(value)
from: Hyprsunset.gammaLowerLimit / 100
value: Hyprsunset.gamma / 100
onMoved: Hyprsunset.setGamma(value * 100)
tooltipContent: `${Math.round(value * 100)}%`
}
}
@@ -6,10 +6,10 @@ import Quickshell.Io
QuickToggleButton {
id: nightLightButton
toggled: Hyprsunset.active
toggled: Hyprsunset.temperatureActive
buttonIcon: Config.options.light.night.automatic ? "night_sight_auto" : "bedtime"
onClicked: {
Hyprsunset.toggle()
Hyprsunset.toggleTemperature()
}
altAction: () => {
@@ -54,8 +54,8 @@ Item { // Bar content region
height: (root.height - middleSection.height) / 2
width: Appearance.sizes.verticalBarWidth
onScrollDown: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05)
onScrollUp: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05)
onScrollDown: Brightness.decreaseBrightness()
onScrollUp: Brightness.increaseBrightness()
onMovedAway: GlobalStates.osdBrightnessOpen = false
onPressed: event => {
if (event.button === Qt.LeftButton)