Fix sidebar, history, camera, icons, and scanner issues #1

Merged
bnied merged 0 commits from code-review-fixes into main 2026-06-06 04:43:56 +00:00
bnied commented 2026-06-06 04:42:30 +00:00 (Migrated from codeberg.org)

Addresses a batch of behavioral/parity gaps found reviewing the port
against the original neofsn. Builds clean; verified headless and on a real
Wayland display.

Sidebar — was frozen at the initial scan depth and synced only one way:

  • FileTreeModel now populates children lazily (hasChildren / canFetchMore /
    fetchMore via a shallow depth-1 scan), driven by a new
    FileSystemNode::childrenLoaded flag, so the tree reaches any depth.
  • Added FileTreeModel::indexForPath (fetching rows along the path) and
    BrowserModel::indexForPath. Sidebar.qml now expands ancestors and scrolls
    the item selected in the 3D scene into view, deduped so hover noise
    doesn't re-scroll.

History / Back — the back stack was append-only and mutated before a guard
that could no-op:

  • History is changed only once a scan is accepted (in onCurrentScanned),
    via truncate-or-push: returning to a folder already in the stack
    (Back / breadcrumb / back-tile / reload) truncates instead of appending,
    so it can't grow unboundedly. goBack/reload no longer pre-mutate.
  • Navigation requests arriving mid-scan are coalesced and queued (latest
    wins) instead of being silently dropped.

Fly camera:

  • The 60Hz timer now idles when nothing is animating (no flight, no held
    keys, ~zero velocity) and restarts on input / flyTo, instead of waking
    60x/s forever.
  • Camera is driven by a quaternion rotation (yaw·Y then pitch·X, matching
    forwardVector) instead of eulerRotation, removing Euler-order ambiguity at
    steep pitch; Scene3D.qml binds rotation.
  • A movement keydown now cancels an in-flight fly animation, matching the
    mouse.

Texture provider / icons:

  • Icon QImages are resolved on the GUI thread (QIcon::fromTheme isn't
    thread-safe and requestImage runs on a worker thread) and cached by
    name+size.
  • Replaced the no-op fallbackChain stub with a real chain
    (specific → category-generic → octet-stream/unknown via hasThemeIcon;
    "application" folds straight to octet-stream since Breeze has no
    application-x-generic). Fixed the config glyph (wrong DOS-exe icon →
    preferences-system).

Scanner — no longer follows symlinked directories, and tracks canonical
paths in a visited-set to stop self-referential link cycles from
duplicating subtrees; symlinks are still listed as leaf entries.

Metadata HUD — fileInfo now counts a directory's items from the
already-scanned tree (findNode) instead of QDir::entryInfoList on the GUI
thread, falling back to a live read only when the node isn't scanned. No
more UI stalls hovering large / network dirs.

Platform — documented that kfsn is Linux/KDE-only by design (macOS stays on
neofsn) in README and CMakeLists; KF6 is already a hard find_package.

KDE-session style fix — force the Basic QtQuick Controls style
(QT_QUICK_CONTROLS_STYLE=Basic) in main(). All QML already imports
Controls.Basic, but under a KDE session the default style is Breeze, and the
QtQuick.Dialogs FolderDialog fallback loaded it, spamming
ButtonBackground.qml "Value is null" TypeErrors. No visible change; native
dialogs are unaffected.

Addresses a batch of behavioral/parity gaps found reviewing the port against the original neofsn. Builds clean; verified headless and on a real Wayland display. Sidebar — was frozen at the initial scan depth and synced only one way: - FileTreeModel now populates children lazily (hasChildren / canFetchMore / fetchMore via a shallow depth-1 scan), driven by a new FileSystemNode::childrenLoaded flag, so the tree reaches any depth. - Added FileTreeModel::indexForPath (fetching rows along the path) and BrowserModel::indexForPath. Sidebar.qml now expands ancestors and scrolls the item selected in the 3D scene into view, deduped so hover noise doesn't re-scroll. History / Back — the back stack was append-only and mutated before a guard that could no-op: - History is changed only once a scan is accepted (in onCurrentScanned), via truncate-or-push: returning to a folder already in the stack (Back / breadcrumb / back-tile / reload) truncates instead of appending, so it can't grow unboundedly. goBack/reload no longer pre-mutate. - Navigation requests arriving mid-scan are coalesced and queued (latest wins) instead of being silently dropped. Fly camera: - The 60Hz timer now idles when nothing is animating (no flight, no held keys, ~zero velocity) and restarts on input / flyTo, instead of waking 60x/s forever. - Camera is driven by a quaternion rotation (yaw·Y then pitch·X, matching forwardVector) instead of eulerRotation, removing Euler-order ambiguity at steep pitch; Scene3D.qml binds rotation. - A movement keydown now cancels an in-flight fly animation, matching the mouse. Texture provider / icons: - Icon QImages are resolved on the GUI thread (QIcon::fromTheme isn't thread-safe and requestImage runs on a worker thread) and cached by name+size. - Replaced the no-op fallbackChain stub with a real chain (specific → category-generic → octet-stream/unknown via hasThemeIcon; "application" folds straight to octet-stream since Breeze has no application-x-generic). Fixed the config glyph (wrong DOS-exe icon → preferences-system). Scanner — no longer follows symlinked directories, and tracks canonical paths in a visited-set to stop self-referential link cycles from duplicating subtrees; symlinks are still listed as leaf entries. Metadata HUD — fileInfo now counts a directory's items from the already-scanned tree (findNode) instead of QDir::entryInfoList on the GUI thread, falling back to a live read only when the node isn't scanned. No more UI stalls hovering large / network dirs. Platform — documented that kfsn is Linux/KDE-only by design (macOS stays on neofsn) in README and CMakeLists; KF6 is already a hard find_package. KDE-session style fix — force the Basic QtQuick Controls style (QT_QUICK_CONTROLS_STYLE=Basic) in main(). All QML already imports Controls.Basic, but under a KDE session the default style is Breeze, and the QtQuick.Dialogs FolderDialog fallback loaded it, spamming ButtonBackground.qml "Value is null" TypeErrors. No visible change; native dialogs are unaffected.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
spaceduck/kfsn!1
No description provided.