Show folder names immediately and refresh stale index sizes without walking the whole drive.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-26 11:21:20 +02:00
parent 6fc7506eb7
commit e2916aef9c
88 changed files with 5373 additions and 544 deletions

View File

@@ -839,7 +839,7 @@ Bitte diese Punkte klären. Empfohlene Defaults in Klammern:
## Hintergrundprozess: Explorer.Host.exe
Indexing, USN/watchers, transfer queue, hash worker, and history rollup run in **`Explorer.Host.exe`**, not in the WPF window.
Indexing, USN/watchers, transfer queue, hash worker, and history rollup run in **`Explorer.Host.exe`**, not in the WPF window. Idle-aware background maintenance is coordinated there as well (`GetLastInputInfo` / power status — no WPF dependency).
| | Explorer.Host.exe (current) | Windows Service |
|---|---|---|
@@ -893,7 +893,7 @@ Deviations from the design above, with reasons:
3. **WPF-UI (lepoco)** — not used. Light/Dark Fluent-style brushes live in `Themes/Dark.xaml` and `Themes/Light.xaml` so the UI toolkit stays replaceable.
4. **`PRAGMA mmap_size` / large `cache_size`** — not applied at runtime. They made SQLite native startup unreliable under concurrent test hosts; WAL + `synchronous=NORMAL` remain.
5. **App data folder**`%LocalAppData%\ExplorerWorkbench` (not `Explorer`) so the working name does not collide with Windows Explorer.
6. **Background work** — indexer, transfer queue, hash worker, history rollup, and watchers run as `IHostedService` instances inside **`Explorer.Host.exe`**. The WPF window is a named-pipe client (`Explorer.Hosting.Client`) with a read-only SQLite store. No Windows Service; optional current-user sign-in (`HKCU\Software\Microsoft\Windows\CurrentVersion\Run`).
6. **Background work** — indexer, transfer queue, hash worker, and watchers run as `IHostedService` instances inside **`Explorer.Host.exe`**. `BackgroundMaintenanceCoordinator` is the one extra 1s timer: it uses `IUserIdleMonitor` / `BackgroundWorkPolicy` to pause or resume duplicate hashing, enqueue at most one idle local full scan (`IndexWorkOrigin.Idle`, distinct from user/watcher/USN work), and call `HistoryRollupService` (no longer its own hosted loop). Copy/move/delete and explicit scans are never idle work. The WPF window is a named-pipe client (`Explorer.Hosting.Client`) with a read-only SQLite store. No Windows Service; optional current-user sign-in (`HKCU\Software\Microsoft\Windows\CurrentVersion\Run`).
7. **Search syntax** — structured `SearchQuery` exists; Everything-like lexer is not shipped (Phase 7).
8. **UNIQUE identity**`UNIQUE (source_id, ifnull(parent_id,-1), name_norm)` because SQLite UNIQUE treats NULLs as distinct.
9. **INSERT ids**`Microsoft.Data.Sqlite` + Dapper `ExecuteScalarAsync` on `INSERT … RETURNING` leaves the write connection busy and hangs the next command. Writer-connection SQL uses `SqliteCommand` (`SqliteExec`) and `last_insert_rowid()`.
@@ -901,4 +901,6 @@ Deviations from the design above, with reasons:
11. **Schema apply** — Microsoft.Data.Sqlite/`Execute` splitting on `;` broke `CREATE TRIGGER` bodies. Schema is applied as an explicit statement array (`SchemaScript.Statements`).
12. **Search CurrentFolder**`SearchRequest.DirectChildrenOnly` restricts to the folders children in SQL (not a client-side filter after paging).
13. **Duplicate hashing** — full-file hashes run only when another same-size file already shares the partial hash. Unique partial hashes skip the full read.
14. **Index freshness** — folder sizes in the listing come from `aggregate_size`. Watcher reconcile stays one directory deep. Opening a folder enqueues a 1-level reconcile of that path, then `FolderDisplayRefresh` probes up to 8 largest/visible child dirs (child count). Mismatches get `EnqueueVerify` for that child only and are cancelled when the browse generation changes. Idle maintenance still verifies each local indexed source (deep walk, cap 48). USN directory deletes also tombstone the path prefix.
15. **Browse names first** — live folder listing starts without waiting for source lookup, archive index, `MarkReachable`, or child-index overlay. The first name is published immediately (`BrowseHydration.FirstPublish`); folder sizes, cloud state, and Git badges arrive as later `BrowseDelta` updates. Archive paths still resolve through the index before live enumeration.

View File

@@ -44,7 +44,7 @@ Specialized tools still do specialized jobs. 7-Zip compresses. FFmpeg converts a
| --- | --- |
| `%LocalAppData%\ExplorerWorkbench\index.db` | Index, queue, profiles |
| `%LocalAppData%\ExplorerWorkbench\logs\` | Rolling logs |
| `%LocalAppData%\ExplorerWorkbench\ui-preferences.txt` | Theme, layout, tool paths, organize destinations |
| `%LocalAppData%\ExplorerWorkbench\ui-preferences.txt` | Theme, layout, tool paths, organize destinations, favorite folders |
---
@@ -52,9 +52,10 @@ Specialized tools still do specialized jobs. 7-Zip compresses. FFmpeg converts a
- **Title bar** — Explorer Workbench; minimize / maximize / close.
- **Menu** — File (including Stop background host), View, Tools, Settings, Help. Tools is grouped: Storage, Locations, File Operations (including Archives and Convert), Automation, Development, Recycle Bin.
- **Toolbar** — path, navigation, view mode, search, storage, queue summary.
- **Tree** — This PC, Network, Cloud (grouping is optional in Settings).
- **Folder pane** — details, list, or preview. Split pane is optional.
- **Toolbar** — navigation, view mode, search.
- **Tree** — Favorites, Home, This PC, Network, Cloud (Network/Cloud grouping and tree synchronization are in Settings → Navigation).
- **Folder pane** — breadcrumb bar (click the empty space, or `Ctrl+L` / `Alt+D`, to type a path), then details, list, or preview. Split pane is optional.
- **Status bar** — item count and size for the active folder, or for the current selection; Git badge; queue.
- **Queue** — compact status; expand for the full File Operations Queue.
### Tabs and panes
@@ -65,6 +66,7 @@ Specialized tools still do specialized jobs. 7-Zip compresses. FFmpeg converts a
| Close tab | File → Close tab, or `Ctrl+W` |
| Split pane | File → Split pane |
| Details / List / Preview | View menu or toolbar |
| Type a path | Click empty space in the tab breadcrumb bar, or `Ctrl+L` / `Alt+D` |
| Refresh | View → Refresh, or `F5` |
Tabs, split panes, and the folder shown in each pane are restored the next time you open Workbench.
@@ -73,6 +75,18 @@ Tabs, split panes, and the folder shown in each pane are restored the next time
## Locations
### Favorites
Pinned folders of your choosing, at the top of the tree. Add a folder with **Add to Favorites** on the folder or tree context menu, or drop a folder onto the Favorites root. Remove it with **Remove from Favorites**. Unpinning only removes the pin — it does not delete files, forget a location, or change the index.
Favorites are stored in `ui-preferences.txt`. A pin that points at a missing folder still appears, marked Offline, so you can unpin it.
The folder pane always shows the real filesystem path. Breadcrumbs stay the same. The locations tree is separate: by default it keeps the branch you are already in. Opening a folder under This PC, Home, Network, or Cloud does not switch the tree to Favorites just because that folder is also pinned. If you opened the folder from a Favorite, the tree stays under Favorites. **Settings → Navigation → Prefer Favorites when synchronizing the locations tree** selects a matching Favorite pin instead.
### Home
Documents, Downloads, Pictures, Videos, and Music from Windows known folders. They have their own root, not under This PC. Folders that do not exist on this PC are omitted.
### This PC
Local NTFS volumes and removable disks. Capacity and free space show next to size where Windows reports them.
@@ -81,6 +95,8 @@ Local NTFS volumes and removable disks. Capacity and free space show next to siz
Add a UNC path with **Tools → Locations → Add network…** (`\\server\share`). Mapped Windows drive letters can be imported when Workbench discovers them. Forgetting a Workbench location does **not** disconnect the Windows mapping.
After a Windows start, shares can show **Offline** until they answer. Opening a folder or a file on the share marks it online in the tree; sleeping NAS boxes may take a second or two.
### Cloud
OneDrive, Google Drive, and Nextcloud appear when you add their **mounted Windows folders** (**Tools → Locations → Add OneDrive…** / **Google Drive…** / **Nextcloud…**). Workbench browses those paths with Win32 like any other folder. Plugins only overlay status, pin/dehydrate actions, and quota. Cloud folders stay ordinary locations — they are not a separate “cloud filesystem.”
@@ -102,13 +118,13 @@ Open it from **Tools → Recycle Bin**. Workbench talks to the real Windows Recy
The open folder is always the live filesystem when the location is online. Index data fills in folder sizes, search, and analysis.
Large folders appear as soon as names are known. Size, date, and type from the directory listing show with the row. Cloud status, indexed folder totals, and Git badges fill in shortly after — blank cells mean that extra metadata has not arrived yet, not that the file is empty. Opening another folder cancels leftover work from the previous one.
Large folders appear as soon as names are known — the previous folder stays on screen until the first new name arrives. Size, date, and type from the directory listing show with the row. Cloud status, indexed folder totals, and Git badges fill in shortly after — blank cells mean that extra metadata has not arrived yet, not that the file is empty. Opening another folder cancels leftover work from the previous one. The status bar shows how many items are in the active folder and their known size; with a selection it switches to how many are selected and the size of that selection. Folder sizes appear in the total once the index has them.
**Preview** shows a wrapping thumbnail grid. Only the tiles on screen (plus a small prefetch) are decoded, on background threads. Other files keep a generic icon until you scroll to them. Online-only cloud files are never opened just to make a thumbnail. Returning to a folder reuses thumbnails that are still in memory.
Sorting by name or type happens once the listing is in. Sorting by size waits until indexed folder totals are applied, so rows do not jump on every update. Clicking a column sorts immediately with whatever is already known.
Hidden files follow Settings. Protected system locations (`System Volume Information`, Recovery, pagefile, and similar) are hidden unless you turn them on. Recycle Bin folders stay hidden. Access-denied folders show as access denied — never as 0 bytes.
Hidden files follow Settings → Navigation. Protected system locations (`System Volume Information`, Recovery, pagefile, and similar) are hidden unless you turn them on. Recycle Bin folders stay hidden. Access-denied folders show as access denied — never as 0 bytes.
| Shortcut | Action |
| --- | --- |
@@ -118,13 +134,17 @@ Hidden files follow Settings. Protected system locations (`System Volume Informa
| `F5` | Refresh |
| `Enter` | Open |
| `F2` | Rename (single item, immediate) |
| `Ctrl+A` | Select all |
| `Ctrl+C` / `Ctrl+X` / `Ctrl+V` | Copy / Cut / Paste |
| `Delete` | Recycle (queued) |
| `Escape` | Cancel rubber-band selection |
| `Ctrl+T` / `Ctrl+W` | New tab / Close tab |
Drag and drop copies by default. Hold `Shift` to move. Right-drag offers a menu.
Drag an empty area of the folder list to rubber-band select, as in File Explorer. The rectangle selects every row it touches in Details and List, and every tile it intersects in Preview. `Ctrl` adds to the current selection; `Escape` restores the previous one. Right-drag selects, then opens the context menu.
Hidden files follow Settings. Protected system locations (`System Volume Information`, Recovery, pagefile, and similar) are hidden unless you turn them on. Recycle Bin folders stay hidden. Access-denied folders show as access denied — never as 0 bytes.
Drag and drop copies by default. Hold `Shift` to move. Right-drag of selected items offers a menu.
Hidden files follow Settings → Navigation. Protected system locations (`System Volume Information`, Recovery, pagefile, and similar) are hidden unless you turn them on. Recycle Bin folders stay hidden. Access-denied folders show as access denied — never as 0 bytes.
---
@@ -134,7 +154,11 @@ Indexing is **user-triggered**, then kept current in the background:
- Local NTFS: USN journal when Windows allows it; otherwise folder reconcile + watcher
- Network: scan + watcher (best effort)
- Archives: optional (Settings → include archive contents)
- Archives: optional (Settings → Indexing → include archive contents)
- Folder sizes in Details come from the index. Opening a folder reconciles **that folder only**, then probes the largest or visible child folders (child count vs index). A mismatch queues a targeted verify of that child — not a walk of C:\. Navigating away cancels further probes. Idle maintenance still verifies whole local drives.
- After the PC has been idle (Settings → Indexing), the background host checks local indexed drives for folders whose contents no longer match the index. A full rescan still happens only when a drive is marked out of date or has not been indexed for 7 days.
- Before Delete, Workbench checks that the path still exists and refreshes that folder in the index. Leftovers under Program Files can still fail if Windows needs administrator rights — that is separate from the stale size.
- Idle maintenance: when the PC has been idle (Settings → Indexing), the background host may hash duplicates, recapture history, and rescan stale **local** indexes. Copy, move, delete, explicit scans, and sync you started are not idle work and keep running. Cloud files are never hydrated. Network, cloud, and removable locations are not scanned just because the PC is idle.
Default excludes include Windows, recycle bins, `node_modules`, `.git`, and similar. Inaccessible paths are skipped.
@@ -152,6 +176,8 @@ even when that NAS is currently offline — if the archive was indexed earlier.
**Tools → Storage → Storage analysis** (or the toolbar). WinDirStat-style trees, biggest folders/files, by type, by source. Figures come from the index, so build the index first.
**Tools → Storage → Run background maintenance now** runs the same idle-maintenance pipeline immediately (still skipped while a copy/move/delete is running). The status bar may show Idle maintenance, Scanning a location, or Paused because user is active.
---
## Duplicates
@@ -206,7 +232,7 @@ Metadata placeholders such as `{CreatedDate}` or `{Width}` are not implemented y
## Archives
Needs **7-Zip** on the machine (Settings can point at `7z.exe`; otherwise Program Files and PATH). 7-Zip is not bundled.
Needs **7-Zip** on the machine (Settings → File Operations can point at `7z.exe`; otherwise Program Files and PATH). 7-Zip is not bundled.
| Action | Menu |
| --- | --- |
@@ -221,7 +247,7 @@ Jobs go through the queue. Online-only cloud archives are refused so Workbench w
## Convert
Needs **`ffmpeg.exe`** on the machine. FFmpeg is usually a zip, not an installer: unpack a Windows build and either put `ffmpeg.exe` on PATH, under `Program Files\ffmpeg\bin\`, or point Settings at the file. `ffprobe` / `ffplay` are not required. FFmpeg is not bundled. This is not HandBrake — a few conversions only.
Needs **`ffmpeg.exe`** on the machine. FFmpeg is usually a zip, not an installer: unpack a Windows build and either put `ffmpeg.exe` on PATH, under `Program Files\ffmpeg\bin\`, or point Settings → File Operations at the file. `ffprobe` / `ffplay` are not required. FFmpeg is not bundled. This is not HandBrake — a few conversions only.
| Kind | Output |
| --- | --- |
@@ -300,7 +326,7 @@ Workbench detects repositories and shows a badge (branch, modified, untracked, a
**Pull (fast-forward)** is `git pull --ff-only --no-rebase`. If that cannot fast-forward, Workbench offers **Pull (merge)** (`git pull --no-rebase`) or a terminal. Fetch and push are the matching `git` commands. There is no stash, branch UI, mergetool, or credential dialog (`GIT_TERMINAL_PROMPT=0`).
Missing `git.exe` means no badge and no Git actions. Path can be set in Settings. Git is not bundled. Profiles can require a clean working tree.
Missing `git.exe` means no badge and no Git actions. Path can be set in Settings → Advanced. Git is not bundled. Profiles can require a clean working tree.
---
@@ -318,21 +344,18 @@ Workbench never starts a cloud vendors own two-way sync. It never hydrates a
## Settings
**Settings** in the menu:
**Settings** opens a window with categories on the left. The last category you opened is remembered until you quit Workbench. Empty categories are omitted.
- Dark / Light theme
- Group network under Network; group cloud under Cloud (independent)
- Show hidden files
- Show protected system locations
- Auto-clear queue when done
- Include archive contents in the index
- Automatically index removable drives when they appear
- Start Explorer.Host.exe at Windows sign-in (current-user Startup, no administrator rights)
- Path to 7-Zip
- Path to git.exe
- Path to ffmpeg.exe
| Category | Options |
| --- | --- |
| General | Start Explorer.Host.exe at Windows sign-in (current-user Startup, no administrator rights) |
| Appearance | Dark / Light theme |
| Navigation | Group network under Network; group cloud under Cloud (independent); prefer Favorites when synchronizing the locations tree (off by default); show hidden files; show protected system locations |
| File Operations | Auto-clear queue when done; path to 7-Zip; path to ffmpeg.exe |
| Indexing | Include archive contents in the index; automatically index removable drives when they appear; enable idle background maintenance; idle threshold (5 / 10 / 30 minutes); only run expensive maintenance on AC power |
| Advanced | Path to git.exe |
These options change what Workbench shows and indexes. They do not change Windows Explorer settings.
These options change what Workbench shows and indexes. They do not change Windows Explorer settings. Layout, favorite pins, organize destinations, and open tabs are stored in `ui-preferences.txt` but are not edited here.
---