Tray: add drawer logic

TraySettings: add drawer toggle
i18n: add translations for drawer toggle
This commit is contained in:
Ly-sec
2025-11-06 17:10:32 +01:00
parent e29c6ee1a6
commit 9f357aef25
17 changed files with 118 additions and 66 deletions
+57 -49
View File
@@ -37,9 +37,10 @@ Rectangle {
readonly property bool density: Settings.data.bar.density
property real itemSize: Math.round(Style.capsuleHeight * 0.65)
property list<string> blacklist: widgetSettings.blacklist || widgetMetadata.blacklist || [] // Read from settings
property list<string> 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<string> 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
@@ -117,9 +117,9 @@ Item {
shapeContainer: backgroundsShape
}
// TrayDropdown
// TrayDrawer
PanelBackground {
panel: root.windowRoot.trayDropdownPanel
panel: root.windowRoot.trayDrawerPanel
shapeContainer: backgroundsShape
}
+5 -5
View File
@@ -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)
}
}
@@ -21,6 +21,7 @@ Popup {
height: content.implicitHeight + padding * 2
padding: Style.marginXL
modal: true
dim: false
anchors.centerIn: parent
onOpened: {
@@ -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
}
}
+3 -3
View File
@@ -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
+5 -5
View File
@@ -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()
}
}
+1 -1
View File
@@ -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()
}