diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml index cd21f479f..12f197ddd 100644 --- a/Modules/Bar/Widgets/ActiveWindow.qml +++ b/Modules/Bar/Widgets/ActiveWindow.qml @@ -11,375 +11,375 @@ import qs.Services.UI import qs.Widgets Item { - id: root - Layout.preferredHeight: isVerticalBar ? -1 : Style.getBarHeightForScreen(screenName) - Layout.preferredWidth: isVerticalBar ? Style.getBarHeightForScreen(screenName) : -1 - Layout.fillHeight: false - Layout.fillWidth: false + id: root + Layout.preferredHeight: isVerticalBar ? -1 : Style.getBarHeightForScreen(screenName) + Layout.preferredWidth: isVerticalBar ? Style.getBarHeightForScreen(screenName) : -1 + Layout.fillHeight: false + Layout.fillWidth: false - property ShellScreen screen + property ShellScreen screen - // Widget properties passed from Bar.qml for per-instance settings - property string widgetId: "" - property string section: "" - property int sectionWidgetIndex: -1 - property int sectionWidgetsCount: 0 + // Widget properties passed from Bar.qml for per-instance settings + property string widgetId: "" + property string section: "" + property int sectionWidgetIndex: -1 + property int sectionWidgetsCount: 0 - property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId] || {} - // Explicit screenName property ensures reactive binding when screen changes - readonly property string screenName: screen ? screen.name : "" - property var widgetSettings: { - if (section && sectionWidgetIndex >= 0 && screenName) { - var widgets = Settings.getBarWidgetsForScreen(screenName)[section]; - if (widgets && sectionWidgetIndex < widgets.length && widgets[sectionWidgetIndex]) { - return widgets[sectionWidgetIndex]; - } - } - return {}; + property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId] || {} + // Explicit screenName property ensures reactive binding when screen changes + readonly property string screenName: screen ? screen.name : "" + property var widgetSettings: { + if (section && sectionWidgetIndex >= 0 && screenName) { + var widgets = Settings.getBarWidgetsForScreen(screenName)[section]; + if (widgets && sectionWidgetIndex < widgets.length && widgets[sectionWidgetIndex]) { + return widgets[sectionWidgetIndex]; + } + } + return {}; + } + + // Widget settings - matching MediaMini pattern + readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : (widgetMetadata.showIcon || false) + readonly property bool showText: (widgetSettings.showText !== undefined) ? widgetSettings.showText : (widgetMetadata.showText || false) + readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : (widgetMetadata.hideMode || "hidden") + readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : (widgetMetadata.scrollingMode || "hover") + + // Maximum widget width with user settings support + readonly property real maxWidth: (widgetSettings.maxWidth !== undefined) ? widgetSettings.maxWidth : Math.max(widgetMetadata.maxWidth || 0, screen ? screen.width * 0.06 : 0) + readonly property bool useFixedWidth: (widgetSettings.useFixedWidth !== undefined) ? widgetSettings.useFixedWidth : (widgetMetadata.useFixedWidth || false) + readonly property string textColorKey: (widgetSettings.textColor !== undefined) ? widgetSettings.textColor : widgetMetadata.textColor + readonly property color textColor: Color.resolveColorKey(textColorKey) + + readonly property string barPosition: Settings.getBarPositionForScreen(screenName) + readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right" + readonly property real barHeight: Style.getBarHeightForScreen(screenName) + readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName) + readonly property real barFontSize: Style.getBarFontSizeForScreen(screenName) + readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null + readonly property string windowTitle: CompositorService.getFocusedWindowTitle() || "No active window" + readonly property string fallbackIcon: "user-desktop" + + readonly property int iconSize: Style.toOdd(capsuleHeight * 0.75) + readonly property int verticalSize: Style.toOdd(capsuleHeight * 0.85) + + // For horizontal bars, height is always barHeight (no animation needed) + // For vertical bars, collapse to 0 when hidden + implicitHeight: isVerticalBar ? (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : verticalSize) : barHeight + implicitWidth: isVerticalBar ? (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : verticalSize) : (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : dynamicWidth) + + // "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty + visible: (hideMode !== "hidden" || hasFocusedWindow) || opacity > 0 + opacity: ((hideMode !== "hidden" || hasFocusedWindow) && (hideMode !== "transparent" || hasFocusedWindow)) ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.OutCubic + } + } + + Behavior on implicitWidth { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutCubic + } + } + + Behavior on implicitHeight { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutCubic + } + } + + function calculateContentWidth() { + // Calculate the actual content width based on visible elements + var contentWidth = 0; + var margins = Style.margin2S; // Left and right margins + + // Icon width (if visible) + if (showIcon) { + contentWidth += iconSize; + if (showText) { + contentWidth += Style.marginS; // Spacing after icon + } } - // Widget settings - matching MediaMini pattern - readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : (widgetMetadata.showIcon || false) - readonly property bool showText: (widgetSettings.showText !== undefined) ? widgetSettings.showText : (widgetMetadata.showText || false) - readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : (widgetMetadata.hideMode || "hidden") - readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : (widgetMetadata.scrollingMode || "hover") - - // Maximum widget width with user settings support - readonly property real maxWidth: (widgetSettings.maxWidth !== undefined) ? widgetSettings.maxWidth : Math.max(widgetMetadata.maxWidth || 0, screen ? screen.width * 0.06 : 0) - readonly property bool useFixedWidth: (widgetSettings.useFixedWidth !== undefined) ? widgetSettings.useFixedWidth : (widgetMetadata.useFixedWidth || false) - readonly property string textColorKey: (widgetSettings.textColor !== undefined) ? widgetSettings.textColor : widgetMetadata.textColor - readonly property color textColor: Color.resolveColorKey(textColorKey) - - readonly property string barPosition: Settings.getBarPositionForScreen(screenName) - readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right" - readonly property real barHeight: Style.getBarHeightForScreen(screenName) - readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName) - readonly property real barFontSize: Style.getBarFontSizeForScreen(screenName) - readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null - readonly property string windowTitle: CompositorService.getFocusedWindowTitle() || "No active window" - readonly property string fallbackIcon: "user-desktop" - - readonly property int iconSize: Style.toOdd(capsuleHeight * 0.75) - readonly property int verticalSize: Style.toOdd(capsuleHeight * 0.85) - - // For horizontal bars, height is always barHeight (no animation needed) - // For vertical bars, collapse to 0 when hidden - implicitHeight: isVerticalBar ? (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : verticalSize) : barHeight - implicitWidth: isVerticalBar ? (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : verticalSize) : (((!hasFocusedWindow) && hideMode === "hidden") ? 0 : dynamicWidth) - - // "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty - visible: (hideMode !== "hidden" || hasFocusedWindow) || opacity > 0 - opacity: ((hideMode !== "hidden" || hasFocusedWindow) && (hideMode !== "transparent" || hasFocusedWindow)) ? 1.0 : 0.0 - Behavior on opacity { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.OutCubic - } + // Text width (use the measured width) + if (showText) { + contentWidth += titleContainer.measuredWidth; + // Additional small margin for text + contentWidth += Style.margin2XXS; } - Behavior on implicitWidth { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutCubic - } + // Add container margins + contentWidth += margins; + + return Math.ceil(contentWidth); + } + + // Dynamic width: adapt to content but respect maximum width setting + readonly property real dynamicWidth: { + // If using fixed width mode, always use maxWidth + if (useFixedWidth) { + return maxWidth; } - - Behavior on implicitHeight { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutCubic - } + // Otherwise, adapt to content + if (!hasFocusedWindow) { + return Math.min(calculateContentWidth(), maxWidth); } + // Use content width but don't exceed user-set maximum width + return Math.min(calculateContentWidth(), maxWidth); + } - function calculateContentWidth() { - // Calculate the actual content width based on visible elements - var contentWidth = 0; - var margins = Style.margin2S; // Left and right margins - - // Icon width (if visible) - if (showIcon) { - contentWidth += iconSize; - if (showText) { - contentWidth += Style.marginS; // Spacing after icon - } - } - - // Text width (use the measured width) - if (showText) { - contentWidth += titleContainer.measuredWidth; - // Additional small margin for text - contentWidth += Style.margin2XXS; - } - - // Add container margins - contentWidth += margins; - - return Math.ceil(contentWidth); - } - - // Dynamic width: adapt to content but respect maximum width setting - readonly property real dynamicWidth: { - // If using fixed width mode, always use maxWidth - if (useFixedWidth) { - return maxWidth; - } - // Otherwise, adapt to content - if (!hasFocusedWindow) { - return Math.min(calculateContentWidth(), maxWidth); - } - // Use content width but don't exceed user-set maximum width - return Math.min(calculateContentWidth(), maxWidth); - } - - function getAppIcon() { + function getAppIcon() { + try { + // Try CompositorService first + const focusedWindow = CompositorService.getFocusedWindow(); + if (focusedWindow && focusedWindow.appId) { try { - // Try CompositorService first - const focusedWindow = CompositorService.getFocusedWindow(); - if (focusedWindow && focusedWindow.appId) { - try { - const idValue = focusedWindow.appId; - const normalizedId = (typeof idValue === 'string') ? idValue : String(idValue); - const iconResult = ThemeIcons.iconForAppId(normalizedId.toLowerCase()); - if (iconResult && iconResult !== "") { - return iconResult; - } - } catch (iconError) { - Logger.w("ActiveWindow", "Error getting icon from CompositorService:", iconError); - } - } - - if (CompositorService.isHyprland) { - // Fallback to ToplevelManager - if (ToplevelManager && ToplevelManager.activeToplevel) { - try { - const activeToplevel = ToplevelManager.activeToplevel; - if (activeToplevel.appId) { - const idValue2 = activeToplevel.appId; - const normalizedId2 = (typeof idValue2 === 'string') ? idValue2 : String(idValue2); - const iconResult2 = ThemeIcons.iconForAppId(normalizedId2.toLowerCase()); - if (iconResult2 && iconResult2 !== "") { - return iconResult2; - } - } - } catch (fallbackError) { - Logger.w("ActiveWindow", "Error getting icon from ToplevelManager:", fallbackError); - } - } - } - - return ThemeIcons.iconFromName(fallbackIcon); - } catch (e) { - Logger.w("ActiveWindow", "Error in getAppIcon:", e); - return ThemeIcons.iconFromName(fallbackIcon); + const idValue = focusedWindow.appId; + const normalizedId = (typeof idValue === 'string') ? idValue : String(idValue); + const iconResult = ThemeIcons.iconForAppId(normalizedId.toLowerCase()); + if (iconResult && iconResult !== "") { + return iconResult; + } + } catch (iconError) { + Logger.w("ActiveWindow", "Error getting icon from CompositorService:", iconError); } + } + + if (CompositorService.isHyprland) { + // Fallback to ToplevelManager + if (ToplevelManager && ToplevelManager.activeToplevel) { + try { + const activeToplevel = ToplevelManager.activeToplevel; + if (activeToplevel.appId) { + const idValue2 = activeToplevel.appId; + const normalizedId2 = (typeof idValue2 === 'string') ? idValue2 : String(idValue2); + const iconResult2 = ThemeIcons.iconForAppId(normalizedId2.toLowerCase()); + if (iconResult2 && iconResult2 !== "") { + return iconResult2; + } + } + } catch (fallbackError) { + Logger.w("ActiveWindow", "Error getting icon from ToplevelManager:", fallbackError); + } + } + } + + return ThemeIcons.iconFromName(fallbackIcon); + } catch (e) { + Logger.w("ActiveWindow", "Error in getAppIcon:", e); + return ThemeIcons.iconFromName(fallbackIcon); + } + } + + NPopupContextMenu { + id: contextMenu + + model: [ + { + "label": I18n.tr("actions.widget-settings"), + "action": "widget-settings", + "icon": "settings" + }, + ] + + onTriggered: action => { + contextMenu.close(); + PanelService.closeContextMenu(screen); + + if (action === "widget-settings") { + BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings); + } + } + } + + Rectangle { + id: windowActiveRect + visible: root.visible + x: isVerticalBar ? Style.pixelAlignCenter(parent.width, width) : 0 + y: isVerticalBar ? 0 : Style.pixelAlignCenter(parent.height, height) + width: isVerticalBar ? ((!hasFocusedWindow) && hideMode === "hidden" ? 0 : verticalSize) : ((!hasFocusedWindow) && (hideMode === "hidden") ? 0 : dynamicWidth) + height: isVerticalBar ? ((!hasFocusedWindow) && hideMode === "hidden" ? 0 : verticalSize) : capsuleHeight + radius: Style.radiusM + color: Style.capsuleColor + border.color: Style.capsuleBorderColor + border.width: Style.capsuleBorderWidth + + // Smooth width transition + Behavior on width { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutCubic + } } - NPopupContextMenu { - id: contextMenu + Item { + id: mainContainer + anchors.fill: parent + anchors.leftMargin: isVerticalBar ? 0 : Style.marginS + anchors.rightMargin: isVerticalBar ? 0 : Style.marginS - model: [ - { - "label": I18n.tr("actions.widget-settings"), - "action": "widget-settings", - "icon": "settings" - }, - ] - - onTriggered: action => { - contextMenu.close(); - PanelService.closeContextMenu(screen); - - if (action === "widget-settings") { - BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings); - } - } - } - - Rectangle { - id: windowActiveRect - visible: root.visible - x: isVerticalBar ? Style.pixelAlignCenter(parent.width, width) : 0 - y: isVerticalBar ? 0 : Style.pixelAlignCenter(parent.height, height) - width: isVerticalBar ? ((!hasFocusedWindow) && hideMode === "hidden" ? 0 : verticalSize) : ((!hasFocusedWindow) && (hideMode === "hidden") ? 0 : dynamicWidth) - height: isVerticalBar ? ((!hasFocusedWindow) && hideMode === "hidden" ? 0 : verticalSize) : capsuleHeight - radius: Style.radiusM - color: Style.capsuleColor - border.color: Style.capsuleBorderColor - border.width: Style.capsuleBorderWidth - - // Smooth width transition - Behavior on width { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutCubic - } - } + // Horizontal layout for top/bottom bars + RowLayout { + id: rowLayout + anchors.verticalCenter: parent.verticalCenter + spacing: Style.marginS + visible: !isVerticalBar + z: 1 + // Window icon Item { - id: mainContainer + Layout.preferredWidth: iconSize + Layout.preferredHeight: iconSize + Layout.alignment: Qt.AlignVCenter + visible: showIcon + + IconImage { + id: windowIcon anchors.fill: parent - anchors.leftMargin: isVerticalBar ? 0 : Style.marginS - anchors.rightMargin: isVerticalBar ? 0 : Style.marginS + source: getAppIcon() + asynchronous: true + smooth: true + visible: source !== "" - // Horizontal layout for top/bottom bars - RowLayout { - id: rowLayout - anchors.verticalCenter: parent.verticalCenter - spacing: Style.marginS - visible: !isVerticalBar - z: 1 + // Apply dock shader to active window icon (always themed) + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mSurfaceVariant + property real colorizeMode: 0.0 // Dock mode (grayscale) - // Window icon - Item { - Layout.preferredWidth: iconSize - Layout.preferredHeight: iconSize - Layout.alignment: Qt.AlignVCenter - visible: showIcon - - IconImage { - id: windowIcon - anchors.fill: parent - source: getAppIcon() - asynchronous: true - smooth: true - visible: source !== "" - - // Apply dock shader to active window icon (always themed) - layer.enabled: widgetSettings.colorizeIcons !== false - layer.effect: ShaderEffect { - property color targetColor: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mSurfaceVariant - property real colorizeMode: 0.0 // Dock mode (grayscale) - - fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") - } - } - } - - NScrollText { - id: titleContainer - text: windowTitle - Layout.alignment: Qt.AlignVCenter - Layout.preferredHeight: root.capsuleHeight - fadeRoundLeftCorners: !showIcon - visible: showText - - maxWidth: { - // Calculate available width based on other elements - var iconWidth = (showIcon && windowIcon.visible ? (iconSize + Style.marginS) : 0); - var totalMargins = Style.margin2XXS; - var availableWidth = mainContainer.width - iconWidth - totalMargins; - return Math.max(20, availableWidth); - } - scrollMode: { - if (scrollingMode === "always") - return NScrollText.ScrollMode.Always; - if (scrollingMode === "hover") - return NScrollText.ScrollMode.Hover; - return NScrollText.ScrollMode.Never; - } - forcedHover: mainMouseArea.containsMouse - fadeExtent: 0.1 - fadeCornerRadius: Style.radiusM - - NText { - text: windowTitle - pointSize: barFontSize - applyUiScale: false - font.weight: Style.fontWeightMedium - color: root.textColor - } - } + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") } - - // Vertical layout for left/right bars - icon only - Item { - id: verticalLayout - width: parent.width - Style.margin2M - height: parent.height - Style.margin2M - x: Style.pixelAlignCenter(parent.width, width) - y: Style.pixelAlignCenter(parent.height, height) - visible: isVerticalBar - z: 1 - - // Window icon - Item { - id: verticalIconContainer - width: root.iconSize - height: width - x: Style.pixelAlignCenter(parent.width, width) - y: Style.pixelAlignCenter(parent.height, height) - visible: windowTitle !== "" - - IconImage { - id: windowIconVertical - anchors.fill: parent - source: getAppIcon() - asynchronous: true - smooth: true - visible: source !== "" - - // Apply dock shader to active window icon (always themed) - layer.enabled: widgetSettings.colorizeIcons !== false - layer.effect: ShaderEffect { - property color targetColor: Color.mOnSurface - property real colorizeMode: 0.0 // Dock mode (grayscale) - - fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") - } - } - } - } - - // Mouse area moved to root + } } + + NScrollText { + id: titleContainer + text: windowTitle + Layout.alignment: Qt.AlignVCenter + Layout.preferredHeight: root.capsuleHeight + fadeRoundLeftCorners: !showIcon + visible: showText + + maxWidth: { + // Calculate available width based on other elements + var iconWidth = (showIcon && windowIcon.visible ? (iconSize + Style.marginS) : 0); + var totalMargins = Style.margin2XXS; + var availableWidth = mainContainer.width - iconWidth - totalMargins; + return Math.max(20, availableWidth); + } + scrollMode: { + if (scrollingMode === "always") + return NScrollText.ScrollMode.Always; + if (scrollingMode === "hover") + return NScrollText.ScrollMode.Hover; + return NScrollText.ScrollMode.Never; + } + forcedHover: mainMouseArea.containsMouse + fadeExtent: 0.1 + fadeCornerRadius: Style.radiusM + + NText { + text: windowTitle + pointSize: barFontSize + applyUiScale: false + font.weight: Style.fontWeightMedium + color: root.textColor + } + } + } + + // Vertical layout for left/right bars - icon only + Item { + id: verticalLayout + width: parent.width - Style.margin2M + height: parent.height - Style.margin2M + x: Style.pixelAlignCenter(parent.width, width) + y: Style.pixelAlignCenter(parent.height, height) + visible: isVerticalBar + z: 1 + + // Window icon + Item { + id: verticalIconContainer + width: root.iconSize + height: width + x: Style.pixelAlignCenter(parent.width, width) + y: Style.pixelAlignCenter(parent.height, height) + visible: windowTitle !== "" + + IconImage { + id: windowIconVertical + anchors.fill: parent + source: getAppIcon() + asynchronous: true + smooth: true + visible: source !== "" + + // Apply dock shader to active window icon (always themed) + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 0.0 // Dock mode (grayscale) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } + } + } + } + + // Mouse area moved to root } + } - // Mouse area for hover detection - MouseArea { - id: mainMouseArea - anchors.fill: parent + // Mouse area for hover detection + MouseArea { + id: mainMouseArea + anchors.fill: parent - // Extend click area to screen edge if widget is at the start/end - anchors.leftMargin: (!isVerticalBar && section === "left" && sectionWidgetIndex === 0) ? -Style.marginS : 0 - anchors.rightMargin: (!isVerticalBar && section === "right" && sectionWidgetIndex === sectionWidgetsCount - 1) ? -Style.marginS : 0 - anchors.topMargin: (isVerticalBar && section === "left" && sectionWidgetIndex === 0) ? -Style.marginM : 0 - anchors.bottomMargin: (isVerticalBar && section === "right" && sectionWidgetIndex === sectionWidgetsCount - 1) ? -Style.marginM : 0 + // Extend click area to screen edge if widget is at the start/end + anchors.leftMargin: (!isVerticalBar && section === "left" && sectionWidgetIndex === 0) ? -Style.marginS : 0 + anchors.rightMargin: (!isVerticalBar && section === "right" && sectionWidgetIndex === sectionWidgetsCount - 1) ? -Style.marginS : 0 + anchors.topMargin: (isVerticalBar && section === "left" && sectionWidgetIndex === 0) ? -Style.marginM : 0 + anchors.bottomMargin: (isVerticalBar && section === "right" && sectionWidgetIndex === sectionWidgetsCount - 1) ? -Style.marginM : 0 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton - onEntered: { - if ((windowTitle !== "") && isVerticalBar || (scrollingMode === "never")) { - TooltipService.show(root, windowTitle, BarService.getTooltipDirection(root.screen?.name)); - } - } - onExited: { - TooltipService.hide(); - } - onClicked: mouse => { - if (mouse.button === Qt.RightButton) { - PanelService.showContextMenu(contextMenu, root, screen); - } - } + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + onEntered: { + if ((windowTitle !== "") && isVerticalBar || (scrollingMode === "never")) { + TooltipService.show(root, windowTitle, BarService.getTooltipDirection(root.screen?.name)); + } } - - Connections { - target: CompositorService - function onActiveWindowChanged() { - try { - windowIcon.source = Qt.binding(getAppIcon); - windowIconVertical.source = Qt.binding(getAppIcon); - } catch (e) { - Logger.w("ActiveWindow", "Error in onActiveWindowChanged:", e); - } - } - function onWindowListChanged() { - try { - windowIcon.source = Qt.binding(getAppIcon); - windowIconVertical.source = Qt.binding(getAppIcon); - } catch (e) { - Logger.w("ActiveWindow", "Error in onWindowListChanged:", e); - } - } + onExited: { + TooltipService.hide(); } + onClicked: mouse => { + if (mouse.button === Qt.RightButton) { + PanelService.showContextMenu(contextMenu, root, screen); + } + } + } + + Connections { + target: CompositorService + function onActiveWindowChanged() { + try { + windowIcon.source = Qt.binding(getAppIcon); + windowIconVertical.source = Qt.binding(getAppIcon); + } catch (e) { + Logger.w("ActiveWindow", "Error in onActiveWindowChanged:", e); + } + } + function onWindowListChanged() { + try { + windowIcon.source = Qt.binding(getAppIcon); + windowIconVertical.source = Qt.binding(getAppIcon); + } catch (e) { + Logger.w("ActiveWindow", "Error in onWindowListChanged:", e); + } + } + } } diff --git a/Modules/Panels/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml b/Modules/Panels/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml index bfe7fbbbd..f997fd6b2 100644 --- a/Modules/Panels/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml +++ b/Modules/Panels/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml @@ -5,164 +5,164 @@ import qs.Commons import qs.Widgets ColumnLayout { - id: root - spacing: Style.marginM + id: root + spacing: Style.marginM - // Properties to receive data from parent - property var screen: null - property var widgetData: null - property var widgetMetadata: null + // Properties to receive data from parent + property var screen: null + property var widgetData: null + property var widgetMetadata: null - signal settingsChanged(var settings) + signal settingsChanged(var settings) - // Local state - property bool valueShowIcon: widgetData.showIcon !== undefined ? widgetData.showIcon : widgetMetadata.showIcon - property bool valueShowText: widgetData.showText !== undefined ? widgetData.showText : widgetMetadata.showText - property string valueHideMode: widgetData.hideMode !== undefined ? widgetData.hideMode : widgetMetadata.hideMode - property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode - property int valueMaxWidth: widgetData.maxWidth !== undefined ? widgetData.maxWidth : widgetMetadata.maxWidth - property bool valueUseFixedWidth: widgetData.useFixedWidth !== undefined ? widgetData.useFixedWidth : widgetMetadata.useFixedWidth - property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons - property string valueTextColor: widgetData.textColor !== undefined ? widgetData.textColor : widgetMetadata.textColor + // Local state + property bool valueShowIcon: widgetData.showIcon !== undefined ? widgetData.showIcon : widgetMetadata.showIcon + property bool valueShowText: widgetData.showText !== undefined ? widgetData.showText : widgetMetadata.showText + property string valueHideMode: widgetData.hideMode !== undefined ? widgetData.hideMode : widgetMetadata.hideMode + property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode + property int valueMaxWidth: widgetData.maxWidth !== undefined ? widgetData.maxWidth : widgetMetadata.maxWidth + property bool valueUseFixedWidth: widgetData.useFixedWidth !== undefined ? widgetData.useFixedWidth : widgetMetadata.useFixedWidth + property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons + property string valueTextColor: widgetData.textColor !== undefined ? widgetData.textColor : widgetMetadata.textColor - Component.onCompleted: { - if (widgetData && widgetData.hideMode !== undefined) { - valueHideMode = widgetData.hideMode; - } + Component.onCompleted: { + if (widgetData && widgetData.hideMode !== undefined) { + valueHideMode = widgetData.hideMode; } + } - function saveSettings() { - var settings = Object.assign({}, widgetData || {}); - settings.hideMode = valueHideMode; - settings.showIcon = valueShowIcon; - settings.showText = valueShowText; - settings.scrollingMode = valueScrollingMode; - settings.maxWidth = parseInt(widthInput.text) || widgetMetadata.maxWidth; - settings.useFixedWidth = valueUseFixedWidth; - settings.colorizeIcons = valueColorizeIcons; - settings.textColor = valueTextColor; - settingsChanged(settings); - } + function saveSettings() { + var settings = Object.assign({}, widgetData || {}); + settings.hideMode = valueHideMode; + settings.showIcon = valueShowIcon; + settings.showText = valueShowText; + settings.scrollingMode = valueScrollingMode; + settings.maxWidth = parseInt(widthInput.text) || widgetMetadata.maxWidth; + settings.useFixedWidth = valueUseFixedWidth; + settings.colorizeIcons = valueColorizeIcons; + settings.textColor = valueTextColor; + settingsChanged(settings); + } - NComboBox { - Layout.fillWidth: true - label: I18n.tr("bar.taskbar.hide-mode-label") - description: I18n.tr("bar.active-window.hide-mode-description") - model: [ - { - "key": "visible", - "name": I18n.tr("hide-modes.visible") - }, - { - "key": "hidden", - "name": I18n.tr("hide-modes.hidden") - }, - { - "key": "transparent", - "name": I18n.tr("hide-modes.transparent") - } - ] - currentKey: root.valueHideMode - onSelected: key => { - root.valueHideMode = key; - saveSettings(); - } - defaultValue: widgetMetadata.hideMode - } + NComboBox { + Layout.fillWidth: true + label: I18n.tr("bar.taskbar.hide-mode-label") + description: I18n.tr("bar.active-window.hide-mode-description") + model: [ + { + "key": "visible", + "name": I18n.tr("hide-modes.visible") + }, + { + "key": "hidden", + "name": I18n.tr("hide-modes.hidden") + }, + { + "key": "transparent", + "name": I18n.tr("hide-modes.transparent") + } + ] + currentKey: root.valueHideMode + onSelected: key => { + root.valueHideMode = key; + saveSettings(); + } + defaultValue: widgetMetadata.hideMode + } - NColorChoice { - label: I18n.tr("common.select-color") - currentKey: valueTextColor - onSelected: key => { - valueTextColor = key; - saveSettings(); - } - defaultValue: widgetMetadata.textColor - } + NColorChoice { + label: I18n.tr("common.select-color") + currentKey: valueTextColor + onSelected: key => { + valueTextColor = key; + saveSettings(); + } + defaultValue: widgetMetadata.textColor + } - NToggle { - Layout.fillWidth: true - label: I18n.tr("bar.active-window.show-app-text-label") - description: I18n.tr("bar.active-window.show-app-text-description") - checked: root.valueShowText - onToggled: checked => { - root.valueShowText = checked; - saveSettings(); - } - defaultValue: widgetMetadata.showText - } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.active-window.show-app-text-label") + description: I18n.tr("bar.active-window.show-app-text-description") + checked: root.valueShowText + onToggled: checked => { + root.valueShowText = checked; + saveSettings(); + } + defaultValue: widgetMetadata.showText + } - NToggle { - Layout.fillWidth: true - label: I18n.tr("bar.active-window.show-app-icon-label") - description: I18n.tr("bar.active-window.show-app-icon-description") - checked: root.valueShowIcon - onToggled: checked => { - root.valueShowIcon = checked; - saveSettings(); - } - defaultValue: widgetMetadata.showIcon - } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.active-window.show-app-icon-label") + description: I18n.tr("bar.active-window.show-app-icon-description") + checked: root.valueShowIcon + onToggled: checked => { + root.valueShowIcon = checked; + saveSettings(); + } + defaultValue: widgetMetadata.showIcon + } - NToggle { - Layout.fillWidth: true - label: I18n.tr("bar.tray.colorize-icons-label") - description: I18n.tr("bar.active-window.colorize-icons-description") - checked: root.valueColorizeIcons - onToggled: checked => { - root.valueColorizeIcons = checked; - saveSettings(); - } - visible: root.valueShowIcon - defaultValue: widgetMetadata.colorizeIcons - } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.tray.colorize-icons-label") + description: I18n.tr("bar.active-window.colorize-icons-description") + checked: root.valueColorizeIcons + onToggled: checked => { + root.valueColorizeIcons = checked; + saveSettings(); + } + visible: root.valueShowIcon + defaultValue: widgetMetadata.colorizeIcons + } - NTextInput { - id: widthInput - Layout.fillWidth: true - label: I18n.tr("bar.taskbar.max-width-label") - description: I18n.tr("bar.media-mini.max-width-description") - placeholderText: widgetMetadata.maxWidth - text: valueMaxWidth - onTextChanged: saveSettings() - defaultValue: String(widgetMetadata.maxWidth) - } + NTextInput { + id: widthInput + Layout.fillWidth: true + label: I18n.tr("bar.taskbar.max-width-label") + description: I18n.tr("bar.media-mini.max-width-description") + placeholderText: widgetMetadata.maxWidth + text: valueMaxWidth + onTextChanged: saveSettings() + defaultValue: String(widgetMetadata.maxWidth) + } - NToggle { - Layout.fillWidth: true - label: I18n.tr("bar.media-mini.use-fixed-width-label") - description: I18n.tr("bar.media-mini.use-fixed-width-description") - checked: valueUseFixedWidth - onToggled: checked => { - valueUseFixedWidth = checked; - saveSettings(); - } - defaultValue: widgetMetadata.useFixedWidth - } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.media-mini.use-fixed-width-label") + description: I18n.tr("bar.media-mini.use-fixed-width-description") + checked: valueUseFixedWidth + onToggled: checked => { + valueUseFixedWidth = checked; + saveSettings(); + } + defaultValue: widgetMetadata.useFixedWidth + } - NComboBox { - label: I18n.tr("bar.media-mini.scrolling-mode-label") - description: I18n.tr("bar.active-window.scrolling-mode-description") - model: [ - { - "key": "always", - "name": I18n.tr("options.scrolling-modes.always") - }, - { - "key": "hover", - "name": I18n.tr("options.scrolling-modes.hover") - }, - { - "key": "never", - "name": I18n.tr("options.scrolling-modes.never") - } - ] - currentKey: valueScrollingMode - defaultValue: widgetMetadata.scrollingMode - onSelected: key => { - valueScrollingMode = key; - saveSettings(); - } - minimumWidth: 200 - } + NComboBox { + label: I18n.tr("bar.media-mini.scrolling-mode-label") + description: I18n.tr("bar.active-window.scrolling-mode-description") + model: [ + { + "key": "always", + "name": I18n.tr("options.scrolling-modes.always") + }, + { + "key": "hover", + "name": I18n.tr("options.scrolling-modes.hover") + }, + { + "key": "never", + "name": I18n.tr("options.scrolling-modes.never") + } + ] + currentKey: valueScrollingMode + defaultValue: widgetMetadata.scrollingMode + onSelected: key => { + valueScrollingMode = key; + saveSettings(); + } + minimumWidth: 200 + } }