forked from Shinonome/dots-hyprland
Decrease gamma when attempting to decrease brightness below 0 (#3122)
This commit is contained in:
@@ -12,11 +12,11 @@ QuickToggleModel {
|
|||||||
name: Translation.tr("Night Light")
|
name: Translation.tr("Night Light")
|
||||||
statusText: (auto ? Translation.tr("Auto, ") : "") + (toggled ? Translation.tr("Active") : Translation.tr("Inactive"))
|
statusText: (auto ? Translation.tr("Auto, ") : "") + (toggled ? Translation.tr("Active") : Translation.tr("Inactive"))
|
||||||
|
|
||||||
toggled: Hyprsunset.active
|
toggled: Hyprsunset.temperatureActive
|
||||||
icon: auto ? "night_sight_auto" : "bedtime"
|
icon: auto ? "night_sight_auto" : "bedtime"
|
||||||
|
|
||||||
mainAction: () => {
|
mainAction: () => {
|
||||||
Hyprsunset.toggle()
|
Hyprsunset.toggleTemperature()
|
||||||
}
|
}
|
||||||
hasMenu: true
|
hasMenu: true
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Slider {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property list<real> stopIndicatorValues: [1]
|
property list<real> stopIndicatorValues: [1]
|
||||||
|
property list<real> dividerValues: []
|
||||||
enum Configuration {
|
enum Configuration {
|
||||||
Wavy = 4,
|
Wavy = 4,
|
||||||
XS = 12,
|
XS = 12,
|
||||||
@@ -45,6 +46,7 @@ Slider {
|
|||||||
property real handleHeight: (configuration === StyledSlider.Configuration.Wavy) ? 24 : Math.max(33, trackWidth + 9)
|
property real handleHeight: (configuration === StyledSlider.Configuration.Wavy) ? 24 : Math.max(33, trackWidth + 9)
|
||||||
property real handleWidth: root.pressed ? handlePressedWidth : handleDefaultWidth
|
property real handleWidth: root.pressed ? handlePressedWidth : handleDefaultWidth
|
||||||
property real handleMargins: 4
|
property real handleMargins: 4
|
||||||
|
property real dividerMargins: 2
|
||||||
property real trackDotSize: 3
|
property real trackDotSize: 3
|
||||||
property bool usePercentTooltip: true
|
property bool usePercentTooltip: true
|
||||||
property string tooltipContent: usePercentTooltip ? `${Math.round(((value - from) / (to - from)) * 100)}%` : `${Math.round(value)}`
|
property string tooltipContent: usePercentTooltip ? `${Math.round(((value - from) / (to - from)) * 100)}%` : `${Math.round(value)}`
|
||||||
@@ -94,71 +96,94 @@ Slider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
background: Item {
|
background: Item {
|
||||||
|
id: background
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: parent.width
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: root.width
|
||||||
implicitHeight: trackWidth
|
implicitHeight: trackWidth
|
||||||
|
property var normalized: root.dividerValues.map(v => (v - root.from) / (root.to - root.from))
|
||||||
|
property var filtered: normalized.filter(v => Math.abs(v - root.visualPosition) * effectiveDraggingWidth > handleMargins + handleWidth / 2 - dividerMargins)
|
||||||
|
property var leftValues: [0, ...filtered.filter(v => v < root.visualPosition), root.visualPosition]
|
||||||
|
property var rightValues: [root.visualPosition, ...filtered.filter(v => v > root.visualPosition), 1]
|
||||||
|
property var leftWidths: leftValues.map((v, i, a) => a[i + 1] - v).slice(0, -1)
|
||||||
|
property var rightWidths: rightValues.map((v, i, a) => a[i + 1] - v).slice(0, -1)
|
||||||
|
|
||||||
// Fill left
|
// Fill left
|
||||||
Loader {
|
Repeater {
|
||||||
anchors {
|
model: background.leftWidths.length
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
left: parent.left
|
Loader {
|
||||||
}
|
required property real index
|
||||||
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
anchors.verticalCenter: background.verticalCenter
|
||||||
height: root.trackWidth
|
property real leftMargin: index > 0 ? root.dividerMargins : 0
|
||||||
active: !root.wavy
|
property real rightMargin: index < background.leftWidths.length - 1 ? root.dividerMargins : root.handleMargins
|
||||||
sourceComponent: Rectangle {
|
x: background.leftValues[index] * root.effectiveDraggingWidth + leftMargin + (index > 0 ? leftPadding : 0)
|
||||||
color: root.highlightColor
|
width: background.leftWidths[index] * root.effectiveDraggingWidth - leftMargin - rightMargin - (index === background.leftWidths.length - 1 ? handleWidth / 2 : 0) + (index === 0 ? leftPadding : 0)
|
||||||
topLeftRadius: root.trackRadius
|
height: root.trackWidth
|
||||||
bottomLeftRadius: root.trackRadius
|
active: !root.wavy
|
||||||
topRightRadius: root.unsharpenRadius
|
sourceComponent: Rectangle {
|
||||||
bottomRightRadius: root.unsharpenRadius
|
color: root.highlightColor
|
||||||
|
topLeftRadius: index === 0 ? root.trackRadius : root.unsharpenRadius
|
||||||
|
bottomLeftRadius: index === 0 ? root.trackRadius : root.unsharpenRadius
|
||||||
|
topRightRadius: root.unsharpenRadius
|
||||||
|
bottomRightRadius: root.unsharpenRadius
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Repeater {
|
||||||
anchors {
|
model: background.leftWidths.length
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
left: parent.left
|
Loader {
|
||||||
}
|
required property int index
|
||||||
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
anchors.verticalCenter: background.verticalCenter
|
||||||
height: root.height
|
property real leftMargin: index > 0 ? root.dividerMargins : 0
|
||||||
active: root.wavy
|
property real rightMargin: index < background.leftWidths.length - 1 ? root.dividerMargins : root.handleMargins
|
||||||
sourceComponent: WavyLine {
|
x: background.leftValues[index] * root.effectiveDraggingWidth + leftMargin + (index > 0 ? leftPadding : 0)
|
||||||
id: wavyFill
|
width: background.leftWidths[index] * root.effectiveDraggingWidth - leftMargin - rightMargin - (index === background.leftWidths.length - 1 ? handleWidth / 2 : 0) + (index === 0 ? leftPadding : 0)
|
||||||
frequency: root.waveFrequency
|
height: root.height
|
||||||
fullLength: root.width
|
active: root.wavy
|
||||||
color: root.highlightColor
|
sourceComponent: WavyLine {
|
||||||
amplitudeMultiplier: root.wavy ? 0.5 : 0
|
id: wavyFill
|
||||||
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
frequency: root.waveFrequency
|
||||||
height: root.trackWidth
|
fullLength: root.width
|
||||||
Connections {
|
color: root.highlightColor
|
||||||
target: root
|
amplitudeMultiplier: root.wavy ? 0.5 : 0
|
||||||
function onValueChanged() { wavyFill.requestPaint(); }
|
width: parent.width
|
||||||
function onHighlightColorChanged() { wavyFill.requestPaint(); }
|
height: root.trackWidth
|
||||||
}
|
Connections {
|
||||||
FrameAnimation {
|
target: root
|
||||||
running: root.animateWave
|
function onValueChanged() { wavyFill.requestPaint(); }
|
||||||
onTriggered: {
|
function onHighlightColorChanged() { wavyFill.requestPaint(); }
|
||||||
wavyFill.requestPaint()
|
}
|
||||||
|
FrameAnimation {
|
||||||
|
running: root.animateWave
|
||||||
|
onTriggered: {
|
||||||
|
wavyFill.requestPaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill right
|
// Fill right
|
||||||
Rectangle {
|
Repeater {
|
||||||
anchors {
|
model: background.rightWidths.length
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
right: parent.right
|
Rectangle {
|
||||||
|
required property int index
|
||||||
|
anchors.verticalCenter: background.verticalCenter
|
||||||
|
property real leftMargin: index > 0 ? root.dividerMargins : root.handleMargins
|
||||||
|
property real rightMargin: index < background.rightWidths.length - 1 ? root.dividerMargins : 0
|
||||||
|
x: background.rightValues[index] * root.effectiveDraggingWidth + leftMargin + (index === 0 ? handleWidth / 2 : 0) + leftPadding
|
||||||
|
width: background.rightWidths[index] * root.effectiveDraggingWidth - leftMargin - rightMargin - (index === 0 ? handleWidth / 2 : 0) + (index === background.rightWidths.length - 1 ? rightPadding : 0)
|
||||||
|
height: trackWidth
|
||||||
|
color: root.trackColor
|
||||||
|
topRightRadius: index === background.rightWidths.length - 1 ? root.trackRadius : root.unsharpenRadius
|
||||||
|
bottomRightRadius: index === background.rightWidths.length - 1 ? root.trackRadius : root.unsharpenRadius
|
||||||
|
topLeftRadius: root.unsharpenRadius
|
||||||
|
bottomLeftRadius: root.unsharpenRadius
|
||||||
}
|
}
|
||||||
width: root.handleMargins + ((1 - root.visualPosition) * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
|
||||||
height: trackWidth
|
|
||||||
color: root.trackColor
|
|
||||||
topRightRadius: root.trackRadius
|
|
||||||
bottomRightRadius: root.trackRadius
|
|
||||||
topLeftRadius: root.unsharpenRadius
|
|
||||||
bottomLeftRadius: root.unsharpenRadius
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop indicators
|
// Stop indicators
|
||||||
@@ -177,7 +202,7 @@ Slider {
|
|||||||
|
|
||||||
implicitWidth: root.handleWidth
|
implicitWidth: root.handleWidth
|
||||||
implicitHeight: root.handleHeight
|
implicitHeight: root.handleHeight
|
||||||
x: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2)
|
x: root.leftPadding + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
radius: Appearance.rounding.full
|
radius: Appearance.rounding.full
|
||||||
color: root.handleColor
|
color: root.handleColor
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ Item { // Bar content region
|
|||||||
implicitWidth: leftSectionRowLayout.implicitWidth
|
implicitWidth: leftSectionRowLayout.implicitWidth
|
||||||
implicitHeight: Appearance.sizes.baseBarHeight
|
implicitHeight: Appearance.sizes.baseBarHeight
|
||||||
|
|
||||||
onScrollDown: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05)
|
onScrollDown: Brightness.decreaseBrightness()
|
||||||
onScrollUp: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05)
|
onScrollUp: Brightness.increaseBrightness()
|
||||||
onMovedAway: GlobalStates.osdBrightnessOpen = false
|
onMovedAway: GlobalStates.osdBrightnessOpen = false
|
||||||
onPressed: event => {
|
onPressed: event => {
|
||||||
if (event.button === Qt.LeftButton)
|
if (event.button === Qt.LeftButton)
|
||||||
@@ -70,7 +70,7 @@ Item { // Bar content region
|
|||||||
// Visual content
|
// Visual content
|
||||||
ScrollHint {
|
ScrollHint {
|
||||||
reveal: barLeftSideMouseArea.hovered
|
reveal: barLeftSideMouseArea.hovered
|
||||||
icon: "light_mode"
|
icon: Hyprsunset.gamma === 100 ? "light_mode" : "wb_twilight"
|
||||||
tooltipText: Translation.tr("Scroll to change brightness")
|
tooltipText: Translation.tr("Scroll to change brightness")
|
||||||
side: "left"
|
side: "left"
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ Scope {
|
|||||||
id: "brightness",
|
id: "brightness",
|
||||||
sourceUrl: "indicators/BrightnessIndicator.qml"
|
sourceUrl: "indicators/BrightnessIndicator.qml"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "gamma",
|
||||||
|
sourceUrl: "indicators/GammaIndicator.qml"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function triggerOsd() {
|
function triggerOsd() {
|
||||||
@@ -52,6 +56,15 @@ Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Hyprsunset
|
||||||
|
function onGammaChangeAttempt() {
|
||||||
|
root.protectionMessage = "";
|
||||||
|
root.currentIndicator = "gamma";
|
||||||
|
root.triggerOsd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
// Listen to volume changes
|
// Listen to volume changes
|
||||||
target: Audio.sink?.audio ?? null
|
target: Audio.sink?.audio ?? null
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Item {
|
|||||||
required property string name
|
required property string name
|
||||||
property bool rotateIcon: false
|
property bool rotateIcon: false
|
||||||
property bool scaleIcon: false
|
property bool scaleIcon: false
|
||||||
|
property alias from: valueProgressBar.from
|
||||||
|
property alias to: valueProgressBar.to
|
||||||
|
|
||||||
property real valueIndicatorVerticalPadding: 9
|
property real valueIndicatorVerticalPadding: 9
|
||||||
property real valueIndicatorLeftPadding: 10
|
property real valueIndicatorLeftPadding: 10
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ OsdValueIndicator {
|
|||||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||||
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
||||||
|
|
||||||
icon: Hyprsunset.active ? "routine" : "light_mode"
|
icon: Hyprsunset.temperatureActive ? "routine" : "light_mode"
|
||||||
rotateIcon: true
|
rotateIcon: true
|
||||||
scaleIcon: true
|
scaleIcon: true
|
||||||
name: Translation.tr("Brightness")
|
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)
|
if (!Config.options.sidebar.cornerOpen.valueScroll)
|
||||||
return;
|
return;
|
||||||
if (cornerWidget.isLeft)
|
if (cornerWidget.isLeft)
|
||||||
cornerPanelWindow.brightnessMonitor.setBrightness(cornerPanelWindow.brightnessMonitor.brightness - 0.05);
|
Brightness.decreaseBrightness()
|
||||||
else {
|
else {
|
||||||
const currentVolume = Audio.value;
|
const currentVolume = Audio.value;
|
||||||
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||||
@@ -109,7 +109,7 @@ Scope {
|
|||||||
if (!Config.options.sidebar.cornerOpen.valueScroll)
|
if (!Config.options.sidebar.cornerOpen.valueScroll)
|
||||||
return;
|
return;
|
||||||
if (cornerWidget.isLeft)
|
if (cornerWidget.isLeft)
|
||||||
cornerPanelWindow.brightnessMonitor.setBrightness(cornerPanelWindow.brightnessMonitor.brightness + 0.05);
|
Brightness.increaseBrightness()
|
||||||
else {
|
else {
|
||||||
const currentVolume = Audio.value;
|
const currentVolume = Audio.value;
|
||||||
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||||
|
|||||||
@@ -40,10 +40,25 @@ Rectangle {
|
|||||||
visible: active
|
visible: active
|
||||||
active: Config.options.sidebar.quickSliders.showBrightness
|
active: Config.options.sidebar.quickSliders.showBrightness
|
||||||
sourceComponent: QuickSlider {
|
sourceComponent: QuickSlider {
|
||||||
materialSymbol: "brightness_6"
|
materialSymbol: "light_mode"
|
||||||
value: root.brightnessMonitor.brightness
|
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: {
|
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 {
|
component QuickSlider: StyledSlider {
|
||||||
id: quickSlider
|
id: quickSlider
|
||||||
required property string materialSymbol
|
required property string materialSymbol
|
||||||
|
property string secondaryMaterialSymbol
|
||||||
configuration: StyledSlider.Configuration.M
|
configuration: StyledSlider.Configuration.M
|
||||||
stopIndicatorValues: []
|
stopIndicatorValues: []
|
||||||
|
dividerValues: secondaryMaterialSymbol.length > 0 ? [secondaryIcon.iconLocation] : []
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
id: icon
|
id: icon
|
||||||
property bool nearFull: quickSlider.value >= 0.9
|
property bool nearFull: quickSlider.value >= 0.9
|
||||||
anchors {
|
anchors {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: quickSlider.verticalCenter
|
||||||
right: nearFull ? quickSlider.handle.right : parent.right
|
right: nearFull ? quickSlider.handle.right : quickSlider.right
|
||||||
rightMargin: quickSlider.nearFull ? 14 : 8
|
rightMargin: nearFull ? 14 : 8
|
||||||
}
|
}
|
||||||
iconSize: 20
|
iconSize: 20
|
||||||
color: nearFull ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
|
color: nearFull ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
|
||||||
@@ -105,7 +122,25 @@ Rectangle {
|
|||||||
Behavior on anchors.rightMargin {
|
Behavior on anchors.rightMargin {
|
||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
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
|
id: root
|
||||||
property var screen: root.QsWindow.window?.screen
|
property var screen: root.QsWindow.window?.screen
|
||||||
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
|
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
|
||||||
backgroundHeight: 600
|
backgroundHeight: 700
|
||||||
|
|
||||||
WindowDialogTitle {
|
WindowDialogTitle {
|
||||||
text: Translation.tr("Eye protection")
|
text: Translation.tr("Eye protection")
|
||||||
@@ -44,9 +44,9 @@ WindowDialog {
|
|||||||
iconSize: Appearance.font.pixelSize.larger
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
buttonIcon: "check"
|
buttonIcon: "check"
|
||||||
text: Translation.tr("Enable now")
|
text: Translation.tr("Enable now")
|
||||||
checked: Hyprsunset.active
|
checked: Hyprsunset.temperatureActive
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Hyprsunset.toggle(checked)
|
Hyprsunset.toggleTemperature(checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +146,33 @@ WindowDialog {
|
|||||||
id: brightnessColumn
|
id: brightnessColumn
|
||||||
Layout.topMargin: -16
|
Layout.topMargin: -16
|
||||||
Layout.fillWidth: true
|
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
|
Layout.fillHeight: true
|
||||||
|
|
||||||
WindowDialogSlider {
|
WindowDialogSlider {
|
||||||
@@ -155,9 +182,10 @@ WindowDialog {
|
|||||||
leftMargin: 4
|
leftMargin: 4
|
||||||
rightMargin: 4
|
rightMargin: 4
|
||||||
}
|
}
|
||||||
// text: Translation.tr("Brightness")
|
from: Hyprsunset.gammaLowerLimit / 100
|
||||||
value: root.brightnessMonitor.brightness
|
value: Hyprsunset.gamma / 100
|
||||||
onMoved: root.brightnessMonitor.setBrightness(value)
|
onMoved: Hyprsunset.setGamma(value * 100)
|
||||||
|
tooltipContent: `${Math.round(value * 100)}%`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,10 +6,10 @@ import Quickshell.Io
|
|||||||
|
|
||||||
QuickToggleButton {
|
QuickToggleButton {
|
||||||
id: nightLightButton
|
id: nightLightButton
|
||||||
toggled: Hyprsunset.active
|
toggled: Hyprsunset.temperatureActive
|
||||||
buttonIcon: Config.options.light.night.automatic ? "night_sight_auto" : "bedtime"
|
buttonIcon: Config.options.light.night.automatic ? "night_sight_auto" : "bedtime"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Hyprsunset.toggle()
|
Hyprsunset.toggleTemperature()
|
||||||
}
|
}
|
||||||
|
|
||||||
altAction: () => {
|
altAction: () => {
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ Item { // Bar content region
|
|||||||
height: (root.height - middleSection.height) / 2
|
height: (root.height - middleSection.height) / 2
|
||||||
width: Appearance.sizes.verticalBarWidth
|
width: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
onScrollDown: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05)
|
onScrollDown: Brightness.decreaseBrightness()
|
||||||
onScrollUp: root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05)
|
onScrollUp: Brightness.increaseBrightness()
|
||||||
onMovedAway: GlobalStates.osdBrightnessOpen = false
|
onMovedAway: GlobalStates.osdBrightnessOpen = false
|
||||||
onPressed: event => {
|
onPressed: event => {
|
||||||
if (event.button === Qt.LeftButton)
|
if (event.button === Qt.LeftButton)
|
||||||
|
|||||||
+2
-2
@@ -87,9 +87,9 @@ Item {
|
|||||||
name: Translation.tr("Enable now")
|
name: Translation.tr("Enable now")
|
||||||
description: Translation.tr("More comfortable viewing at night")
|
description: Translation.tr("More comfortable viewing at night")
|
||||||
iconName: WIcons.nightLightIcon
|
iconName: WIcons.nightLightIcon
|
||||||
checked: Hyprsunset.active
|
checked: Hyprsunset.temperatureActive
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Hyprsunset.toggle(checked);
|
Hyprsunset.toggleTemperature(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Singleton {
|
|||||||
|
|
||||||
property string bluetoothIcon: BluetoothStatus.connected ? "bluetooth-connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth-disabled"
|
property string bluetoothIcon: BluetoothStatus.connected ? "bluetooth-connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth-disabled"
|
||||||
|
|
||||||
property string nightLightIcon: Hyprsunset.active ? "weather-moon" : "weather-moon-off"
|
property string nightLightIcon: Hyprsunset.temperatureActive ? "weather-moon" : "weather-moon-off"
|
||||||
|
|
||||||
property string notificationsIcon: Notifications.silent ? "alert-snooze" : "alert"
|
property string notificationsIcon: Notifications.silent ? "alert-snooze" : "alert"
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function increaseBrightness(): void {
|
function increaseBrightness(): void {
|
||||||
|
// if gamma is not yet 100, first increase gamma
|
||||||
|
if (Hyprsunset.gamma !== 100) {
|
||||||
|
Hyprsunset.setGamma(Hyprsunset.gamma + 5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const focusedName = Hyprland.focusedMonitor.name;
|
const focusedName = Hyprland.focusedMonitor.name;
|
||||||
const monitor = monitors.find(m => focusedName === m.screen.name);
|
const monitor = monitors.find(m => focusedName === m.screen.name);
|
||||||
if (monitor)
|
if (monitor)
|
||||||
@@ -37,8 +43,12 @@ Singleton {
|
|||||||
function decreaseBrightness(): void {
|
function decreaseBrightness(): void {
|
||||||
const focusedName = Hyprland.focusedMonitor.name;
|
const focusedName = Hyprland.focusedMonitor.name;
|
||||||
const monitor = monitors.find(m => focusedName === m.screen.name);
|
const monitor = monitors.find(m => focusedName === m.screen.name);
|
||||||
if (monitor)
|
if (monitor && monitor.brightness > 0)
|
||||||
monitor.setBrightness(monitor.brightness - 0.05);
|
monitor.setBrightness(monitor.brightness - 0.05);
|
||||||
|
// if brightness is 0, then decrease gamma
|
||||||
|
else {
|
||||||
|
Hyprsunset.setGamma(Hyprsunset.gamma - 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadableId: "brightness"
|
reloadableId: "brightness"
|
||||||
|
|||||||
@@ -13,13 +13,18 @@ import Quickshell.Hyprland
|
|||||||
*/
|
*/
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
signal gammaChangeAttempt()
|
||||||
|
|
||||||
|
readonly property real gammaLowerLimit: 25
|
||||||
|
|
||||||
property string from: Config.options?.light?.night?.from ?? "19:00"
|
property string from: Config.options?.light?.night?.from ?? "19:00"
|
||||||
property string to: Config.options?.light?.night?.to ?? "06:30"
|
property string to: Config.options?.light?.night?.to ?? "06:30"
|
||||||
property bool automatic: Config.options?.light?.night?.automatic && (Config?.ready ?? true)
|
property bool automatic: Config.options?.light?.night?.automatic && (Config?.ready ?? true)
|
||||||
property int colorTemperature: Config.options?.light?.night?.colorTemperature ?? 5000
|
property int colorTemperature: Config.options?.light?.night?.colorTemperature ?? 5000
|
||||||
|
property int gamma: 100
|
||||||
property bool shouldBeOn
|
property bool shouldBeOn
|
||||||
property bool firstEvaluation: true
|
property bool firstEvaluation: true
|
||||||
property bool active: false
|
property bool temperatureActive: false
|
||||||
|
|
||||||
property int fromHour: Number(from.split(":")[0])
|
property int fromHour: Number(from.split(":")[0])
|
||||||
property int fromMinute: Number(from.split(":")[1])
|
property int fromMinute: Number(from.split(":")[1])
|
||||||
@@ -71,24 +76,52 @@ Singleton {
|
|||||||
if (!root.automatic || root.manualActive !== undefined)
|
if (!root.automatic || root.manualActive !== undefined)
|
||||||
return;
|
return;
|
||||||
if (root.shouldBeOn) {
|
if (root.shouldBeOn) {
|
||||||
root.enable();
|
root.enableTemperature();
|
||||||
} else {
|
} else {
|
||||||
root.disable();
|
root.disableTemperature();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function load() { } // Dummy to force init
|
function startHyprsunset() {
|
||||||
|
Quickshell.execDetached(["bash", "-c", `pidof hyprsunset || hyprsunset`]);
|
||||||
function enable() {
|
|
||||||
root.active = true;
|
|
||||||
// console.log("[Hyprsunset] Enabling");
|
|
||||||
Quickshell.execDetached(["bash", "-c", `pidof hyprsunset || hyprsunset --temperature ${root.colorTemperature}`]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable() {
|
function load() {
|
||||||
root.active = false;
|
root.startHyprsunset();
|
||||||
|
updateHyprsunset.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: updateHyprsunset
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
root.ensureState();
|
||||||
|
root.setGamma(root.gamma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableTemperature() {
|
||||||
|
root.temperatureActive = true;
|
||||||
|
|
||||||
|
// console.log("[Hyprsunset] Enabling");
|
||||||
|
root.startHyprsunset();
|
||||||
|
Quickshell.execDetached(["bash", "-c", `hyprctl hyprsunset temperature ${root.colorTemperature}`]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableTemperature() {
|
||||||
|
root.temperatureActive = false;
|
||||||
// console.log("[Hyprsunset] Disabling");
|
// console.log("[Hyprsunset] Disabling");
|
||||||
Quickshell.execDetached(["bash", "-c", `pkill hyprsunset`]);
|
Quickshell.execDetached(["hyprctl", "hyprsunset", "identity"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setGamma(gamma) {
|
||||||
|
root.gamma = Math.max(root.gammaLowerLimit, Math.min(100, gamma));
|
||||||
|
|
||||||
|
root.gammaChangeAttempt();
|
||||||
|
|
||||||
|
root.startHyprsunset();
|
||||||
|
Quickshell.execDetached(["bash", "-c", `hyprctl hyprsunset gamma ${root.gamma}`]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchState() {
|
function fetchState() {
|
||||||
@@ -104,26 +137,26 @@ Singleton {
|
|||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const output = stateCollector.text.trim();
|
const output = stateCollector.text.trim();
|
||||||
if (output.length == 0 || output.startsWith("Couldn't"))
|
if (output.length == 0 || output.startsWith("Couldn't"))
|
||||||
root.active = false;
|
root.temperatureActive = false;
|
||||||
else
|
else
|
||||||
root.active = (output != "6500"); // 6500 is the default when off
|
root.temperatureActive = (output != "6500"); // 6500 is the default when off
|
||||||
// console.log("[Hyprsunset] Fetched state:", output, "->", root.active);
|
// console.log("[Hyprsunset] Fetched state:", output, "->", root.temperatureActive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle(active = undefined) {
|
function toggleTemperature(active = undefined) {
|
||||||
if (root.manualActive === undefined) {
|
if (root.manualActive === undefined) {
|
||||||
root.manualActive = root.active;
|
root.manualActive = root.temperatureActive;
|
||||||
root.manualActiveHour = root.clockHour;
|
root.manualActiveHour = root.clockHour;
|
||||||
root.manualActiveMinute = root.clockMinute;
|
root.manualActiveMinute = root.clockMinute;
|
||||||
}
|
}
|
||||||
|
|
||||||
root.manualActive = active !== undefined ? active : !root.manualActive;
|
root.manualActive = active !== undefined ? active : !root.manualActive;
|
||||||
if (root.manualActive) {
|
if (root.manualActive) {
|
||||||
root.enable();
|
root.enableTemperature();
|
||||||
} else {
|
} else {
|
||||||
root.disable();
|
root.disableTemperature();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +164,9 @@ Singleton {
|
|||||||
Connections {
|
Connections {
|
||||||
target: Config.options.light.night
|
target: Config.options.light.night
|
||||||
function onColorTemperatureChanged() {
|
function onColorTemperatureChanged() {
|
||||||
if (!root.active) return;
|
if (!root.temperatureActive) return;
|
||||||
Hyprland.dispatch(`hyprctl hyprsunset temperature ${Config.options.light.night.colorTemperature}`);
|
Hyprland.dispatch(`hyprctl hyprsunset temperature ${Config.options.light.night.colorTemperature}`);
|
||||||
Quickshell.execDetached(["hyprctl", "hyprsunset", "temperature", `${Config.options.light.night.colorTemperature}`]);
|
Quickshell.execDetached(["hyprctl", "hyprsunset", "temperature", `${Config.options.light.night.colorTemperature}`]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
"Unknown function call: %1": "Unknown function call: %1",
|
"Unknown function call: %1": "Unknown function call: %1",
|
||||||
"Online | %1's model | Delivers fast, responsive and well-formatted answers. Disadvantages: not very eager to do stuff; might make up unknown function calls": "Online | %1's model | Delivers fast, responsive and well-formatted answers. Disadvantages: not very eager to do stuff; might make up unknown function calls",
|
"Online | %1's model | Delivers fast, responsive and well-formatted answers. Disadvantages: not very eager to do stuff; might make up unknown function calls": "Online | %1's model | Delivers fast, responsive and well-formatted answers. Disadvantages: not very eager to do stuff; might make up unknown function calls",
|
||||||
"Volume": "Volume",
|
"Volume": "Volume",
|
||||||
|
"Gamma": "Gamma",
|
||||||
"Medium": "Medium",
|
"Medium": "Medium",
|
||||||
"Copy code": "Copy code",
|
"Copy code": "Copy code",
|
||||||
"Exceeded max allowed": "Exceeded max allowed",
|
"Exceeded max allowed": "Exceeded max allowed",
|
||||||
|
|||||||
Reference in New Issue
Block a user