Add tooltips, fix tray menu

This commit is contained in:
ly-sec 2025-07-16 13:56:09 +02:00
parent a7fbccaf8b
commit 32e1160f8f
13 changed files with 319 additions and 69 deletions

View file

@ -176,7 +176,7 @@ Scope {
id: bottomLeftCorner
position: "topleft"
size: 1.3
fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222"
fillColor: "#00FFFF"
offsetX: -39
offsetY: 0
anchors.top: parent.top
@ -198,7 +198,7 @@ Scope {
id: bottomRightCorner
position: "topright"
size: 1.3
fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222"
fillColor: "#00FFFF"//(Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222"
offsetX: 39
offsetY: 0
anchors.top: parent.top

View file

@ -15,6 +15,7 @@ PanelWindow {
margins.top: barHeight
visible: activeWindowWrapper.shouldShow
implicitHeight: activeWindowTitleContainer.height
implicitWidth: activeWindowTitleContainer.x
property int barHeight: 36
color: "transparent"

View file

@ -40,6 +40,19 @@ Item {
iconCircleColor: Theme.accentPrimary
iconTextColor: Theme.backgroundPrimary
textColor: Theme.textPrimary
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: brightnessTooltip.tooltipVisible = true
onExited: brightnessTooltip.tooltipVisible = false
}
StyledTooltip {
id: brightnessTooltip
text: "Brightness: " + brightness + "%"
tooltipVisible: false
targetItem: pill
delay: 200
}
}
Component.onCompleted: {

View file

@ -18,7 +18,7 @@ PopupWindow {
property real anchorY
anchor.item: anchorItem ? anchorItem : null
anchor.rect.x: anchorX
anchor.rect.x: anchorX + 10
anchor.rect.y: anchorY
function showAt(item, x, y) {
@ -51,10 +51,10 @@ PopupWindow {
Rectangle {
id: bg
anchors.fill: parent
color: Theme.backgroundPrimary
border.color: Theme.accentPrimary
border.width: 2
radius: 20
color: Theme.backgroundElevated || "#222"
border.color: Theme.border || "#444"
border.width: 1
radius: 12
z: 0
}
@ -76,15 +76,15 @@ PopupWindow {
required property var modelData
width: listView.width
height: (modelData?.isSeparator) ? 8 : 28
height: (modelData?.isSeparator) ? 8 : 32
color: "transparent"
radius: 6
radius: 12
Rectangle {
anchors.centerIn: parent
width: parent.width - 20
height: 1
color: Qt.darker(Theme.backgroundPrimary, 1.4)
color: Qt.darker(Theme.backgroundElevated || "#222", 1.4)
visible: modelData?.isSeparator ?? false
}
@ -92,14 +92,14 @@ PopupWindow {
id: bg
anchors.fill: parent
color: mouseArea.containsMouse ? Theme.highlight : "transparent"
radius: 6
radius: 12
visible: !(modelData?.isSeparator ?? false)
property color hoverTextColor: mouseArea.containsMouse ? Theme.onAccent : Theme.textPrimary
RowLayout {
anchors.fill: parent
anchors.leftMargin: 10
anchors.rightMargin: 10
anchors.leftMargin: 12
anchors.rightMargin: 12
spacing: 8
Text {

View file

@ -6,6 +6,7 @@ import Qt5Compat.GraphicalEffects
import Quickshell.Services.SystemTray
import Quickshell.Widgets
import qs.Settings
import qs.Components
Row {
property var bar
@ -110,8 +111,8 @@ Row {
modelData.secondaryActivate && modelData.secondaryActivate()
} else if (mouse.button === Qt.RightButton) {
trayTooltip.tooltipVisible = false
console.log("Right click on", modelData.id, "hasMenu:", modelData.hasMenu, "menu:", modelData.menu)
// If menu is already visible, close it
if (trayMenu && trayMenu.visible) {
trayMenu.hideMenu()
@ -129,6 +130,16 @@ Row {
}
}
}
onEntered: trayTooltip.tooltipVisible = true
onExited: trayTooltip.tooltipVisible = false
}
StyledTooltip {
id: trayTooltip
text: modelData.name || modelData.id || "Tray Item"
tooltipVisible: false
targetItem: trayIcon
delay: 200
}
Component.onDestruction: {

View file

@ -21,6 +21,13 @@ Item {
iconCircleColor: Theme.accentPrimary
iconTextColor: Theme.backgroundPrimary
textColor: Theme.textPrimary
StyledTooltip {
id: volumeTooltip
text: "Volume: " + volume + "%\nScroll up/down to change volume"
tooltipVisible: false
targetItem: pillIndicator
delay: 200
}
}
Connections {
@ -47,6 +54,8 @@ Item {
hoverEnabled: true
acceptedButtons: Qt.NoButton // Accept wheel events only
propagateComposedEvents: true
onEntered: volumeTooltip.tooltipVisible = true
onExited: volumeTooltip.tooltipVisible = false
onWheel:(wheel) => {
if (!shell) return;
let step = 5;

View file

@ -0,0 +1,84 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import qs.Settings
Window {
id: tooltipWindow
property string text: ""
property bool tooltipVisible: false
property Item targetItem: null
property int delay: 300
flags: Qt.ToolTip | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
color: "transparent"
visible: false
minimumWidth: Math.max(minimumWidth, tooltipText.implicitWidth + 24)
minimumHeight: Math.max(minimumHeight, tooltipText.implicitHeight + 16)
property var _timerObj: null
onTooltipVisibleChanged: {
if (tooltipVisible) {
if (delay > 0) {
if (_timerObj) { _timerObj.destroy(); _timerObj = null; }
_timerObj = Qt.createQmlObject('import QtQuick 2.0; Timer { interval: ' + delay + '; running: true; repeat: false; onTriggered: tooltipWindow._showNow() }', tooltipWindow);
} else {
_showNow();
}
} else {
_hideNow();
}
}
function _showNow() {
if (!targetItem) return;
var pos = targetItem.mapToGlobal(0, targetItem.height);
x = pos.x - width / 2 + targetItem.width / 2;
y = pos.y + 8;
visible = true;
console.log("StyledTooltip _showNow called");
console.log("StyledTooltip Theme.textPrimary:", Theme.textPrimary);
}
function _hideNow() {
visible = false;
if (_timerObj) { _timerObj.destroy(); _timerObj = null; }
}
Connections {
target: targetItem
onXChanged: if (tooltipWindow.visible) tooltipWindow._showNow()
onYChanged: if (tooltipWindow.visible) tooltipWindow._showNow()
onWidthChanged: if (tooltipWindow.visible) tooltipWindow._showNow()
onHeightChanged: if (tooltipWindow.visible) tooltipWindow._showNow()
}
Component.onCompleted: console.log("Tooltip window loaded")
Rectangle {
anchors.fill: parent
radius: 6
color: "#222"
border.color: Theme.border || "#444"
border.width: 1
opacity: 0.97
z: 1
}
Text {
id: tooltipText
text: tooltipWindow.text
color: Theme.textPrimary
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
padding: 8
z: 2
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onExited: tooltipWindow.tooltipVisible = false
cursorShape: Qt.ArrowCursor
}
onTextChanged: {
width = Math.max(minimumWidth, tooltipText.implicitWidth + 24);
height = Math.max(minimumHeight, tooltipText.implicitHeight + 16);
}
}

View file

@ -1,28 +1,28 @@
{
"backgroundPrimary": "#0F1012",
"backgroundSecondary": "#1B1C1E",
"backgroundTertiary": "#27282A",
"backgroundPrimary": "#0E0F10",
"backgroundSecondary": "#1A1B1C",
"backgroundTertiary": "#262728",
"surface": "#222325",
"surfaceVariant": "#333436",
"surface": "#212223",
"surfaceVariant": "#323334",
"textPrimary": "#DBF7F5",
"textSecondary": "#C5DEDD",
"textDisabled": "#839493",
"textPrimary": "#F0F1E0",
"textSecondary": "#D8D9CA",
"textDisabled": "#909186",
"accentPrimary": "#5D9BEC",
"accentSecondary": "#7DAFF0",
"accentTertiary": "#4A7CBD",
"accentPrimary": "#A3A485",
"accentSecondary": "#B5B69D",
"accentTertiary": "#82836A",
"error": "#D687D8",
"warning": "#DFA2E1",
"error": "#A5A9ED",
"warning": "#B9BCF1",
"highlight": "#9EC3F4",
"rippleEffect": "#6DA5EE",
"highlight": "#C8C8B6",
"rippleEffect": "#ACAD91",
"onAccent": "#0F1012",
"outline": "#575859",
"onAccent": "#0E0F10",
"outline": "#565758",
"shadow": "#0F1012",
"overlay": "#0F1012"
"shadow": "#0E0F10",
"overlay": "#0E0F10"
}

View file

@ -0,0 +1,29 @@
# Ghostty theme template for wallust
# Add to wallust config: ghostty = { src = "ghostty.conf", dst = "~/.config/ghostty/theme.conf" }
# And add to ghostty config: theme = "theme.conf"
palette = 0={{ color0 }}
palette = 1={{ color1 }}
palette = 2={{ color2 }}
palette = 3={{ color3 }}
palette = 4={{ color4 }}
palette = 5={{ color5 }}
palette = 6={{ color6 }}
palette = 7={{ color7 }}
palette = 8={{ color8 }}
palette = 9={{ color9 }}
palette = 10={{ color10 }}
palette = 11={{ color11 }}
palette = 12={{ color12 }}
palette = 13={{ color13 }}
palette = 14={{ color14 }}
palette = 15={{ color15 }}
background = {{ background }}
foreground = {{ foreground }}
cursor-color = {{ cursor }}
cursor-text = {{ foreground }}
selection-background = {{ color8 }}
selection-foreground = {{ foreground }}

View file

@ -6,7 +6,7 @@ import qs.Settings
PanelWindow {
id: window
implicitWidth: 350
implicitHeight: notificationColumn.implicitHeight + 60
implicitHeight: notificationColumn.implicitHeight
color: "transparent"
visible: notificationModel.count > 0
screen: Quickshell.primaryScreen !== undefined ? Quickshell.primaryScreen : null
@ -16,7 +16,7 @@ PanelWindow {
anchors.top: true
anchors.right: true
margins.top: barVisible ? -20 : 10
margins.top: 6
margins.right: 6
ListModel {

View file

@ -16,7 +16,7 @@ PanelWindow {
screen: modelData
anchors.top: true
anchors.right: true
margins.top: -24
margins.top: 0
WlrLayershell.keyboardFocus: (settingsModal.visible && mouseArea.containsMouse) ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
// Animation properties

View file

@ -3,6 +3,7 @@ import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import Quickshell.Services.UPower
import qs.Settings
import qs.Components
Rectangle {
id: card
@ -28,6 +29,7 @@ Rectangle {
opacity: (typeof PowerProfiles !== 'undefined' && !PowerProfiles.hasPerformanceProfile) ? 0.4 : 1
Text {
id: perfIcon
anchors.centerIn: parent
text: "speed"
font.family: "Material Symbols Outlined"
@ -49,6 +51,15 @@ Rectangle {
if (typeof PowerProfiles !== 'undefined')
PowerProfiles.profile = PowerProfile.Performance;
}
onEntered: perfTooltip.tooltipVisible = true
onExited: perfTooltip.tooltipVisible = false
}
StyledTooltip {
id: perfTooltip
text: "Performance Profile"
tooltipVisible: false
targetItem: perfIcon
delay: 200
}
}
@ -64,6 +75,7 @@ Rectangle {
opacity: 1
Text {
id: balIcon
anchors.centerIn: parent
text: "balance"
font.family: "Material Symbols Outlined"
@ -85,6 +97,15 @@ Rectangle {
if (typeof PowerProfiles !== 'undefined')
PowerProfiles.profile = PowerProfile.Balanced;
}
onEntered: balTooltip.tooltipVisible = true
onExited: balTooltip.tooltipVisible = false
}
StyledTooltip {
id: balTooltip
text: "Balanced Profile"
tooltipVisible: false
targetItem: balIcon
delay: 200
}
}
@ -100,6 +121,7 @@ Rectangle {
opacity: 1
Text {
id: saveIcon
anchors.centerIn: parent
text: "eco"
font.family: "Material Symbols Outlined"
@ -121,6 +143,15 @@ Rectangle {
if (typeof PowerProfiles !== 'undefined')
PowerProfiles.profile = PowerProfile.PowerSaver;
}
onEntered: saveTooltip.tooltipVisible = true
onExited: saveTooltip.tooltipVisible = false
}
StyledTooltip {
id: saveTooltip
text: "Power Saver Profile"
tooltipVisible: false
targetItem: saveIcon
delay: 200
}
}
}

View file

@ -27,48 +27,120 @@ Rectangle {
Layout.alignment: Qt.AlignVCenter
// CPU Usage
CircularProgressBar {
progress: Sysinfo.cpuUsage / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "speed"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
Item {
width: 50; height: 50
CircularProgressBar {
id: cpuBar
progress: Sysinfo.cpuUsage / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "speed"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
}
MouseArea {
id: cpuBarMouse
anchors.fill: parent
hoverEnabled: true
onEntered: cpuTooltip.tooltipVisible = true
onExited: cpuTooltip.tooltipVisible = false
}
StyledTooltip {
id: cpuTooltip
text: 'CPU Usage: ' + Sysinfo.cpuUsage + '%'
tooltipVisible: false
targetItem: cpuBar
delay: 200
}
}
// Cpu Temp
CircularProgressBar {
progress: Sysinfo.cpuTemp / 100
size: 50
strokeWidth: 4
hasNotch: true
units: "°C"
notchIcon: "thermometer"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
Item {
width: 50; height: 50
CircularProgressBar {
id: tempBar
progress: Sysinfo.cpuTemp / 100
size: 50
strokeWidth: 4
hasNotch: true
units: "°C"
notchIcon: "thermometer"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
}
MouseArea {
id: tempBarMouse
anchors.fill: parent
hoverEnabled: true
onEntered: tempTooltip.tooltipVisible = true
onExited: tempTooltip.tooltipVisible = false
}
StyledTooltip {
id: tempTooltip
text: 'CPU Temp: ' + Sysinfo.cpuTemp + '°C'
tooltipVisible: false
targetItem: tempBar
delay: 200
}
}
// Memory Usage
CircularProgressBar {
progress: Sysinfo.memoryUsagePer / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "memory"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
Item {
width: 50; height: 50
CircularProgressBar {
id: memBar
progress: Sysinfo.memoryUsagePer / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "memory"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
}
MouseArea {
id: memBarMouse
anchors.fill: parent
hoverEnabled: true
onEntered: memTooltip.tooltipVisible = true
onExited: memTooltip.tooltipVisible = false
}
StyledTooltip {
id: memTooltip
text: 'Memory Usage: ' + Sysinfo.memoryUsagePer + '% (' + Sysinfo.memoryUsageStr + ' used)'
tooltipVisible: false
targetItem: memBar
delay: 200
}
}
// Disk Usage
CircularProgressBar {
progress: Sysinfo.diskUsage / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "storage"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
Item {
width: 50; height: 50
CircularProgressBar {
id: diskBar
progress: Sysinfo.diskUsage / 100
size: 50
strokeWidth: 4
hasNotch: true
notchIcon: "storage"
notchIconSize: 14
Layout.alignment: Qt.AlignHCenter
}
MouseArea {
id: diskBarMouse
anchors.fill: parent
hoverEnabled: true
onEntered: diskTooltip.tooltipVisible = true
onExited: diskTooltip.tooltipVisible = false
}
StyledTooltip {
id: diskTooltip
text: 'Disk Usage: ' + Sysinfo.diskUsage + '%'
tooltipVisible: false
targetItem: diskBar
delay: 200
}
}
}
}