ActiveWindow: implement dynamic width with max width setting

This commit is contained in:
Sakari
2025-10-17 15:11:53 +08:00
parent d56c197fd3
commit a12fbca80b
9 changed files with 70 additions and 28 deletions
+3 -3
View File
@@ -918,9 +918,9 @@
"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."
},
"colorize-icons": {
"label": "Symbole einfärben",
+3 -3
View File
@@ -901,9 +901,9 @@
"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."
},
"colorize-icons": {
"label": "Colorize Icons",
+3 -3
View File
@@ -901,9 +901,9 @@
"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."
},
"colorize-icons": {
"label": "Colorear iconos",
+3 -3
View File
@@ -901,9 +901,9 @@
"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."
},
"colorize-icons": {
"label": "Coloriser les icônes",
+3 -3
View File
@@ -901,9 +901,9 @@
"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."
},
"colorize-icons": {
"label": "Colorir ícones",
+3 -3
View File
@@ -901,9 +901,9 @@
"label": "滚动模式",
"description": "控制何时为长窗口标题启用文本滚动。"
},
"width": {
"description": "控制小部件的水平尺寸。",
"label": "小部件宽度"
"max-width": {
"label": "最大宽度",
"description": "设置小部件的最大水平尺寸。当内容较短时,小部件会自动收缩以适应内容。"
},
"colorize-icons": {
"label": "着色图标",
+45 -3
View File
@@ -35,7 +35,9 @@ 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 isVerticalBar: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right")
readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null
@@ -43,7 +45,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 +61,38 @@ 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 (!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 +151,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
@@ -17,7 +17,7 @@ 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 valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
Component.onCompleted: {
@@ -31,7 +31,7 @@ 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.colorizeIcons = valueColorizeIcons
return settings
}
@@ -73,10 +73,10 @@ 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
}
NComboBox {
+1 -1
View File
@@ -44,7 +44,7 @@ Singleton {
"hideMode": "hidden",
"scrollingMode"// "visible", "hidden", "transparent"
: "hover",
"width": 145,
"maxWidth": 145,
"colorizeIcons": false
},
"Battery": {