Fix hover, systray menu and theming

This commit is contained in:
Amaro Lopes
2025-09-24 17:02:46 -03:00
parent 161988cbb6
commit c66d043ece
8 changed files with 116 additions and 53 deletions

View File

@@ -67,7 +67,7 @@ Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
text: audioTextText text: audioTextText
font.bold: true font.bold: true
font.pixelSize: 14 font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily font.family: Theme.fontFamily
color: Theme.textColor color: Theme.textColor
} }

View File

@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Io
import qs.Services import qs.Services
import qs.Common import qs.Common
@@ -12,22 +13,48 @@ Item {
} }
Rectangle { Rectangle {
id: clock
color: Theme.backgroudColor color: Theme.backgroudColor
implicitWidth: clockText.implicitWidth * 1.6 implicitWidth: clockText.implicitWidth * 1.6
implicitHeight: Theme.heightGaps //root.implicitHeight*0.8 implicitHeight: Theme.heightGaps
radius: 25 radius: 25
property string calendar: ""
Text { Text {
id: clockText id: clockText
anchors.centerIn: parent anchors.centerIn: parent
text: Time.time text: Time.time
font.bold: true font.bold: true
font.pixelSize: 14 font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily font.family: Theme.fontFamily
color: Theme.textColor color: Theme.textColor
} }
Process {
id: cal
running: true
command: ["cal","-S3"]
stdout: StdioCollector {
onStreamFinished: {clock.calendar=this.text}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
cal.running = true
PopUpHover.start(clock,"time")
}
onExited: {
PopUpHover.exit()
}
}
} }
} }

View File

@@ -8,11 +8,7 @@ Singleton {
property var component: null property var component: null
property string type: "" property string type: ""
property int width: 100
property int height: 100
property int x: component? component.implicitWidth : 0 property int x: component? component.implicitWidth : 0
property int y: component? (component.implicitHeight + Theme.gaps) : 100 property int y: component? (component.implicitHeight + Theme.gaps) : 100
property bool visible: false
} }

View File

@@ -9,7 +9,9 @@ Singleton {
readonly property int barSize: 35 readonly property int barSize: 35
readonly property double heightGaps: barSize * 0.8 readonly property double heightGaps: barSize * 0.8
readonly property string fontFamily: "Source Code Pro" readonly property string fontFamily: "Noto Sans"
readonly property string fontFamilyMono: "SauceCodePro Nerd Font Mono"
readonly property int pixelSize: 14
readonly property int gaps: 5 readonly property int gaps: 5
readonly property int animationDuration: 200 readonly property int animationDuration: 200
@@ -23,25 +25,25 @@ Singleton {
} }
readonly property var walColorsText: walColors.text().split('\n') readonly property var walColorsText: walColors.text().split('\n')
property double barOpacity: 0.2 readonly property double barOpacity: 0.2
property color backgroudColor: walColorsText[0] readonly property color backgroudColor: walColorsText[0]
property color color2: walColorsText[1] readonly property color color2: walColorsText[1]
property color color3: walColorsText[2] readonly property color color3: walColorsText[2]
property color color4: walColorsText[3] readonly property color color4: walColorsText[3]
property color color5: walColorsText[4] readonly property color color5: walColorsText[4]
property color color6: walColorsText[5] readonly property color color6: walColorsText[5]
property color color7: walColorsText[6] readonly property color color7: walColorsText[6]
property color foregroundColor: walColorsText[7] readonly property color foregroundColor: walColorsText[7]
property color backgroudColorBright: walColorsText[8] readonly property color backgroudColorBright: walColorsText[8]
property color color2Bright: walColorsText[9] readonly property color color2Bright: walColorsText[9]
property color color3Bright: walColorsText[10] readonly property color color3Bright: walColorsText[10]
property color color4Bright: walColorsText[11] readonly property color color4Bright: walColorsText[11]
property color color5Bright: walColorsText[12] readonly property color color5Bright: walColorsText[12]
property color color6Bright: walColorsText[13] readonly property color color6Bright: walColorsText[13]
property color color7Bright: walColorsText[14] readonly property color color7Bright: walColorsText[14]
property color foregroundColorBright: walColorsText[15] readonly property color foregroundColorBright: walColorsText[15]
readonly property color textColor: foregroundColor readonly property color textColor: foregroundColorBright
// background "#0e1721" // background "#0e1721"
// color2 "#463e44" // color2 "#463e44"
// color3 "#7b4834" // color3 "#7b4834"

View File

@@ -15,7 +15,7 @@ Item {
Rectangle { Rectangle {
color: Theme.backgroudColor color: Theme.backgroudColor
implicitWidth: clockText.implicitWidth * 1.6 implicitWidth: clockText.implicitWidth * 1.6
implicitHeight: Theme.heightGaps //root.implicitHeight*0.8 implicitHeight: Theme.heightGaps
radius: 25 radius: 25
Text { Text {
@@ -24,7 +24,7 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
text: "OPA!" text: "OPA!"
font.bold: true font.bold: true
font.pixelSize: 14 font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily font.family: Theme.fontFamily
color: Theme.textColor color: Theme.textColor
} }

View File

@@ -14,12 +14,13 @@ Singleton {
function start(component, type) { function start(component, type) {
HoverMediator.component = component HoverMediator.component = component
HoverMediator.type = type HoverMediator.type = type
hoverPopUp.anchor.updateAnchor()
hoverTimer.start() hoverTimer.start()
} }
function exit() { function exit() {
hoverTimer.stop() hoverTimer.stop()
wsPopUp.opacity=0 hoverPopUp.visible = false
} }
PopupWindow { PopupWindow {
@@ -31,25 +32,58 @@ Singleton {
anchor.rect.x: (HoverMediator.x - this.implicitWidth)/2 anchor.rect.x: (HoverMediator.x - this.implicitWidth)/2
implicitHeight: wsPopUp.implicitHeight implicitHeight: wsPopUp.implicitHeight
implicitWidth: wsPopUp.implicitWidth implicitWidth: wsPopUp.implicitWidth
// implicitHeight: HoverMediator.height
// implicitWidth: HoverMediator.width
color:"transparent" color:"transparent"
visible:true
Component { Component {
id: stub id: stub
Text { Text {
text: "stub" text: "stub"
font.bold: true
font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily
color: Theme.textColor
}
}
Component {
id: systray
Text {
text: {
if (!HoverMediator.component.model) return ""
if (HoverMediator.component.model.tooltipTitle) return HoverMediator.component.model.tooltipTitle
if (HoverMediator.component.model.title) return HoverMediator.component.model.title
else return ""
}
font.bold: true
font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily
color: Theme.textColor
}
}
Component {
id: time
Text {
property string calendar:(HoverMediator.component.calendar)? HoverMediator.component.calendar: ""
text: calendar
font.bold: true
font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamilyMono
color: Theme.textColor
} }
} }
Component { Component {
id: audio id: audio
Text { Text {
property string sinkDescription:(HoverMediator.component && HoverMediator.component.sink)? HoverMediator.component.sink.description : "" property string sinkDescription:(HoverMediator.component.sink)? HoverMediator.component.sink.description : ""
text: sinkDescription text: sinkDescription
color:"white" font.bold: true
font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily
color: Theme.textColor
} }
} }
@@ -86,7 +120,7 @@ Singleton {
bottomMargin: Theme.gaps bottomMargin: Theme.gaps
color: Theme.backgroudColor color: Theme.backgroudColor
radius: 25 radius: 25
opacity: 0 opacity: 1
Behavior on opacity { Behavior on opacity {
NumberAnimation { property: "opacity"; duration: Theme.animationDuration} NumberAnimation { property: "opacity"; duration: Theme.animationDuration}
} }
@@ -97,6 +131,8 @@ Singleton {
if(!HoverMediator.type) return stub if(!HoverMediator.type) return stub
if(HoverMediator.type === "workspace") return workspaceComponent if(HoverMediator.type === "workspace") return workspaceComponent
if(HoverMediator.type === "audio") return audio if(HoverMediator.type === "audio") return audio
if(HoverMediator.type === "time") return time
if(HoverMediator.type === "systray") return systray
} }
} }
} }
@@ -108,8 +144,8 @@ Singleton {
interval: 300 interval: 300
onTriggered: { onTriggered: {
wsPopUp.opacity = 1 // wsPopUp.opacity = 1
// hoverPopUp.visible = true hoverPopUp.visible = true
} }
} }
} }

View File

@@ -7,6 +7,7 @@ import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Services.SystemTray import Quickshell.Services.SystemTray
import qs.Common import qs.Common
import qs.Services
WrapperRectangle { WrapperRectangle {
id: systrayRoot id: systrayRoot
@@ -60,24 +61,26 @@ WrapperRectangle {
source: systrayItem.iconSource source: systrayItem.iconSource
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onEntered: {
PopUpHover.start(systrayItem,"systray")
}
onExited: {
PopUpHover.exit()
}
onClicked: (mouse) => { onClicked: (mouse) => {
if (mouse.button === Qt.RightButton) { if (mouse.button === Qt.RightButton) {
const globalPos = mapToGlobal(0, 0);
const currentScreen = parent.monitor
const relativeX = globalPos.x;
menuAnchor.menu = systrayItem.model.menu; menuAnchor.menu = systrayItem.model.menu;
menuAnchor.anchor.window = root; menuAnchor.anchor.item = systrayItem;
menuAnchor.anchor.rect = Qt.rect( menuAnchor.anchor.rect = Qt.rect(
globalPos.x, 0,
globalPos.y+10, systrayItem.implicitHeight,
1, 0,
1 0
); );
menuAnchor.open(); menuAnchor.open();
@@ -97,4 +100,4 @@ WrapperRectangle {
id: menuAnchor id: menuAnchor
} }
} }

View File

@@ -78,7 +78,9 @@ WrapperMouseArea {
] ]
Behavior on color { Behavior on color {
ColorAnimation {duration: Theme.animationDuration} ColorAnimation {
duration: Theme.animationDuration
}
} }
Behavior on implicitWidth { Behavior on implicitWidth {
@@ -94,7 +96,7 @@ WrapperMouseArea {
anchors.centerIn: parent anchors.centerIn: parent
text: workspaceName text: workspaceName
font.bold: true font.bold: true
font.pixelSize: 14 font.pixelSize: Theme.pixelSize
font.family: Theme.fontFamily font.family: Theme.fontFamily
color: Theme.textColor color: Theme.textColor
} }
@@ -104,13 +106,10 @@ WrapperMouseArea {
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
if (parent.hasTopLevel) { if (parent.hasTopLevel) {
// PopUpHover.show(workspacesRectangle)
PopUpHover.start(workspacesRectangle, "workspace") PopUpHover.start(workspacesRectangle, "workspace")
} }
} }
onExited: { onExited: {
// PopUpHover.exit()
PopUpHover.exit() PopUpHover.exit()
} }
onClicked: { onClicked: {