diff --git a/Modules/Bar/Widgets/TaskbarGrouped.qml b/Modules/Bar/Widgets/TaskbarGrouped.qml index d6f7f765..a30d16db 100644 --- a/Modules/Bar/Widgets/TaskbarGrouped.qml +++ b/Modules/Bar/Widgets/TaskbarGrouped.qml @@ -33,14 +33,21 @@ Item { } return {} } - readonly property bool hideUnoccupied: (widgetSettings.hideUnoccupied !== undefined) ? widgetSettings.hideUnoccupied : false + readonly property string labelMode: (widgetSettings.labelMode !== undefined) ? widgetSettings.labelMode : widgetMetadata.labelMode + readonly property bool hideUnoccupied: (widgetSettings.hideUnoccupied !== undefined) ? widgetSettings.hideUnoccupied : widgetMetadata.hideUnoccupied + readonly property int characterCount: 2 readonly property bool showWorkspaceNumbers: (widgetSettings.showWorkspaceNumbers !== undefined) ? widgetSettings.showWorkspaceNumbers : true readonly property bool showNumbersOnlyWhenOccupied: (widgetSettings.showNumbersOnlyWhenOccupied !== undefined) ? widgetSettings.showNumbersOnlyWhenOccupied : true + readonly property bool colorizeIcons: (widgetSettings.colorizeIcons !== undefined) ? widgetSettings.colorizeIcons : widgetMetadata.colorizeIcons property ListModel localWorkspaces: ListModel {} property real masterProgress: 0.0 property bool effectsActive: false property color effectColor: Color.mPrimary + // Wheel scroll handling + property int wheelAccumulatedDelta: 0 + property bool wheelCooldown: false + function refreshWorkspaces() { localWorkspaces.clear() if (!screen) @@ -80,11 +87,34 @@ Item { } } + function getFocusedLocalIndex() { + for (var i = 0; i < localWorkspaces.count; i++) { + if (localWorkspaces.get(i).isFocused === true) + return i + } + return -1 + } + + function switchByOffset(offset) { + if (localWorkspaces.count === 0) + return + var current = getFocusedLocalIndex() + if (current < 0) + current = 0 + var next = (current + offset) % localWorkspaces.count + if (next < 0) + next = localWorkspaces.count - 1 + const ws = localWorkspaces.get(next) + if (ws && ws.idx !== undefined) + CompositorService.switchToWorkspace(ws) + } + Component.onCompleted: { refreshWorkspaces() } onScreenChanged: refreshWorkspaces() + onHideUnoccupiedChanged: refreshWorkspaces() implicitWidth: isVerticalBar ? taskbarGrid.implicitWidth + Style.marginM * 2 : Math.round(taskbarGrid.implicitWidth + Style.marginM * 2) implicitHeight: isVerticalBar ? Math.round(taskbarGrid.implicitHeight + Style.marginM * 2) : Style.barHeight @@ -128,6 +158,46 @@ Item { } } + // Debounce timer for wheel interactions + Timer { + id: wheelDebounce + interval: 150 + repeat: false + onTriggered: { + root.wheelCooldown = false + root.wheelAccumulatedDelta = 0 + } + } + + // Scroll to switch workspaces + WheelHandler { + id: wheelHandler + target: root + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + onWheel: function (event) { + if (root.wheelCooldown) + return + // Prefer vertical delta, fall back to horizontal if needed + var dy = event.angleDelta.y + var dx = event.angleDelta.x + var useDy = Math.abs(dy) >= Math.abs(dx) + var delta = useDy ? dy : dx + // One notch is typically 120 + root.wheelAccumulatedDelta += delta + var step = 120 + if (Math.abs(root.wheelAccumulatedDelta) >= step) { + var direction = root.wheelAccumulatedDelta > 0 ? -1 : 1 + // For vertical layout, natural mapping: wheel up -> previous, down -> next (already handled by sign) + // For horizontal layout, same mapping using vertical wheel + root.switchByOffset(direction) + root.wheelCooldown = true + wheelDebounce.restart() + root.wheelAccumulatedDelta = 0 + event.accepted = true + } + } + } + Component { id: workspaceRepeaterDelegate @@ -192,7 +262,7 @@ Item { smooth: true asynchronous: true opacity: model.isFocused ? Style.opacityFull : 0.6 - layer.enabled: widgetSettings.colorizeIcons === true + layer.enabled: root.colorizeIcons && !model.isFocused Behavior on opacity { NumberAnimation { @@ -252,7 +322,7 @@ Item { Item { id: workspaceNumberContainer - visible: root.showWorkspaceNumbers && (!root.showNumbersOnlyWhenOccupied || container.hasWindows) + visible: root.labelMode !== "none" && root.showWorkspaceNumbers && (!root.showNumbersOnlyWhenOccupied || container.hasWindows) anchors { left: parent.left @@ -318,7 +388,13 @@ Item { anchors.centerIn: parent - text: workspaceModel.idx.toString() + text: { + if (root.labelMode === "name" && workspaceModel.name && workspaceModel.name.length > 0) { + return workspaceModel.name.substring(0, root.characterCount) + } else { + return workspaceModel.idx.toString() + } + } family: Settings.data.ui.fontFixed font { diff --git a/Modules/Panels/Settings/Bar/WidgetSettings/TaskbarGroupedSettings.qml b/Modules/Panels/Settings/Bar/WidgetSettings/TaskbarGroupedSettings.qml index 09342c35..2f5ac5d6 100644 --- a/Modules/Panels/Settings/Bar/WidgetSettings/TaskbarGroupedSettings.qml +++ b/Modules/Panels/Settings/Bar/WidgetSettings/TaskbarGroupedSettings.qml @@ -12,16 +12,56 @@ ColumnLayout { property var widgetData: null property var widgetMetadata: null - property bool valueShowWorkspaceNumbers: widgetData.showWorkspaceNumbers !== undefined ? widgetData.showWorkspaceNumbers : widgetMetadata.showWorkspaceNumbers - property bool valueShowNumbersOnlyWhenOccupied: widgetData.showNumbersOnlyWhenOccupied !== undefined ? widgetData.showNumbersOnlyWhenOccupied : widgetMetadata.showNumbersOnlyWhenOccupied + property string valueLabelMode: widgetData.labelMode !== undefined ? widgetData.labelMode : (widgetMetadata ? widgetMetadata.labelMode : "index") + property bool valueHideUnoccupied: widgetData.hideUnoccupied !== undefined ? widgetData.hideUnoccupied : (widgetMetadata ? widgetMetadata.hideUnoccupied : false) + property bool valueShowWorkspaceNumbers: widgetData.showWorkspaceNumbers !== undefined ? widgetData.showWorkspaceNumbers : (widgetMetadata ? widgetMetadata.showWorkspaceNumbers : true) + property bool valueShowNumbersOnlyWhenOccupied: widgetData.showNumbersOnlyWhenOccupied !== undefined ? widgetData.showNumbersOnlyWhenOccupied : (widgetMetadata ? widgetMetadata.showNumbersOnlyWhenOccupied : true) + property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : (widgetMetadata ? widgetMetadata.colorizeIcons : false) function saveSettings() { var settings = Object.assign({}, widgetData || {}) + settings.labelMode = valueLabelMode + settings.hideUnoccupied = valueHideUnoccupied settings.showWorkspaceNumbers = valueShowWorkspaceNumbers settings.showNumbersOnlyWhenOccupied = valueShowNumbersOnlyWhenOccupied + settings.colorizeIcons = valueColorizeIcons return settings } + NComboBox { + id: labelModeCombo + label: I18n.tr("bar.widget-settings.workspace.label-mode.label") + description: I18n.tr("bar.widget-settings.workspace.label-mode.description") + model: [{ + "key": "none", + "name": I18n.tr("options.workspace-labels.none") + }, { + "key": "index", + "name": I18n.tr("options.workspace-labels.index") + }, { + "key": "name", + "name": I18n.tr("options.workspace-labels.name") + }] + currentKey: widgetData.labelMode || widgetMetadata.labelMode + onSelected: key => valueLabelMode = key + minimumWidth: 200 + } + + NToggle { + label: I18n.tr("bar.widget-settings.workspace.hide-unoccupied.label") + description: I18n.tr("bar.widget-settings.workspace.hide-unoccupied.description") + checked: valueHideUnoccupied + onToggled: checked => valueHideUnoccupied = checked + } + + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.active-window.colorize-icons.label") + description: I18n.tr("bar.widget-settings.active-window.colorize-icons.description") + checked: root.valueColorizeIcons + onToggled: checked => root.valueColorizeIcons = checked + } + NToggle { Layout.fillWidth: true label: I18n.tr("bar.widget-settings.taskbar-grouped.show-workspace-numbers.label") diff --git a/Modules/Panels/Settings/SettingsPanel.qml b/Modules/Panels/Settings/SettingsPanel.qml index 6333a26b..c0dda187 100644 --- a/Modules/Panels/Settings/SettingsPanel.qml +++ b/Modules/Panels/Settings/SettingsPanel.qml @@ -260,6 +260,17 @@ SmartPanel { "icon": "settings-screen-recorder", "source": screenRecorderTab }, { + "id": SettingsPanel.Tab.SessionMenu, + "label": "settings.session-menu.title", + "icon": "settings-session-menu", + "source": sessionMenuTab + }, // { + // "id": SettingsPanel.Tab.SystemMonitor, + // "label": "settings.system-monitor.title", + // "icon": "settings-system-monitor", + // "source": systemMonitorTab + // }, + { "id": SettingsPanel.Tab.Hooks, "label": "settings.hooks.title", "icon": "settings-hooks", diff --git a/Services/UI/BarWidgetRegistry.qml b/Services/UI/BarWidgetRegistry.qml index c6427c9e..c4133e47 100644 --- a/Services/UI/BarWidgetRegistry.qml +++ b/Services/UI/BarWidgetRegistry.qml @@ -162,7 +162,11 @@ Singleton { "TaskbarGrouped": { "allowUserSettings": true, "showWorkspaceNumbers": true, - "showNumbersOnlyWhenOccupied": true + "showNumbersOnlyWhenOccupied": true, + "labelMode": "index", + "hideUnoccupied": false, + "characterCount": 2, + "colorizeIcons": false }, "Tray": { "allowUserSettings": true,