diff --git a/quickshell/Modules/DankDash/MediaPlayerTab.qml b/quickshell/Modules/DankDash/MediaPlayerTab.qml index 74e615fd..1d8da039 100644 --- a/quickshell/Modules/DankDash/MediaPlayerTab.qml +++ b/quickshell/Modules/DankDash/MediaPlayerTab.qml @@ -16,6 +16,10 @@ Item { property MprisPlayer activePlayer: MprisController.activePlayer property var allPlayers: MprisController.availablePlayers + DankTooltipV2 { + id: sharedTooltip + } + readonly property bool isRightEdge: (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top) === SettingsData.Position.Right readonly property bool volumeAvailable: (activePlayer && activePlayer.volumeSupported) || (AudioService.sink && AudioService.sink.audio) readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported @@ -1070,6 +1074,12 @@ Item { onClicked: { parent.playersExpanded = !parent.playersExpanded; } + onEntered: { + sharedTooltip.show("Media Players", playerSelectorButton, 0, 0, isRightEdge ? "right" : "left"); + } + onExited: { + sharedTooltip.hide(); + } } } @@ -1182,6 +1192,12 @@ Item { onClicked: { parent.devicesExpanded = !parent.devicesExpanded; } + onEntered: { + sharedTooltip.show("Output Device", audioDevicesButton, 0, 0, isRightEdge ? "right" : "left"); + } + onExited: { + sharedTooltip.hide(); + } } } } diff --git a/quickshell/Modules/Settings/WidgetsTabSection.qml b/quickshell/Modules/Settings/WidgetsTabSection.qml index c75c1726..ad86eb54 100644 --- a/quickshell/Modules/Settings/WidgetsTabSection.qml +++ b/quickshell/Modules/Settings/WidgetsTabSection.qml @@ -281,7 +281,7 @@ Column { onEntered: { var currentEnabled = modelData.minimumWidth !== undefined ? modelData.minimumWidth : true; const tooltipText = currentEnabled ? "Force Padding" : "Dynamic Width"; - sharedTooltip.show(tooltipText, minimumWidthButton, 0, 0); + sharedTooltip.show(tooltipText, minimumWidthButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -302,7 +302,7 @@ Column { onEntered: { var currentEnabled = modelData.showSwap !== undefined ? modelData.showSwap : false; const tooltipText = currentEnabled ? "Hide Swap" : "Show Swap"; - sharedTooltip.show(tooltipText, showSwapButton, 0, 0); + sharedTooltip.show(tooltipText, showSwapButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -324,7 +324,7 @@ Column { root.compactModeChanged("music", 0); } onEntered: { - sharedTooltip.show("Small", smallSizeButton, 0, 0); + sharedTooltip.show("Small", smallSizeButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -342,7 +342,7 @@ Column { root.compactModeChanged("music", 1); } onEntered: { - sharedTooltip.show("Medium", mediumSizeButton, 0, 0); + sharedTooltip.show("Medium", mediumSizeButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -360,7 +360,7 @@ Column { root.compactModeChanged("music", 2); } onEntered: { - sharedTooltip.show("Large", largeSizeButton, 0, 0); + sharedTooltip.show("Large", largeSizeButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -416,7 +416,7 @@ Column { } else if (modelData.id === "keyboard_layout_name") { tooltipText = SettingsData.keyboardLayoutNameCompactMode ? "Full Size" : "Compact"; } - sharedTooltip.show(tooltipText, compactModeButton, 0, 0); + sharedTooltip.show(tooltipText, compactModeButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -435,7 +435,7 @@ Column { } onEntered: { const tooltipText = SettingsData.runningAppsGroupByApp ? "Ungroup" : "Group by App"; - sharedTooltip.show(tooltipText, groupByAppButton, 0, 0); + sharedTooltip.show(tooltipText, groupByAppButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); @@ -523,7 +523,7 @@ Column { } onEntered: { const tooltipText = modelData.enabled ? "Hide" : "Show"; - sharedTooltip.show(tooltipText, visibilityButton, 0, 0); + sharedTooltip.show(tooltipText, visibilityButton, 0, 0, "bottom"); } onExited: { sharedTooltip.hide(); diff --git a/quickshell/Widgets/DankTooltipV2.qml b/quickshell/Widgets/DankTooltipV2.qml index 3f9c99fd..b3e87644 100644 --- a/quickshell/Widgets/DankTooltipV2.qml +++ b/quickshell/Widgets/DankTooltipV2.qml @@ -7,22 +7,82 @@ Item { property string text: "" - function show(text, item, offsetX, offsetY) { - if (!item) return; + function show(text, item, offsetX, offsetY, preferredSide) { + if (!item) + return; - tooltip.parent = item.Window.window?.contentItem || item; + const windowContentItem = item.Window.window?.contentItem; + if (!windowContentItem) + return; + + tooltip.parent = windowContentItem; tooltip.text = text; - const itemPos = item.mapToItem(tooltip.parent, 0, 0); - const itemCenterX = itemPos.x + item.width / 2; - const itemBottomY = itemPos.y + item.height; + const itemPos = item.mapToItem(windowContentItem, 0, 0); + const parentWidth = windowContentItem.width; + const parentHeight = windowContentItem.height; + const tooltipWidth = tooltip.implicitWidth; + const tooltipHeight = tooltip.implicitHeight; - tooltip.x = itemCenterX - tooltip.width / 2 + (offsetX || 0); - tooltip.y = itemBottomY + 8 + (offsetY || 0); + const side = preferredSide || _determineBestSide(itemPos, item, parentWidth, parentHeight, tooltipWidth, tooltipHeight); + + let targetX = 0; + let targetY = 0; + + switch (side) { + case "left": + targetX = itemPos.x - tooltipWidth - 8; + targetY = itemPos.y + (item.height - tooltipHeight) / 2; + break; + case "right": + targetX = itemPos.x + item.width + 8; + targetY = itemPos.y + (item.height - tooltipHeight) / 2; + break; + case "top": + targetX = itemPos.x + (item.width - tooltipWidth) / 2; + targetY = itemPos.y - tooltipHeight - 8; + break; + case "bottom": + default: + targetX = itemPos.x + (item.width - tooltipWidth) / 2; + targetY = itemPos.y + item.height + 8; + break; + } + + tooltip.x = Math.max(4, Math.min(parentWidth - tooltipWidth - 4, targetX + (offsetX || 0))); + tooltip.y = Math.max(4, Math.min(parentHeight - tooltipHeight - 4, targetY + (offsetY || 0))); tooltip.open(); } + function _determineBestSide(itemPos, item, parentWidth, parentHeight, tooltipWidth, tooltipHeight) { + const itemCenterX = itemPos.x + item.width / 2; + const itemCenterY = itemPos.y + item.height / 2; + + const spaceLeft = itemPos.x; + const spaceRight = parentWidth - (itemPos.x + item.width); + const spaceTop = itemPos.y; + const spaceBottom = parentHeight - (itemPos.y + item.height); + + if (spaceRight >= tooltipWidth + 16) { + return "right"; + } + if (spaceLeft >= tooltipWidth + 16) { + return "left"; + } + if (spaceBottom >= tooltipHeight + 16) { + return "bottom"; + } + if (spaceTop >= tooltipHeight + 16) { + return "top"; + } + + if (itemCenterX > parentWidth / 2) { + return "left"; + } + return "right"; + } + function hide() { tooltip.close(); } @@ -32,8 +92,10 @@ Item { property string text: "" - width: Math.min(300, Math.max(120, textContent.implicitWidth + Theme.spacingM * 2)) - height: textContent.implicitHeight + Theme.spacingS * 2 + implicitWidth: Math.min(300, Math.max(120, textContent.implicitWidth + Theme.spacingM * 2)) + implicitHeight: textContent.implicitHeight + Theme.spacingS * 2 + width: implicitWidth + height: implicitHeight padding: 0 closePolicy: Popup.NoAutoClose @@ -65,8 +127,8 @@ Item { property: "opacity" from: 0 to: 1 - duration: 150 - easing.type: Easing.OutQuad + duration: Theme.shortDuration + easing.type: Theme.standardEasing } } @@ -75,8 +137,8 @@ Item { property: "opacity" from: 1 to: 0 - duration: 100 - easing.type: Easing.InQuad + duration: Theme.shorterDuration + easing.type: Theme.standardEasing } } }