mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
TaskbarGrouped is now consolidated in the Workspace widget.
This commit is contained in:
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Titelbreite zurücksetzen"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Zeige nur die Workspace-Bezeichnung für Workspaces an, die offene Fenster haben.",
|
||||
"label": "Zeige Label nur bei Belegung"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Theme-Farben auf Tray-Symbole anwenden.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Wählen Sie, wie Arbeitsbereichs-Beschriftungen angezeigt werden.",
|
||||
"label": "Beschriftungsmodus"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Anwendungssymbole in jedem Arbeitsbereich anzeigen.",
|
||||
"label": "Anwendungen anzeigen"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Arbeitsbereichsbezeichnungen nur anzeigen, wenn sie Fenster enthalten.",
|
||||
"label": "Beschriftungen nur anzeigen, wenn belegt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Reset title width"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Only show workspace label for workspaces that have open windows.",
|
||||
"label": "Show label only when occupied"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Apply theme colors to tray icons.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Choose how workspace labels are displayed.",
|
||||
"label": "Label mode"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Display application icons inside each workspace.",
|
||||
"label": "Show applications"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Only show workspace labels when they contain windows.",
|
||||
"label": "Show labels only when occupied"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Restablecer ancho del título"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Mostrar solo la etiqueta del espacio de trabajo para los espacios de trabajo que tienen ventanas abiertas.",
|
||||
"label": "Mostrar etiqueta solo cuando esté ocupado."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Aplicar colores del tema a los iconos de la bandeja del sistema.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Elegir cómo se muestran las etiquetas de los espacios de trabajo.",
|
||||
"label": "Modo de etiqueta"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Mostrar los iconos de las aplicaciones dentro de cada espacio de trabajo.",
|
||||
"label": "Mostrar aplicaciones"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Mostrar solo las etiquetas del espacio de trabajo cuando contengan ventanas.",
|
||||
"label": "Mostrar etiquetas solo cuando esté ocupado."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Réinitialiser la largeur du titre"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Afficher uniquement l'étiquette de l'espace de travail pour les espaces de travail qui ont des fenêtres ouvertes.",
|
||||
"label": "Afficher l'étiquette uniquement lorsque c'est occupé."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Appliquer les couleurs du thème aux icônes de la barre système.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Choisir comment les étiquettes d'espace de travail sont affichées.",
|
||||
"label": "Mode d'étiquette"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Afficher les icônes des applications dans chaque espace de travail.",
|
||||
"label": "Afficher les applications"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Afficher uniquement les étiquettes d'espace de travail lorsqu'elles contiennent des fenêtres.",
|
||||
"label": "Afficher les étiquettes uniquement lorsque le champ est occupé."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "タイトル幅をリセット"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "ウィンドウが開いているワークスペースにのみラベルを表示します。",
|
||||
"label": "ウィンドウがある時のみラベルを表示"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "トレイのアイコンにテーマカラーを適用します。",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "ワークスペースラベルの表示方法を選択します。",
|
||||
"label": "ラベルモード"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "ワークスペース内にアプリケーションのアイコンを表示する。",
|
||||
"label": "アプリケーションを表示 (Apuriikeeshon o hyōji)"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "ウィンドウを含む場合にのみ、ワークスペースのラベルを表示する。",
|
||||
"label": "占有されている場合のみラベルを表示する"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Titelbreedte resetten"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Toon alleen de werkomgevinglabels voor werkomgevingen met open vensters.",
|
||||
"label": "Label alleen tonen wanneer bezet"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Pas themakleuren toe op systeemvakpictogrammen.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Kies hoe labels van werkruimten worden weergegeven.",
|
||||
"label": "Labelmodus"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Toon applicatiepictogrammen in elke werkruimte.",
|
||||
"label": "Toon applicaties"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Toon alleen werkruimtelabels wanneer ze vensters bevatten.",
|
||||
"label": "Toon labels alleen wanneer bezet."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Redefinir largura do título"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Mostrar apenas o rótulo da área de trabalho para áreas de trabalho que têm janelas abertas.",
|
||||
"label": "Mostrar rótulo somente quando ocupado."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Aplicar cores do tema aos ícones da bandeja do sistema.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Escolher como os rótulos de espaço de trabalho são exibidos.",
|
||||
"label": "Modo de rótulo"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Exibir ícones de aplicativos dentro de cada espaço de trabalho.",
|
||||
"label": "Mostrar aplicativos"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Mostrar rótulos de área de trabalho apenas quando contiverem janelas.",
|
||||
"label": "Mostrar rótulos apenas quando ocupado."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Сбросить ширину заголовка"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Отображать метку рабочего пространства только для тех рабочих пространств, в которых есть открытые окна.",
|
||||
"label": "Показывать метку только когда занято"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Применить цвета темы к иконкам трея.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Выберите, как отображаются метки рабочих пространств.",
|
||||
"label": "Режим метки"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Отображать значки приложений внутри каждого рабочего пространства.",
|
||||
"label": "Показать приложения"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Показывать метки рабочих пространств только тогда, когда они содержат окна.",
|
||||
"label": "Показывать метки только при наличии содержимого"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Başlık genişliğini sıfırla"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Sadece açık pencereleri olan çalışma alanları için çalışma alanı etiketini göster.",
|
||||
"label": "Sadece dolu olduğunda etiketi göster."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Tepsi simgelerine tema renklerini uygula.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Çalışma alanı etiketlerinin nasıl gösterileceğini seçin.",
|
||||
"label": "Etiket Modu"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Her çalışma alanının içinde uygulama simgelerini görüntüle.",
|
||||
"label": "Uygulamaları göster"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Yalnızca pencere içeren çalışma alanı etiketlerini göster.",
|
||||
"label": "Yalnızca dolu olduğunda etiketleri göster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "Скинути ширину заголовка"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Показувати мітку робочого простору лише для робочих просторів, які мають відкриті вікна.",
|
||||
"label": "Показувати мітку лише коли зайнято"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Застосувати кольори теми до значків трея.",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "Виберіть, як відображаються мітки робочих просторів.",
|
||||
"label": "Режим міток"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "Відображати значки програм у кожному робочому просторі.",
|
||||
"label": "Показати застосунки"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "Показувати мітки робочих просторів лише тоді, коли вони містять вікна.",
|
||||
"label": "Показувати мітки лише коли поле заповнене"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,6 @@
|
||||
"reset-tooltip": "重置标题宽度"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "只显示有打开窗口的工作区标签。",
|
||||
"label": "仅在被占用时显示标签"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "将主题颜色应用到系统托盘图标。",
|
||||
@@ -410,6 +404,14 @@
|
||||
"label-mode": {
|
||||
"description": "选择工作区标签的显示方式。",
|
||||
"label": "标签模式"
|
||||
},
|
||||
"show-applications": {
|
||||
"description": "在每个工作区内显示应用程序图标。",
|
||||
"label": "显示应用程序"
|
||||
},
|
||||
"show-labels-only-when-occupied": {
|
||||
"description": "仅在工作区包含窗口时显示工作区标签。",
|
||||
"label": "仅在被占用时显示标签"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
// Migrate TaskbarGrouped widgets to Workspace with showApplications: true
|
||||
function migrate(adapter, logger, rawJson) {
|
||||
logger.i("Settings", "Migrating settings to v28");
|
||||
|
||||
// Check bar widgets in all sections
|
||||
const sections = ["left", "center", "right"];
|
||||
|
||||
for (const section of sections) {
|
||||
if (!rawJson?.bar?.widgets?.[section])
|
||||
continue;
|
||||
|
||||
const widgets = rawJson.bar.widgets[section];
|
||||
for (let i = 0; i < widgets.length; i++) {
|
||||
if (widgets[i].id === "TaskbarGrouped") {
|
||||
// Convert TaskbarGrouped to Workspace with showApplications
|
||||
const oldWidget = widgets[i];
|
||||
adapter.bar.widgets[section][i] = {
|
||||
id: "Workspace",
|
||||
showApplications: true,
|
||||
labelMode: oldWidget.labelMode || "index",
|
||||
hideUnoccupied: oldWidget.hideUnoccupied || false,
|
||||
showLabelsOnlyWhenOccupied: oldWidget.showLabelsOnlyWhenOccupied ?? true,
|
||||
colorizeIcons: oldWidget.colorizeIcons || false
|
||||
};
|
||||
logger.i("Settings", "Migrated TaskbarGrouped to Workspace in " + section + " section");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@ QtObject {
|
||||
|
||||
// Map of version number to migration component
|
||||
readonly property var migrations: ({
|
||||
27: migration27Component
|
||||
27: migration27Component,
|
||||
28: migration28Component
|
||||
})
|
||||
|
||||
// Migration components
|
||||
property Component migration27Component: Migration27 {}
|
||||
property Component migration28Component: Migration28 {}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Singleton {
|
||||
- Default cache directory: ~/.cache/noctalia
|
||||
*/
|
||||
readonly property alias data: adapter // Used to access via Settings.data.xxx.yyy
|
||||
readonly property int settingsVersion: 27
|
||||
readonly property int settingsVersion: 28
|
||||
readonly property bool isDebug: Quickshell.env("NOCTALIA_DEBUG") === "1"
|
||||
readonly property string shellName: "noctalia"
|
||||
readonly property string configDir: Quickshell.env("NOCTALIA_CONFIG_DIR") || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/"
|
||||
|
||||
@@ -1,639 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Widgets
|
||||
import qs.Commons
|
||||
import qs.Modules.Bar.Extras
|
||||
import qs.Services.Compositor
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
property string section: ""
|
||||
property int sectionWidgetIndex: -1
|
||||
property int sectionWidgetsCount: 0
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
|
||||
readonly property string density: Settings.data.bar.density
|
||||
readonly property real itemSize: (density === "compact") ? Style.capsuleHeight * 0.9 : Style.capsuleHeight * 0.8
|
||||
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
|
||||
property var widgetSettings: {
|
||||
if (section && sectionWidgetIndex >= 0) {
|
||||
var widgets = Settings.data.bar.widgets[section];
|
||||
if (widgets && sectionWidgetIndex < widgets.length) {
|
||||
return widgets[sectionWidgetIndex];
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
readonly property int characterCount: 2
|
||||
readonly property bool hideUnoccupied: (widgetSettings.hideUnoccupied !== undefined) ? widgetSettings.hideUnoccupied : widgetMetadata.hideUnoccupied
|
||||
readonly property string labelMode: (widgetSettings.labelMode !== undefined) ? widgetSettings.labelMode : widgetMetadata.labelMode
|
||||
readonly property bool showLabelsOnlyWhenOccupied: (widgetSettings.showLabelsOnlyWhenOccupied !== undefined) ? widgetSettings.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
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
|
||||
|
||||
// Context menu state
|
||||
property var selectedWindow: null
|
||||
property string selectedAppName: ""
|
||||
property int modelUpdateTrigger: 0 // Dummy property to force model re-evaluation
|
||||
|
||||
function refreshWorkspaces() {
|
||||
localWorkspaces.clear();
|
||||
if (!screen)
|
||||
return;
|
||||
const screenName = screen.name.toLowerCase();
|
||||
|
||||
for (var i = 0; i < CompositorService.workspaces.count; i++) {
|
||||
const ws = CompositorService.workspaces.get(i);
|
||||
|
||||
if (ws.output.toLowerCase() !== screenName)
|
||||
continue;
|
||||
if (hideUnoccupied && !ws.isOccupied && !ws.isFocused)
|
||||
continue;
|
||||
|
||||
// Copy all properties from ws and add windows
|
||||
var workspaceData = Object.assign({}, ws);
|
||||
workspaceData.windows = CompositorService.getWindowsForWorkspace(ws.id);
|
||||
|
||||
localWorkspaces.append(workspaceData);
|
||||
}
|
||||
|
||||
updateWorkspaceFocus();
|
||||
}
|
||||
|
||||
function triggerUnifiedWave() {
|
||||
effectColor = Color.mPrimary;
|
||||
masterAnimation.restart();
|
||||
}
|
||||
|
||||
function updateWorkspaceFocus() {
|
||||
for (var i = 0; i < localWorkspaces.count; i++) {
|
||||
const ws = localWorkspaces.get(i);
|
||||
if (ws.isFocused === true) {
|
||||
root.triggerUnifiedWave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
|
||||
function onWorkspacesChanged() {
|
||||
refreshWorkspaces();
|
||||
}
|
||||
|
||||
function onWindowListChanged() {
|
||||
refreshWorkspaces();
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: masterAnimation
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "effectsActive"
|
||||
value: true
|
||||
}
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "masterProgress"
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
duration: Style.animationSlow * 2
|
||||
easing.type: Easing.OutQuint
|
||||
}
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "effectsActive"
|
||||
value: false
|
||||
}
|
||||
PropertyAction {
|
||||
target: root
|
||||
property: "masterProgress"
|
||||
value: 0.0
|
||||
}
|
||||
}
|
||||
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
|
||||
model: {
|
||||
// Reference modelUpdateTrigger to make binding reactive
|
||||
const _ = root.modelUpdateTrigger;
|
||||
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
onTriggered: action => {
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.close();
|
||||
}
|
||||
|
||||
if (action === "activate" && selectedWindow) {
|
||||
CompositorService.focusWindow(selectedWindow);
|
||||
} else if (action === "close" && selectedWindow) {
|
||||
CompositorService.closeWindow(selectedWindow);
|
||||
} else if (action === "widget-settings") {
|
||||
BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings);
|
||||
}
|
||||
selectedWindow = null;
|
||||
selectedAppName = "";
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
Rectangle {
|
||||
id: container
|
||||
|
||||
required property var model
|
||||
property var workspaceModel: model
|
||||
property bool hasWindows: workspaceModel.windows.count > 0
|
||||
|
||||
radius: Style.radiusS
|
||||
border.color: workspaceModel.isFocused ? Color.mPrimary : Color.mOutline
|
||||
border.width: Style.borderS
|
||||
width: (hasWindows ? iconsFlow.implicitWidth : root.itemSize * 0.8) + (root.isVerticalBar ? Style.marginXS : Style.marginL)
|
||||
height: (hasWindows ? iconsFlow.implicitHeight : root.itemSize * 0.8) + (root.isVerticalBar ? Style.marginL : Style.marginXS)
|
||||
color: Style.capsuleColor
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !hasWindows
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
onPressed: mouse => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.switchToWorkspace(workspaceModel);
|
||||
}
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = "";
|
||||
root.selectedAppName = "";
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = container.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer1.globalX = globalPos.x;
|
||||
contextMenuOpenTimer1.globalY = globalPos.y;
|
||||
contextMenuOpenTimer1.itemWidth = container.width;
|
||||
contextMenuOpenTimer1.itemHeight = container.height;
|
||||
contextMenuOpenTimer1.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: iconsFlow
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
flow: root.isVerticalBar ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
model: workspaceModel.windows
|
||||
|
||||
delegate: Item {
|
||||
id: taskbarItem
|
||||
|
||||
property bool itemHovered: false
|
||||
|
||||
width: root.itemSize * 0.8
|
||||
height: root.itemSize * 0.8
|
||||
|
||||
// Smooth scale animation on hover
|
||||
scale: itemHovered ? 1.1 : 1.0
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutBack
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: appIcon
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
source: ThemeIcons.iconForAppId(model.appId)
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
opacity: model.isFocused ? Style.opacityFull : 0.6
|
||||
layer.enabled: root.colorizeIcons && !model.isFocused
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: focusIndicator
|
||||
anchors.bottomMargin: -2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: model.isFocused ? 4 : 0
|
||||
height: model.isFocused ? 4 : 0
|
||||
color: model.isFocused ? Color.mPrimary : Color.transparent
|
||||
radius: Math.min(Style.radiusXXS, width / 2)
|
||||
}
|
||||
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mSurfaceVariant
|
||||
property real colorizeMode: 0
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
|
||||
onPressed: mouse => {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.focusWindow(model);
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = model;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(model.appId, model.title);
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = taskbarItem.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer2.globalX = globalPos.x;
|
||||
contextMenuOpenTimer2.globalY = globalPos.y;
|
||||
contextMenuOpenTimer2.itemWidth = taskbarItem.width;
|
||||
contextMenuOpenTimer2.itemHeight = taskbarItem.height;
|
||||
contextMenuOpenTimer2.restart();
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
taskbarItem.itemHovered = true;
|
||||
TooltipService.show(taskbarItem, model.title || model.appId || "Unknown app.", BarService.getTooltipDirection());
|
||||
}
|
||||
onExited: {
|
||||
taskbarItem.itemHovered = false;
|
||||
TooltipService.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: workspaceNumberContainer
|
||||
|
||||
visible: root.labelMode !== "none" && (!root.showLabelsOnlyWhenOccupied || container.hasWindows)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: -Style.fontSizeXS * 0.5
|
||||
topMargin: -Style.fontSizeXS * 0.5
|
||||
}
|
||||
|
||||
// Doube width margin necessary here for Name or Name+Index, but double height not needed.
|
||||
width: Math.max(workspaceNumber.implicitWidth + (Style.marginXS * 2), Style.fontSizeXXS * 2)
|
||||
height: Math.max(workspaceNumber.implicitHeight + Style.marginXS, Style.fontSizeXXS * 2)
|
||||
|
||||
Rectangle {
|
||||
id: workspaceNumberBackground
|
||||
|
||||
anchors.fill: parent
|
||||
radius: Math.min(Style.radiusL, width / 2)
|
||||
|
||||
color: {
|
||||
if (workspaceModel.isFocused)
|
||||
return Color.mPrimary;
|
||||
if (workspaceModel.isUrgent)
|
||||
return Color.mError;
|
||||
if (hasWindows)
|
||||
return Color.mSecondary;
|
||||
|
||||
if (Settings.data.colorSchemes.darkMode) {
|
||||
return Qt.darker(Color.mSecondary, 1.5);
|
||||
} else {
|
||||
return Qt.lighter(Color.mSecondary, 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
scale: workspaceModel.isActive ? 1.0 : 0.9
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutBack
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Burst effect overlay for focused workspace number (smaller outline)
|
||||
Rectangle {
|
||||
id: workspaceNumberBurst
|
||||
anchors.centerIn: workspaceNumberContainer
|
||||
width: workspaceNumberContainer.width + 12 * root.masterProgress
|
||||
height: workspaceNumberContainer.height + 12 * root.masterProgress
|
||||
radius: width / 2
|
||||
color: Color.transparent
|
||||
border.color: root.effectColor
|
||||
border.width: Math.max(1, Math.round((2 + 4 * (1.0 - root.masterProgress))))
|
||||
opacity: root.effectsActive && workspaceModel.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
|
||||
visible: root.effectsActive && workspaceModel.isFocused
|
||||
z: 1
|
||||
}
|
||||
|
||||
NText {
|
||||
id: workspaceNumber
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
text: {
|
||||
if (workspaceModel.name && workspaceModel.name.length > 0) {
|
||||
if (root.labelMode === "name") {
|
||||
return workspaceModel.name.substring(0, root.characterCount);
|
||||
}
|
||||
if (root.labelMode === "index+name") {
|
||||
return (workspaceModel.idx.toString() + workspaceModel.name.substring(0, 1));
|
||||
}
|
||||
}
|
||||
return workspaceModel.idx.toString();
|
||||
}
|
||||
|
||||
family: Settings.data.ui.fontFixed
|
||||
font {
|
||||
pointSize: Style.fontSizeXXS
|
||||
weight: Style.fontWeightBold
|
||||
capitalization: Font.AllUppercase
|
||||
}
|
||||
applyUiScale: false
|
||||
|
||||
color: {
|
||||
if (workspaceModel.isFocused)
|
||||
return Color.mOnPrimary;
|
||||
if (workspaceModel.isUrgent)
|
||||
return Color.mOnError;
|
||||
// if (hasWindows)
|
||||
// return Color.mOnSecondary;
|
||||
|
||||
return Color.mOnSecondary;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: taskbarGrid
|
||||
|
||||
anchors.verticalCenter: isVerticalBar ? undefined : parent.verticalCenter
|
||||
anchors.left: isVerticalBar ? undefined : parent.left
|
||||
anchors.leftMargin: isVerticalBar ? 0 : Style.marginM
|
||||
anchors.horizontalCenter: isVerticalBar ? parent.horizontalCenter : undefined
|
||||
anchors.top: isVerticalBar ? parent.top : undefined
|
||||
anchors.topMargin: isVerticalBar ? Style.marginM : 0
|
||||
|
||||
spacing: Style.marginS
|
||||
flow: isVerticalBar ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
model: localWorkspaces
|
||||
delegate: workspaceRepeaterDelegate
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: contextMenuOpenTimer1
|
||||
interval: 10
|
||||
repeat: false
|
||||
property real globalX: 0
|
||||
property real globalY: 0
|
||||
property real itemWidth: 0
|
||||
property real itemHeight: 0
|
||||
onTriggered: openContextMenu(globalX, globalY, itemWidth, itemHeight)
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: contextMenuOpenTimer2
|
||||
interval: 10
|
||||
repeat: false
|
||||
property real globalX: 0
|
||||
property real globalY: 0
|
||||
property real itemWidth: 0
|
||||
property real itemHeight: 0
|
||||
onTriggered: openContextMenu(globalX, globalY, itemWidth, itemHeight)
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
function openContextMenu(globalX, globalY, itemWidth, itemHeight) {
|
||||
// Directly build and set model as a new array (bypass binding issues)
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
|
||||
// Set the model directly
|
||||
contextMenu.model = items;
|
||||
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.open();
|
||||
|
||||
// Calculate menu position
|
||||
let menuX, menuY;
|
||||
if (root.barPosition === "top") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = Style.barHeight + Style.marginS;
|
||||
} else if (root.barPosition === "bottom") {
|
||||
const menuHeight = 12 + contextMenu.model.length * contextMenu.itemHeight;
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = -menuHeight - Style.marginS;
|
||||
} else if (root.barPosition === "left") {
|
||||
menuX = Style.barHeight + Style.marginS;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
} else {
|
||||
// right
|
||||
menuX = -contextMenu.implicitWidth - Style.marginS;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
}
|
||||
|
||||
contextMenu.openAtItem(root, menuX, menuY);
|
||||
popupMenuWindow.contentItem = contextMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import qs.Commons
|
||||
import qs.Modules.Bar.Extras
|
||||
import qs.Services.Compositor
|
||||
@@ -49,6 +50,17 @@ Item {
|
||||
readonly property bool followFocusedScreen: (widgetSettings.followFocusedScreen !== undefined) ? widgetSettings.followFocusedScreen : widgetMetadata.followFocusedScreen
|
||||
readonly property int characterCount: isVertical ? 2 : ((widgetSettings.characterCount !== undefined) ? widgetSettings.characterCount : widgetMetadata.characterCount)
|
||||
|
||||
// Grouped mode (show applications) settings
|
||||
readonly property bool showApplications: (widgetSettings.showApplications !== undefined) ? widgetSettings.showApplications : widgetMetadata.showApplications
|
||||
readonly property bool showLabelsOnlyWhenOccupied: (widgetSettings.showLabelsOnlyWhenOccupied !== undefined) ? widgetSettings.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
readonly property bool colorizeIcons: (widgetSettings.colorizeIcons !== undefined) ? widgetSettings.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
readonly property real itemSize: (density === "compact") ? Style.capsuleHeight * 0.9 : Style.capsuleHeight * 0.8
|
||||
|
||||
// Context menu state for grouped mode
|
||||
property var selectedWindow: null
|
||||
property string selectedAppName: ""
|
||||
property int modelUpdateTrigger: 0
|
||||
|
||||
property bool isDestroying: false
|
||||
property bool hovered: false
|
||||
|
||||
@@ -66,8 +78,8 @@ Item {
|
||||
|
||||
signal workspaceChanged(int workspaceId, color accentColor)
|
||||
|
||||
implicitWidth: isVertical ? Style.barHeight : computeWidth()
|
||||
implicitHeight: isVertical ? computeHeight() : Style.barHeight
|
||||
implicitWidth: showApplications ? (isVertical ? groupedGrid.implicitWidth + Style.marginM * 2 : Math.round(groupedGrid.implicitWidth + Style.marginM * 2)) : (isVertical ? Style.barHeight : computeWidth())
|
||||
implicitHeight: showApplications ? (isVertical ? Math.round(groupedGrid.implicitHeight + Style.marginM * 2) : Style.barHeight) : (isVertical ? computeHeight() : Style.barHeight)
|
||||
|
||||
function getWorkspaceWidth(ws) {
|
||||
const d = Style.capsuleHeight * root.baseDimensionRatio;
|
||||
@@ -159,6 +171,10 @@ Item {
|
||||
function onWorkspacesChanged() {
|
||||
refreshWorkspaces();
|
||||
}
|
||||
function onWindowListChanged() {
|
||||
if (showApplications || showLabelsOnlyWhenOccupied)
|
||||
refreshWorkspaces();
|
||||
}
|
||||
}
|
||||
|
||||
function refreshWorkspaces() {
|
||||
@@ -174,12 +190,22 @@ Item {
|
||||
}
|
||||
|
||||
if (screen !== null) {
|
||||
const screenName = screen.name.toLowerCase();
|
||||
for (var i = 0; i < CompositorService.workspaces.count; i++) {
|
||||
const ws = CompositorService.workspaces.get(i);
|
||||
if ((followFocusedScreen && ws.output.toLowerCase() == focusedOutput) || (!followFocusedScreen && ws.output.toLowerCase() == screen.name.toLowerCase())) {
|
||||
if (hideUnoccupied && !ws.isOccupied && !ws.isFocused) {
|
||||
continue;
|
||||
}
|
||||
const matchesScreen = (followFocusedScreen && ws.output.toLowerCase() == focusedOutput) || (!followFocusedScreen && ws.output.toLowerCase() == screenName);
|
||||
|
||||
if (!matchesScreen)
|
||||
continue;
|
||||
if (hideUnoccupied && !ws.isOccupied && !ws.isFocused)
|
||||
continue;
|
||||
|
||||
if (showApplications) {
|
||||
// For grouped mode, attach windows to each workspace
|
||||
var workspaceData = Object.assign({}, ws);
|
||||
workspaceData.windows = CompositorService.getWindowsForWorkspace(ws.id);
|
||||
localWorkspaces.append(workspaceData);
|
||||
} else {
|
||||
localWorkspaces.append(ws);
|
||||
}
|
||||
}
|
||||
@@ -235,13 +261,31 @@ Item {
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
|
||||
model: [
|
||||
{
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
},
|
||||
]
|
||||
model: {
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
onTriggered: action => {
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
@@ -249,14 +293,21 @@ Item {
|
||||
popupMenuWindow.close();
|
||||
}
|
||||
|
||||
if (action === "widget-settings") {
|
||||
if (action === "activate" && selectedWindow) {
|
||||
CompositorService.focusWindow(selectedWindow);
|
||||
} else if (action === "close" && selectedWindow) {
|
||||
CompositorService.closeWindow(selectedWindow);
|
||||
} else if (action === "widget-settings") {
|
||||
BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings);
|
||||
}
|
||||
selectedWindow = null;
|
||||
selectedAppName = "";
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: workspaceBackground
|
||||
visible: !showApplications
|
||||
width: isVertical ? Style.capsuleHeight : parent.width
|
||||
height: isVertical ? parent.height : Style.capsuleHeight
|
||||
radius: Style.radiusM
|
||||
@@ -327,7 +378,7 @@ Item {
|
||||
spacing: spacingBetweenPills
|
||||
anchors.verticalCenter: workspaceBackground.verticalCenter
|
||||
x: horizontalPadding
|
||||
visible: !isVertical
|
||||
visible: !isVertical && !showApplications
|
||||
|
||||
Repeater {
|
||||
id: workspaceRepeaterHorizontal
|
||||
@@ -342,7 +393,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
Loader {
|
||||
active: (labelMode !== "none")
|
||||
active: (labelMode !== "none") && (!root.showLabelsOnlyWhenOccupied || model.isOccupied || model.isFocused)
|
||||
sourceComponent: Component {
|
||||
NText {
|
||||
x: (pill.width - width) / 2
|
||||
@@ -476,7 +527,7 @@ Item {
|
||||
spacing: spacingBetweenPills
|
||||
anchors.horizontalCenter: workspaceBackground.horizontalCenter
|
||||
y: horizontalPadding
|
||||
visible: isVertical
|
||||
visible: isVertical && !showApplications
|
||||
|
||||
Repeater {
|
||||
id: workspaceRepeaterVertical
|
||||
@@ -491,7 +542,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
Loader {
|
||||
active: (labelMode !== "none")
|
||||
active: (labelMode !== "none") && (!root.showLabelsOnlyWhenOccupied || model.isOccupied)
|
||||
sourceComponent: Component {
|
||||
NText {
|
||||
x: (pillVertical.width - width) / 2
|
||||
@@ -618,4 +669,316 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Grouped mode (showApplications = true)
|
||||
// ========================================
|
||||
|
||||
Component {
|
||||
id: groupedWorkspaceDelegate
|
||||
|
||||
Rectangle {
|
||||
id: groupedContainer
|
||||
|
||||
required property var model
|
||||
property var workspaceModel: model
|
||||
|
||||
radius: Style.radiusS
|
||||
border.color: workspaceModel.isFocused ? Color.mPrimary : Color.mOutline
|
||||
border.width: Style.borderS
|
||||
width: (workspaceModel.isOccupied ? groupedIconsFlow.implicitWidth : root.itemSize * 0.8) + (root.isVertical ? Style.marginXS : Style.marginL)
|
||||
height: (workspaceModel.isOccupied ? groupedIconsFlow.implicitHeight : root.itemSize * 0.8) + (root.isVertical ? Style.marginL : Style.marginXS)
|
||||
color: Style.capsuleColor
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !groupedContainer.workspaceModel.isOccupied
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
onPressed: mouse => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.switchToWorkspace(groupedContainer.workspaceModel);
|
||||
}
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = null;
|
||||
root.selectedAppName = "";
|
||||
openGroupedContextMenu(groupedContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: groupedIconsFlow
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
flow: root.isVertical ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
model: groupedContainer.workspaceModel.windows
|
||||
|
||||
delegate: Item {
|
||||
id: groupedTaskbarItem
|
||||
|
||||
property bool itemHovered: false
|
||||
|
||||
width: root.itemSize * 0.8
|
||||
height: root.itemSize * 0.8
|
||||
|
||||
scale: itemHovered ? 1.1 : 1.0
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutBack
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: groupedAppIcon
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
source: ThemeIcons.iconForAppId(model.appId)
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
opacity: model.isFocused ? Style.opacityFull : 0.6
|
||||
layer.enabled: root.colorizeIcons && !model.isFocused
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: groupedFocusIndicator
|
||||
anchors.bottomMargin: -2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: model.isFocused ? 4 : 0
|
||||
height: model.isFocused ? 4 : 0
|
||||
color: model.isFocused ? Color.mPrimary : Color.transparent
|
||||
radius: Math.min(Style.radiusXXS, width / 2)
|
||||
}
|
||||
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mSurfaceVariant
|
||||
property real colorizeMode: 0
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
|
||||
onPressed: mouse => {
|
||||
if (!model)
|
||||
return;
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.focusWindow(model);
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
if (!model)
|
||||
return;
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = model;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(model.appId, model.title);
|
||||
openGroupedContextMenu(groupedTaskbarItem);
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
groupedTaskbarItem.itemHovered = true;
|
||||
TooltipService.show(groupedTaskbarItem, model.title || model.appId || "Unknown app.", BarService.getTooltipDirection());
|
||||
}
|
||||
onExited: {
|
||||
groupedTaskbarItem.itemHovered = false;
|
||||
TooltipService.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: groupedWorkspaceNumberContainer
|
||||
|
||||
visible: root.labelMode !== "none" && (!root.showLabelsOnlyWhenOccupied || groupedContainer.workspaceModel.isOccupied)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: -Style.fontSizeXS * 0.5
|
||||
topMargin: -Style.fontSizeXS * 0.5
|
||||
}
|
||||
|
||||
width: Math.max(groupedWorkspaceNumber.implicitWidth + (Style.marginXS * 2), Style.fontSizeXXS * 2)
|
||||
height: Math.max(groupedWorkspaceNumber.implicitHeight + Style.marginXS, Style.fontSizeXXS * 2)
|
||||
|
||||
Rectangle {
|
||||
id: groupedWorkspaceNumberBackground
|
||||
|
||||
anchors.fill: parent
|
||||
radius: Math.min(Style.radiusL, width / 2)
|
||||
|
||||
color: {
|
||||
if (groupedContainer.workspaceModel.isFocused)
|
||||
return Color.mPrimary;
|
||||
if (groupedContainer.workspaceModel.isUrgent)
|
||||
return Color.mError;
|
||||
if (groupedContainer.workspaceModel.isOccupied)
|
||||
return Color.mSecondary;
|
||||
|
||||
if (Settings.data.colorSchemes.darkMode) {
|
||||
return Qt.darker(Color.mSecondary, 1.5);
|
||||
} else {
|
||||
return Qt.lighter(Color.mSecondary, 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
scale: groupedContainer.workspaceModel.isActive ? 1.0 : 0.9
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutBack
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Burst effect overlay for focused workspace number
|
||||
Rectangle {
|
||||
id: groupedWorkspaceNumberBurst
|
||||
anchors.centerIn: groupedWorkspaceNumberContainer
|
||||
width: groupedWorkspaceNumberContainer.width + 12 * root.masterProgress
|
||||
height: groupedWorkspaceNumberContainer.height + 12 * root.masterProgress
|
||||
radius: width / 2
|
||||
color: Color.transparent
|
||||
border.color: root.effectColor
|
||||
border.width: Math.max(1, Math.round((2 + 4 * (1.0 - root.masterProgress))))
|
||||
opacity: root.effectsActive && groupedContainer.workspaceModel.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
|
||||
visible: root.effectsActive && groupedContainer.workspaceModel.isFocused
|
||||
z: 1
|
||||
}
|
||||
|
||||
NText {
|
||||
id: groupedWorkspaceNumber
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
text: {
|
||||
if (groupedContainer.workspaceModel.name && groupedContainer.workspaceModel.name.length > 0) {
|
||||
if (root.labelMode === "name") {
|
||||
return groupedContainer.workspaceModel.name.substring(0, root.characterCount);
|
||||
}
|
||||
if (root.labelMode === "index+name") {
|
||||
return (groupedContainer.workspaceModel.idx.toString() + groupedContainer.workspaceModel.name.substring(0, 1));
|
||||
}
|
||||
}
|
||||
return groupedContainer.workspaceModel.idx.toString();
|
||||
}
|
||||
|
||||
family: Settings.data.ui.fontFixed
|
||||
font {
|
||||
pointSize: Style.fontSizeXXS
|
||||
weight: Style.fontWeightBold
|
||||
capitalization: Font.AllUppercase
|
||||
}
|
||||
applyUiScale: false
|
||||
|
||||
color: {
|
||||
if (groupedContainer.workspaceModel.isFocused)
|
||||
return Color.mOnPrimary;
|
||||
if (groupedContainer.workspaceModel.isUrgent)
|
||||
return Color.mOnError;
|
||||
|
||||
return Color.mOnSecondary;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: groupedGrid
|
||||
visible: showApplications
|
||||
|
||||
anchors.verticalCenter: isVertical ? undefined : parent.verticalCenter
|
||||
anchors.left: isVertical ? undefined : parent.left
|
||||
anchors.leftMargin: isVertical ? 0 : Style.marginM
|
||||
anchors.horizontalCenter: isVertical ? parent.horizontalCenter : undefined
|
||||
anchors.top: isVertical ? parent.top : undefined
|
||||
anchors.topMargin: isVertical ? Style.marginM : 0
|
||||
|
||||
spacing: Style.marginS
|
||||
flow: isVertical ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
model: showApplications ? localWorkspaces : null
|
||||
delegate: groupedWorkspaceDelegate
|
||||
}
|
||||
}
|
||||
|
||||
function openGroupedContextMenu(item) {
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.open();
|
||||
|
||||
const globalPos = item.mapToItem(root, 0, 0);
|
||||
let menuX, menuY;
|
||||
if (root.barPosition === "top") {
|
||||
menuX = globalPos.x + (item.width / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = Style.barHeight + Style.marginS;
|
||||
} else if (root.barPosition === "bottom") {
|
||||
const menuHeight = 12 + contextMenu.model.length * contextMenu.itemHeight;
|
||||
menuX = globalPos.x + (item.width / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = -menuHeight - Style.marginS;
|
||||
} else if (root.barPosition === "left") {
|
||||
menuX = Style.barHeight + Style.marginS;
|
||||
menuY = globalPos.y + (item.height / 2) - (contextMenu.implicitHeight / 2);
|
||||
} else {
|
||||
menuX = -contextMenu.implicitWidth - Style.marginS;
|
||||
menuY = globalPos.y + (item.height / 2) - (contextMenu.implicitHeight / 2);
|
||||
}
|
||||
|
||||
contextMenu.openAtItem(root, menuX, menuY);
|
||||
popupMenuWindow.contentItem = contextMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import qs.Commons
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: Style.marginM
|
||||
|
||||
// Properties to receive data from parent
|
||||
property var widgetData: null
|
||||
property var widgetMetadata: null
|
||||
|
||||
property bool valueHideUnoccupied: widgetData.hideUnoccupied !== undefined ? widgetData.hideUnoccupied : widgetMetadata.hideUnoccupied
|
||||
property string valueLabelMode: widgetData.labelMode !== undefined ? widgetData.labelMode : widgetMetadata.labelMode
|
||||
property bool valueShowLabelsOnlyWhenOccupied: widgetData.showLabelsOnlyWhenOccupied !== undefined ? widgetData.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
|
||||
function saveSettings() {
|
||||
var settings = Object.assign({}, widgetData || {});
|
||||
|
||||
settings.hideUnoccupied = valueHideUnoccupied;
|
||||
settings.labelMode = valueLabelMode;
|
||||
settings.showLabelsOnlyWhenOccupied = valueShowLabelsOnlyWhenOccupied;
|
||||
settings.colorizeIcons = valueColorizeIcons;
|
||||
return settings;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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")
|
||||
},
|
||||
{
|
||||
"key": "index+name",
|
||||
"name": I18n.tr("options.workspace-labels.index+name")
|
||||
}
|
||||
]
|
||||
currentKey: widgetData.labelMode
|
||||
onSelected: key => valueLabelMode = key
|
||||
minimumWidth: 200
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.taskbar-grouped.show-labels-only-when-occupied.label")
|
||||
description: I18n.tr("bar.widget-settings.taskbar-grouped.show-labels-only-when-occupied.description")
|
||||
checked: root.valueShowLabelsOnlyWhenOccupied
|
||||
onToggled: checked => root.valueShowLabelsOnlyWhenOccupied = 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
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,20 @@ ColumnLayout {
|
||||
property bool valueFollowFocusedScreen: widgetData.followFocusedScreen !== undefined ? widgetData.followFocusedScreen : widgetMetadata.followFocusedScreen
|
||||
property int valueCharacterCount: widgetData.characterCount !== undefined ? widgetData.characterCount : widgetMetadata.characterCount
|
||||
|
||||
// Grouped mode settings
|
||||
property bool valueShowApplications: widgetData.showApplications !== undefined ? widgetData.showApplications : widgetMetadata.showApplications
|
||||
property bool valueShowLabelsOnlyWhenOccupied: widgetData.showLabelsOnlyWhenOccupied !== undefined ? widgetData.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
|
||||
function saveSettings() {
|
||||
var settings = Object.assign({}, widgetData || {});
|
||||
settings.labelMode = valueLabelMode;
|
||||
settings.hideUnoccupied = valueHideUnoccupied;
|
||||
settings.characterCount = valueCharacterCount;
|
||||
settings.followFocusedScreen = valueFollowFocusedScreen;
|
||||
settings.showApplications = valueShowApplications;
|
||||
settings.showLabelsOnlyWhenOccupied = valueShowLabelsOnlyWhenOccupied;
|
||||
settings.colorizeIcons = valueColorizeIcons;
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -53,20 +61,6 @@ ColumnLayout {
|
||||
minimumWidth: 200
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.workspace.follow-focused-screen.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.follow-focused-screen.description")
|
||||
checked: valueFollowFocusedScreen
|
||||
onToggled: checked => valueFollowFocusedScreen = checked
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
NSpinBox {
|
||||
label: I18n.tr("bar.widget-settings.workspace.character-count.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.character-count.description")
|
||||
@@ -76,4 +70,40 @@ ColumnLayout {
|
||||
onValueChanged: valueCharacterCount = value
|
||||
visible: valueLabelMode === "name"
|
||||
}
|
||||
|
||||
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 {
|
||||
label: I18n.tr("bar.widget-settings.workspace.show-labels-only-when-occupied.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.show-labels-only-when-occupied.description")
|
||||
checked: valueShowLabelsOnlyWhenOccupied
|
||||
onToggled: checked => valueShowLabelsOnlyWhenOccupied = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.workspace.follow-focused-screen.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.follow-focused-screen.description")
|
||||
checked: valueFollowFocusedScreen
|
||||
onToggled: checked => valueFollowFocusedScreen = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.workspace.show-applications.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.show-applications.description")
|
||||
checked: valueShowApplications
|
||||
onToggled: checked => valueShowApplications = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.active-window.colorize-icons.label")
|
||||
description: I18n.tr("bar.widget-settings.active-window.colorize-icons.description")
|
||||
checked: valueColorizeIcons
|
||||
onToggled: checked => valueColorizeIcons = checked
|
||||
visible: valueShowApplications
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ Singleton {
|
||||
"Spacer": spacerComponent,
|
||||
"SystemMonitor": systemMonitorComponent,
|
||||
"Taskbar": taskbarComponent,
|
||||
"TaskbarGrouped": taskbarGroupedComponent,
|
||||
"Tray": trayComponent,
|
||||
"Volume": volumeComponent,
|
||||
"VPN": vpnComponent,
|
||||
@@ -60,7 +59,6 @@ Singleton {
|
||||
"Spacer": "WidgetSettings/SpacerSettings.qml",
|
||||
"SystemMonitor": "WidgetSettings/SystemMonitorSettings.qml",
|
||||
"Taskbar": "WidgetSettings/TaskbarSettings.qml",
|
||||
"TaskbarGrouped": "WidgetSettings/TaskbarGroupedSettings.qml",
|
||||
"Tray": "WidgetSettings/TraySettings.qml",
|
||||
"Volume": "WidgetSettings/VolumeSettings.qml",
|
||||
"VPN": "WidgetSettings/VPNSettings.qml",
|
||||
@@ -211,13 +209,6 @@ Singleton {
|
||||
"smartWidth": true,
|
||||
"maxTaskbarWidth": 40
|
||||
},
|
||||
"TaskbarGrouped": {
|
||||
"allowUserSettings": true,
|
||||
"hideUnoccupied": false,
|
||||
"labelMode": "index",
|
||||
"showLabelsOnlyWhenOccupied": true,
|
||||
"colorizeIcons": false
|
||||
},
|
||||
"Tray": {
|
||||
"allowUserSettings": true,
|
||||
"blacklist": [],
|
||||
@@ -238,7 +229,10 @@ Singleton {
|
||||
"labelMode": "index",
|
||||
"followFocusedScreen": false,
|
||||
"hideUnoccupied": false,
|
||||
"characterCount": 2
|
||||
"characterCount": 2,
|
||||
"showApplications": false,
|
||||
"showLabelsOnlyWhenOccupied": true,
|
||||
"colorizeIcons": false
|
||||
},
|
||||
"Volume": {
|
||||
"allowUserSettings": true,
|
||||
@@ -334,10 +328,6 @@ Singleton {
|
||||
property Component taskbarComponent: Component {
|
||||
Taskbar {}
|
||||
}
|
||||
property Component taskbarGroupedComponent: Component {
|
||||
TaskbarGrouped {}
|
||||
}
|
||||
|
||||
function init() {
|
||||
Logger.i("BarWidgetRegistry", "Service started");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user