From 32e1160f8f84a7b4974ea61b32f15613cdfaa3c0 Mon Sep 17 00:00:00 2001 From: ly-sec Date: Wed, 16 Jul 2025 13:56:09 +0200 Subject: [PATCH] Add tooltips, fix tray menu --- Bar/Bar.qml | 4 +- Bar/Modules/ActiveWindow.qml | 1 + Bar/Modules/Brightness.qml | 13 +++ Bar/Modules/CustomTrayMenu.qml | 22 ++-- Bar/Modules/SystemTray.qml | 13 ++- Bar/Modules/Volume.qml | 9 ++ Components/StyledTooltip.qml | 84 +++++++++++++++ Settings/Theme.json | 38 +++---- Templates/templates/ghostty | 29 +++++ Widgets/NotificationPopup.qml | 4 +- Widgets/Sidebar/Panel/PanelPopup.qml | 2 +- Widgets/Sidebar/Panel/PowerProfile.qml | 31 ++++++ Widgets/Sidebar/Panel/SystemMonitor.qml | 138 ++++++++++++++++++------ 13 files changed, 319 insertions(+), 69 deletions(-) create mode 100644 Components/StyledTooltip.qml create mode 100644 Templates/templates/ghostty diff --git a/Bar/Bar.qml b/Bar/Bar.qml index ccdc72d..2eb8423 100644 --- a/Bar/Bar.qml +++ b/Bar/Bar.qml @@ -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 diff --git a/Bar/Modules/ActiveWindow.qml b/Bar/Modules/ActiveWindow.qml index eeda285..cf05cfd 100644 --- a/Bar/Modules/ActiveWindow.qml +++ b/Bar/Modules/ActiveWindow.qml @@ -15,6 +15,7 @@ PanelWindow { margins.top: barHeight visible: activeWindowWrapper.shouldShow implicitHeight: activeWindowTitleContainer.height + implicitWidth: activeWindowTitleContainer.x property int barHeight: 36 color: "transparent" diff --git a/Bar/Modules/Brightness.qml b/Bar/Modules/Brightness.qml index 2f33cc5..2616646 100644 --- a/Bar/Modules/Brightness.qml +++ b/Bar/Modules/Brightness.qml @@ -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: { diff --git a/Bar/Modules/CustomTrayMenu.qml b/Bar/Modules/CustomTrayMenu.qml index 78ea369..b6d286a 100644 --- a/Bar/Modules/CustomTrayMenu.qml +++ b/Bar/Modules/CustomTrayMenu.qml @@ -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 { diff --git a/Bar/Modules/SystemTray.qml b/Bar/Modules/SystemTray.qml index 98f95b1..5211481 100644 --- a/Bar/Modules/SystemTray.qml +++ b/Bar/Modules/SystemTray.qml @@ -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: { diff --git a/Bar/Modules/Volume.qml b/Bar/Modules/Volume.qml index 7e342a5..7327c37 100644 --- a/Bar/Modules/Volume.qml +++ b/Bar/Modules/Volume.qml @@ -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; diff --git a/Components/StyledTooltip.qml b/Components/StyledTooltip.qml new file mode 100644 index 0000000..f94303c --- /dev/null +++ b/Components/StyledTooltip.qml @@ -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); + } + +} \ No newline at end of file diff --git a/Settings/Theme.json b/Settings/Theme.json index 14fe370..c20e7b1 100644 --- a/Settings/Theme.json +++ b/Settings/Theme.json @@ -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" } diff --git a/Templates/templates/ghostty b/Templates/templates/ghostty new file mode 100644 index 0000000..3a92b28 --- /dev/null +++ b/Templates/templates/ghostty @@ -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 }} diff --git a/Widgets/NotificationPopup.qml b/Widgets/NotificationPopup.qml index ef996ab..41641f4 100644 --- a/Widgets/NotificationPopup.qml +++ b/Widgets/NotificationPopup.qml @@ -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 { diff --git a/Widgets/Sidebar/Panel/PanelPopup.qml b/Widgets/Sidebar/Panel/PanelPopup.qml index f7d1857..f59035a 100644 --- a/Widgets/Sidebar/Panel/PanelPopup.qml +++ b/Widgets/Sidebar/Panel/PanelPopup.qml @@ -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 diff --git a/Widgets/Sidebar/Panel/PowerProfile.qml b/Widgets/Sidebar/Panel/PowerProfile.qml index 2e3bf20..48c7f55 100644 --- a/Widgets/Sidebar/Panel/PowerProfile.qml +++ b/Widgets/Sidebar/Panel/PowerProfile.qml @@ -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 } } } diff --git a/Widgets/Sidebar/Panel/SystemMonitor.qml b/Widgets/Sidebar/Panel/SystemMonitor.qml index ba2ebf5..d22e836 100644 --- a/Widgets/Sidebar/Panel/SystemMonitor.qml +++ b/Widgets/Sidebar/Panel/SystemMonitor.qml @@ -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 + } } } }