| Age | Commit message (Collapse) | Author |
|
Wire the navigator mark API into the window actions, grid badges, and
keyboard/pointer controls:
- Navigator: add a path-based range anchor (p_last_mark) set on `v`
toggle-on and cleared on unmark-of-anchor / clear_marks / remove /
mark_removed / rescan-prune; expose navigator_get_last_mark().
navigator_mark_removed now clears the removed file's mark (decision Q
/ task du0) and the anchor if it was it, without touching unrelated
marks, and emits "changed" whenever the removed set or marks actually
changed so grid badges and the header never go stale.
- Window: add win.mark-range (`V`: range from the last-mark anchor to the
current/grid-selected image), register it, wire Shift+V, and document
it in the shortcuts overlay. Trash/delete clear marks via mark_removed.
- Grid: middle-click on a cell selects it and dispatches win.mark
(pointer-accessible marks).
- Tests: unit test_marks_anchor_and_remove and
test_marks_anchor_pruned_on_rescan; integration test_marks.c covering
toggle, all+clear, range, persistence across view switch,
clear-on-trash, and the middle-click gesture wiring; updated
test_shortcut.c action table + count.
clang-format clean; full suite + ASan leak check green.
|
|
_on_nav_changed rebuilt every cell on every navigator "changed" signal,
so a single h/l/j/k press destroyed and recreated all 613 GtkPicture
cells (each re-requesting its thumbnail) and the grid flashed blank.
Now it only does a full ggaze_grid_refresh when the file count actually
changed (rescan/trash/move); a mere current/mark change just refreshes
mark badges in place and re-selects the cursor.
Add j/k row navigation: ggaze_grid_move_cursor finds the cell in the
adjacent row closest to the current column via gtk_widget_compute_bounds
and sets navigator.current to it (so the header / large-view preview
track the move and the light nav-changed path re-selects it). h/l stay
linear via the existing global win.next/prev. Also document j/k in the
? shortcuts overlay.
|
|
The navigator already had a mark API and the grid rendered mark badges,
but nothing could set marks — so multi-file ops (D, Ctrl+c, m) only ever
acted on the single current image. Wire up marking in the UI:
- v toggles a mark on the highlighted grid cell (or the current image in
large view). navigator_toggle_mark does not emit "changed", so the
cell's badge is updated in place via ggaze_grid_update_mark_badge
(no reflow / re-decode).
- Ctrl+a marks all; Esc now clears marks first (contextual), then keeps
its existing back/quit behavior.
- The window title appends "N marked" so multi-selection is visible.
- A GtkCssProvider styles .ggaze-marked (accent border + tint) — the
class was set but had no styling, so badges were invisible.
Also add a ? -> win.shortcuts action that presents a GtkShortcutsWindow
(grouped: navigation, view, selection, files, zoom) built from an inline
GtkBuilder UI string, transient to the window.
tests/test_shortcut.c full-table test updated for the three new bindings
(v, Ctrl+a, ?) -> 23 rows, 19 actions.
|
|
Arrow-key navigation in the grid moved the GtkFlowBox selection but never
updated navigator.current, so Enter (and toggling to large with t) opened
the stale current image instead of the highlighted one. _on_flow_key
emitted the activate signal directly without syncing, unlike the
double-click path (_on_child_activated) which does sync.
Add ggaze_grid_sync_current(): reads the selected flowbox child and calls
navigator_set_current_file. Call it from _on_flow_key before emitting
activate, and from _action_toggle_view's grid→large branch (then load
the now-current image). Mirrors the existing double-click sync.
|
|
black grid)
GgazeGrid is a GtkWidget with a single child (the GtkScrolledWindow
holding the GtkFlowBox) but set no layout manager and overrode no
measure/size_allocate vfunc, so GTK4 never allocated the child and the
grid stayed a 0x0 black area (`Trying to snapshot GtkScrolledWindow
without a current allocation`). Add a GtkBinLayout in class_init so the
child is sized to fill the grid and the flowbox renders.
|
|
M7 (task jt0): thumbnail cache + grid view + trash.
- src/trash.{c,h}: ./Trash bin (lazy create, collision suffix -1/-2, restore_last
for u undo, permanent delete for D). Plain-C, unit-tested.
- src/thumbnail.{c,h}: freedesktop TMS cache (normal/large/x-large buckets,
md5(URI) key, Thumb::URI/MTime/Size, mtime verify). Async GTask worker with
GCancellable so the grid can cancel pending requests on dispose.
- src/gridview.{c,h}: GgazeGrid (GtkWidget wrapping GtkFlowBox): one cell per
navigator file, lazy thumbnail decode on realize, +/- resize 64-512, dim
removed cells, mark badges, Enter/double-click → 'activate' signal, cursor
sync. ggaze_grid_detach() breaks the nav ref before dispose.
- src/navigator.{c,h}: removed set (mark_removed/is_removed/unmark_removed);
_relist preserves removed items (stay dimmed even if absent from disk);
get_remaining = count - removed_count.
- src/window.c: d (trash+mark_removed+advance), D (permanent delete, confirm
dialog if >1 marked), u (restore_last+rescan), t (toggle grid/large),
+/- (viewer zoom in large / grid resize). Header counter uses remaining.
- src/shortcuts.c: d/D/u/t/+/= bindings added.
- tests: unit test_trash + test_thumbnail, integration test_grid_cull
(grid count + trash/undo + ./sample-images 613-cell grid). 13/13 green,
ASan clean.
Fixed: grid dispose UAF (detach before nav freed), g_file_get_basename leak,
test p_plain lifetime, thumbnail async-cancellable for clean dispose, test
grid-toggle avoiding async-thumbnail drain issues.
|