pragma Singleton import QtQuick import Quickshell import qs.Commons import qs.Modules.Tooltip Singleton { id: root property var activeTooltip: null property var pendingTooltip: null // Track tooltip being created property Component tooltipComponent: Component { Tooltip {} } function show(target, text, direction, delay, fontFamily) { if (!Settings.data.ui.tooltipsEnabled) { return; } // Don't create if no text if (!target || !text) { Logger.i("Tooltip", "No target or text"); return; } // If we have a pending tooltip for a different target, cancel it if (pendingTooltip && pendingTooltip.targetItem !== target) { pendingTooltip.hideImmediately(); pendingTooltip.destroy(); pendingTooltip = null; } // If we have an active tooltip for a different target, hide it if (activeTooltip && activeTooltip.targetItem !== target) { activeTooltip.hideImmediately(); // Don't destroy immediately - let it clean itself up activeTooltip = null; } // If we already have a tooltip for this target, just update it if (activeTooltip && activeTooltip.targetItem === target) { activeTooltip.updateText(text); return activeTooltip; } // Create new tooltip instance const newTooltip = tooltipComponent.createObject(null); if (newTooltip) { // Track as pending until it's visible pendingTooltip = newTooltip; // Connect cleanup when tooltip hides newTooltip.visibleChanged.connect(() => { if (!newTooltip.visible) { // Clean up after a delay to avoid interfering with new tooltips Qt.callLater(() => { if (newTooltip && !newTooltip.visible) { if (activeTooltip === newTooltip) { activeTooltip = null; } if (pendingTooltip === newTooltip) { pendingTooltip = null; } newTooltip.destroy(); } }); } else { // Tooltip is now visible, move from pending to active if (pendingTooltip === newTooltip) { activeTooltip = newTooltip; pendingTooltip = null; } } }); // Show the tooltip newTooltip.show(target, text, direction || "auto", delay || Style.tooltipDelay, fontFamily); return newTooltip; } else { Logger.e("Tooltip", "Failed to create tooltip instance"); } return null; } function hide() { if (pendingTooltip) { pendingTooltip.hide(); } if (activeTooltip) { activeTooltip.hide(); } } function hideImmediately() { if (pendingTooltip) { pendingTooltip.hideImmediately(); pendingTooltip.destroy(); pendingTooltip = null; } if (activeTooltip) { activeTooltip.hideImmediately(); activeTooltip.destroy(); activeTooltip = null; } } function updateText(newText) { if (activeTooltip) { activeTooltip.updateText(newText); } } }