mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-29 16:02:51 -05:00
feat: Dock Overflow/Updated Settings Options
This commit is contained in:
@@ -443,6 +443,9 @@ Singleton {
|
|||||||
property int dockLauncherLogoSizeOffset: 0
|
property int dockLauncherLogoSizeOffset: 0
|
||||||
property real dockLauncherLogoBrightness: 0.5
|
property real dockLauncherLogoBrightness: 0.5
|
||||||
property real dockLauncherLogoContrast: 1
|
property real dockLauncherLogoContrast: 1
|
||||||
|
property int dockMaxVisibleApps: 0
|
||||||
|
property int dockMaxVisibleRunningApps: 0
|
||||||
|
property bool dockShowOverflowBadge: true
|
||||||
|
|
||||||
property bool notificationOverlayEnabled: false
|
property bool notificationOverlayEnabled: false
|
||||||
property int overviewRows: 2
|
property int overviewRows: 2
|
||||||
|
|||||||
@@ -272,6 +272,9 @@ var SPEC = {
|
|||||||
dockLauncherLogoSizeOffset: { def: 0 },
|
dockLauncherLogoSizeOffset: { def: 0 },
|
||||||
dockLauncherLogoBrightness: { def: 0.5, coerce: percentToUnit },
|
dockLauncherLogoBrightness: { def: 0.5, coerce: percentToUnit },
|
||||||
dockLauncherLogoContrast: { def: 1, coerce: percentToUnit },
|
dockLauncherLogoContrast: { def: 1, coerce: percentToUnit },
|
||||||
|
dockMaxVisibleApps: { def: 0 },
|
||||||
|
dockMaxVisibleRunningApps: { def: 0 },
|
||||||
|
dockShowOverflowBadge: { def: true },
|
||||||
|
|
||||||
notificationOverlayEnabled: { def: false },
|
notificationOverlayEnabled: { def: false },
|
||||||
overviewRows: { def: 2, persist: false },
|
overviewRows: { def: 2, persist: false },
|
||||||
|
|||||||
@@ -379,13 +379,17 @@ Variants {
|
|||||||
if (!dock.isVertical) {
|
if (!dock.isVertical) {
|
||||||
const isBottom = SettingsData.dockPosition === SettingsData.Position.Bottom;
|
const isBottom = SettingsData.dockPosition === SettingsData.Position.Bottom;
|
||||||
const globalX = buttonGlobalPos.x + dock.hoveredButton.width / 2 + adjacentLeftBarWidth;
|
const globalX = buttonGlobalPos.x + dock.hoveredButton.width / 2 + adjacentLeftBarWidth;
|
||||||
const screenRelativeY = isBottom ? (screenHeight - dock.effectiveBarHeight - SettingsData.dockSpacing - SettingsData.dockBottomGap - SettingsData.dockMargin - barSpacing - 35) : (buttonGlobalPos.y - screenY + dock.hoveredButton.height + Theme.spacingS);
|
const tooltipHeight = 32;
|
||||||
|
const tooltipOffset = dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin + barSpacing + Theme.spacingM;
|
||||||
|
const screenRelativeY = isBottom
|
||||||
|
? (screenHeight - tooltipOffset - tooltipHeight)
|
||||||
|
: tooltipOffset;
|
||||||
dockTooltip.show(tooltipText, globalX, screenRelativeY, dock.screen, false, false);
|
dockTooltip.show(tooltipText, globalX, screenRelativeY, dock.screen, false, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLeft = SettingsData.dockPosition === SettingsData.Position.Left;
|
const isLeft = SettingsData.dockPosition === SettingsData.Position.Left;
|
||||||
const tooltipOffset = dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockMargin + barSpacing + Theme.spacingXS;
|
const tooltipOffset = dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin + barSpacing + Theme.spacingM;
|
||||||
const tooltipX = isLeft ? tooltipOffset : (dock.screen.width - tooltipOffset);
|
const tooltipX = isLeft ? tooltipOffset : (dock.screen.width - tooltipOffset);
|
||||||
const screenRelativeY = buttonGlobalPos.y - screenY + dock.hoveredButton.height / 2 + adjacentTopBarHeight;
|
const screenRelativeY = buttonGlobalPos.y - screenY + dock.hoveredButton.height / 2 + adjacentTopBarHeight;
|
||||||
dockTooltip.show(tooltipText, screenX + tooltipX, screenRelativeY, dock.screen, isLeft, !isLeft);
|
dockTooltip.show(tooltipText, screenX + tooltipX, screenRelativeY, dock.screen, isLeft, !isLeft);
|
||||||
@@ -437,21 +441,19 @@ Variants {
|
|||||||
|
|
||||||
height: {
|
height: {
|
||||||
if (dock.isVertical) {
|
if (dock.isVertical) {
|
||||||
const extra = 4 + dock.borderThickness;
|
if (!dock.reveal)
|
||||||
const hiddenHeight = Math.min(Math.max(dockBackground.implicitHeight + 64, 200), screenHeight * 0.5);
|
return Math.min(Math.max(dockBackground.height + 64, 200), screenHeight * 0.5);
|
||||||
return dock.reveal ? Math.max(Math.min(dockBackground.implicitHeight + extra, maxDockHeight), hiddenHeight) : hiddenHeight;
|
return Math.min(dockBackground.height + 8 + dock.borderThickness, maxDockHeight);
|
||||||
} else {
|
|
||||||
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1;
|
|
||||||
}
|
}
|
||||||
|
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1;
|
||||||
}
|
}
|
||||||
width: {
|
width: {
|
||||||
if (dock.isVertical) {
|
if (dock.isVertical) {
|
||||||
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1;
|
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1;
|
||||||
} else {
|
|
||||||
const extra = 4 + dock.borderThickness;
|
|
||||||
const hiddenWidth = Math.min(Math.max(dockBackground.implicitWidth + 64, 200), screenWidth * 0.5);
|
|
||||||
return dock.reveal ? Math.max(Math.min(dockBackground.implicitWidth + extra, maxDockWidth), hiddenWidth) : hiddenWidth;
|
|
||||||
}
|
}
|
||||||
|
if (!dock.reveal)
|
||||||
|
return Math.min(Math.max(dockBackground.width + 64, 200), screenWidth * 0.5);
|
||||||
|
return Math.min(dockBackground.width + 8 + dock.borderThickness, maxDockWidth);
|
||||||
}
|
}
|
||||||
anchors {
|
anchors {
|
||||||
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? undefined : parent.top) : undefined
|
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? undefined : parent.top) : undefined
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ Item {
|
|||||||
property bool showTooltip: mouseArea.containsMouse && !dragging
|
property bool showTooltip: mouseArea.containsMouse && !dragging
|
||||||
property var cachedDesktopEntry: null
|
property var cachedDesktopEntry: null
|
||||||
property real actualIconSize: 40
|
property real actualIconSize: 40
|
||||||
|
property bool shouldShowIndicator: {
|
||||||
|
if (!appData)
|
||||||
|
return false;
|
||||||
|
if (appData.type === "window")
|
||||||
|
return true;
|
||||||
|
if (appData.type === "grouped")
|
||||||
|
return appData.windowCount > 0;
|
||||||
|
return appData.isRunning;
|
||||||
|
}
|
||||||
readonly property string coreIconColorOverride: SettingsData.dockLauncherLogoColorOverride
|
readonly property string coreIconColorOverride: SettingsData.dockLauncherLogoColorOverride
|
||||||
readonly property bool coreIconHasCustomColor: coreIconColorOverride !== "" && coreIconColorOverride !== "primary" && coreIconColorOverride !== "surface"
|
readonly property bool coreIconHasCustomColor: coreIconColorOverride !== "" && coreIconColorOverride !== "primary" && coreIconColorOverride !== "surface"
|
||||||
readonly property color effectiveCoreIconColor: {
|
readonly property color effectiveCoreIconColor: {
|
||||||
@@ -206,7 +215,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
enabled: true
|
enabled: true
|
||||||
preventStealing: true
|
preventStealing: dragging || longPressing
|
||||||
cursorShape: longPressing ? Qt.DragMoveCursor : Qt.PointingHandCursor
|
cursorShape: longPressing ? Qt.DragMoveCursor : Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
@@ -295,7 +304,7 @@ Item {
|
|||||||
groupedToplevel.activate();
|
groupedToplevel.activate();
|
||||||
} else if (contextMenu) {
|
} else if (contextMenu) {
|
||||||
const shouldHidePin = appData.appId === "org.quickshell";
|
const shouldHidePin = appData.appId === "org.quickshell";
|
||||||
contextMenu.showForButton(root, appData, root.height + 25, shouldHidePin, cachedDesktopEntry, parentDockScreen);
|
contextMenu.showForButton(root, appData, root.height + 25, shouldHidePin, cachedDesktopEntry, parentDockScreen, dockApps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -342,7 +351,7 @@ Item {
|
|||||||
case "grouped":
|
case "grouped":
|
||||||
if (contextMenu) {
|
if (contextMenu) {
|
||||||
const shouldHidePin = appData.appId === "org.quickshell";
|
const shouldHidePin = appData.appId === "org.quickshell";
|
||||||
contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen);
|
contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen, dockApps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -365,7 +374,7 @@ Item {
|
|||||||
if (!contextMenu)
|
if (!contextMenu)
|
||||||
return;
|
return;
|
||||||
const shouldHidePin = appData.appId === "org.quickshell";
|
const shouldHidePin = appData.appId === "org.quickshell";
|
||||||
contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen);
|
contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen, dockApps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,15 +507,7 @@ Item {
|
|||||||
|
|
||||||
sourceComponent: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? columnIndicator : rowIndicator
|
sourceComponent: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? columnIndicator : rowIndicator
|
||||||
|
|
||||||
visible: {
|
visible: root.shouldShowIndicator
|
||||||
if (!appData)
|
|
||||||
return false;
|
|
||||||
if (appData.type === "window")
|
|
||||||
return true;
|
|
||||||
if (appData.type === "grouped")
|
|
||||||
return appData.windowCount > 0;
|
|
||||||
return appData.isRunning;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,40 +17,55 @@ Item {
|
|||||||
property int draggedIndex: -1
|
property int draggedIndex: -1
|
||||||
property int dropTargetIndex: -1
|
property int dropTargetIndex: -1
|
||||||
property bool suppressShiftAnimation: false
|
property bool suppressShiftAnimation: false
|
||||||
|
property int maxVisibleApps: SettingsData.dockMaxVisibleApps
|
||||||
|
property int maxVisibleRunningApps: SettingsData.dockMaxVisibleRunningApps
|
||||||
|
property bool overflowExpanded: false
|
||||||
|
property int overflowItemCount: 0
|
||||||
|
|
||||||
|
readonly property real baseImplicitWidth: isVertical ? baseAppHeight : baseAppWidth
|
||||||
|
readonly property real baseImplicitHeight: isVertical ? baseAppWidth : baseAppHeight
|
||||||
|
readonly property real baseAppWidth: {
|
||||||
|
let count = 0;
|
||||||
|
const items = repeater.dockItems;
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
if (item.isInOverflow)
|
||||||
|
continue;
|
||||||
|
if (item.type === "separator") {
|
||||||
|
count += 8 / (iconSize * 1.2);
|
||||||
|
} else {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count * (iconSize * 1.2) + Math.max(0, count - 1) * layoutFlow.spacing;
|
||||||
|
}
|
||||||
|
readonly property real baseAppHeight: iconSize
|
||||||
|
|
||||||
clip: false
|
clip: false
|
||||||
implicitWidth: isVertical ? appLayout.height : appLayout.width
|
implicitWidth: isVertical ? appLayout.height : appLayout.width
|
||||||
implicitHeight: isVertical ? appLayout.width : appLayout.height
|
implicitHeight: isVertical ? appLayout.width : appLayout.height
|
||||||
|
|
||||||
function dockIndexToPinnedIndex(dockIndex) {
|
function dockIndexToPinnedIndex(dockIndex) {
|
||||||
if (!SettingsData.dockLauncherEnabled) {
|
if (!SettingsData.dockLauncherEnabled)
|
||||||
return dockIndex;
|
return dockIndex;
|
||||||
}
|
|
||||||
|
|
||||||
const launcherPos = SessionData.dockLauncherPosition;
|
const launcherPos = SessionData.dockLauncherPosition;
|
||||||
if (dockIndex < launcherPos) {
|
return dockIndex < launcherPos ? dockIndex : dockIndex - 1;
|
||||||
return dockIndex;
|
|
||||||
} else {
|
|
||||||
return dockIndex - 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function movePinnedApp(fromDockIndex, toDockIndex) {
|
function movePinnedApp(fromDockIndex, toDockIndex) {
|
||||||
const fromPinnedIndex = dockIndexToPinnedIndex(fromDockIndex);
|
const fromPinnedIndex = dockIndexToPinnedIndex(fromDockIndex);
|
||||||
const toPinnedIndex = dockIndexToPinnedIndex(toDockIndex);
|
const toPinnedIndex = dockIndexToPinnedIndex(toDockIndex);
|
||||||
|
|
||||||
if (fromPinnedIndex === toPinnedIndex) {
|
if (fromPinnedIndex === toPinnedIndex)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const currentPinned = [...(SessionData.pinnedApps || [])];
|
const currentPinned = [...(SessionData.pinnedApps || [])];
|
||||||
if (fromPinnedIndex < 0 || fromPinnedIndex >= currentPinned.length || toPinnedIndex < 0 || toPinnedIndex >= currentPinned.length) {
|
if (fromPinnedIndex < 0 || fromPinnedIndex >= currentPinned.length || toPinnedIndex < 0 || toPinnedIndex >= currentPinned.length)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const movedApp = currentPinned.splice(fromPinnedIndex, 1)[0];
|
const movedApp = currentPinned.splice(fromPinnedIndex, 1)[0];
|
||||||
currentPinned.splice(toPinnedIndex, 0, movedApp);
|
currentPinned.splice(toPinnedIndex, 0, movedApp);
|
||||||
|
|
||||||
SessionData.setPinnedApps(currentPinned);
|
SessionData.setPinnedApps(currentPinned);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,13 +109,10 @@ Item {
|
|||||||
function getCoreAppData(appId) {
|
function getCoreAppData(appId) {
|
||||||
if (typeof AppSearchService === "undefined")
|
if (typeof AppSearchService === "undefined")
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const coreApps = AppSearchService.coreApps || [];
|
const coreApps = AppSearchService.coreApps || [];
|
||||||
for (let i = 0; i < coreApps.length; i++) {
|
for (let i = 0; i < coreApps.length; i++) {
|
||||||
const app = coreApps[i];
|
if (coreApps[i].builtInPluginId === appId)
|
||||||
if (app.builtInPluginId === appId) {
|
return coreApps[i];
|
||||||
return app;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -108,21 +120,197 @@ Item {
|
|||||||
function getCoreAppDataByTitle(windowTitle) {
|
function getCoreAppDataByTitle(windowTitle) {
|
||||||
if (typeof AppSearchService === "undefined" || !windowTitle)
|
if (typeof AppSearchService === "undefined" || !windowTitle)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const coreApps = AppSearchService.coreApps || [];
|
const coreApps = AppSearchService.coreApps || [];
|
||||||
for (let i = 0; i < coreApps.length; i++) {
|
for (let i = 0; i < coreApps.length; i++) {
|
||||||
const app = coreApps[i];
|
if (coreApps[i].name === windowTitle)
|
||||||
if (app.name === windowTitle) {
|
return coreApps[i];
|
||||||
return app;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildBaseItems() {
|
||||||
|
const items = [];
|
||||||
|
const pinnedApps = [...(SessionData.pinnedApps || [])];
|
||||||
|
const allToplevels = CompositorService.sortedToplevels;
|
||||||
|
const sortedToplevels = (SettingsData.dockIsolateDisplays && root.dockScreen) ? allToplevels.filter(t => isOnScreen(t, root.dockScreen.name)) : allToplevels;
|
||||||
|
|
||||||
|
if (root.groupByApp) {
|
||||||
|
return buildGroupedItems(pinnedApps, sortedToplevels);
|
||||||
|
}
|
||||||
|
return buildUngroupedItems(pinnedApps, sortedToplevels);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildGroupedItems(pinnedApps, sortedToplevels) {
|
||||||
|
const items = [];
|
||||||
|
const appGroups = new Map();
|
||||||
|
|
||||||
|
pinnedApps.forEach(rawAppId => {
|
||||||
|
const appId = Paths.moddedAppId(rawAppId);
|
||||||
|
const coreAppData = getCoreAppData(appId);
|
||||||
|
appGroups.set(appId, {
|
||||||
|
appId: appId,
|
||||||
|
isPinned: true,
|
||||||
|
windows: [],
|
||||||
|
isCoreApp: coreAppData !== null,
|
||||||
|
coreAppData: coreAppData
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
sortedToplevels.forEach((toplevel, index) => {
|
||||||
|
const rawAppId = toplevel.appId || "unknown";
|
||||||
|
let appId = Paths.moddedAppId(rawAppId);
|
||||||
|
let coreAppData = null;
|
||||||
|
|
||||||
|
if (rawAppId === "org.quickshell") {
|
||||||
|
coreAppData = getCoreAppDataByTitle(toplevel.title);
|
||||||
|
if (coreAppData)
|
||||||
|
appId = coreAppData.builtInPluginId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!appGroups.has(appId)) {
|
||||||
|
appGroups.set(appId, {
|
||||||
|
appId: appId,
|
||||||
|
isPinned: false,
|
||||||
|
windows: [],
|
||||||
|
isCoreApp: coreAppData !== null,
|
||||||
|
coreAppData: coreAppData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
appGroups.get(appId).windows.push({
|
||||||
|
toplevel: toplevel,
|
||||||
|
index: index
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const pinnedGroups = [];
|
||||||
|
const unpinnedGroups = [];
|
||||||
|
|
||||||
|
appGroups.forEach((group, appId) => {
|
||||||
|
const firstWindow = group.windows.length > 0 ? group.windows[0] : null;
|
||||||
|
const item = {
|
||||||
|
uniqueKey: "grouped_" + appId,
|
||||||
|
type: "grouped",
|
||||||
|
appId: appId,
|
||||||
|
toplevel: firstWindow ? firstWindow.toplevel : null,
|
||||||
|
isPinned: group.isPinned,
|
||||||
|
isRunning: group.windows.length > 0,
|
||||||
|
windowCount: group.windows.length,
|
||||||
|
allWindows: group.windows,
|
||||||
|
isCoreApp: group.isCoreApp || false,
|
||||||
|
coreAppData: group.coreAppData || null,
|
||||||
|
isInOverflow: false
|
||||||
|
};
|
||||||
|
(group.isPinned ? pinnedGroups : unpinnedGroups).push(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
pinnedGroups.forEach(item => items.push(item));
|
||||||
|
insertLauncher(items);
|
||||||
|
|
||||||
|
if (pinnedGroups.length > 0 && unpinnedGroups.length > 0) {
|
||||||
|
items.push(createSeparator("separator_grouped"));
|
||||||
|
}
|
||||||
|
unpinnedGroups.forEach(item => items.push(item));
|
||||||
|
|
||||||
|
root.pinnedAppCount = pinnedGroups.length + (SettingsData.dockLauncherEnabled ? 1 : 0);
|
||||||
|
return {
|
||||||
|
items,
|
||||||
|
pinnedCount: pinnedGroups.length,
|
||||||
|
runningCount: unpinnedGroups.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildUngroupedItems(pinnedApps, sortedToplevels) {
|
||||||
|
const items = [];
|
||||||
|
const runningAppIds = new Set();
|
||||||
|
const windowItems = [];
|
||||||
|
|
||||||
|
sortedToplevels.forEach((toplevel, index) => {
|
||||||
|
let uniqueKey = "window_" + index;
|
||||||
|
if (CompositorService.isHyprland && Hyprland.toplevels) {
|
||||||
|
const hyprlandToplevels = Array.from(Hyprland.toplevels.values);
|
||||||
|
for (let i = 0; i < hyprlandToplevels.length; i++) {
|
||||||
|
if (hyprlandToplevels[i].wayland === toplevel) {
|
||||||
|
uniqueKey = "window_" + hyprlandToplevels[i].address;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawAppId = toplevel.appId || "unknown";
|
||||||
|
const moddedAppId = Paths.moddedAppId(rawAppId);
|
||||||
|
let coreAppData = null;
|
||||||
|
let isCoreApp = false;
|
||||||
|
|
||||||
|
if (rawAppId === "org.quickshell") {
|
||||||
|
coreAppData = getCoreAppDataByTitle(toplevel.title);
|
||||||
|
if (coreAppData)
|
||||||
|
isCoreApp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalAppId = isCoreApp ? coreAppData.builtInPluginId : moddedAppId;
|
||||||
|
windowItems.push({
|
||||||
|
uniqueKey: uniqueKey,
|
||||||
|
type: "window",
|
||||||
|
appId: finalAppId,
|
||||||
|
toplevel: toplevel,
|
||||||
|
isPinned: false,
|
||||||
|
isRunning: true,
|
||||||
|
isCoreApp: isCoreApp,
|
||||||
|
coreAppData: coreAppData,
|
||||||
|
isInOverflow: false
|
||||||
|
});
|
||||||
|
runningAppIds.add(finalAppId);
|
||||||
|
});
|
||||||
|
|
||||||
|
const remainingWindowItems = windowItems.slice();
|
||||||
|
|
||||||
|
pinnedApps.forEach(rawAppId => {
|
||||||
|
const appId = Paths.moddedAppId(rawAppId);
|
||||||
|
const coreAppData = getCoreAppData(appId);
|
||||||
|
const matchIndex = remainingWindowItems.findIndex(item => item.appId === appId);
|
||||||
|
|
||||||
|
if (matchIndex !== -1) {
|
||||||
|
const windowItem = remainingWindowItems.splice(matchIndex, 1)[0];
|
||||||
|
windowItem.isPinned = true;
|
||||||
|
windowItem.uniqueKey = "pinned_" + appId;
|
||||||
|
if (!windowItem.isCoreApp && coreAppData) {
|
||||||
|
windowItem.isCoreApp = true;
|
||||||
|
windowItem.coreAppData = coreAppData;
|
||||||
|
}
|
||||||
|
items.push(windowItem);
|
||||||
|
} else {
|
||||||
|
items.push({
|
||||||
|
uniqueKey: "pinned_" + appId,
|
||||||
|
type: "pinned",
|
||||||
|
appId: appId,
|
||||||
|
toplevel: null,
|
||||||
|
isPinned: true,
|
||||||
|
isRunning: runningAppIds.has(appId),
|
||||||
|
isCoreApp: coreAppData !== null,
|
||||||
|
coreAppData: coreAppData,
|
||||||
|
isInOverflow: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
root.pinnedAppCount = pinnedApps.length + (SettingsData.dockLauncherEnabled ? 1 : 0);
|
||||||
|
insertLauncher(items);
|
||||||
|
|
||||||
|
if (pinnedApps.length > 0 && remainingWindowItems.length > 0) {
|
||||||
|
items.push(createSeparator("separator_ungrouped"));
|
||||||
|
}
|
||||||
|
remainingWindowItems.forEach(item => items.push(item));
|
||||||
|
|
||||||
|
return {
|
||||||
|
items,
|
||||||
|
pinnedCount: pinnedApps.length,
|
||||||
|
runningCount: remainingWindowItems.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function insertLauncher(targetArray) {
|
function insertLauncher(targetArray) {
|
||||||
if (!SettingsData.dockLauncherEnabled)
|
if (!SettingsData.dockLauncherEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const launcherItem = {
|
const launcherItem = {
|
||||||
uniqueKey: "launcher_button",
|
uniqueKey: "launcher_button",
|
||||||
type: "launcher",
|
type: "launcher",
|
||||||
@@ -131,187 +319,166 @@ Item {
|
|||||||
isPinned: true,
|
isPinned: true,
|
||||||
isRunning: false
|
isRunning: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const pos = Math.max(0, Math.min(SessionData.dockLauncherPosition, targetArray.length));
|
const pos = Math.max(0, Math.min(SessionData.dockLauncherPosition, targetArray.length));
|
||||||
targetArray.splice(pos, 0, launcherItem);
|
targetArray.splice(pos, 0, launcherItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateModel() {
|
function createSeparator(key) {
|
||||||
const items = [];
|
return {
|
||||||
const pinnedApps = [...(SessionData.pinnedApps || [])];
|
uniqueKey: key,
|
||||||
const allToplevels = CompositorService.sortedToplevels;
|
type: "separator",
|
||||||
const sortedToplevels = (SettingsData.dockIsolateDisplays && root.dockScreen) ? allToplevels.filter(t => isOnScreen(t, root.dockScreen.name)) : allToplevels;
|
appId: "__SEPARATOR__",
|
||||||
|
toplevel: null,
|
||||||
|
isPinned: false,
|
||||||
|
isRunning: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (root.groupByApp) {
|
function markAsOverflow(item) {
|
||||||
const appGroups = new Map();
|
return {
|
||||||
|
uniqueKey: item.uniqueKey,
|
||||||
|
type: item.type,
|
||||||
|
appId: item.appId,
|
||||||
|
toplevel: item.toplevel,
|
||||||
|
isPinned: item.isPinned,
|
||||||
|
isRunning: item.isRunning,
|
||||||
|
windowCount: item.windowCount,
|
||||||
|
allWindows: item.allWindows,
|
||||||
|
isCoreApp: item.isCoreApp,
|
||||||
|
coreAppData: item.coreAppData,
|
||||||
|
isInOverflow: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pinnedApps.forEach(rawAppId => {
|
function markAsVisible(item) {
|
||||||
const appId = Paths.moddedAppId(rawAppId);
|
return {
|
||||||
const coreAppData = getCoreAppData(appId);
|
uniqueKey: item.uniqueKey,
|
||||||
appGroups.set(appId, {
|
type: item.type,
|
||||||
appId: appId,
|
appId: item.appId,
|
||||||
isPinned: true,
|
toplevel: item.toplevel,
|
||||||
windows: [],
|
isPinned: item.isPinned,
|
||||||
isCoreApp: coreAppData !== null,
|
isRunning: item.isRunning,
|
||||||
coreAppData: coreAppData
|
windowCount: item.windowCount,
|
||||||
});
|
allWindows: item.allWindows,
|
||||||
});
|
isCoreApp: item.isCoreApp,
|
||||||
|
coreAppData: item.coreAppData,
|
||||||
|
isInOverflow: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
sortedToplevels.forEach((toplevel, index) => {
|
function applyOverflow(baseResult) {
|
||||||
const rawAppId = toplevel.appId || "unknown";
|
const {
|
||||||
let appId = Paths.moddedAppId(rawAppId);
|
items
|
||||||
|
} = baseResult;
|
||||||
|
const maxPinned = root.maxVisibleApps;
|
||||||
|
const maxRunning = root.maxVisibleRunningApps;
|
||||||
|
|
||||||
let coreAppData = null;
|
const pinnedItems = items.filter(i => (i.type === "pinned" || i.type === "grouped" || i.type === "window") && i.isPinned && i.appId !== "__LAUNCHER__");
|
||||||
if (rawAppId === "org.quickshell") {
|
const runningItems = items.filter(i => (i.type === "window" || i.type === "grouped") && i.isRunning && !i.isPinned);
|
||||||
coreAppData = getCoreAppDataByTitle(toplevel.title);
|
|
||||||
if (coreAppData) {
|
const pinnedOverflow = maxPinned > 0 && pinnedItems.length > maxPinned;
|
||||||
appId = coreAppData.builtInPluginId;
|
const runningOverflow = maxRunning > 0 && runningItems.length > maxRunning;
|
||||||
|
|
||||||
|
if (!pinnedOverflow && !runningOverflow) {
|
||||||
|
root.overflowItemCount = 0;
|
||||||
|
return items.map(i => markAsVisible(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
const visiblePinnedKeys = new Set(pinnedOverflow ? pinnedItems.slice(0, maxPinned).map(i => i.uniqueKey) : pinnedItems.map(i => i.uniqueKey));
|
||||||
|
const visibleRunningKeys = new Set(runningOverflow ? runningItems.slice(0, maxRunning).map(i => i.uniqueKey) : runningItems.map(i => i.uniqueKey));
|
||||||
|
|
||||||
|
const overflowPinnedCount = pinnedOverflow ? pinnedItems.length - maxPinned : 0;
|
||||||
|
const overflowRunningCount = runningOverflow ? runningItems.length - maxRunning : 0;
|
||||||
|
const totalOverflow = overflowPinnedCount + overflowRunningCount;
|
||||||
|
root.overflowItemCount = totalOverflow;
|
||||||
|
|
||||||
|
const finalItems = [];
|
||||||
|
let addedSeparator = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
switch (item.type) {
|
||||||
|
case "launcher":
|
||||||
|
finalItems.push(item);
|
||||||
|
break;
|
||||||
|
case "separator":
|
||||||
|
break;
|
||||||
|
case "pinned":
|
||||||
|
case "grouped":
|
||||||
|
case "window":
|
||||||
|
if (item.isPinned && item.appId !== "__LAUNCHER__") {
|
||||||
|
if (visiblePinnedKeys.has(item.uniqueKey)) {
|
||||||
|
finalItems.push(markAsVisible(item));
|
||||||
|
} else {
|
||||||
|
finalItems.push(markAsOverflow(item));
|
||||||
|
}
|
||||||
|
} else if (item.isRunning && !item.isPinned) {
|
||||||
|
if (!addedSeparator && finalItems.length > 0) {
|
||||||
|
finalItems.push(createSeparator("separator_overflow"));
|
||||||
|
addedSeparator = true;
|
||||||
|
}
|
||||||
|
if (visibleRunningKeys.has(item.uniqueKey)) {
|
||||||
|
finalItems.push(markAsVisible(item));
|
||||||
|
} else {
|
||||||
|
finalItems.push(markAsOverflow(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if (!appGroups.has(appId)) {
|
|
||||||
appGroups.set(appId, {
|
|
||||||
appId: appId,
|
|
||||||
isPinned: false,
|
|
||||||
windows: [],
|
|
||||||
isCoreApp: coreAppData !== null,
|
|
||||||
coreAppData: coreAppData
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
appGroups.get(appId).windows.push({
|
|
||||||
toplevel: toplevel,
|
|
||||||
index: index
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const pinnedGroups = [];
|
|
||||||
const unpinnedGroups = [];
|
|
||||||
|
|
||||||
Array.from(appGroups.entries()).forEach(([appId, group]) => {
|
|
||||||
const firstWindow = group.windows.length > 0 ? group.windows[0] : null;
|
|
||||||
|
|
||||||
const item = {
|
|
||||||
uniqueKey: "grouped_" + appId,
|
|
||||||
type: "grouped",
|
|
||||||
appId: appId,
|
|
||||||
toplevel: firstWindow ? firstWindow.toplevel : null,
|
|
||||||
isPinned: group.isPinned,
|
|
||||||
isRunning: group.windows.length > 0,
|
|
||||||
windowCount: group.windows.length,
|
|
||||||
allWindows: group.windows,
|
|
||||||
isCoreApp: group.isCoreApp || false,
|
|
||||||
coreAppData: group.coreAppData || null
|
|
||||||
};
|
|
||||||
|
|
||||||
if (group.isPinned) {
|
|
||||||
pinnedGroups.push(item);
|
|
||||||
} else {
|
|
||||||
unpinnedGroups.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
pinnedGroups.forEach(item => items.push(item));
|
|
||||||
|
|
||||||
insertLauncher(items);
|
|
||||||
|
|
||||||
if (pinnedGroups.length > 0 && unpinnedGroups.length > 0) {
|
|
||||||
items.push({
|
|
||||||
uniqueKey: "separator_grouped",
|
|
||||||
type: "separator",
|
|
||||||
appId: "__SEPARATOR__",
|
|
||||||
toplevel: null,
|
|
||||||
isPinned: false,
|
|
||||||
isRunning: false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unpinnedGroups.forEach(item => items.push(item));
|
if (totalOverflow > 0) {
|
||||||
root.pinnedAppCount = pinnedGroups.length + (SettingsData.dockLauncherEnabled ? 1 : 0);
|
const toggleIndex = finalItems.findIndex(i => i.type === "separator");
|
||||||
} else {
|
const insertPos = toggleIndex >= 0 ? toggleIndex : finalItems.length;
|
||||||
pinnedApps.forEach(rawAppId => {
|
finalItems.splice(insertPos, 0, {
|
||||||
const appId = Paths.moddedAppId(rawAppId);
|
uniqueKey: "overflow_toggle",
|
||||||
const coreAppData = getCoreAppData(appId);
|
type: "overflow-toggle",
|
||||||
items.push({
|
appId: "__OVERFLOW_TOGGLE__",
|
||||||
uniqueKey: "pinned_" + appId,
|
toplevel: null,
|
||||||
type: "pinned",
|
isPinned: false,
|
||||||
appId: appId,
|
isRunning: false,
|
||||||
toplevel: null,
|
overflowCount: totalOverflow
|
||||||
isPinned: true,
|
|
||||||
isRunning: false,
|
|
||||||
isCoreApp: coreAppData !== null,
|
|
||||||
coreAppData: coreAppData
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
root.pinnedAppCount = pinnedApps.length + (SettingsData.dockLauncherEnabled ? 1 : 0);
|
|
||||||
|
|
||||||
insertLauncher(items);
|
|
||||||
|
|
||||||
if (pinnedApps.length > 0 && sortedToplevels.length > 0) {
|
|
||||||
items.push({
|
|
||||||
uniqueKey: "separator_ungrouped",
|
|
||||||
type: "separator",
|
|
||||||
appId: "__SEPARATOR__",
|
|
||||||
toplevel: null,
|
|
||||||
isPinned: false,
|
|
||||||
isRunning: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sortedToplevels.forEach((toplevel, index) => {
|
|
||||||
let uniqueKey = "window_" + index;
|
|
||||||
if (CompositorService.isHyprland && Hyprland.toplevels) {
|
|
||||||
const hyprlandToplevels = Array.from(Hyprland.toplevels.values);
|
|
||||||
for (let i = 0; i < hyprlandToplevels.length; i++) {
|
|
||||||
if (hyprlandToplevels[i].wayland === toplevel) {
|
|
||||||
uniqueKey = "window_" + hyprlandToplevels[i].address;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rawAppId = toplevel.appId || "unknown";
|
|
||||||
const moddedAppId = Paths.moddedAppId(rawAppId);
|
|
||||||
|
|
||||||
// Check if this is a core app window (e.g., Settings modal with appId "org.quickshell")
|
|
||||||
let coreAppData = null;
|
|
||||||
let isCoreApp = false;
|
|
||||||
if (rawAppId === "org.quickshell") {
|
|
||||||
coreAppData = getCoreAppDataByTitle(toplevel.title);
|
|
||||||
if (coreAppData) {
|
|
||||||
isCoreApp = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const finalAppId = isCoreApp ? coreAppData.builtInPluginId : moddedAppId;
|
|
||||||
const isPinned = pinnedApps.indexOf(finalAppId) !== -1;
|
|
||||||
|
|
||||||
items.push({
|
|
||||||
uniqueKey: uniqueKey,
|
|
||||||
type: "window",
|
|
||||||
appId: finalAppId,
|
|
||||||
toplevel: toplevel,
|
|
||||||
isPinned: isPinned,
|
|
||||||
isRunning: true,
|
|
||||||
isCoreApp: isCoreApp,
|
|
||||||
coreAppData: coreAppData
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dockItems = items;
|
return finalItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModel() {
|
||||||
|
const baseResult = buildBaseItems();
|
||||||
|
dockItems = applyOverflow(baseResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: delegateItem
|
id: delegateItem
|
||||||
|
|
||||||
property var dockButton: itemData.type === "launcher" ? launcherButton : button
|
property var dockButton: itemData.type === "launcher" ? launcherButton : button
|
||||||
property var itemData: modelData
|
property var itemData: modelData
|
||||||
|
readonly property bool isOverflowToggle: itemData.type === "overflow-toggle"
|
||||||
|
readonly property bool isInOverflow: itemData.isInOverflow === true
|
||||||
|
|
||||||
clip: false
|
clip: false
|
||||||
z: (itemData.type === "launcher" ? launcherButton.dragging : button.dragging) ? 100 : 0
|
z: (itemData.type === "launcher" ? launcherButton.dragging : button.dragging) ? 100 : 0
|
||||||
|
visible: !isInOverflow || root.overflowExpanded
|
||||||
|
opacity: (isInOverflow && !root.overflowExpanded) ? 0 : 1
|
||||||
|
scale: (isInOverflow && !root.overflowExpanded) ? 0.8 : 1
|
||||||
|
|
||||||
width: itemData.type === "separator" ? (root.isVertical ? root.iconSize : 8) : (root.isVertical ? root.iconSize : root.iconSize * 1.2)
|
width: (isInOverflow && !root.overflowExpanded) ? 0 : (itemData.type === "separator" ? (root.isVertical ? root.iconSize : 8) : (root.isVertical ? root.iconSize : root.iconSize * 1.2))
|
||||||
height: itemData.type === "separator" ? (root.isVertical ? 8 : root.iconSize) : (root.isVertical ? root.iconSize * 1.2 : root.iconSize)
|
height: (isInOverflow && !root.overflowExpanded) ? 0 : (itemData.type === "separator" ? (root.isVertical ? 8 : root.iconSize) : (root.isVertical ? root.iconSize * 1.2 : root.iconSize))
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property real shiftOffset: {
|
property real shiftOffset: {
|
||||||
if (root.draggedIndex < 0 || !itemData.isPinned || itemData.type === "separator")
|
if (root.draggedIndex < 0 || !itemData.isPinned || itemData.type === "separator")
|
||||||
@@ -363,34 +530,42 @@ Item {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DockOverflowButton {
|
||||||
|
id: overflowButton
|
||||||
|
visible: isOverflowToggle
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: delegateItem.width
|
||||||
|
height: delegateItem.height
|
||||||
|
actualIconSize: root.iconSize
|
||||||
|
overflowCount: itemData.overflowCount || 0
|
||||||
|
overflowExpanded: root.overflowExpanded
|
||||||
|
isVertical: root.isVertical
|
||||||
|
onClicked: root.overflowExpanded = !root.overflowExpanded
|
||||||
|
}
|
||||||
|
|
||||||
DockLauncherButton {
|
DockLauncherButton {
|
||||||
id: launcherButton
|
id: launcherButton
|
||||||
visible: itemData.type === "launcher"
|
visible: itemData.type === "launcher"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
width: delegateItem.width
|
width: delegateItem.width
|
||||||
height: delegateItem.height
|
height: delegateItem.height
|
||||||
actualIconSize: root.iconSize
|
actualIconSize: root.iconSize
|
||||||
|
|
||||||
dockApps: root
|
dockApps: root
|
||||||
index: model.index
|
index: model.index
|
||||||
}
|
}
|
||||||
|
|
||||||
DockAppButton {
|
DockAppButton {
|
||||||
id: button
|
id: button
|
||||||
visible: itemData.type !== "separator" && itemData.type !== "launcher"
|
visible: !isOverflowToggle && itemData.type !== "separator" && itemData.type !== "launcher"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
width: delegateItem.width
|
width: delegateItem.width
|
||||||
height: delegateItem.height
|
height: delegateItem.height
|
||||||
actualIconSize: root.iconSize
|
actualIconSize: root.iconSize
|
||||||
|
|
||||||
appData: itemData
|
appData: itemData
|
||||||
contextMenu: root.contextMenu
|
contextMenu: root.contextMenu
|
||||||
dockApps: root
|
dockApps: root
|
||||||
index: model.index
|
index: model.index
|
||||||
parentDockScreen: root.dockScreen
|
parentDockScreen: root.dockScreen
|
||||||
|
|
||||||
showWindowTitle: itemData?.type === "window" || itemData?.type === "grouped"
|
showWindowTitle: itemData?.type === "window" || itemData?.type === "grouped"
|
||||||
windowTitle: {
|
windowTitle: {
|
||||||
const title = itemData?.toplevel?.title || "(Unnamed)";
|
const title = itemData?.toplevel?.title || "(Unnamed)";
|
||||||
@@ -420,10 +595,17 @@ Item {
|
|||||||
root.suppressShiftAnimation = false;
|
root.suppressShiftAnimation = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function onDockLauncherPositionChanged() {
|
||||||
|
root.suppressShiftAnimation = true;
|
||||||
|
root.draggedIndex = -1;
|
||||||
|
root.dropTargetIndex = -1;
|
||||||
|
repeater.updateModel();
|
||||||
|
Qt.callLater(() => {
|
||||||
|
root.suppressShiftAnimation = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onGroupByAppChanged: repeater.updateModel()
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onDockIsolateDisplaysChanged() {
|
function onDockIsolateDisplaysChanged() {
|
||||||
@@ -438,18 +620,13 @@ Item {
|
|||||||
root.suppressShiftAnimation = false;
|
root.suppressShiftAnimation = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
function onDockMaxVisibleAppsChanged() {
|
||||||
|
repeater.updateModel();
|
||||||
Connections {
|
}
|
||||||
target: SessionData
|
function onDockMaxVisibleRunningAppsChanged() {
|
||||||
function onDockLauncherPositionChanged() {
|
|
||||||
root.suppressShiftAnimation = true;
|
|
||||||
root.draggedIndex = -1;
|
|
||||||
root.dropTargetIndex = -1;
|
|
||||||
repeater.updateModel();
|
repeater.updateModel();
|
||||||
Qt.callLater(() => {
|
|
||||||
root.suppressShiftAnimation = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onGroupByAppChanged: repeater.updateModel()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -19,22 +18,24 @@ PanelWindow {
|
|||||||
property bool hidePin: false
|
property bool hidePin: false
|
||||||
property var desktopEntry: null
|
property var desktopEntry: null
|
||||||
property bool isDmsWindow: appData?.appId === "org.quickshell"
|
property bool isDmsWindow: appData?.appId === "org.quickshell"
|
||||||
|
property var dockApps: null
|
||||||
|
|
||||||
function showForButton(button, data, dockHeight, hidePinOption, entry, dockScreen) {
|
function showForButton(button, data, dockHeight, hidePinOption, entry, dockScreen, parentDockApps) {
|
||||||
if (dockScreen) {
|
if (dockScreen) {
|
||||||
root.screen = dockScreen
|
root.screen = dockScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
anchorItem = button
|
anchorItem = button;
|
||||||
appData = data
|
appData = data;
|
||||||
dockVisibleHeight = dockHeight || 40
|
dockVisibleHeight = dockHeight || 40;
|
||||||
hidePin = hidePinOption || false
|
hidePin = hidePinOption || false;
|
||||||
desktopEntry = entry || null
|
desktopEntry = entry || null;
|
||||||
|
dockApps = parentDockApps || null;
|
||||||
|
|
||||||
visible = true
|
visible = true;
|
||||||
}
|
}
|
||||||
function close() {
|
function close() {
|
||||||
visible = false
|
visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen: null
|
screen: null
|
||||||
@@ -55,110 +56,110 @@ PanelWindow {
|
|||||||
onAnchorItemChanged: updatePosition()
|
onAnchorItemChanged: updatePosition()
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
updatePosition()
|
updatePosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePosition() {
|
function updatePosition() {
|
||||||
if (!anchorItem) {
|
if (!anchorItem) {
|
||||||
anchorPos = Qt.point(screen.width / 2, screen.height - 100)
|
anchorPos = Qt.point(screen.width / 2, screen.height - 100);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dockWindow = anchorItem.Window.window
|
const dockWindow = anchorItem.Window.window;
|
||||||
if (!dockWindow) {
|
if (!dockWindow) {
|
||||||
anchorPos = Qt.point(screen.width / 2, screen.height - 100)
|
anchorPos = Qt.point(screen.width / 2, screen.height - 100);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonPosInDock = anchorItem.mapToItem(dockWindow.contentItem, 0, 0)
|
const buttonPosInDock = anchorItem.mapToItem(dockWindow.contentItem, 0, 0);
|
||||||
let actualDockHeight = root.dockVisibleHeight
|
let actualDockHeight = root.dockVisibleHeight;
|
||||||
|
|
||||||
function findDockBackground(item) {
|
function findDockBackground(item) {
|
||||||
if (item.objectName === "dockBackground") {
|
if (item.objectName === "dockBackground") {
|
||||||
return item
|
return item;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < item.children.length; i++) {
|
for (var i = 0; i < item.children.length; i++) {
|
||||||
const found = findDockBackground(item.children[i])
|
const found = findDockBackground(item.children[i]);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dockBackground = findDockBackground(dockWindow.contentItem)
|
const dockBackground = findDockBackground(dockWindow.contentItem);
|
||||||
let actualDockWidth = dockWindow.width
|
let actualDockWidth = dockWindow.width;
|
||||||
if (dockBackground) {
|
if (dockBackground) {
|
||||||
actualDockHeight = dockBackground.height
|
actualDockHeight = dockBackground.height;
|
||||||
actualDockWidth = dockBackground.width
|
actualDockWidth = dockBackground.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right;
|
||||||
const dockMargin = SettingsData.dockMargin + 16
|
const dockMargin = SettingsData.dockMargin + 16;
|
||||||
let buttonScreenX, buttonScreenY
|
let buttonScreenX, buttonScreenY;
|
||||||
|
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
const dockContentHeight = dockWindow.height
|
const dockContentHeight = dockWindow.height;
|
||||||
const screenHeight = root.screen.height
|
const screenHeight = root.screen.height;
|
||||||
const dockTopMargin = Math.round((screenHeight - dockContentHeight) / 2)
|
const dockTopMargin = Math.round((screenHeight - dockContentHeight) / 2);
|
||||||
buttonScreenY = dockTopMargin + buttonPosInDock.y + anchorItem.height / 2
|
buttonScreenY = dockTopMargin + buttonPosInDock.y + anchorItem.height / 2;
|
||||||
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Right) {
|
if (SettingsData.dockPosition === SettingsData.Position.Right) {
|
||||||
buttonScreenX = root.screen.width - actualDockWidth - dockMargin - 20
|
buttonScreenX = root.screen.width - actualDockWidth - dockMargin - 20;
|
||||||
} else {
|
} else {
|
||||||
buttonScreenX = actualDockWidth + dockMargin + 20
|
buttonScreenX = actualDockWidth + dockMargin + 20;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom
|
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom;
|
||||||
|
|
||||||
if (isDockAtBottom) {
|
if (isDockAtBottom) {
|
||||||
buttonScreenY = root.screen.height - actualDockHeight - dockMargin - 20
|
buttonScreenY = root.screen.height - actualDockHeight - dockMargin - 20;
|
||||||
} else {
|
} else {
|
||||||
buttonScreenY = actualDockHeight + dockMargin + 20
|
buttonScreenY = actualDockHeight + dockMargin + 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dockContentWidth = dockWindow.width
|
const dockContentWidth = dockWindow.width;
|
||||||
const screenWidth = root.screen.width
|
const screenWidth = root.screen.width;
|
||||||
const dockLeftMargin = Math.round((screenWidth - dockContentWidth) / 2)
|
const dockLeftMargin = Math.round((screenWidth - dockContentWidth) / 2);
|
||||||
buttonScreenX = dockLeftMargin + buttonPosInDock.x + anchorItem.width / 2
|
buttonScreenX = dockLeftMargin + buttonPosInDock.x + anchorItem.width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
anchorPos = Qt.point(buttonScreenX, buttonScreenY)
|
anchorPos = Qt.point(buttonScreenX, buttonScreenY);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: menuContainer
|
id: menuContainer
|
||||||
|
|
||||||
x: {
|
x: {
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right;
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
const isDockAtRight = SettingsData.dockPosition === SettingsData.Position.Right
|
const isDockAtRight = SettingsData.dockPosition === SettingsData.Position.Right;
|
||||||
if (isDockAtRight) {
|
if (isDockAtRight) {
|
||||||
return Math.max(10, root.anchorPos.x - width + 30)
|
return Math.max(10, root.anchorPos.x - width + 30);
|
||||||
} else {
|
} else {
|
||||||
return Math.min(root.width - width - 10, root.anchorPos.x - 30)
|
return Math.min(root.width - width - 10, root.anchorPos.x - 30);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const left = 10
|
const left = 10;
|
||||||
const right = root.width - width - 10
|
const right = root.width - width - 10;
|
||||||
const want = root.anchorPos.x - width / 2
|
const want = root.anchorPos.x - width / 2;
|
||||||
return Math.max(left, Math.min(right, want))
|
return Math.max(left, Math.min(right, want));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y: {
|
y: {
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right;
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
const top = 10
|
const top = 10;
|
||||||
const bottom = root.height - height - 10
|
const bottom = root.height - height - 10;
|
||||||
const want = root.anchorPos.y - height / 2
|
const want = root.anchorPos.y - height / 2;
|
||||||
return Math.max(top, Math.min(bottom, want))
|
return Math.max(top, Math.min(bottom, want));
|
||||||
} else {
|
} else {
|
||||||
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom
|
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom;
|
||||||
if (isDockAtBottom) {
|
if (isDockAtBottom) {
|
||||||
return Math.max(10, root.anchorPos.y - height + 30)
|
return Math.max(10, root.anchorPos.y - height + 30);
|
||||||
} else {
|
} else {
|
||||||
return Math.min(root.height - height - 10, root.anchorPos.y - 30)
|
return Math.min(root.height - height - 10, root.anchorPos.y - 30);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,17 +203,18 @@ PanelWindow {
|
|||||||
// Window list for grouped apps
|
// Window list for grouped apps
|
||||||
Repeater {
|
Repeater {
|
||||||
model: {
|
model: {
|
||||||
if (!root.appData || root.appData.type !== "grouped") return []
|
if (!root.appData || root.appData.type !== "grouped")
|
||||||
|
return [];
|
||||||
|
|
||||||
const toplevels = []
|
const toplevels = [];
|
||||||
const allToplevels = ToplevelManager.toplevels.values
|
const allToplevels = ToplevelManager.toplevels.values;
|
||||||
for (let i = 0; i < allToplevels.length; i++) {
|
for (let i = 0; i < allToplevels.length; i++) {
|
||||||
const toplevel = allToplevels[i]
|
const toplevel = allToplevels[i];
|
||||||
if (toplevel.appId === root.appData.appId) {
|
if (toplevel.appId === root.appData.appId) {
|
||||||
toplevels.push(toplevel)
|
toplevels.push(toplevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toplevels
|
return toplevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -227,7 +229,7 @@ PanelWindow {
|
|||||||
anchors.right: closeButton.left
|
anchors.right: closeButton.left
|
||||||
anchors.rightMargin: Theme.spacingXS
|
anchors.rightMargin: Theme.spacingXS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: (modelData && modelData.title) ? modelData.title: I18n.tr("(Unnamed)")
|
text: (modelData && modelData.title) ? modelData.title : I18n.tr("(Unnamed)")
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
@@ -259,9 +261,9 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData && modelData.close) {
|
if (modelData && modelData.close) {
|
||||||
modelData.close()
|
modelData.close();
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,9 +276,9 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData && modelData.activate) {
|
if (modelData && modelData.activate) {
|
||||||
modelData.activate()
|
modelData.activate();
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,9 +286,11 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: {
|
visible: {
|
||||||
if (!root.appData) return false
|
if (!root.appData)
|
||||||
if (root.appData.type !== "grouped") return false
|
return false;
|
||||||
return root.appData.windowCount > 0
|
if (root.appData.type !== "grouped")
|
||||||
|
return false;
|
||||||
|
return root.appData.windowCount > 0;
|
||||||
}
|
}
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
@@ -343,9 +347,9 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData) {
|
if (modelData) {
|
||||||
SessionService.launchDesktopAction(root.desktopEntry, modelData)
|
SessionService.launchDesktopAction(root.desktopEntry, modelData);
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,9 +358,9 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
visible: {
|
visible: {
|
||||||
if (!root.desktopEntry?.actions || root.desktopEntry.actions.length === 0) {
|
if (!root.desktopEntry?.actions || root.desktopEntry.actions.length === 0) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
return !root.hidePin || (!root.isDmsWindow && root.desktopEntry && SessionService.nvidiaCommand)
|
return !root.hidePin || (!root.isDmsWindow && root.desktopEntry && SessionService.nvidiaCommand);
|
||||||
}
|
}
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
@@ -390,26 +394,26 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!root.appData) {
|
if (!root.appData)
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
if (root.appData.isPinned) {
|
if (root.appData.isPinned) {
|
||||||
SessionData.removePinnedApp(root.appData.appId)
|
SessionData.removePinnedApp(root.appData.appId);
|
||||||
} else {
|
} else {
|
||||||
SessionData.addPinnedApp(root.appData.appId)
|
SessionData.addPinnedApp(root.appData.appId);
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: {
|
visible: {
|
||||||
const hasNvidia = !root.isDmsWindow && root.desktopEntry && SessionService.nvidiaCommand
|
const hasNvidia = !root.isDmsWindow && root.desktopEntry && SessionService.nvidiaCommand;
|
||||||
const hasWindow = root.appData && (root.appData.type === "window" || (root.appData.type === "grouped" && root.appData.windowCount > 0))
|
const hasWindow = root.appData && (root.appData.type === "window" || (root.appData.type === "grouped" && root.appData.windowCount > 0));
|
||||||
const hasPinOption = !root.hidePin
|
const hasPinOption = !root.hidePin;
|
||||||
const hasContentAbove = hasPinOption || hasNvidia
|
const hasContentAbove = hasPinOption || hasNvidia;
|
||||||
return hasContentAbove && hasWindow
|
return hasContentAbove && hasWindow;
|
||||||
}
|
}
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
@@ -444,9 +448,9 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.desktopEntry) {
|
if (root.desktopEntry) {
|
||||||
SessionService.launchDesktopEntry(root.desktopEntry, true)
|
SessionService.launchDesktopEntry(root.desktopEntry, true);
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,9 +470,9 @@ PanelWindow {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: {
|
text: {
|
||||||
if (root.appData && root.appData.type === "grouped") {
|
if (root.appData && root.appData.type === "grouped") {
|
||||||
return "Close All Windows"
|
return "Close All Windows";
|
||||||
}
|
}
|
||||||
return "Close Window"
|
return "Close Window";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: closeArea.containsMouse ? Theme.error : Theme.surfaceText
|
color: closeArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||||
@@ -484,11 +488,11 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.appData?.type === "window") {
|
if (root.appData?.type === "window") {
|
||||||
root.appData?.toplevel?.close()
|
root.appData?.toplevel?.close();
|
||||||
} else if (root.appData?.type === "grouped") {
|
} else if (root.appData?.type === "grouped") {
|
||||||
root.appData?.allWindows?.forEach(window => window.toplevel?.close())
|
root.appData?.allWindows?.forEach(window => window.toplevel?.close());
|
||||||
}
|
}
|
||||||
root.close()
|
root.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
enabled: true
|
enabled: true
|
||||||
preventStealing: true
|
preventStealing: dragging || longPressing
|
||||||
cursorShape: longPressing ? Qt.DragMoveCursor : Qt.PointingHandCursor
|
cursorShape: longPressing ? Qt.DragMoveCursor : Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
|
|||||||
75
quickshell/Modules/Dock/DockOverflowButton.qml
Normal file
75
quickshell/Modules/Dock/DockOverflowButton.qml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real actualIconSize: 40
|
||||||
|
property int overflowCount: 0
|
||||||
|
property bool overflowExpanded: false
|
||||||
|
property bool isVertical: false
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonBackground
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: actualIconSize
|
||||||
|
height: actualIconSize
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, mouseArea.containsMouse ? 0.2 : 0.1)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
id: arrowIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
size: actualIconSize * 0.6
|
||||||
|
name: "expand_more"
|
||||||
|
color: Theme.surfaceText
|
||||||
|
rotation: isVertical ? (overflowExpanded ? 180 : 0) : (overflowExpanded ? 90 : -90)
|
||||||
|
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: overflowCount > 0 && !overflowExpanded && SettingsData.dockShowOverflowBadge
|
||||||
|
anchors.right: buttonBackground.right
|
||||||
|
anchors.top: buttonBackground.top
|
||||||
|
anchors.rightMargin: -4
|
||||||
|
anchors.topMargin: -4
|
||||||
|
width: Math.max(18, badgeText.width + 8)
|
||||||
|
height: 18
|
||||||
|
radius: 9
|
||||||
|
color: Theme.primary
|
||||||
|
z: 10
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: badgeText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: `+${overflowCount}`
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.onPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: root.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -162,6 +162,39 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
settingKey: "dockMaxVisibleApps"
|
||||||
|
tags: ["dock", "overflow", "max", "apps", "limit"]
|
||||||
|
text: I18n.tr("Max Pinned Apps (0 = Unlimited)")
|
||||||
|
minimum: 0
|
||||||
|
maximum: 30
|
||||||
|
value: SettingsData.dockMaxVisibleApps
|
||||||
|
defaultValue: 0
|
||||||
|
unit: ""
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("dockMaxVisibleApps", newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
settingKey: "dockMaxVisibleRunningApps"
|
||||||
|
tags: ["dock", "overflow", "max", "running", "apps", "limit"]
|
||||||
|
text: I18n.tr("Max Running Apps (0 = Unlimited)")
|
||||||
|
minimum: 0
|
||||||
|
maximum: 30
|
||||||
|
value: SettingsData.dockMaxVisibleRunningApps
|
||||||
|
defaultValue: 0
|
||||||
|
unit: ""
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("dockMaxVisibleRunningApps", newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "dockShowOverflowBadge"
|
||||||
|
tags: ["dock", "overflow", "badge", "count", "indicator"]
|
||||||
|
text: I18n.tr("Show Overflow Badge Count")
|
||||||
|
description: I18n.tr("Displays count when overflow is active")
|
||||||
|
checked: SettingsData.dockShowOverflowBadge
|
||||||
|
onToggled: checked => SettingsData.set("dockShowOverflowBadge", checked)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
|||||||
Reference in New Issue
Block a user