mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
Tray: hide all non pinned entries, reactive chevron
i18n: translation changes for tray
This commit is contained in:
@@ -771,7 +771,9 @@
|
||||
"description": "Ausschlussregeln für die Tray-Symbolleiste hinzufügen, unterstützt Platzhalter (*).",
|
||||
"label": "Ausschlussliste",
|
||||
"placeholder": "z.B., nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Anwendung anheften",
|
||||
"unpin-application": "Anheftung aufheben"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -772,8 +772,8 @@
|
||||
"label": "Blacklist",
|
||||
"placeholder": "e.g., nm-applet, Fcitx*"
|
||||
},
|
||||
"add-as-favorite": "Add as Favorite",
|
||||
"remove-from-favorites": "Remove from Favorites"
|
||||
"pin-application": "Pin Application",
|
||||
"unpin-application": "Unpin Application"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "Agregar reglas de exclusión de la bandeja, admite comodines (*).",
|
||||
"label": "Lista negra",
|
||||
"placeholder": "ej., nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Fijar Aplicación",
|
||||
"unpin-application": "Desfijar Aplicación"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "Ajouter des règles d'exclusion pour la boîte à miniatures, prend en charge les caractères génériques (*).",
|
||||
"label": "Liste noire",
|
||||
"placeholder": "ex: nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Épingler l'Application",
|
||||
"unpin-application": "Désépingler l'Application"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "Adicione regras de exclusão para a bandeja do sistema, suporta curingas (*).",
|
||||
"label": "Lista Negra",
|
||||
"placeholder": "ex: nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Fixar Aplicativo",
|
||||
"unpin-application": "Desfixar Aplicativo"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "Tepsi hariç tutma kuralları ekleyin, joker karakterleri destekler (*).",
|
||||
"label": "Kara liste",
|
||||
"placeholder": "örn., nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Uygulamayı Sabitle",
|
||||
"unpin-application": "Sabitlemeyi Kaldır"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "Додайте правила виключення з трея, підтримує шаблони (*).",
|
||||
"label": "Чорний список",
|
||||
"placeholder": "напр., nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "Закріпити Застосунок",
|
||||
"unpin-application": "Відкріпити Застосунок"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -771,7 +771,9 @@
|
||||
"description": "添加托盘排除规则,支持通配符 (*)。",
|
||||
"label": "黑名单",
|
||||
"placeholder": "例如:nm-applet, Fcitx*"
|
||||
}
|
||||
},
|
||||
"pin-application": "固定应用程序",
|
||||
"unpin-application": "取消固定应用程序"
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
|
||||
@@ -16,7 +16,7 @@ NPanel {
|
||||
// Widget info for menu functionality
|
||||
property string widgetSection: ""
|
||||
property int widgetIndex: -1
|
||||
|
||||
|
||||
// Trigger refresh when settings change
|
||||
property int settingsVersion: 0
|
||||
|
||||
@@ -24,26 +24,36 @@ NPanel {
|
||||
readonly property var favoritesList: {
|
||||
// Reference settingsVersion to force recalculation when it changes
|
||||
var _ = root.settingsVersion
|
||||
if (widgetSection === "" || widgetIndex < 0) return []
|
||||
if (widgetSection === "" || widgetIndex < 0)
|
||||
return []
|
||||
var widgets = Settings.data.bar.widgets[widgetSection]
|
||||
if (!widgets || widgetIndex >= widgets.length) return []
|
||||
if (!widgets || widgetIndex >= widgets.length)
|
||||
return []
|
||||
var widgetSettings = widgets[widgetIndex]
|
||||
if (!widgetSettings || widgetSettings.id !== "Tray") return []
|
||||
if (!widgetSettings || widgetSettings.id !== "Tray")
|
||||
return []
|
||||
return widgetSettings.favorites || []
|
||||
}
|
||||
|
||||
function wildCardMatch(str, rule) {
|
||||
if (!str || !rule) return false
|
||||
if (!str || !rule)
|
||||
return false
|
||||
let escaped = rule.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
let pattern = '^' + escaped.replace(/\\\*/g, '.*') + '$'
|
||||
try { return new RegExp(pattern, 'i').test(str) } catch(e) { return false }
|
||||
try {
|
||||
return new RegExp(pattern, 'i').test(str)
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isFavorite(item) {
|
||||
if (!favoritesList || favoritesList.length === 0) return false
|
||||
if (!favoritesList || favoritesList.length === 0)
|
||||
return false
|
||||
const title = item?.tooltipTitle || item?.name || item?.id || ""
|
||||
for (var i = 0; i < favoritesList.length; i++) {
|
||||
if (wildCardMatch(title, favoritesList[i])) return true
|
||||
if (wildCardMatch(title, favoritesList[i]))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -51,7 +61,9 @@ NPanel {
|
||||
// Dynamic sizing based on item count
|
||||
// Show items that are NOT favorites (non-favorites go to dropdown)
|
||||
readonly property var trayValuesAll: (SystemTray.items && SystemTray.items.values) ? SystemTray.items.values : []
|
||||
readonly property var trayValues: trayValuesAll.filter(function(it){ return !root.isFavorite(it) })
|
||||
readonly property var trayValues: trayValuesAll.filter(function (it) {
|
||||
return !root.isFavorite(it)
|
||||
})
|
||||
readonly property int itemCount: trayValues.length
|
||||
readonly property int maxColumns: 8
|
||||
readonly property real cellSize: Math.round(Style.capsuleHeight * 0.65)
|
||||
@@ -126,32 +138,34 @@ NPanel {
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (!modelData)
|
||||
return
|
||||
if (mouse.button === Qt.RightButton && modelData.hasMenu && modelData.menu && trayMenu.item) {
|
||||
trayMenu.item.menu = modelData.menu
|
||||
trayMenu.item.screen = root.screen
|
||||
trayMenu.item.trayItem = modelData
|
||||
trayMenu.item.widgetSection = root.widgetSection
|
||||
trayMenu.item.widgetIndex = root.widgetIndex
|
||||
const menuX = (root.columns > 1) ? (trayIcon.width / 2) : 0
|
||||
const menuY = trayIcon.height
|
||||
trayMenu.item.showAt(trayIcon, menuX, menuY)
|
||||
} else if (mouse.button === Qt.LeftButton) {
|
||||
modelData.activate?.()
|
||||
// Close the dropdown after activation
|
||||
PanelService.getPanel("trayDropdownPanel", root.screen)?.close()
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
modelData.secondaryActivate?.()
|
||||
PanelService.getPanel("trayDropdownPanel", root.screen)?.close()
|
||||
}
|
||||
}
|
||||
onClicked: mouse => {
|
||||
if (!modelData)
|
||||
return
|
||||
if (mouse.button === Qt.RightButton && modelData.hasMenu && modelData.menu && trayMenu.item) {
|
||||
trayMenu.item.menu = modelData.menu
|
||||
trayMenu.item.screen = root.screen
|
||||
trayMenu.item.trayItem = modelData
|
||||
trayMenu.item.widgetSection = root.widgetSection
|
||||
trayMenu.item.widgetIndex = root.widgetIndex
|
||||
const menuX = (root.columns > 1) ? (trayIcon.width / 2) : 0
|
||||
const menuY = trayIcon.height
|
||||
trayMenu.item.showAt(trayIcon, menuX, menuY)
|
||||
} else if (mouse.button === Qt.LeftButton) {
|
||||
modelData.activate()
|
||||
// Close the dropdown after activation
|
||||
PanelService.getPanel("trayDropdownPanel", root.screen)?.close()
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
modelData.secondaryActivate()
|
||||
PanelService.getPanel("trayDropdownPanel", root.screen)?.close()
|
||||
}
|
||||
}
|
||||
|
||||
onWheel: (wheel) => {
|
||||
if (wheel.angleDelta.y > 0) modelData?.scrollUp?.()
|
||||
else if (wheel.angleDelta.y < 0) modelData?.scrollDown?.()
|
||||
}
|
||||
onWheel: wheel => {
|
||||
if (wheel.angleDelta.y > 0)
|
||||
modelData?.scrollUp()
|
||||
else if (wheel.angleDelta.y < 0)
|
||||
modelData?.scrollDown()
|
||||
}
|
||||
|
||||
onEntered: TooltipService.show(Screen, trayIcon, modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item", BarService.getTooltipDirection())
|
||||
onExited: TooltipService.hide()
|
||||
@@ -169,4 +183,4 @@ NPanel {
|
||||
source: "TrayMenu.qml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,18 +303,23 @@ PopupWindow {
|
||||
|
||||
// Check if item is already a favorite
|
||||
readonly property bool isFavorite: {
|
||||
if (!root.trayItem || root.widgetSection === "" || root.widgetIndex < 0) return false
|
||||
if (!root.trayItem || root.widgetSection === "" || root.widgetIndex < 0)
|
||||
return false
|
||||
const itemName = root.trayItem.tooltipTitle || root.trayItem.name || root.trayItem.id || ""
|
||||
if (!itemName) return false
|
||||
|
||||
if (!itemName)
|
||||
return false
|
||||
|
||||
var widgets = Settings.data.bar.widgets[root.widgetSection]
|
||||
if (!widgets || root.widgetIndex >= widgets.length) return false
|
||||
if (!widgets || root.widgetIndex >= widgets.length)
|
||||
return false
|
||||
var widgetSettings = widgets[root.widgetIndex]
|
||||
if (!widgetSettings || widgetSettings.id !== "Tray") return false
|
||||
|
||||
if (!widgetSettings || widgetSettings.id !== "Tray")
|
||||
return false
|
||||
|
||||
var favorites = widgetSettings.favorites || []
|
||||
for (var i = 0; i < favorites.length; i++) {
|
||||
if (favorites[i] === itemName) return true
|
||||
if (favorites[i] === itemName)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -343,7 +348,7 @@ PopupWindow {
|
||||
NText {
|
||||
Layout.fillWidth: true
|
||||
color: Color.mPrimary
|
||||
text: addToFavoriteEntry.isFavorite ? I18n.tr("settings.bar.tray.remove-from-favorites") : I18n.tr("settings.bar.tray.add-as-favorite")
|
||||
text: addToFavoriteEntry.isFavorite ? I18n.tr("settings.bar.tray.unpin-application") : I18n.tr("settings.bar.tray.pin-application")
|
||||
pointSize: Style.fontSizeS
|
||||
font.weight: Font.Medium
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
@@ -414,6 +419,14 @@ PopupWindow {
|
||||
Settings.saveImmediate()
|
||||
|
||||
Logger.i("TrayMenu", "Added", itemName, "as favorite")
|
||||
|
||||
// Close the tray dropdown panel after pinning
|
||||
if (root.screen) {
|
||||
const panel = PanelService.getPanel("trayDropdownPanel", root.screen)
|
||||
if (panel) {
|
||||
panel.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromFavorites() {
|
||||
|
||||
@@ -109,7 +109,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
// Build inline (favorites) and dropdown (non-favorites) lists
|
||||
// If favorites list is empty, all items are inline
|
||||
// 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 = []
|
||||
@@ -132,15 +132,19 @@ Rectangle {
|
||||
const cand = newItems[v]
|
||||
let isFavorite = false
|
||||
for (var f = 0; f < filteredItems.length; f++) {
|
||||
if (filteredItems[f] === cand) { isFavorite = true; break }
|
||||
if (filteredItems[f] === cand) {
|
||||
isFavorite = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isFavorite) nonFav.push(cand)
|
||||
if (!isFavorite)
|
||||
nonFav.push(cand)
|
||||
}
|
||||
dropdownItems = nonFav
|
||||
} else {
|
||||
// No favorites: all items are inline
|
||||
filteredItems = newItems
|
||||
dropdownItems = []
|
||||
// No favorites: all items go to dropdown (none inline)
|
||||
filteredItems = []
|
||||
dropdownItems = newItems
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,9 +307,20 @@ Rectangle {
|
||||
NIconButton {
|
||||
id: dropdownButton
|
||||
visible: dropdownItems.length > 0
|
||||
width: itemSize
|
||||
height: itemSize
|
||||
icon: isVertical ? (barPosition === "left" ? "chevron-right" : "chevron-left") : "chevron-down"
|
||||
width: Math.round(itemSize * 1.4)
|
||||
height: Math.round(itemSize * 1.4)
|
||||
icon: {
|
||||
if (barPosition === "top")
|
||||
return "chevron-down"
|
||||
else if (barPosition === "bottom")
|
||||
return "chevron-up"
|
||||
else if (barPosition === "left")
|
||||
return "chevron-right"
|
||||
else if (barPosition === "right")
|
||||
return "chevron-left"
|
||||
else
|
||||
return "chevron-down" // default fallback
|
||||
}
|
||||
tooltipText: I18n.tr("open-control-center") // reuse generic tooltip text
|
||||
onClicked: {
|
||||
const panel = PanelService.getPanel("trayDropdownPanel", root.screen)
|
||||
|
||||
Reference in New Issue
Block a user