add noctalia and fuzzel
This commit is contained in:
+249
@@ -0,0 +1,249 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Compositor
|
||||
import qs.Services.Hardware
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: Style.marginL
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL
|
||||
|
||||
Repeater {
|
||||
model: Quickshell.screens || []
|
||||
delegate: NBox {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: Math.round(contentCol.implicitHeight + Style.margin2L)
|
||||
color: Color.mSurface
|
||||
|
||||
property var brightnessMonitor: BrightnessService.getMonitorForScreen(modelData)
|
||||
property real localBrightness: 0.5
|
||||
property bool localBrightnessChanging: false
|
||||
readonly property string automaticOptionLabel: {
|
||||
var baseLabel = I18n.tr("panels.display.monitors-backlight-device-auto-option");
|
||||
var autoDevicePath = (BrightnessService.availableBacklightDevices && BrightnessService.availableBacklightDevices.length > 0) ? BrightnessService.availableBacklightDevices[0] : "";
|
||||
if (autoDevicePath === "")
|
||||
return baseLabel;
|
||||
|
||||
var autoDeviceName = BrightnessService.getBacklightDeviceName(autoDevicePath) || autoDevicePath;
|
||||
return baseLabel + "(" + autoDeviceName + ")";
|
||||
}
|
||||
readonly property var backlightDeviceOptions: {
|
||||
var options = [
|
||||
{
|
||||
"key": "",
|
||||
"name": automaticOptionLabel
|
||||
}
|
||||
];
|
||||
|
||||
var devices = BrightnessService.availableBacklightDevices || [];
|
||||
for (var i = 0; i < devices.length; i++) {
|
||||
var devicePath = devices[i];
|
||||
var deviceName = BrightnessService.getBacklightDeviceName(devicePath) || devicePath;
|
||||
options.push({
|
||||
"key": devicePath,
|
||||
"name": deviceName
|
||||
});
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
onBrightnessMonitorChanged: {
|
||||
if (brightnessMonitor && !localBrightnessChanging)
|
||||
localBrightness = brightnessMonitor.brightness || 0.5;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: BrightnessService
|
||||
function onMonitorBrightnessChanged(monitor, newBrightness) {
|
||||
if (monitor === brightnessMonitor && !localBrightnessChanging) {
|
||||
localBrightness = newBrightness;
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: brightnessMonitor
|
||||
ignoreUnknownSignals: true
|
||||
function onBrightnessUpdated() {
|
||||
if (brightnessMonitor && !localBrightnessChanging) {
|
||||
localBrightness = brightnessMonitor.brightness || 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: debounceTimer
|
||||
interval: 120
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (brightnessMonitor && brightnessMonitor.brightnessControlAvailable && Math.abs(localBrightness - brightnessMonitor.brightness) >= 0.005) {
|
||||
brightnessMonitor.setBrightness(localBrightness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: contentCol
|
||||
width: parent.width - 2 * Style.marginL
|
||||
x: Style.marginL
|
||||
y: Style.marginL
|
||||
spacing: Style.marginXXS
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
NText {
|
||||
text: modelData.name || "Unknown"
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightSemiBold
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
|
||||
NText {
|
||||
Layout.fillWidth: true
|
||||
readonly property real compositorScale: {
|
||||
const info = CompositorService.displayScales[modelData.name];
|
||||
return (info && info.scale) ? info.scale : 1.0;
|
||||
}
|
||||
text: {
|
||||
I18n.tr("system.monitor-description", {
|
||||
"model": modelData.model,
|
||||
"width": modelData.width * compositorScale,
|
||||
"height": modelData.height * compositorScale,
|
||||
"scale": compositorScale
|
||||
});
|
||||
}
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignRight
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS
|
||||
Layout.fillWidth: true
|
||||
visible: brightnessMonitor !== undefined && brightnessMonitor !== null
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL
|
||||
|
||||
NText {
|
||||
text: I18n.tr("common.brightness")
|
||||
Layout.preferredWidth: 90
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NValueSlider {
|
||||
id: brightnessSlider
|
||||
from: 0
|
||||
to: 1
|
||||
value: localBrightness
|
||||
stepSize: 0.01
|
||||
enabled: brightnessMonitor ? brightnessMonitor.brightnessControlAvailable : false
|
||||
onMoved: value => {
|
||||
if (brightnessMonitor && brightnessMonitor.brightnessControlAvailable) {
|
||||
localBrightness = value;
|
||||
debounceTimer.restart();
|
||||
}
|
||||
}
|
||||
onPressedChanged: (pressed, value) => {
|
||||
localBrightnessChanging = pressed;
|
||||
if (brightnessMonitor && brightnessMonitor.brightnessControlAvailable) {
|
||||
if (pressed) {
|
||||
localBrightness = value;
|
||||
debounceTimer.restart();
|
||||
} else {
|
||||
localBrightness = value;
|
||||
debounceTimer.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NText {
|
||||
text: brightnessMonitor ? Math.round(localBrightness * 100) + "%" : "N/A"
|
||||
Layout.preferredWidth: 55
|
||||
horizontalAlignment: Text.AlignRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
opacity: brightnessMonitor && !brightnessMonitor.brightnessControlAvailable ? 0.5 : 1.0
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 30
|
||||
Layout.fillHeight: true
|
||||
NIcon {
|
||||
icon: brightnessMonitor && brightnessMonitor.method == "internal" ? "device-laptop" : "device-desktop"
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: brightnessMonitor && !brightnessMonitor.brightnessControlAvailable ? 0.5 : 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
visible: brightnessMonitor && !brightnessMonitor.brightnessControlAvailable && !(brightnessMonitor.method === "internal" && brightnessMonitor.initInProgress)
|
||||
text: !Settings.data.brightness.enableDdcSupport ? I18n.tr("panels.display.monitors-brightness-unavailable-ddc-disabled") : I18n.tr("panels.display.monitors-brightness-unavailable-generic")
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
Layout.fillWidth: true
|
||||
visible: brightnessMonitor && brightnessMonitor.method === "internal"
|
||||
label: I18n.tr("panels.display.monitors-backlight-device-label")
|
||||
description: I18n.tr("panels.display.monitors-backlight-device-description")
|
||||
model: backlightDeviceOptions
|
||||
currentKey: BrightnessService.getMappedBacklightDevice(modelData.name) || ""
|
||||
onSelected: key => BrightnessService.setMappedBacklightDevice(modelData.name, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSpinBox {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("panels.display.monitors-brightness-step-label")
|
||||
description: I18n.tr("panels.display.monitors-brightness-step-description")
|
||||
minimum: 1
|
||||
maximum: 50
|
||||
value: Settings.data.brightness.brightnessStep
|
||||
stepSize: 1
|
||||
suffix: "%"
|
||||
onValueChanged: Settings.data.brightness.brightnessStep = value
|
||||
defaultValue: Settings.getDefaultValue("brightness.brightnessStep")
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("panels.display.monitors-enforce-minimum-label")
|
||||
description: I18n.tr("panels.display.monitors-enforce-minimum-description")
|
||||
checked: Settings.data.brightness.enforceMinimum
|
||||
onToggled: checked => Settings.data.brightness.enforceMinimum = checked
|
||||
defaultValue: Settings.getDefaultValue("brightness.enforceMinimum")
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("panels.display.monitors-external-brightness-label")
|
||||
description: I18n.tr("panels.display.monitors-external-brightness-description")
|
||||
checked: Settings.data.brightness.enableDdcSupport
|
||||
onToggled: checked => {
|
||||
Settings.data.brightness.enableDdcSupport = checked;
|
||||
}
|
||||
defaultValue: Settings.getDefaultValue("brightness.enableDdcSupport")
|
||||
}
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Services.Location
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: 0
|
||||
|
||||
// Time dropdown options (00:00 .. 23:30)
|
||||
ListModel {
|
||||
id: timeOptions
|
||||
}
|
||||
|
||||
function populateTimeOptions() {
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Qt.callLater(populateTimeOptions);
|
||||
}
|
||||
|
||||
// Check for wlsunset availability when enabling Night Light
|
||||
Process {
|
||||
id: wlsunsetCheck
|
||||
command: ["sh", "-c", "command -v wlsunset"]
|
||||
running: false
|
||||
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0) {
|
||||
Settings.data.nightLight.enabled = true;
|
||||
NightLightService.apply();
|
||||
ToastService.showNotice(I18n.tr("common.night-light"), I18n.tr("common.enabled"), "nightlight-on");
|
||||
} else {
|
||||
Settings.data.nightLight.enabled = false;
|
||||
ToastService.showWarning(I18n.tr("common.night-light"), I18n.tr("toast.night-light.not-installed"));
|
||||
}
|
||||
}
|
||||
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
}
|
||||
|
||||
NTabBar {
|
||||
id: subTabBar
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: Style.marginM
|
||||
distributeEvenly: true
|
||||
currentIndex: tabView.currentIndex
|
||||
|
||||
NTabButton {
|
||||
text: I18n.tr("common.brightness")
|
||||
tabIndex: 0
|
||||
checked: subTabBar.currentIndex === 0
|
||||
}
|
||||
NTabButton {
|
||||
text: I18n.tr("common.night-light")
|
||||
tabIndex: 1
|
||||
checked: subTabBar.currentIndex === 1
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.marginL
|
||||
}
|
||||
|
||||
NTabView {
|
||||
id: tabView
|
||||
currentIndex: subTabBar.currentIndex
|
||||
|
||||
BrightnessSubTab {}
|
||||
NightLightSubTab {
|
||||
timeOptions: timeOptions
|
||||
onCheckWlsunset: wlsunsetCheck.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import qs.Commons
|
||||
import qs.Services.Location
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: Style.marginL
|
||||
Layout.fillWidth: true
|
||||
|
||||
property var timeOptions
|
||||
|
||||
signal checkWlsunset
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("panels.display.night-light-enable-label")
|
||||
description: I18n.tr("panels.display.night-light-enable-description")
|
||||
checked: Settings.data.nightLight.enabled
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
root.checkWlsunset();
|
||||
} else {
|
||||
Settings.data.nightLight.enabled = false;
|
||||
Settings.data.nightLight.forced = false;
|
||||
NightLightService.apply();
|
||||
ToastService.showNotice(I18n.tr("common.night-light"), I18n.tr("common.disabled"), "nightlight-off");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
spacing: Style.marginL
|
||||
Layout.fillWidth: true
|
||||
|
||||
NLabel {
|
||||
label: I18n.tr("panels.display.night-light-temperature-night")
|
||||
description: I18n.tr("panels.display.night-light-temperature-night-description")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
NSlider {
|
||||
id: nightSlider
|
||||
Layout.fillWidth: true
|
||||
from: 1000
|
||||
to: 6500
|
||||
value: Settings.data.nightLight.nightTemp
|
||||
|
||||
onValueChanged: {
|
||||
var dayTemp = parseInt(Settings.data.nightLight.dayTemp);
|
||||
var v = Math.round(value);
|
||||
if (!isNaN(dayTemp)) {
|
||||
var maxNight = dayTemp - 500;
|
||||
v = Math.min(maxNight, Math.max(1000, v));
|
||||
} else {
|
||||
v = Math.max(1000, v);
|
||||
}
|
||||
if (v !== value)
|
||||
value = v;
|
||||
}
|
||||
|
||||
onPressedChanged: {
|
||||
if (!pressed) {
|
||||
var dayTemp = parseInt(Settings.data.nightLight.dayTemp);
|
||||
var v = Math.round(value);
|
||||
if (!isNaN(dayTemp)) {
|
||||
var maxNight = dayTemp - 500;
|
||||
v = Math.min(maxNight, Math.max(1000, v));
|
||||
} else {
|
||||
v = Math.max(1000, v);
|
||||
}
|
||||
Settings.data.nightLight.nightTemp = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: nightSlider.value + "K"
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
NLabel {
|
||||
label: I18n.tr("panels.display.night-light-temperature-day")
|
||||
description: I18n.tr("panels.display.night-light-temperature-day-description")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
NSlider {
|
||||
id: daySlider
|
||||
Layout.fillWidth: true
|
||||
from: 1000
|
||||
to: 6500
|
||||
value: Settings.data.nightLight.dayTemp
|
||||
|
||||
onValueChanged: {
|
||||
var nightTemp = parseInt(Settings.data.nightLight.nightTemp);
|
||||
var v = Math.round(value);
|
||||
if (!isNaN(nightTemp)) {
|
||||
var minDay = nightTemp + 500;
|
||||
v = Math.max(minDay, Math.min(6500, v));
|
||||
} else {
|
||||
v = Math.min(6500, v);
|
||||
}
|
||||
if (v !== value)
|
||||
value = v;
|
||||
}
|
||||
|
||||
onPressedChanged: {
|
||||
if (!pressed) {
|
||||
var nightTemp = parseInt(Settings.data.nightLight.nightTemp);
|
||||
var v = Math.round(value);
|
||||
if (!isNaN(nightTemp)) {
|
||||
var minDay = nightTemp + 500;
|
||||
v = Math.max(minDay, Math.min(6500, v));
|
||||
} else {
|
||||
v = Math.min(6500, v);
|
||||
}
|
||||
Settings.data.nightLight.dayTemp = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: daySlider.value + "K"
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("panels.display.night-light-auto-schedule-label")
|
||||
description: I18n.tr("panels.display.night-light-auto-schedule-description", {
|
||||
"location": LocationService.stableName
|
||||
})
|
||||
checked: Settings.data.nightLight.autoSchedule
|
||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS
|
||||
Layout.fillWidth: true
|
||||
visible: !Settings.data.nightLight.autoSchedule && !Settings.data.nightLight.forced
|
||||
|
||||
NLabel {
|
||||
label: I18n.tr("panels.display.night-light-manual-schedule-label")
|
||||
description: I18n.tr("panels.display.night-light-manual-schedule-description")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("panels.display.night-light-manual-schedule-sunrise")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
model: root.timeOptions
|
||||
currentKey: Settings.data.nightLight.manualSunrise
|
||||
placeholder: I18n.tr("panels.display.night-light-manual-schedule-select-start")
|
||||
onSelected: key => Settings.data.nightLight.manualSunrise = key
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("panels.display.night-light-manual-schedule-sunset")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
model: root.timeOptions
|
||||
currentKey: Settings.data.nightLight.manualSunset
|
||||
placeholder: I18n.tr("panels.display.night-light-manual-schedule-select-stop")
|
||||
onSelected: key => Settings.data.nightLight.manualSunset = key
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("panels.display.night-light-force-activation-label")
|
||||
description: I18n.tr("panels.display.night-light-force-activation-description")
|
||||
checked: Settings.data.nightLight.forced
|
||||
onToggled: checked => {
|
||||
Settings.data.nightLight.forced = checked;
|
||||
if (checked && !Settings.data.nightLight.enabled) {
|
||||
root.checkWlsunset();
|
||||
} else {
|
||||
NightLightService.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user