diff --git a/src/apps/components/shell/Shell/Taskbar/OpenedApps.svelte b/src/apps/components/shell/Shell/Taskbar/OpenedApps.svelte index 88f21176..6ca94df0 100755 --- a/src/apps/components/shell/Shell/Taskbar/OpenedApps.svelte +++ b/src/apps/components/shell/Shell/Taskbar/OpenedApps.svelte @@ -3,17 +3,122 @@ import { Daemon, Stack } from "$ts/env"; import { ProcessesHelper } from "$ts/helpers/processes"; import { isPopulatable } from "$ts/util/apps"; + import { draggable } from "@neodrag/svelte"; import OpenedApp from "./OpenedApps/OpenedApp.svelte"; + import type { IProcess } from "$interfaces/IProcess"; + import { flip } from "svelte/animate"; const { process }: { process: IShellRuntime } = $props(); const { userPreferences } = process; const { store } = Stack; + + function shouldShow(openedProcess: IProcess) { + return ( + ProcessesHelper.IsAnyGraphicalAppProcess(openedProcess) && + !openedProcess._disposed && + (isPopulatable(openedProcess.app.data) || openedProcess.overridePopulatable) && + (!$userPreferences.shell.taskbar.openedAppsPerWorkspace || + Daemon?.workspaces?.getDesktopIndexByUuid(openedProcess.app.desktop || "") === $userPreferences.workspaces.index) + ); + } + + let positions = $state>(new Map()); + let tabs = $state>(new Map()); + + // get any exisiting processes + // just in case + store() + .entries() + .forEach(([pid, process]) => { + if (shouldShow(process)) { + tabs.set(pid, process); + } + }); + + store.subscribe((v) => { + if (tabs.size === v.size) return; + + // add new processes + + v.entries().forEach(([pid, process]) => { + if (!tabs.keys().toArray().includes(pid) && shouldShow(process)) { + tabs.set(pid, process); + positions.set(pid, { x: 0, y: 0 }); + } + }); + + // remove dead processes + + tabs = new Map( + [...tabs.entries()].filter(([pid]) => { + return v.keys().toArray().includes(pid); + }) + ); + + positions = new Map( + [...positions.entries()].filter(([pid]) => { + return v.keys().toArray().includes(pid); + }) + ); + }); + + function getPos(pid: number) { + if (!positions.has(pid)) { + positions.set(pid, { x: 0, y: 0 }); + } + return positions.get(pid)!; + }
- {#each [...$store] as [pid, openedProcess] (pid)} - {#if ProcessesHelper.IsAnyGraphicalAppProcess(openedProcess) && !openedProcess._disposed && (isPopulatable(openedProcess.app.data) || openedProcess.overridePopulatable) && (!$userPreferences.shell.taskbar.openedAppsPerWorkspace || Daemon?.workspaces?.getDesktopIndexByUuid(openedProcess.app.desktop || "") === $userPreferences.workspaces.index)} + {#each [...tabs] as [pid, openedProcess] (pid)} +
= 0 ? Math.floor(iconDragDist) : Math.ceil(iconDragDist); + const iconGridDragDist = + Math.abs(iconDragDist) - Math.abs(iconDragDistRounded) >= movementActuationDistance + ? iconDragDist < 0 + ? iconDragDistRounded - 1 + : iconDragDistRounded + 1 + : iconDragDistRounded; + + const currentEntryIdx = tabs + .keys() + .toArray() + .findIndex((val) => { + return val === pid; + }); + + const currentEntry = tabs.entries().toArray().at(currentEntryIdx); + if (!currentEntry) return; + + // begin repositioning + + const entries = [...tabs]; + entries.splice(currentEntryIdx, 1); + entries.splice(currentEntryIdx + iconGridDragDist, 0, currentEntry); + tabs = new Map(entries); + + // force reset position so it's not visually offset + positions.set(pid, { x: 0, y: 0 }); + }, + }} + > - {/if} +
{/each}
diff --git a/src/css/apps/components/shell/taskbar/openedapps.css b/src/css/apps/components/shell/taskbar/openedapps.css index 9cc5f083..eba4e594 100755 --- a/src/css/apps/components/shell/taskbar/openedapps.css +++ b/src/css/apps/components/shell/taskbar/openedapps.css @@ -15,8 +15,12 @@ div.shell div.taskbar div.opened-apps::-webkit-scrollbar { width: 1px; } -#arcShell div.shell div.taskbar div.opened-apps button { +#arcShell div.shell div.taskbar div.opened-apps div.drag-container { display: inline-flex; +} + +#arcShell div.shell div.taskbar div.opened-apps button { + display: flex; max-width: 180px; align-items: center; gap: 10px; @@ -52,7 +56,7 @@ div.shell div.taskbar div.opened-apps::-webkit-scrollbar { transform-origin: left; } -#arcShell div.shell div.taskbar div.opened-apps button.iconic.closing + button { +#arcShell div.shell div.taskbar div.opened-apps button.iconic.closing+button { margin-left: -40px; transition: margin-left 0.3s, @@ -71,7 +75,7 @@ div.shell div.taskbar div.opened-apps::-webkit-scrollbar { white-space: nowrap; } -#arcShell div.shell div.taskbar div.opened-apps button + button { +#arcShell div.shell div.taskbar div.opened-apps div:has(button)+div:has(button) { margin-left: 5px; } @@ -104,10 +108,12 @@ div.shell div.taskbar div.opened-apps button:hover img.backdrop { #arcShell div.shell div.taskbar button.start-button.active { background-color: var(--button-glass-active-bg); } + #arcShell div.shell div.taskbar div.opened-apps button { outline: var(--shell-component-outline) 1px solid !important; outline-offset: -1px; } + div.shell div.taskbar div.opened-apps button.active img.backdrop { opacity: 0.5; filter: brightness(1.3) blur(7px); @@ -122,7 +128,7 @@ div.shell div.taskbar div.opened-apps button.active img.backdrop { opacity: 0.7; } -#arcShell > div.body div.taskbar button.opened-app.blinking { +#arcShell>div.body div.taskbar button.opened-app.blinking { animation: blinking 0.7s infinite alternate; } @@ -130,4 +136,4 @@ div.shell div.taskbar div.opened-apps button.active img.backdrop { to { background-color: var(--clr-orange-fg); } -} +} \ No newline at end of file