mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat: Add showText variable to show/hide name of Active Window
This commit is contained in:
@@ -11,370 +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 {};
|
||||
}
|
||||
|
||||
// Widget settings - matching MediaMini pattern
|
||||
readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : (widgetMetadata.showIcon || 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;
|
||||
contentWidth += Style.marginS; // Spacing after icon
|
||||
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 {};
|
||||
}
|
||||
|
||||
// Text width (use the measured width)
|
||||
contentWidth += titleContainer.measuredWidth;
|
||||
// Widget settings - matching MediaMini pattern
|
||||
readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : (widgetMetadata.showIcon || false)
|
||||
readonly property bool showText: false //(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")
|
||||
|
||||
// Additional small margin for text
|
||||
contentWidth += Style.margin2XXS;
|
||||
// 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)
|
||||
|
||||
// Add container margins
|
||||
contentWidth += margins;
|
||||
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"
|
||||
|
||||
return Math.ceil(contentWidth);
|
||||
}
|
||||
readonly property int iconSize: Style.toOdd(capsuleHeight * 0.75)
|
||||
readonly property int verticalSize: Style.toOdd(capsuleHeight * 0.85)
|
||||
|
||||
// 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;
|
||||
// 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
|
||||
}
|
||||
}
|
||||
// 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() {
|
||||
try {
|
||||
// Try CompositorService first
|
||||
const focusedWindow = CompositorService.getFocusedWindow();
|
||||
if (focusedWindow && focusedWindow.appId) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
Logger.w("ActiveWindow", "Error getting icon from ToplevelManager:", fallbackError);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: mainContainer
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: isVerticalBar ? 0 : Style.marginS
|
||||
anchors.rightMargin: isVerticalBar ? 0 : Style.marginS
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
|
||||
// Horizontal layout for top/bottom bars
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
visible: !isVerticalBar
|
||||
z: 1
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// Window icon
|
||||
Item {
|
||||
Layout.preferredWidth: iconSize
|
||||
Layout.preferredHeight: iconSize
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: showIcon
|
||||
|
||||
IconImage {
|
||||
id: windowIcon
|
||||
id: mainContainer
|
||||
anchors.fill: parent
|
||||
source: getAppIcon()
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
visible: source !== ""
|
||||
anchors.leftMargin: isVerticalBar ? 0 : Style.marginS
|
||||
anchors.rightMargin: isVerticalBar ? 0 : Style.marginS
|
||||
|
||||
// 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)
|
||||
// Horizontal layout for top/bottom bars
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS
|
||||
visible: !isVerticalBar
|
||||
z: 1
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NScrollText {
|
||||
id: titleContainer
|
||||
text: windowTitle
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredHeight: root.capsuleHeight
|
||||
fadeRoundLeftCorners: !showIcon
|
||||
// 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
|
||||
|
||||
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
|
||||
// Window icon
|
||||
Item {
|
||||
id: verticalIconContainer
|
||||
width: root.iconSize
|
||||
height: width
|
||||
x: Style.pixelAlignCenter(parent.width, width)
|
||||
y: Style.pixelAlignCenter(parent.height, height)
|
||||
visible: windowTitle !== ""
|
||||
|
||||
NText {
|
||||
text: windowTitle
|
||||
pointSize: barFontSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: root.textColor
|
||||
}
|
||||
}
|
||||
}
|
||||
IconImage {
|
||||
id: windowIconVertical
|
||||
anchors.fill: parent
|
||||
source: getAppIcon()
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
visible: source !== ""
|
||||
|
||||
// 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
|
||||
// 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)
|
||||
|
||||
// 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")
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse area moved to root
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
function onWindowListChanged() {
|
||||
try {
|
||||
windowIcon.source = Qt.binding(getAppIcon);
|
||||
windowIconVertical.source = Qt.binding(getAppIcon);
|
||||
} catch (e) {
|
||||
Logger.w("ActiveWindow", "Error in onWindowListChanged:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user