mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 15:32:50 -05:00
feat: Dock Overflow/Updated Settings Options
This commit is contained in:
@@ -17,40 +17,55 @@ Item {
|
||||
property int draggedIndex: -1
|
||||
property int dropTargetIndex: -1
|
||||
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
|
||||
implicitWidth: isVertical ? appLayout.height : appLayout.width
|
||||
implicitHeight: isVertical ? appLayout.width : appLayout.height
|
||||
|
||||
function dockIndexToPinnedIndex(dockIndex) {
|
||||
if (!SettingsData.dockLauncherEnabled) {
|
||||
if (!SettingsData.dockLauncherEnabled)
|
||||
return dockIndex;
|
||||
}
|
||||
|
||||
const launcherPos = SessionData.dockLauncherPosition;
|
||||
if (dockIndex < launcherPos) {
|
||||
return dockIndex;
|
||||
} else {
|
||||
return dockIndex - 1;
|
||||
}
|
||||
return dockIndex < launcherPos ? dockIndex : dockIndex - 1;
|
||||
}
|
||||
|
||||
function movePinnedApp(fromDockIndex, toDockIndex) {
|
||||
const fromPinnedIndex = dockIndexToPinnedIndex(fromDockIndex);
|
||||
const toPinnedIndex = dockIndexToPinnedIndex(toDockIndex);
|
||||
|
||||
if (fromPinnedIndex === toPinnedIndex) {
|
||||
if (fromPinnedIndex === toPinnedIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const movedApp = currentPinned.splice(fromPinnedIndex, 1)[0];
|
||||
currentPinned.splice(toPinnedIndex, 0, movedApp);
|
||||
|
||||
SessionData.setPinnedApps(currentPinned);
|
||||
}
|
||||
|
||||
@@ -94,13 +109,10 @@ Item {
|
||||
function getCoreAppData(appId) {
|
||||
if (typeof AppSearchService === "undefined")
|
||||
return null;
|
||||
|
||||
const coreApps = AppSearchService.coreApps || [];
|
||||
for (let i = 0; i < coreApps.length; i++) {
|
||||
const app = coreApps[i];
|
||||
if (app.builtInPluginId === appId) {
|
||||
return app;
|
||||
}
|
||||
if (coreApps[i].builtInPluginId === appId)
|
||||
return coreApps[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -108,21 +120,197 @@ Item {
|
||||
function getCoreAppDataByTitle(windowTitle) {
|
||||
if (typeof AppSearchService === "undefined" || !windowTitle)
|
||||
return null;
|
||||
|
||||
const coreApps = AppSearchService.coreApps || [];
|
||||
for (let i = 0; i < coreApps.length; i++) {
|
||||
const app = coreApps[i];
|
||||
if (app.name === windowTitle) {
|
||||
return app;
|
||||
}
|
||||
if (coreApps[i].name === windowTitle)
|
||||
return coreApps[i];
|
||||
}
|
||||
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) {
|
||||
if (!SettingsData.dockLauncherEnabled)
|
||||
return;
|
||||
|
||||
const launcherItem = {
|
||||
uniqueKey: "launcher_button",
|
||||
type: "launcher",
|
||||
@@ -131,187 +319,166 @@ Item {
|
||||
isPinned: true,
|
||||
isRunning: false
|
||||
};
|
||||
|
||||
const pos = Math.max(0, Math.min(SessionData.dockLauncherPosition, targetArray.length));
|
||||
targetArray.splice(pos, 0, launcherItem);
|
||||
}
|
||||
|
||||
function updateModel() {
|
||||
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;
|
||||
function createSeparator(key) {
|
||||
return {
|
||||
uniqueKey: key,
|
||||
type: "separator",
|
||||
appId: "__SEPARATOR__",
|
||||
toplevel: null,
|
||||
isPinned: false,
|
||||
isRunning: false
|
||||
};
|
||||
}
|
||||
|
||||
if (root.groupByApp) {
|
||||
const appGroups = new Map();
|
||||
function markAsOverflow(item) {
|
||||
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 => {
|
||||
const appId = Paths.moddedAppId(rawAppId);
|
||||
const coreAppData = getCoreAppData(appId);
|
||||
appGroups.set(appId, {
|
||||
appId: appId,
|
||||
isPinned: true,
|
||||
windows: [],
|
||||
isCoreApp: coreAppData !== null,
|
||||
coreAppData: coreAppData
|
||||
});
|
||||
});
|
||||
function markAsVisible(item) {
|
||||
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: false
|
||||
};
|
||||
}
|
||||
|
||||
sortedToplevels.forEach((toplevel, index) => {
|
||||
const rawAppId = toplevel.appId || "unknown";
|
||||
let appId = Paths.moddedAppId(rawAppId);
|
||||
function applyOverflow(baseResult) {
|
||||
const {
|
||||
items
|
||||
} = baseResult;
|
||||
const maxPinned = root.maxVisibleApps;
|
||||
const maxRunning = root.maxVisibleRunningApps;
|
||||
|
||||
let coreAppData = null;
|
||||
if (rawAppId === "org.quickshell") {
|
||||
coreAppData = getCoreAppDataByTitle(toplevel.title);
|
||||
if (coreAppData) {
|
||||
appId = coreAppData.builtInPluginId;
|
||||
const pinnedItems = items.filter(i => (i.type === "pinned" || i.type === "grouped" || i.type === "window") && i.isPinned && i.appId !== "__LAUNCHER__");
|
||||
const runningItems = items.filter(i => (i.type === "window" || i.type === "grouped") && i.isRunning && !i.isPinned);
|
||||
|
||||
const pinnedOverflow = maxPinned > 0 && pinnedItems.length > maxPinned;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unpinnedGroups.forEach(item => items.push(item));
|
||||
root.pinnedAppCount = pinnedGroups.length + (SettingsData.dockLauncherEnabled ? 1 : 0);
|
||||
} else {
|
||||
pinnedApps.forEach(rawAppId => {
|
||||
const appId = Paths.moddedAppId(rawAppId);
|
||||
const coreAppData = getCoreAppData(appId);
|
||||
items.push({
|
||||
uniqueKey: "pinned_" + appId,
|
||||
type: "pinned",
|
||||
appId: appId,
|
||||
toplevel: null,
|
||||
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
|
||||
});
|
||||
if (totalOverflow > 0) {
|
||||
const toggleIndex = finalItems.findIndex(i => i.type === "separator");
|
||||
const insertPos = toggleIndex >= 0 ? toggleIndex : finalItems.length;
|
||||
finalItems.splice(insertPos, 0, {
|
||||
uniqueKey: "overflow_toggle",
|
||||
type: "overflow-toggle",
|
||||
appId: "__OVERFLOW_TOGGLE__",
|
||||
toplevel: null,
|
||||
isPinned: false,
|
||||
isRunning: false,
|
||||
overflowCount: totalOverflow
|
||||
});
|
||||
}
|
||||
|
||||
dockItems = items;
|
||||
return finalItems;
|
||||
}
|
||||
|
||||
function updateModel() {
|
||||
const baseResult = buildBaseItems();
|
||||
dockItems = applyOverflow(baseResult);
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
id: delegateItem
|
||||
|
||||
property var dockButton: itemData.type === "launcher" ? launcherButton : button
|
||||
property var itemData: modelData
|
||||
readonly property bool isOverflowToggle: itemData.type === "overflow-toggle"
|
||||
readonly property bool isInOverflow: itemData.isInOverflow === true
|
||||
|
||||
clip: false
|
||||
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)
|
||||
height: itemData.type === "separator" ? (root.isVertical ? 8 : root.iconSize) : (root.isVertical ? root.iconSize * 1.2 : root.iconSize)
|
||||
width: (isInOverflow && !root.overflowExpanded) ? 0 : (itemData.type === "separator" ? (root.isVertical ? root.iconSize : 8) : (root.isVertical ? root.iconSize : root.iconSize * 1.2))
|
||||
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: {
|
||||
if (root.draggedIndex < 0 || !itemData.isPinned || itemData.type === "separator")
|
||||
@@ -363,34 +530,42 @@ Item {
|
||||
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 {
|
||||
id: launcherButton
|
||||
visible: itemData.type === "launcher"
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: delegateItem.width
|
||||
height: delegateItem.height
|
||||
actualIconSize: root.iconSize
|
||||
|
||||
dockApps: root
|
||||
index: model.index
|
||||
}
|
||||
|
||||
DockAppButton {
|
||||
id: button
|
||||
visible: itemData.type !== "separator" && itemData.type !== "launcher"
|
||||
visible: !isOverflowToggle && itemData.type !== "separator" && itemData.type !== "launcher"
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: delegateItem.width
|
||||
height: delegateItem.height
|
||||
actualIconSize: root.iconSize
|
||||
|
||||
appData: itemData
|
||||
contextMenu: root.contextMenu
|
||||
dockApps: root
|
||||
index: model.index
|
||||
parentDockScreen: root.dockScreen
|
||||
|
||||
showWindowTitle: itemData?.type === "window" || itemData?.type === "grouped"
|
||||
windowTitle: {
|
||||
const title = itemData?.toplevel?.title || "(Unnamed)";
|
||||
@@ -420,10 +595,17 @@ Item {
|
||||
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 {
|
||||
target: SettingsData
|
||||
function onDockIsolateDisplaysChanged() {
|
||||
@@ -438,18 +620,13 @@ Item {
|
||||
root.suppressShiftAnimation = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SessionData
|
||||
function onDockLauncherPositionChanged() {
|
||||
root.suppressShiftAnimation = true;
|
||||
root.draggedIndex = -1;
|
||||
root.dropTargetIndex = -1;
|
||||
function onDockMaxVisibleAppsChanged() {
|
||||
repeater.updateModel();
|
||||
}
|
||||
function onDockMaxVisibleRunningAppsChanged() {
|
||||
repeater.updateModel();
|
||||
Qt.callLater(() => {
|
||||
root.suppressShiftAnimation = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onGroupByAppChanged: repeater.updateModel()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user