Add NightLight, update README, format
This commit is contained in:
parent
71cfbc8c0a
commit
634d78456d
11 changed files with 471 additions and 22 deletions
|
|
@ -129,7 +129,7 @@ Singleton {
|
||||||
widgets: JsonObject {
|
widgets: JsonObject {
|
||||||
property list<string> left: ["SystemMonitor", "ActiveWindow", "MediaMini"]
|
property list<string> left: ["SystemMonitor", "ActiveWindow", "MediaMini"]
|
||||||
property list<string> center: ["Workspace"]
|
property list<string> center: ["Workspace"]
|
||||||
property list<string> right: ["ScreenRecorderIndicator", "Tray", "NotificationHistory", "WiFi", "Bluetooth", "Battery", "Volume", "Brightness", "Clock", "SidePanelToggle"]
|
property list<string> right: ["ScreenRecorderIndicator", "Tray", "NotificationHistory", "WiFi", "Bluetooth", "Battery", "Volume", "Brightness", "NightLight", "Clock", "SidePanelToggle"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,6 +256,16 @@ Singleton {
|
||||||
// External app theming (GTK & Qt)
|
// External app theming (GTK & Qt)
|
||||||
property bool themeApps: false
|
property bool themeApps: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// night light
|
||||||
|
property JsonObject nightLight: JsonObject {
|
||||||
|
property bool enabled: false
|
||||||
|
property real warmth: 0.0
|
||||||
|
property real intensity: 0.8
|
||||||
|
property string startTime: "20:00"
|
||||||
|
property string stopTime: "07:00"
|
||||||
|
property bool autoSchedule: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
85
Modules/Bar/Widgets/NightLight.qml
Normal file
85
Modules/Bar/Widgets/NightLight.qml
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Modules.SettingsPanel
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property ShellScreen screen
|
||||||
|
property real scaling: ScalingService.scale(screen)
|
||||||
|
|
||||||
|
implicitWidth: pill.width
|
||||||
|
implicitHeight: pill.height
|
||||||
|
visible: true
|
||||||
|
|
||||||
|
function getIcon() {
|
||||||
|
if (!NightLightService.enabled) {
|
||||||
|
return "light_mode"
|
||||||
|
}
|
||||||
|
return NightLightService.isActive ? "dark_mode" : "light_mode"
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTooltipText() {
|
||||||
|
if (!NightLightService.enabled) {
|
||||||
|
return "Night Light: Disabled\nLeft click to open settings.\nRight click to enable."
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = NightLightService.isActive ? "Active" : "Inactive (outside schedule)"
|
||||||
|
var warmth = Math.round(NightLightService.warmth * 10)
|
||||||
|
var schedule = NightLightService.autoSchedule ? `Schedule: ${NightLightService.startTime} - ${NightLightService.stopTime}` : "Manual mode"
|
||||||
|
|
||||||
|
return `Night Light: ${status}\nWarmth: ${warmth}/10\n${schedule}\nLeft click to open settings.\nRight click to toggle.`
|
||||||
|
}
|
||||||
|
|
||||||
|
NPill {
|
||||||
|
id: pill
|
||||||
|
icon: getIcon()
|
||||||
|
iconCircleColor: NightLightService.isActive ? Color.mSecondary : Color.mOnSurfaceVariant
|
||||||
|
collapsedIconColor: NightLightService.isActive ? Color.mOnSecondary : Color.mOnSurface
|
||||||
|
autoHide: false
|
||||||
|
text: NightLightService.enabled ? (NightLightService.isActive ? "ON" : "OFF") : "OFF"
|
||||||
|
tooltipText: getTooltipText()
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
// Left click - open settings
|
||||||
|
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||||
|
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||||
|
settingsPanel.open(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
onRightClicked: {
|
||||||
|
// Right click - toggle night light
|
||||||
|
NightLightService.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update when service state changes
|
||||||
|
Connections {
|
||||||
|
target: NightLightService
|
||||||
|
function onEnabledChanged() {
|
||||||
|
pill.icon = getIcon()
|
||||||
|
pill.text = NightLightService.enabled ? (NightLightService.isActive ? "ON" : "OFF") : "OFF"
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
function onIsActiveChanged() {
|
||||||
|
pill.icon = getIcon()
|
||||||
|
pill.text = NightLightService.enabled ? (NightLightService.isActive ? "ON" : "OFF") : "OFF"
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
function onWarmthChanged() {
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
function onStartTimeChanged() {
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
function onStopTimeChanged() {
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
function onAutoScheduleChanged() {
|
||||||
|
pill.tooltipText = getTooltipText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -49,8 +49,6 @@ NPanel {
|
||||||
searchText = ""
|
searchText = ""
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosed: {
|
onClosed: {
|
||||||
|
|
|
||||||
65
Modules/NightLight/NightLight.qml
Normal file
65
Modules/NightLight/NightLight.qml
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
delegate: Loader {
|
||||||
|
required property ShellScreen modelData
|
||||||
|
readonly property real scaling: ScalingService.scale(modelData)
|
||||||
|
|
||||||
|
active: NightLightService.enabled
|
||||||
|
|
||||||
|
sourceComponent: PanelWindow {
|
||||||
|
id: nightlightWindow
|
||||||
|
|
||||||
|
screen: modelData
|
||||||
|
visible: NightLightService.isActive
|
||||||
|
color: Color.transparent
|
||||||
|
|
||||||
|
mask: Region {}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "noctalia-nightlight"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: NightLightService.overlayColor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe connection that checks if the window still exists
|
||||||
|
Connections {
|
||||||
|
target: NightLightService
|
||||||
|
function onIsActiveChanged() {
|
||||||
|
if (nightlightWindow && typeof nightlightWindow.visible !== 'undefined') {
|
||||||
|
nightlightWindow.visible = NightLightService.isActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup when component is being destroyed
|
||||||
|
Component.onDestruction: {
|
||||||
|
Logger.log("NightLight", "PanelWindow being destroyed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe state changes
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!active) {
|
||||||
|
Logger.log("NightLight", "Loader deactivating for screen:", modelData.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,24 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
// Time dropdown options (00:00 .. 23:30)
|
||||||
|
ListModel {
|
||||||
|
id: timeOptions
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var h = 0; h < 24; h++) {
|
||||||
|
for (var m = 0; m < 60; m += 30) {
|
||||||
|
var hh = ("0" + h).slice(-2)
|
||||||
|
var mm = ("0" + m).slice(-2)
|
||||||
|
var key = hh + ":" + mm
|
||||||
|
timeOptions.append({
|
||||||
|
"key": key,
|
||||||
|
"name": key
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper functions to update arrays immutably
|
// Helper functions to update arrays immutably
|
||||||
function addMonitor(list, name) {
|
function addMonitor(list, name) {
|
||||||
const arr = (list || []).slice()
|
const arr = (list || []).slice()
|
||||||
|
|
@ -209,6 +227,154 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Night Light Section
|
||||||
|
NText {
|
||||||
|
text: "Night Light"
|
||||||
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "Reduce blue light emission to help you sleep better and reduce eye strain."
|
||||||
|
font.pointSize: Style.fontSize * scaling
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||||
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
label: "Enable Night Light"
|
||||||
|
description: "Apply a warm color filter to reduce blue light emission."
|
||||||
|
checked: NightLightService.enabled
|
||||||
|
onToggled: checked => {
|
||||||
|
Settings.data.nightLight.enabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
label: "Auto Schedule"
|
||||||
|
description: "Automatically enable night light based on time schedule."
|
||||||
|
checked: NightLightService.autoSchedule
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
onToggled: checked => {
|
||||||
|
NightLightService.setAutoSchedule(checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warmth settings
|
||||||
|
NText {
|
||||||
|
text: "Warmth"
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "Higher values create warmer (more orange) light, lower values create cooler (more blue) light."
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: Style.marginS * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
|
||||||
|
NSlider {
|
||||||
|
id: warmthSlider
|
||||||
|
from: 0
|
||||||
|
to: 10
|
||||||
|
stepSize: 1
|
||||||
|
value: Math.round(NightLightService.warmth * 10)
|
||||||
|
onPressedChanged: {
|
||||||
|
if (!pressed) {
|
||||||
|
NightLightService.setWarmth(value / 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumWidth: 150 * scaling
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: NightLightService
|
||||||
|
function onWarmthChanged() {
|
||||||
|
if (!warmthSlider.pressed) {
|
||||||
|
warmthSlider.value = Math.round(NightLightService.warmth * 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: `${warmthSlider.value}`
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.minimumWidth: 60 * scaling
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule settings
|
||||||
|
NText {
|
||||||
|
text: "Schedule"
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: Style.marginL * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
enabled: NightLightService.enabled
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXXS * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "Start Time"
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
NComboBox {
|
||||||
|
model: timeOptions
|
||||||
|
currentKey: NightLightService.startTime
|
||||||
|
placeholder: "Select time"
|
||||||
|
onSelected: function (key) {
|
||||||
|
NightLightService.setSchedule(key, NightLightService.stopTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXXS * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: "Stop Time"
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
NComboBox {
|
||||||
|
model: timeOptions
|
||||||
|
currentKey: NightLightService.stopTime
|
||||||
|
placeholder: "Select time"
|
||||||
|
onSelected: function (key) {
|
||||||
|
NightLightService.setSchedule(NightLightService.startTime, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
README.md
27
README.md
|
|
@ -105,10 +105,11 @@ nix run github:noctalia-dev/noctalia-shell
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>For flakes</strong></summary>
|
<summary><strong>For flakes</strong></summary>
|
||||||
|
|
||||||
```nix
|
**Step 1**: Add quickshell and noctalia flakes
|
||||||
{
|
|
||||||
description = "Example Nix flake with Noctalia + Quickshell";
|
|
||||||
|
|
||||||
|
```nix
|
||||||
|
|
||||||
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
|
@ -129,21 +130,29 @@ nix run github:noctalia-dev/noctalia-shell
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
in {
|
in {
|
||||||
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
|
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
|
||||||
system = system;
|
|
||||||
modules = [
|
modules = [
|
||||||
./configuration.nix
|
./configuration.nix
|
||||||
# Add noctalia to system packages
|
|
||||||
({ pkgs, ... }: {
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
noctalia.packages.${system}.default
|
|
||||||
quickshell.packages.${system}.default
|
|
||||||
];
|
];
|
||||||
})
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
}```
|
||||||
|
|
||||||
|
and in `configuration.nix`
|
||||||
|
|
||||||
|
```nix
|
||||||
|
|
||||||
|
# your configuration.nix
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
noctalia.packages.${system}.default
|
||||||
|
quickshell.packages.${system}.default
|
||||||
|
];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Singleton {
|
||||||
"Clock": clockComponent,
|
"Clock": clockComponent,
|
||||||
"KeyboardLayout": keyboardLayoutComponent,
|
"KeyboardLayout": keyboardLayoutComponent,
|
||||||
"MediaMini": mediaMiniComponent,
|
"MediaMini": mediaMiniComponent,
|
||||||
|
"NightLight": nightLightComponent,
|
||||||
"NotificationHistory": notificationHistoryComponent,
|
"NotificationHistory": notificationHistoryComponent,
|
||||||
"PowerProfile": powerProfileComponent,
|
"PowerProfile": powerProfileComponent,
|
||||||
"ScreenRecorderIndicator": screenRecorderIndicatorComponent,
|
"ScreenRecorderIndicator": screenRecorderIndicatorComponent,
|
||||||
|
|
@ -53,6 +54,9 @@ Singleton {
|
||||||
property Component mediaMiniComponent: Component {
|
property Component mediaMiniComponent: Component {
|
||||||
MediaMini {}
|
MediaMini {}
|
||||||
}
|
}
|
||||||
|
property Component nightLightComponent: Component {
|
||||||
|
NightLight {}
|
||||||
|
}
|
||||||
property Component notificationHistoryComponent: Component {
|
property Component notificationHistoryComponent: Component {
|
||||||
NotificationHistory {}
|
NotificationHistory {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
108
Services/NightLightService.qml
Normal file
108
Services/NightLightService.qml
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Commons
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Night Light properties - directly bound to settings
|
||||||
|
property bool enabled: Settings.data.nightLight?.enabled || false
|
||||||
|
property real warmth: (Settings.data.nightLight
|
||||||
|
&& Settings.data.nightLight.warmth !== undefined) ? Settings.data.nightLight.warmth : 0.6
|
||||||
|
property real intensity: (Settings.data.nightLight
|
||||||
|
&& Settings.data.nightLight.intensity !== undefined) ? Settings.data.nightLight.intensity : 0.8
|
||||||
|
property string startTime: Settings.data.nightLight?.startTime || "20:00"
|
||||||
|
property string stopTime: Settings.data.nightLight?.stopTime || "07:00"
|
||||||
|
property bool autoSchedule: Settings.data.nightLight?.autoSchedule !== false
|
||||||
|
|
||||||
|
// Computed properties
|
||||||
|
property color overlayColor: enabled ? calculateOverlayColor() : "transparent"
|
||||||
|
property bool isActive: enabled && (autoSchedule ? isWithinSchedule() : true)
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
Logger.log("NightLight", "Service started")
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
Settings.data.nightLight.enabled = !Settings.data.nightLight.enabled
|
||||||
|
Logger.log("NightLight", "Toggled:", Settings.data.nightLight.enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWarmth(value) {
|
||||||
|
Settings.data.nightLight.warmth = Math.max(0.0, Math.min(1.0, value))
|
||||||
|
Logger.log("NightLight", "Warmth set to:", Settings.data.nightLight.warmth)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIntensity(value) {
|
||||||
|
Settings.data.nightLight.intensity = Math.max(0.0, Math.min(1.0, value))
|
||||||
|
Logger.log("NightLight", "Intensity set to:", Settings.data.nightLight.intensity)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSchedule(start, stop) {
|
||||||
|
Settings.data.nightLight.startTime = start
|
||||||
|
Settings.data.nightLight.stopTime = stop
|
||||||
|
Logger.log("NightLight", "Schedule set to:", Settings.data.nightLight.startTime, "-",
|
||||||
|
Settings.data.nightLight.stopTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAutoSchedule(auto) {
|
||||||
|
Settings.data.nightLight.autoSchedule = auto
|
||||||
|
Logger.log("NightLight", "Auto schedule set to:", Settings.data.nightLight.autoSchedule, "enabled:", enabled,
|
||||||
|
"isActive:", isActive, "withinSchedule:", isWithinSchedule())
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateOverlayColor() {
|
||||||
|
if (!isActive)
|
||||||
|
return "transparent"
|
||||||
|
|
||||||
|
// More vibrant color formula - stronger effect at high warmth
|
||||||
|
var red = 1.0
|
||||||
|
var green = 0.85 - warmth * 0.4 // More green reduction for stronger effect
|
||||||
|
var blue = 0.5 - warmth * 0.45 // More blue reduction for warmer feel
|
||||||
|
var alpha = 0.1 + warmth * 0.25 // Higher alpha for more noticeable effect
|
||||||
|
|
||||||
|
// Apply intensity
|
||||||
|
red = red * intensity
|
||||||
|
green = green * intensity
|
||||||
|
blue = blue * intensity
|
||||||
|
|
||||||
|
return Qt.rgba(red, green, blue, alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWithinSchedule() {
|
||||||
|
if (!autoSchedule)
|
||||||
|
return true
|
||||||
|
|
||||||
|
var now = new Date()
|
||||||
|
var currentTime = now.getHours() * 60 + now.getMinutes()
|
||||||
|
|
||||||
|
var startParts = startTime.split(":")
|
||||||
|
var stopParts = stopTime.split(":")
|
||||||
|
var startMinutes = parseInt(startParts[0]) * 60 + parseInt(startParts[1])
|
||||||
|
var stopMinutes = parseInt(stopParts[0]) * 60 + parseInt(stopParts[1])
|
||||||
|
|
||||||
|
// Handle overnight schedule (e.g., 20:00 to 07:00)
|
||||||
|
if (stopMinutes < startMinutes) {
|
||||||
|
return currentTime >= startMinutes || currentTime <= stopMinutes
|
||||||
|
} else {
|
||||||
|
return currentTime >= startMinutes && currentTime <= stopMinutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer to check schedule changes
|
||||||
|
Timer {
|
||||||
|
interval: 60000 // Check every minute
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
if (autoSchedule && enabled) {
|
||||||
|
// Force overlay update when schedule changes
|
||||||
|
Logger.log("NightLight", "Schedule check - enabled:", enabled, "autoSchedule:", autoSchedule, "isActive:",
|
||||||
|
isActive, "withinSchedule:", isWithinSchedule())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -194,17 +194,13 @@ Loader {
|
||||||
property int calculatedY: {
|
property int calculatedY: {
|
||||||
if (panelAnchorVerticalCenter) {
|
if (panelAnchorVerticalCenter) {
|
||||||
return (panelWindow.height - panelHeight) / 2
|
return (panelWindow.height - panelHeight) / 2
|
||||||
}
|
} else if (panelAnchorBottom) {
|
||||||
else if (panelAnchorBottom) {
|
|
||||||
return panelWindow.height - panelHeight - (Style.marginS * scaling)
|
return panelWindow.height - panelHeight - (Style.marginS * scaling)
|
||||||
}
|
} else if (panelAnchorTop) {
|
||||||
else if (panelAnchorTop) {
|
|
||||||
return (Style.marginS * scaling)
|
return (Style.marginS * scaling)
|
||||||
}
|
} else if (panelAnchorBottom) {
|
||||||
else if (panelAnchorBottom) {
|
|
||||||
panelWindow.height - panelHeight - (Style.marginS * scaling)
|
panelWindow.height - panelHeight - (Style.marginS * scaling)
|
||||||
}
|
} else if (!barAtBottom) {
|
||||||
else if (!barAtBottom) {
|
|
||||||
// Below the top bar
|
// Below the top bar
|
||||||
return Style.marginS * scaling
|
return Style.marginS * scaling
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ Item {
|
||||||
signal entered
|
signal entered
|
||||||
signal exited
|
signal exited
|
||||||
signal clicked
|
signal clicked
|
||||||
|
signal rightClicked
|
||||||
signal wheel(int delta)
|
signal wheel(int delta)
|
||||||
|
|
||||||
// Internal state
|
// Internal state
|
||||||
|
|
@ -194,6 +195,7 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
onEntered: {
|
onEntered: {
|
||||||
root.entered()
|
root.entered()
|
||||||
tooltip.show()
|
tooltip.show()
|
||||||
|
|
@ -211,8 +213,12 @@ Item {
|
||||||
}
|
}
|
||||||
tooltip.hide()
|
tooltip.hide()
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: function (mouse) {
|
||||||
root.clicked()
|
if (mouse.button === Qt.LeftButton) {
|
||||||
|
root.clicked()
|
||||||
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
|
root.rightClicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onWheel: wheel => {
|
onWheel: wheel => {
|
||||||
root.wheel(wheel.angleDelta.y)
|
root.wheel(wheel.angleDelta.y)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import qs.Modules.Calendar
|
||||||
import qs.Modules.Dock
|
import qs.Modules.Dock
|
||||||
import qs.Modules.IPC
|
import qs.Modules.IPC
|
||||||
import qs.Modules.LockScreen
|
import qs.Modules.LockScreen
|
||||||
|
import qs.Modules.NightLight
|
||||||
import qs.Modules.Notification
|
import qs.Modules.Notification
|
||||||
import qs.Modules.SettingsPanel
|
import qs.Modules.SettingsPanel
|
||||||
import qs.Modules.PowerPanel
|
import qs.Modules.PowerPanel
|
||||||
|
|
@ -39,6 +40,7 @@ ShellRoot {
|
||||||
ScreenCorners {}
|
ScreenCorners {}
|
||||||
Bar {}
|
Bar {}
|
||||||
Dock {}
|
Dock {}
|
||||||
|
NightLight {}
|
||||||
|
|
||||||
Notification {
|
Notification {
|
||||||
id: notification
|
id: notification
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue