forked from Shinonome/dots-hyprland
osd: unify brightness and volume
This commit is contained in:
@@ -356,7 +356,7 @@ Singleton {
|
||||
property real mediaControlsWidth: 440
|
||||
property real mediaControlsHeight: 160
|
||||
property real notificationPopupWidth: 410
|
||||
property real osdWidth: 200
|
||||
property real osdWidth: 180
|
||||
property real searchWidthCollapsed: 260
|
||||
property real searchWidth: 450
|
||||
property real sidebarWidth: 460
|
||||
|
||||
+49
-33
@@ -15,9 +15,21 @@ Scope {
|
||||
property string protectionMessage: ""
|
||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||
|
||||
property string currentIndicator: "volume"
|
||||
property var indicators: [
|
||||
{
|
||||
id: "volume",
|
||||
sourceUrl: "indicators/VolumeIndicator.qml"
|
||||
},
|
||||
{
|
||||
id: "brightness",
|
||||
sourceUrl: "indicators/BrightnessIndicator.qml"
|
||||
},
|
||||
]
|
||||
|
||||
function triggerOsd() {
|
||||
GlobalStates.osdVolumeOpen = true
|
||||
osdTimeout.restart()
|
||||
GlobalStates.osdVolumeOpen = true;
|
||||
osdTimeout.restart();
|
||||
}
|
||||
|
||||
Timer {
|
||||
@@ -26,35 +38,44 @@ Scope {
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
GlobalStates.osdVolumeOpen = false
|
||||
root.protectionMessage = ""
|
||||
GlobalStates.osdVolumeOpen = false;
|
||||
root.protectionMessage = "";
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Brightness
|
||||
function onBrightnessChanged() {
|
||||
GlobalStates.osdVolumeOpen = false
|
||||
root.protectionMessage = "";
|
||||
root.currentIndicator = "brightness";
|
||||
root.triggerOsd();
|
||||
}
|
||||
}
|
||||
|
||||
Connections { // Listen to volume changes
|
||||
Connections {
|
||||
// Listen to volume changes
|
||||
target: Audio.sink?.audio ?? null
|
||||
function onVolumeChanged() {
|
||||
if (!Audio.ready) return
|
||||
root.triggerOsd()
|
||||
if (!Audio.ready)
|
||||
return;
|
||||
root.currentIndicator = "volume";
|
||||
root.triggerOsd();
|
||||
}
|
||||
function onMutedChanged() {
|
||||
if (!Audio.ready) return
|
||||
root.triggerOsd()
|
||||
if (!Audio.ready)
|
||||
return;
|
||||
root.currentIndicator = "volume";
|
||||
root.triggerOsd();
|
||||
}
|
||||
}
|
||||
|
||||
Connections { // Listen to protection triggers
|
||||
Connections {
|
||||
// Listen to protection triggers
|
||||
target: Audio
|
||||
function onSinkProtectionTriggered(reason) {
|
||||
root.protectionMessage = reason;
|
||||
root.triggerOsd()
|
||||
root.currentIndicator = "volume";
|
||||
root.triggerOsd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +90,7 @@ Scope {
|
||||
Connections {
|
||||
target: root
|
||||
function onFocusedScreenChanged() {
|
||||
osdRoot.screen = root.focusedScreen
|
||||
osdRoot.screen = root.focusedScreen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,10 +118,11 @@ Scope {
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Item {
|
||||
id: osdValuesWrapper
|
||||
// Extra space for shadow
|
||||
implicitHeight: contentColumnLayout.implicitHeight + Appearance.sizes.elevationMargin * 2
|
||||
implicitHeight: contentColumnLayout.implicitHeight
|
||||
implicitWidth: contentColumnLayout.implicitWidth
|
||||
clip: true
|
||||
|
||||
@@ -110,30 +132,25 @@ Scope {
|
||||
onEntered: GlobalStates.osdVolumeOpen = false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Column {
|
||||
id: contentColumnLayout
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: Appearance.sizes.elevationMargin
|
||||
rightMargin: Appearance.sizes.elevationMargin
|
||||
}
|
||||
spacing: 0
|
||||
|
||||
OsdValueIndicator {
|
||||
id: osdValues
|
||||
Layout.fillWidth: true
|
||||
value: Audio.sink?.audio.volume ?? 0
|
||||
icon: Audio.sink?.audio.muted ? "volume_off" : "volume_up"
|
||||
name: Translation.tr("Volume")
|
||||
Loader {
|
||||
id: osdIndicatorLoader
|
||||
source: root.indicators.find(i => i.id === root.currentIndicator)?.sourceUrl
|
||||
}
|
||||
|
||||
Item {
|
||||
id: protectionMessageWrapper
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
implicitHeight: protectionMessageBackground.implicitHeight
|
||||
implicitWidth: protectionMessageBackground.implicitWidth
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
opacity: root.protectionMessage !== "" ? 1 : 0
|
||||
|
||||
StyledRectangularShadow {
|
||||
@@ -174,26 +191,26 @@ Scope {
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "osdVolume"
|
||||
target: "osdVolume"
|
||||
|
||||
function trigger() {
|
||||
root.triggerOsd()
|
||||
function trigger() {
|
||||
root.triggerOsd();
|
||||
}
|
||||
|
||||
function hide() {
|
||||
GlobalStates.osdVolumeOpen = false
|
||||
GlobalStates.osdVolumeOpen = false;
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
GlobalStates.osdVolumeOpen = !GlobalStates.osdVolumeOpen
|
||||
GlobalStates.osdVolumeOpen = !GlobalStates.osdVolumeOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "osdVolumeTrigger"
|
||||
description: "Triggers volume OSD on press"
|
||||
|
||||
onPressed: {
|
||||
root.triggerOsd()
|
||||
root.triggerOsd();
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
@@ -201,8 +218,7 @@ Scope {
|
||||
description: "Hides volume OSD on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.osdVolumeOpen = false
|
||||
GlobalStates.osdVolumeOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
||||
|
||||
function triggerOsd() {
|
||||
GlobalStates.osdBrightnessOpen = true
|
||||
osdTimeout.restart()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: osdTimeout
|
||||
interval: Config.options.osd.timeout
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
GlobalStates.osdBrightnessOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Audio.sink?.audio ?? null
|
||||
function onVolumeChanged() {
|
||||
if (!Audio.ready) return
|
||||
GlobalStates.osdBrightnessOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Brightness
|
||||
function onBrightnessChanged() {
|
||||
if (!root.brightnessMonitor.ready) return
|
||||
root.triggerOsd()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: osdLoader
|
||||
active: GlobalStates.osdBrightnessOpen
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
id: osdRoot
|
||||
color: "transparent"
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onFocusedScreenChanged() {
|
||||
osdRoot.screen = root.focusedScreen
|
||||
}
|
||||
}
|
||||
|
||||
WlrLayershell.namespace: "quickshell:onScreenDisplay"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
anchors {
|
||||
top: !Config.options.bar.bottom
|
||||
bottom: Config.options.bar.bottom
|
||||
}
|
||||
mask: Region {
|
||||
item: osdValuesWrapper
|
||||
}
|
||||
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
exclusiveZone: 0
|
||||
margins {
|
||||
top: Appearance.sizes.barHeight
|
||||
bottom: Appearance.sizes.barHeight
|
||||
}
|
||||
|
||||
implicitWidth: columnLayout.implicitWidth
|
||||
implicitHeight: columnLayout.implicitHeight
|
||||
visible: osdLoader.active
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Item {
|
||||
id: osdValuesWrapper
|
||||
// Extra space for shadow
|
||||
implicitHeight: osdValues.implicitHeight + Appearance.sizes.elevationMargin * 2
|
||||
implicitWidth: osdValues.implicitWidth
|
||||
clip: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: GlobalStates.osdBrightnessOpen = false
|
||||
}
|
||||
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: Appearance.animation.menuDecel.duration
|
||||
easing.type: Appearance.animation.menuDecel.type
|
||||
}
|
||||
}
|
||||
|
||||
OsdValueIndicator {
|
||||
id: osdValues
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.sizes.elevationMargin
|
||||
value: root.brightnessMonitor?.brightness ?? 50
|
||||
icon: "light_mode"
|
||||
rotateIcon: true
|
||||
scaleIcon: true
|
||||
name: Translation.tr("Brightness")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "osdBrightness"
|
||||
|
||||
function trigger() {
|
||||
root.triggerOsd()
|
||||
}
|
||||
|
||||
function hide() {
|
||||
GlobalStates.osdBrightnessOpen = false
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
GlobalStates.osdBrightnessOpen = !GlobalStates.osdBrightnessOpen
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "osdBrightnessTrigger"
|
||||
description: "Triggers brightness OSD on press"
|
||||
|
||||
onPressed: {
|
||||
root.triggerOsd()
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "osdBrightnessHide"
|
||||
description: "Hides brightness OSD on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.osdBrightnessOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,8 @@
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
// import Qt5Compat.GraphicalEffects
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -21,19 +16,23 @@ Item {
|
||||
property real valueIndicatorLeftPadding: 10
|
||||
property real valueIndicatorRightPadding: 20 // An icon is circle ish, a column isn't, hence the extra padding
|
||||
|
||||
Layout.margins: Appearance.sizes.elevationMargin
|
||||
implicitWidth: Appearance.sizes.osdWidth
|
||||
implicitHeight: valueIndicator.implicitHeight
|
||||
implicitWidth: Appearance.sizes.osdWidth + 2 * Appearance.sizes.elevationMargin
|
||||
implicitHeight: valueIndicator.implicitHeight + 2 * Appearance.sizes.elevationMargin
|
||||
|
||||
StyledRectangularShadow {
|
||||
target: valueIndicator
|
||||
}
|
||||
WrapperRectangle {
|
||||
Rectangle {
|
||||
id: valueIndicator
|
||||
anchors.fill: parent
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: Appearance.sizes.elevationMargin
|
||||
}
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.colors.colLayer0
|
||||
|
||||
implicitWidth: valueRow.implicitWidth
|
||||
implicitHeight: valueRow.implicitHeight
|
||||
|
||||
RowLayout { // Icon on the left, stuff on the right
|
||||
id: valueRow
|
||||
@@ -48,6 +47,7 @@ Item {
|
||||
Layout.leftMargin: valueIndicatorLeftPadding
|
||||
Layout.topMargin: valueIndicatorVerticalPadding
|
||||
Layout.bottomMargin: valueIndicatorVerticalPadding
|
||||
|
||||
MaterialSymbol { // Icon
|
||||
anchors {
|
||||
centerIn: parent
|
||||
@@ -101,4 +101,4 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import qs
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import "../"
|
||||
|
||||
OsdValueIndicator {
|
||||
id: root
|
||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
||||
|
||||
value: root.brightnessMonitor?.brightness ?? 50
|
||||
icon: "light_mode"
|
||||
rotateIcon: true
|
||||
scaleIcon: true
|
||||
name: Translation.tr("Brightness")
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import qs
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import "../"
|
||||
|
||||
OsdValueIndicator {
|
||||
id: osdValues
|
||||
value: Audio.sink?.audio.volume ?? 0
|
||||
icon: Audio.sink?.audio.muted ? "volume_off" : "volume_up"
|
||||
name: Translation.tr("Volume")
|
||||
}
|
||||
@@ -42,8 +42,7 @@ ShellRoot {
|
||||
property bool enableLock: true
|
||||
property bool enableMediaControls: true
|
||||
property bool enableNotificationPopup: true
|
||||
property bool enableOnScreenDisplayBrightness: true
|
||||
property bool enableOnScreenDisplayVolume: true
|
||||
property bool enableOnScreenDisplay: true
|
||||
property bool enableOnScreenKeyboard: true
|
||||
property bool enableOverview: true
|
||||
property bool enableReloadPopup: true
|
||||
@@ -72,8 +71,7 @@ ShellRoot {
|
||||
LazyLoader { active: enableLock; component: Lock {} }
|
||||
LazyLoader { active: enableMediaControls; component: MediaControls {} }
|
||||
LazyLoader { active: enableNotificationPopup; component: NotificationPopup {} }
|
||||
LazyLoader { active: enableOnScreenDisplayBrightness; component: OnScreenDisplayBrightness {} }
|
||||
LazyLoader { active: enableOnScreenDisplayVolume; component: OnScreenDisplayVolume {} }
|
||||
LazyLoader { active: enableOnScreenDisplay; component: OnScreenDisplay {} }
|
||||
LazyLoader { active: enableOnScreenKeyboard; component: OnScreenKeyboard {} }
|
||||
LazyLoader { active: enableOverview; component: Overview {} }
|
||||
LazyLoader { active: enableReloadPopup; component: ReloadPopup {} }
|
||||
|
||||
Reference in New Issue
Block a user