forked from Shinonome/dots-hyprland
osd
This commit is contained in:
@@ -12,6 +12,7 @@ Scope {
|
||||
|
||||
readonly property int barHeight: Appearance.sizes.barHeight
|
||||
readonly property int barCenterSideModuleWidth: Appearance.sizes.barCenterSideModuleWidth
|
||||
readonly property int osdHideMouseMoveThreshold: 20
|
||||
|
||||
Process {
|
||||
id: openSidebarRight
|
||||
@@ -21,6 +22,10 @@ Scope {
|
||||
id: openSidebarLeft
|
||||
command: ["qs", "ipc", "call", "sidebarLeft", "open"]
|
||||
}
|
||||
Process {
|
||||
id: hideOsd
|
||||
command: ["qs", "ipc", "call", "osd", "hide"]
|
||||
}
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
@@ -60,18 +65,6 @@ Scope {
|
||||
ActiveWindow {
|
||||
bar: barRoot
|
||||
}
|
||||
|
||||
// Scroll to change brightness
|
||||
WheelHandler {
|
||||
onWheel: (event) => {
|
||||
if (event.angleDelta.y < 0)
|
||||
Brightness.value = -1;
|
||||
else if (event.angleDelta.y > 0)
|
||||
Brightness.value = 1;
|
||||
}
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Middle section
|
||||
@@ -179,9 +172,57 @@ Scope {
|
||||
|
||||
|
||||
}
|
||||
MouseArea {
|
||||
|
||||
// Interactions
|
||||
MouseArea { // Left side: scroll to change brightness
|
||||
id: barLeftSideMouseArea
|
||||
property bool hovered: false
|
||||
property real lastScrollX: 0
|
||||
property real lastScrollY: 0
|
||||
property bool trackingScroll: false
|
||||
anchors.fill: leftSection
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
onEntered: (event) => {
|
||||
barLeftSideMouseArea.hovered = true
|
||||
}
|
||||
onExited: (event) => {
|
||||
barLeftSideMouseArea.hovered = false
|
||||
barLeftSideMouseArea.trackingScroll = false
|
||||
}
|
||||
// Scroll to change brightness
|
||||
WheelHandler {
|
||||
onWheel: (event) => {
|
||||
if (event.angleDelta.y < 0)
|
||||
Brightness.increment = -1;
|
||||
else if (event.angleDelta.y > 0)
|
||||
Brightness.increment = 1;
|
||||
// Store the mouse position and start tracking
|
||||
barLeftSideMouseArea.lastScrollX = event.x;
|
||||
barLeftSideMouseArea.lastScrollY = event.y;
|
||||
barLeftSideMouseArea.trackingScroll = true;
|
||||
}
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
}
|
||||
onPositionChanged: (mouse) => {
|
||||
if (barLeftSideMouseArea.trackingScroll) {
|
||||
const dx = mouse.x - barLeftSideMouseArea.lastScrollX;
|
||||
const dy = mouse.y - barLeftSideMouseArea.lastScrollY;
|
||||
if (Math.sqrt(dx*dx + dy*dy) > osdHideMouseMoveThreshold) {
|
||||
hideOsd.running = true;
|
||||
barLeftSideMouseArea.trackingScroll = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea { // Right side: scroll to change volume
|
||||
id: barRightSideMouseArea
|
||||
property bool hovered: false
|
||||
property real lastScrollX: 0
|
||||
property real lastScrollY: 0
|
||||
property bool trackingScroll: false
|
||||
anchors.fill: rightSection
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
@@ -191,6 +232,7 @@ Scope {
|
||||
}
|
||||
onExited: (event) => {
|
||||
barRightSideMouseArea.hovered = false
|
||||
barRightSideMouseArea.trackingScroll = false
|
||||
}
|
||||
onPressed: (event) => {
|
||||
if (event.button === Qt.LeftButton) {
|
||||
@@ -200,15 +242,29 @@ Scope {
|
||||
// Scroll to change volume
|
||||
WheelHandler {
|
||||
onWheel: (event) => {
|
||||
const currentVolume = Audio.sink?.audio.volume;
|
||||
const currentVolume = Audio.value;
|
||||
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||
if (event.angleDelta.y < 0)
|
||||
Audio.sink.audio.volume -= step;
|
||||
else if (event.angleDelta.y > 0)
|
||||
Audio.sink.audio.volume += step;
|
||||
// Store the mouse position and start tracking
|
||||
barRightSideMouseArea.lastScrollX = event.x;
|
||||
barRightSideMouseArea.lastScrollY = event.y;
|
||||
barRightSideMouseArea.trackingScroll = true;
|
||||
}
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
}
|
||||
onPositionChanged: (mouse) => {
|
||||
if (barRightSideMouseArea.trackingScroll) {
|
||||
const dx = mouse.x - barRightSideMouseArea.lastScrollX;
|
||||
const dy = mouse.y - barRightSideMouseArea.lastScrollY;
|
||||
if (Math.sqrt(dx*dx + dy*dy) > osdHideMouseMoveThreshold) {
|
||||
hideOsd.running = true;
|
||||
barRightSideMouseArea.trackingScroll = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ Singleton {
|
||||
property color colTooltip: m3colors.m3inverseSurface
|
||||
property color colOnTooltip: m3colors.m3inverseOnSurface
|
||||
property color colScrim: transparentize(m3colors.m3scrim, 0.5)
|
||||
property color colShadow: transparentize(m3colors.m3shadow, 0.75)
|
||||
}
|
||||
|
||||
rounding: QtObject {
|
||||
|
||||
@@ -26,12 +26,16 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
property QtObject osd: QtObject {
|
||||
property int timeout: 1000
|
||||
}
|
||||
|
||||
property QtObject resources: QtObject {
|
||||
property int updateInterval: 3000
|
||||
}
|
||||
|
||||
property QtObject hacks: QtObject {
|
||||
property int arbitraryRaceConditionDelay: 10
|
||||
property int arbitraryRaceConditionDelay: 10 // milliseconds
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// From https://github.com/rafzby/circular-progressbar
|
||||
// License: LGPL-3.0 - A copy can be found in `licenses` folder of repo
|
||||
// Modified
|
||||
// Modified so it looks like in Material 3: https://m3.material.io/components/progress-indicators/specs
|
||||
import QtQuick 2.9
|
||||
|
||||
Item {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import "root:/services"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
ProgressBar {
|
||||
id: root
|
||||
property real valueBarWidth: 120
|
||||
property real valueBarHeight: 4
|
||||
property real valueBarGap: 4
|
||||
|
||||
Behavior on value {
|
||||
NumberAnimation {
|
||||
duration: Appearance.animation.elementDecel.duration
|
||||
easing.type: Appearance.animation.elementDecel.type
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
radius: Appearance.rounding.full
|
||||
implicitHeight: valueBarHeight
|
||||
implicitWidth: valueBarWidth
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
|
||||
Rectangle { // Left progress fill
|
||||
width: root.visualPosition * parent.width
|
||||
height: parent.height
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.m3colors.m3primary
|
||||
}
|
||||
Rectangle { // Right remaining part fill
|
||||
anchors.right: parent.right
|
||||
width: (1 - root.visualPosition) * parent.width - valueBarGap
|
||||
height: parent.height
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.m3colors.m3secondaryContainer
|
||||
}
|
||||
Rectangle { // Stop point
|
||||
anchors.right: parent.right
|
||||
width: valueBarGap
|
||||
height: valueBarGap
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.m3colors.m3primary
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import "root:/services/"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
property bool showOsdValues: false
|
||||
|
||||
function triggerOsd() {
|
||||
showOsdValues = true
|
||||
osdTimeout.restart()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: osdTimeout
|
||||
interval: ConfigOptions.osd.timeout
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
showOsdValues = false
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Brightness
|
||||
function onValueChanged() {
|
||||
if (!Brightness.ready) return
|
||||
root.triggerOsd()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Audio.sink.audio
|
||||
function onVolumeChanged() {
|
||||
if (!Audio.ready) return
|
||||
root.triggerOsd()
|
||||
}
|
||||
}
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
property var modelData
|
||||
|
||||
screen: modelData
|
||||
exclusionMode: ExclusionMode.Normal
|
||||
WlrLayershell.namespace: "quickshell:onScreenDisplay"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
color: "transparent"
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
mask: Region {
|
||||
item: columnLayout
|
||||
}
|
||||
|
||||
width: columnLayout.implicitWidth
|
||||
height: columnLayout.implicitHeight
|
||||
visible: showOsdValues
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Item {
|
||||
height: 1 // Prevent Wayland protocol error
|
||||
}
|
||||
Item {
|
||||
implicitHeight: true ? osdValues.implicitHeight : 0
|
||||
implicitWidth: osdValues.implicitWidth
|
||||
clip: true
|
||||
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: Appearance.animation.menuDecel.duration
|
||||
easing.type: Appearance.animation.menuDecel.type
|
||||
}
|
||||
}
|
||||
|
||||
OsdValues {
|
||||
id: osdValues
|
||||
anchors.bottom: parent.bottom
|
||||
// height: showOsdValues ? implicitHeight : 0
|
||||
// implicitHeight: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "osd"
|
||||
|
||||
function trigger() {
|
||||
root.triggerOsd()
|
||||
}
|
||||
|
||||
function hide() {
|
||||
showOsdValues = false
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
showOsdValues = !showOsdValues
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import "root:/services"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property real value
|
||||
required property string icon
|
||||
required property string name
|
||||
|
||||
property real valueIndicatorVerticalPadding: 5
|
||||
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: valueIndicator.implicitWidth
|
||||
implicitHeight: valueIndicator.implicitHeight
|
||||
|
||||
WrapperRectangle {
|
||||
id: valueIndicator
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.colors.colLayer0
|
||||
implicitWidth: valueRow.implicitWidth
|
||||
|
||||
RowLayout { // Icon on the left, stuff on the right
|
||||
id: valueRow
|
||||
spacing: 5
|
||||
Layout.margins: 10
|
||||
|
||||
MaterialSymbol { // Icon
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: valueIndicatorLeftPadding
|
||||
Layout.topMargin: valueIndicatorVerticalPadding
|
||||
Layout.bottomMargin: valueIndicatorVerticalPadding
|
||||
text: root.icon
|
||||
font.pixelSize: 30
|
||||
}
|
||||
ColumnLayout { // Stuff
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.rightMargin: valueIndicatorRightPadding
|
||||
spacing: 5
|
||||
|
||||
RowLayout { // Name fill left, value on the right end
|
||||
Layout.leftMargin: valueBarHeight / 2 // Align text with progressbar radius curve's left end
|
||||
Layout.rightMargin: valueBarHeight / 2 // Align text with progressbar radius curve's left end
|
||||
|
||||
StyledText {
|
||||
color: Appearance.colors.colOnLayer0
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
Layout.fillWidth: true
|
||||
text: root.name
|
||||
}
|
||||
|
||||
StyledText {
|
||||
color: Appearance.colors.colOnLayer0
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
Layout.fillWidth: false
|
||||
text: Math.round(root.value * 100)
|
||||
}
|
||||
}
|
||||
|
||||
StyledProgressBar {
|
||||
id: valueProgressBar
|
||||
value: root.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: valueShadow
|
||||
anchors.fill: valueIndicator
|
||||
source: valueIndicator
|
||||
radius: Appearance.sizes.elevationMargin
|
||||
samples: radius * 2 + 1
|
||||
color: Appearance.colors.colShadow
|
||||
verticalOffset: 2
|
||||
horizontalOffset: 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import "root:/services"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
RowLayout {
|
||||
spacing: -5
|
||||
|
||||
OsdValueIndicator {
|
||||
value: Brightness.value
|
||||
icon: "light_mode"
|
||||
name: "Brightness"
|
||||
}
|
||||
OsdValueIndicator {
|
||||
value: Audio.sink.audio.volume
|
||||
icon: "volume_up"
|
||||
name: "Volume"
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ Scope {
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
id: barRoot
|
||||
visible: (ConfigOptions.appearance.fakeScreenRounding === 1 || (ConfigOptions.appearance.fakeScreenRounding === 2 && !activeWindow?.fullscreen))
|
||||
|
||||
property var modelData
|
||||
|
||||
@@ -162,7 +162,7 @@ Scope {
|
||||
verticalOffset: 2
|
||||
radius: Appearance.sizes.elevationMargin
|
||||
samples: Appearance.sizes.elevationMargin * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs
|
||||
color: Appearance.transparentize(Appearance.m3colors.m3shadow, 0.55)
|
||||
color: Appearance.colors.colShadow
|
||||
source: sidebarRightBackground
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pragma ComponentBehavior: Bound
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool ready: Pipewire.defaultAudioSink.ready
|
||||
property var sink: Pipewire.defaultAudioSink
|
||||
property var source: Pipewire.defaultAudioSource
|
||||
|
||||
|
||||
@@ -6,22 +6,22 @@ pragma ComponentBehavior: Bound
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property string brightness
|
||||
property int value: 0
|
||||
property bool ready: false
|
||||
property real value
|
||||
property int increment: 0
|
||||
|
||||
function refresh() {
|
||||
getBrightness.running = true;
|
||||
}
|
||||
|
||||
onValueChanged: () => {
|
||||
if (value > 0) {
|
||||
onIncrementChanged: () => {
|
||||
if (increment > 0) {
|
||||
increaseBrightness.running = true;
|
||||
root.value = 0;
|
||||
} else if (value < 0) {
|
||||
root.increment = 0;
|
||||
} else if (increment < 0) {
|
||||
decreaseBrightness.running = true;
|
||||
root.value = 0;
|
||||
root.increment = 0;
|
||||
}
|
||||
getBrightness.running = true;
|
||||
}
|
||||
|
||||
Process {
|
||||
@@ -30,12 +30,15 @@ Singleton {
|
||||
command: ["sh", "-c", "brightnessctl -m i | cut -d, -f4"]
|
||||
running: true
|
||||
onExited: {
|
||||
running = false;
|
||||
if (!ready) ready = true
|
||||
}
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: (data) => {
|
||||
root.brightness = data;
|
||||
root.value = parseFloat(data.replace("%", "")) / 100;
|
||||
if (root.value < 0.01) {
|
||||
preventPitchBlack.running = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +51,7 @@ Singleton {
|
||||
running: false
|
||||
onExited: {
|
||||
running = false;
|
||||
getBrightness.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +62,18 @@ Singleton {
|
||||
running: false
|
||||
onExited: {
|
||||
running = false;
|
||||
getBrightness.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: preventPitchBlack
|
||||
|
||||
command: ["brightnessctl", "set", "1%+"]
|
||||
running: false
|
||||
onExited: {
|
||||
running = false;
|
||||
getBrightness.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//@ pragma UseQApplication
|
||||
|
||||
import "./modules/bar/"
|
||||
import "./modules/onScreenDisplay/"
|
||||
import "./modules/screenCorners/"
|
||||
import "./modules/sidebarRight/"
|
||||
import QtQuick
|
||||
@@ -14,5 +15,6 @@ ShellRoot {
|
||||
SidebarRight {}
|
||||
ScreenCorners {}
|
||||
ReloadPopup {}
|
||||
OnScreenDisplay {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user