diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 782e4cef..8de51f20 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -932,9 +932,13 @@ "label": "Scrollmodus", "description": "Steuern, wann Textscrolling für lange Fenstertitel aktiviert ist." }, - "width": { - "description": "Steuert die horizontale Größe des Widgets.", - "label": "Widget-Breite" + "max-width": { + "label": "Maximale Breite", + "description": "Stellt die maximale Horizontalgröße des Widgets ein. Das Widget wird sich an kürzere Inhalte anpassen." + }, + "use-fixed-width": { + "label": "Feste Breite verwenden", + "description": "Wenn aktiviert, verwendet das Widget immer die maximale Breite, anstatt sich dynamisch an den Inhalt anzupassen." }, "colorize-icons": { "label": "Symbole einfärben", diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index fc9bd89c..6e847d7c 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -915,9 +915,13 @@ "label": "Scrolling mode", "description": "Control when text scrolling is enabled for long window titles." }, - "width": { - "label": "Widget Width", - "description": "Controls the horizontal size of the widget." + "max-width": { + "label": "Maximum Width", + "description": "Sets the maximum horizontal size of the widget. The widget will shrink to fit shorter content." + }, + "use-fixed-width": { + "label": "Use Fixed Width", + "description": "When enabled, the widget will always use the maximum width instead of dynamically adjusting to content." }, "colorize-icons": { "label": "Colorize Icons", diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 391f6e90..5c23c800 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -915,9 +915,13 @@ "label": "Modo de desplazamiento", "description": "Controlar cuándo está habilitado el desplazamiento de texto para títulos de ventana largos." }, - "width": { - "description": "Controla el tamaño horizontal del widget.", - "label": "Ancho del widget" + "max-width": { + "label": "Ancho Máximo", + "description": "Establece el tamaño horizontal máximo del widget. El widget se reducirá para adaptarse a contenido más corto." + }, + "use-fixed-width": { + "label": "Usar Ancho Fijo", + "description": "Cuando está activado, el widget siempre usará el ancho máximo en lugar de ajustarse dinámicamente al contenido." }, "colorize-icons": { "label": "Colorear iconos", diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index f0e191a8..555f4bd9 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -915,9 +915,13 @@ "label": "Mode de masquage", "description": "Contrôle le comportement du widget lorsqu'aucune fenêtre n'est active." }, - "width": { - "description": "Contrôle la taille horizontale du widget.", - "label": "Largeur du widget" + "max-width": { + "label": "Largeur Maximale", + "description": "Définit la taille horizontale maximale du widget. Le widget se rétrécira pour s'adapter à un contenu plus court." + }, + "use-fixed-width": { + "label": "Utiliser une Largeur Fixe", + "description": "Lorsque activé, le widget utilisera toujours la largeur maximale au lieu de s'ajuster dynamiquement au contenu." }, "colorize-icons": { "label": "Coloriser les icônes", diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index e2e42698..e685e49f 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -915,9 +915,13 @@ "label": "Modo de rolagem", "description": "Controlar quando a rolagem de texto está habilitada para títulos de janela longos." }, - "width": { - "description": "Controla o tamanho horizontal do widget.", - "label": "Largura do Widget" + "max-width": { + "label": "Largura Máxima", + "description": "Define o tamanho horizontal máximo do widget. O widget será reduzido para se adequar a conteúdo mais curto." + }, + "use-fixed-width": { + "label": "Usar Largura Fixa", + "description": "Quando ativado, o widget sempre usará a largura máxima em vez de ajustar dinamicamente ao conteúdo." }, "colorize-icons": { "label": "Colorir ícones", diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 64dc0d5d..89550dcb 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -915,9 +915,13 @@ "label": "滚动模式", "description": "控制何时为长窗口标题启用文本滚动。" }, - "width": { - "description": "控制小部件的水平尺寸。", - "label": "小部件宽度" + "max-width": { + "label": "最大宽度", + "description": "设置小部件的最大水平尺寸。当内容较短时,小部件会自动收缩以适应内容。" + }, + "use-fixed-width": { + "label": "使用固定宽度", + "description": "启用后,小部件将始终使用最大宽度,而不根据内容动态调整。" }, "colorize-icons": { "label": "着色图标", diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml index 145395d8..4fdf3d2b 100644 --- a/Modules/Bar/Widgets/ActiveWindow.qml +++ b/Modules/Bar/Widgets/ActiveWindow.qml @@ -35,7 +35,10 @@ Item { readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : widgetMetadata.showIcon readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : widgetMetadata.hideMode readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : (widgetMetadata.scrollingMode !== undefined ? widgetMetadata.scrollingMode : "hover") - readonly property int widgetWidth: (widgetSettings.width !== undefined) ? widgetSettings.width : Math.max(widgetMetadata.width, screen.width * 0.06) + + // Maximum widget width with user settings support + readonly property real maxWidth: (widgetSettings.maxWidth !== undefined) ? widgetSettings.maxWidth : Math.max(widgetMetadata.maxWidth, screen.width * 0.06) + readonly property bool useFixedWidth: (widgetSettings.useFixedWidth !== undefined) ? widgetSettings.useFixedWidth : widgetMetadata.useFixedWidth readonly property bool isVerticalBar: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null @@ -43,7 +46,7 @@ Item { readonly property string fallbackIcon: "user-desktop" implicitHeight: visible ? (isVerticalBar ? calculatedVerticalDimension() : Style.barHeight) : 0 - implicitWidth: visible ? (isVerticalBar ? calculatedVerticalDimension() : widgetWidth) : 0 + implicitWidth: visible ? (isVerticalBar ? calculatedVerticalDimension() : dynamicWidth) : 0 // "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty visible: hideMode !== "hidden" || hasFocusedWindow @@ -59,6 +62,43 @@ Item { return Math.round((Style.baseWidgetSize - 5) * scaling) } + function calculateContentWidth() { + // Calculate the actual content width based on visible elements + var contentWidth = 0 + var margins = Style.marginS * scaling * 2 // Left and right margins + + // Icon width (if visible) + if (showIcon) { + contentWidth += 18 * scaling + contentWidth += Style.marginS * scaling // Spacing after icon + } + + // Text width (use the measured width) + contentWidth += fullTitleMetrics.contentWidth + + // Additional small margin for text + contentWidth += Style.marginXXS * 2 + + // 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 maxWidth + } + // Use content width but don't exceed user-set maximum width + return Math.min(calculateContentWidth(), maxWidth) + } + function getAppIcon() { try { // Try CompositorService first @@ -117,11 +157,19 @@ Item { visible: root.visible anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter - width: isVerticalBar ? root.width : widgetWidth + width: isVerticalBar ? root.width : dynamicWidth height: isVerticalBar ? width : Style.capsuleHeight radius: isVerticalBar ? width / 2 : Style.radiusM color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent + // Smooth width transition + Behavior on width { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutCubic + } + } + Item { id: mainContainer anchors.fill: parent diff --git a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml index 643684dd..514733dd 100644 --- a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml @@ -17,7 +17,8 @@ ColumnLayout { property bool valueShowIcon: widgetData.showIcon !== undefined ? widgetData.showIcon : widgetMetadata.showIcon property string valueHideMode: "hidden" // Default to 'Hide When Empty' property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode - property int valueWidth: widgetData.width !== undefined ? widgetData.width : widgetMetadata.width + 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 Component.onCompleted: { @@ -31,7 +32,8 @@ ColumnLayout { settings.hideMode = valueHideMode settings.showIcon = valueShowIcon settings.scrollingMode = valueScrollingMode - settings.width = parseInt(widthInput.text) || widgetMetadata.width + settings.maxWidth = parseInt(widthInput.text) || widgetMetadata.maxWidth + settings.useFixedWidth = valueUseFixedWidth settings.colorizeIcons = valueColorizeIcons return settings } @@ -73,10 +75,18 @@ ColumnLayout { NTextInput { id: widthInput Layout.fillWidth: true - label: I18n.tr("bar.widget-settings.active-window.width.label") - description: I18n.tr("bar.widget-settings.active-window.width.description") - placeholderText: widgetMetadata.width - text: valueWidth + label: I18n.tr("bar.widget-settings.active-window.max-width.label") + description: I18n.tr("bar.widget-settings.active-window.max-width.description") + placeholderText: widgetMetadata.maxWidth + text: valueMaxWidth + } + + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.active-window.use-fixed-width.label") + description: I18n.tr("bar.widget-settings.active-window.use-fixed-width.description") + checked: valueUseFixedWidth + onToggled: checked => valueUseFixedWidth = checked } NComboBox { diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index bd134591..e7f2865c 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -44,7 +44,8 @@ Singleton { "hideMode": "hidden", "scrollingMode"// "visible", "hidden", "transparent" : "hover", - "width": 145, + "maxWidth": 145, + "useFixedWidth": false, "colorizeIcons": false }, "Battery": {