diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index f857d81e..a9bf5064 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Theme-Farben auf Tray-Symbole anwenden.", "label": "Symbole einfärben" + }, + "drawer-enabled": { + "description": "Wenn aktiviert, werden nicht angeheftete Tray-Elemente in einem Schubladen-Panel angezeigt. Wenn deaktiviert, werden alle Tray-Elemente inline angezeigt.", + "label": "Schublade aktivieren" } }, "volume": { diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 5bdb06b9..d2bd0511 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Apply theme colors to tray icons.", "label": "Colorize Icons" + }, + "drawer-enabled": { + "description": "When enabled, unpinned tray items are shown in a drawer panel. When disabled, all tray items are shown inline.", + "label": "Enable Drawer" } }, "volume": { diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index d2ff4d0d..c5d48337 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Aplicar colores del tema a los iconos de la bandeja del sistema.", "label": "Colorear iconos" + }, + "drawer-enabled": { + "description": "Cuando está habilitado, los elementos de la bandeja no anclados se muestran en un panel cajón. Cuando está deshabilitado, todos los elementos de la bandeja se muestran en línea.", + "label": "Habilitar cajón" } }, "volume": { diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index dc288d56..9c453aab 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Appliquer les couleurs du thème aux icônes de la barre système.", "label": "Coloriser les icônes" + }, + "drawer-enabled": { + "description": "Lorsqu'elle est activée, les éléments de la barre système non épinglés sont affichés dans un panneau tiroir. Lorsqu'elle est désactivée, tous les éléments de la barre système sont affichés en ligne.", + "label": "Activer le tiroir" } }, "volume": { diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index e8dceb1d..d689f184 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Aplicar cores do tema aos ícones da bandeja do sistema.", "label": "Colorir ícones" + }, + "drawer-enabled": { + "description": "Quando habilitado, os itens da bandeja não fixados são exibidos em um painel gaveta. Quando desabilitado, todos os itens da bandeja são exibidos inline.", + "label": "Habilitar gaveta" } }, "volume": { diff --git a/Assets/Translations/tr.json b/Assets/Translations/tr.json index 8f12a248..14926d9b 100644 --- a/Assets/Translations/tr.json +++ b/Assets/Translations/tr.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Tepsi ikonlarına tema renklerini uygula.", "label": "İkonları Renklendir" + }, + "drawer-enabled": { + "description": "Etkinleştirildiğinde, sabitlenmemiş tepsi öğeleri bir çekmece panelinde gösterilir. Devre dışı bırakıldığında, tüm tepsi öğeleri satır içi gösterilir.", + "label": "Çekmeceyi Etkinleştir" } }, "volume": { diff --git a/Assets/Translations/uk-UA.json b/Assets/Translations/uk-UA.json index 0bfaa443..5c202ea8 100644 --- a/Assets/Translations/uk-UA.json +++ b/Assets/Translations/uk-UA.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "Застосувати кольори теми до значків трея.", "label": "Розфарбувати значки" + }, + "drawer-enabled": { + "description": "Коли увімкнено, не закріплені елементи трея відображаються на панелі ящика. Коли вимкнено, всі елементи трея відображаються в рядку.", + "label": "Увімкнути ящик" } }, "volume": { diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 5f325884..d45104b0 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -278,6 +278,10 @@ "colorize-icons": { "description": "将主题颜色应用到系统托盘图标。", "label": "着色图标" + }, + "drawer-enabled": { + "description": "启用时,未固定的托盘项显示在抽屉面板中。禁用时,所有托盘项都内联显示。", + "label": "启用抽屉" } }, "volume": { diff --git a/Modules/Bar/Widgets/Tray.qml b/Modules/Bar/Widgets/Tray.qml index 5ab6857e..42bbaadc 100644 --- a/Modules/Bar/Widgets/Tray.qml +++ b/Modules/Bar/Widgets/Tray.qml @@ -37,9 +37,10 @@ Rectangle { readonly property bool density: Settings.data.bar.density property real itemSize: Math.round(Style.capsuleHeight * 0.65) property list blacklist: widgetSettings.blacklist || widgetMetadata.blacklist || [] // Read from settings - property list favorites: widgetSettings.favorites || widgetMetadata.favorites || [] - property var filteredItems: [] // Items to show inline (favorites) - property var dropdownItems: [] // Items to show in dropdown (non-favorites) + property list favorites: widgetSettings.favorites || widgetMetadata.favorites || [] // Pinned items (shown inline) + property bool drawerEnabled: widgetSettings.drawerEnabled !== undefined ? widgetSettings.drawerEnabled : (widgetMetadata.drawerEnabled !== undefined ? widgetMetadata.drawerEnabled : true) // Enable drawer panel + property var filteredItems: [] // Items to show inline (pinned/favorites) + property var dropdownItems: [] // Items to show in drawer (unpinned/non-favorites) function wildCardMatch(str, rule) { if (!str || !rule) { @@ -107,43 +108,49 @@ Rectangle { } } - // Build inline (favorites) and dropdown (non-favorites) lists - // If favorites list is empty, all items go to dropdown (none inline) - // If favorites list has items, favorites are inline, rest go to dropdown - if (favorites && favorites.length > 0) { - let fav = [] - for (var k = 0; k < newItems.length; k++) { - const item2 = newItems[k] - const title2 = item2.tooltipTitle || item2.name || item2.id || "" - for (var m = 0; m < favorites.length; m++) { - const rule2 = favorites[m] - if (wildCardMatch(title2, rule2)) { - fav.push(item2) - break - } - } - } - filteredItems = fav - - // Non-favorites go to dropdown - let nonFav = [] - for (var v = 0; v < newItems.length; v++) { - const cand = newItems[v] - let isFavorite = false - for (var f = 0; f < filteredItems.length; f++) { - if (filteredItems[f] === cand) { - isFavorite = true - break - } - } - if (!isFavorite) - nonFav.push(cand) - } - dropdownItems = nonFav + // If drawer is disabled, show all items inline + if (!root.drawerEnabled) { + filteredItems = newItems + dropdownItems = [] } else { - // No favorites: all items go to dropdown (none inline) - filteredItems = [] - dropdownItems = newItems + // Build inline (pinned/favorites) and drawer (unpinned/non-favorites) lists + // If favorites list is empty, all items go to drawer (none inline) + // If favorites list has items, favorites are inline, rest go to drawer + if (favorites && favorites.length > 0) { + let fav = [] + for (var k = 0; k < newItems.length; k++) { + const item2 = newItems[k] + const title2 = item2.tooltipTitle || item2.name || item2.id || "" + for (var m = 0; m < favorites.length; m++) { + const rule2 = favorites[m] + if (wildCardMatch(title2, rule2)) { + fav.push(item2) + break + } + } + } + filteredItems = fav + + // Non-favorites (unpinned) go to drawer + let nonFav = [] + for (var v = 0; v < newItems.length; v++) { + const cand = newItems[v] + let isFavorite = false + for (var f = 0; f < filteredItems.length; f++) { + if (filteredItems[f] === cand) { + isFavorite = true + break + } + } + if (!isFavorite) + nonFav.push(cand) + } + dropdownItems = nonFav + } else { + // No favorites (pinned): all items go to drawer (none inline) + filteredItems = [] + dropdownItems = newItems + } } } @@ -188,7 +195,7 @@ Rectangle { Repeater { id: repeater - model: SystemTray.items + model: root.filteredItems delegate: Item { width: itemSize @@ -241,27 +248,28 @@ Rectangle { if (mouse.button === Qt.LeftButton) { // Close any open menu first - trayPanel.close() + PanelService.getPanel("trayMenuPanel", root.screen)?.close() if (!modelData.onlyMenu) { modelData.activate() } } else if (mouse.button === Qt.MiddleButton) { // Close any open menu first - trayPanel.close() + PanelService.getPanel("trayMenuPanel", root.screen)?.close() modelData.secondaryActivate && modelData.secondaryActivate() } else if (mouse.button === Qt.RightButton) { TooltipService.hideImmediately() // Close the menu if it was visible - if (trayPanel && trayPanel.visible) { - trayPanel.close() + const menuPanel = PanelService.getPanel("trayMenuPanel", root.screen) + if (menuPanel && menuPanel.visible) { + menuPanel.close() return } if (modelData.hasMenu && modelData.menu) { - const panel = PanelService.getPanel("trayMenu", root.screen) + const panel = PanelService.getPanel("trayMenuPanel", root.screen) if (panel) { panel.menu = modelData.menu panel.trayItem = modelData @@ -277,7 +285,7 @@ Rectangle { } } onEntered: { - trayPanel.close() + PanelService.getPanel("trayMenuPanel", root.screen)?.close() TooltipService.show(Screen, trayIcon, modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item", BarService.getTooltipDirection()) } onExited: TooltipService.hide() @@ -286,10 +294,10 @@ Rectangle { } } - // Dropdown opener - simple icon with hover effect + // Drawer opener - simple icon with hover effect Item { id: dropdownButton - visible: dropdownItems.length > 0 + visible: root.drawerEnabled && dropdownItems.length > 0 width: itemSize height: itemSize @@ -335,7 +343,7 @@ Rectangle { } onClicked: { TooltipService.hideImmediately() - const panel = PanelService.getPanel("trayDropdownPanel", root.screen) + const panel = PanelService.getPanel("trayDrawerPanel", root.screen) if (panel) { panel.widgetSection = root.section panel.widgetIndex = root.sectionWidgetIndex diff --git a/Modules/MainScreen/Backgrounds/AllBackgrounds.qml b/Modules/MainScreen/Backgrounds/AllBackgrounds.qml index 403df4e3..c3c6166c 100644 --- a/Modules/MainScreen/Backgrounds/AllBackgrounds.qml +++ b/Modules/MainScreen/Backgrounds/AllBackgrounds.qml @@ -117,9 +117,9 @@ Item { shapeContainer: backgroundsShape } - // TrayDropdown + // TrayDrawer PanelBackground { - panel: root.windowRoot.trayDropdownPanel + panel: root.windowRoot.trayDrawerPanel shapeContainer: backgroundsShape } diff --git a/Modules/MainScreen/MainScreen.qml b/Modules/MainScreen/MainScreen.qml index 9d869b84..192a5de4 100644 --- a/Modules/MainScreen/MainScreen.qml +++ b/Modules/MainScreen/MainScreen.qml @@ -40,7 +40,7 @@ PanelWindow { readonly property alias sessionMenuPanel: sessionMenuPanel readonly property alias settingsPanel: settingsPanel readonly property alias setupWizardPanel: setupWizardPanel - readonly property alias trayDropdownPanel: trayDropdownPanel + readonly property alias trayDrawerPanel: trayDrawerPanel readonly property alias trayMenuPanel: trayMenuPanel readonly property alias wallpaperPanel: wallpaperPanel readonly property alias wifiPanel: wifiPanel @@ -306,13 +306,13 @@ PanelWindow { } TrayDropdownPanel { - id: trayDropdownPanel + id: trayDrawerPanel screen: root.screen z: 50 Component.onCompleted: { - objectName = "trayDropdownPanel-" + (screen?.name || "unknown") - PanelService.registerPanel(trayDropdownPanel) + objectName = "trayDrawerPanel-" + (screen?.name || "unknown") + PanelService.registerPanel(trayDrawerPanel) Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -324,7 +324,7 @@ PanelWindow { Component.onCompleted: { objectName = "trayMenuPanel-" + (screen?.name || "unknown") - PanelService.registerPanel(trayDropdownPanel) + PanelService.registerPanel(trayMenuPanel) Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } diff --git a/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml b/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml index b6169eee..c6f866fc 100644 --- a/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml +++ b/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml @@ -21,6 +21,7 @@ Popup { height: content.implicitHeight + padding * 2 padding: Style.marginXL modal: true + dim: false anchors.centerIn: parent onOpened: { diff --git a/Modules/Panels/Settings/Bar/WidgetSettings/TraySettings.qml b/Modules/Panels/Settings/Bar/WidgetSettings/TraySettings.qml index 3f2c7d2c..a628863d 100644 --- a/Modules/Panels/Settings/Bar/WidgetSettings/TraySettings.qml +++ b/Modules/Panels/Settings/Bar/WidgetSettings/TraySettings.qml @@ -13,6 +13,7 @@ ColumnLayout { // Local state property var localBlacklist: widgetData.blacklist || [] property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons + property bool valueDrawerEnabled: widgetData.drawerEnabled !== undefined ? widgetData.drawerEnabled : (widgetMetadata.drawerEnabled !== undefined ? widgetMetadata.drawerEnabled : true) ListModel { id: blacklistModel @@ -37,6 +38,14 @@ ColumnLayout { onToggled: checked => root.valueColorizeIcons = checked } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.tray.drawer-enabled.label") + description: I18n.tr("bar.widget-settings.tray.drawer-enabled.description") + checked: root.valueDrawerEnabled + onToggled: checked => root.valueDrawerEnabled = checked + } + ColumnLayout { Layout.fillWidth: true spacing: Style.marginS @@ -140,6 +149,7 @@ ColumnLayout { var settings = Object.assign({}, widgetData || {}) settings.blacklist = newBlacklist settings.colorizeIcons = root.valueColorizeIcons + settings.drawerEnabled = root.valueDrawerEnabled return settings } } diff --git a/Modules/Panels/Settings/Tabs/BarTab.qml b/Modules/Panels/Settings/Tabs/BarTab.qml index f138ccae..90acd077 100644 --- a/Modules/Panels/Settings/Tabs/BarTab.qml +++ b/Modules/Panels/Settings/Tabs/BarTab.qml @@ -224,7 +224,7 @@ ColumnLayout { NSectionEditor { sectionName: "Left" sectionId: "left" - settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Settings/Bar/BarWidgetSettingsDialog.qml") + settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml") widgetRegistry: BarWidgetRegistry widgetModel: Settings.data.bar.widgets.left availableWidgets: availableWidgets @@ -241,7 +241,7 @@ ColumnLayout { NSectionEditor { sectionName: "Center" sectionId: "center" - settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Settings/Bar/BarWidgetSettingsDialog.qml") + settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml") widgetRegistry: BarWidgetRegistry widgetModel: Settings.data.bar.widgets.center availableWidgets: availableWidgets @@ -258,7 +258,7 @@ ColumnLayout { NSectionEditor { sectionName: "Right" sectionId: "right" - settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Settings/Bar/BarWidgetSettingsDialog.qml") + settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml") widgetRegistry: BarWidgetRegistry widgetModel: Settings.data.bar.widgets.right availableWidgets: availableWidgets diff --git a/Modules/Panels/Tray/TrayDropdownPanel.qml b/Modules/Panels/Tray/TrayDropdownPanel.qml index 5e3517cd..62ff7cc1 100644 --- a/Modules/Panels/Tray/TrayDropdownPanel.qml +++ b/Modules/Panels/Tray/TrayDropdownPanel.qml @@ -61,7 +61,7 @@ SmartPanel { } // Dynamic sizing based on item count - // Show items that are NOT favorites (non-favorites go to dropdown) + // Show items that are NOT favorites (unpinned items go to drawer) readonly property var trayValuesAll: (SystemTray.items && SystemTray.items.values) ? SystemTray.items.values : [] readonly property var trayValues: trayValuesAll.filter(function (it) { return !root.isFavorite(it) @@ -144,7 +144,7 @@ SmartPanel { if (!modelData) return if (mouse.button === Qt.RightButton && modelData.hasMenu && modelData.menu) { - const panel = PanelService.getPanel("trayMenu", root.screen) + const panel = PanelService.getPanel("trayMenuPanel", root.screen) if (panel) { panel.menu = modelData.menu panel.trayItem = modelData @@ -154,11 +154,11 @@ SmartPanel { } } else if (mouse.button === Qt.LeftButton) { modelData.activate() - // Close the dropdown after activation - PanelService.getPanel("trayDropdownPanel", root.screen)?.close() + // Close the drawer after activation + PanelService.getPanel("trayDrawerPanel", root.screen)?.close() } else if (mouse.button === Qt.MiddleButton) { modelData.secondaryActivate() - PanelService.getPanel("trayDropdownPanel", root.screen)?.close() + PanelService.getPanel("trayDrawerPanel", root.screen)?.close() } } diff --git a/Modules/Panels/Tray/TrayMenuPanel.qml b/Modules/Panels/Tray/TrayMenuPanel.qml index 94fa5f38..9caa62b4 100644 --- a/Modules/Panels/Tray/TrayMenuPanel.qml +++ b/Modules/Panels/Tray/TrayMenuPanel.qml @@ -575,7 +575,7 @@ SmartPanel { Settings.data.bar.widgets[widgetSection] = widgets Settings.saveImmediate() if (root.screen) { - const panel = PanelService.getPanel("trayDropdownPanel", root.screen) + const panel = PanelService.getPanel("trayDrawerPanel", root.screen) if (panel) panel.close() } diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index 37e20314..d0294098 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -155,7 +155,8 @@ Singleton { "allowUserSettings": true, "blacklist": [], "colorizeIcons": false, - "favorites": [] + "favorites": [], + "drawerEnabled": true }, "WiFi": { "allowUserSettings": true,