summaryrefslogtreecommitdiff
path: root/docs/open-questions.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/open-questions.md')
-rw-r--r--docs/open-questions.md238
1 files changed, 238 insertions, 0 deletions
diff --git a/docs/open-questions.md b/docs/open-questions.md
new file mode 100644
index 0000000..e6962f6
--- /dev/null
+++ b/docs/open-questions.md
@@ -0,0 +1,238 @@
+# Open Questions
+
+Decisions to make before/while coding. None block M0.
+
+Most items are now **decided** — see PLAN.md decisions #29–#38. Each item's
+**Decision:** line records the chosen value; the milestone-level Leans are
+locked in decision #37.
+
+## A. libadwaita or plain GTK4?
+- libadwaita → GNOME-native styling, follows release style, but opinionated
+ (header bar patterns, no theming overrides).
+- plain GTK4 → full control, works under any GTK theme, less "GNOME-native".
+- **Decision:** libadwaita (decision #29).
+
+## B. App ID / GApplication name
+- Placeholder `org.buetow.ggaze`. Confirm domain + naming.
+- **Decision:** `org.buetow.ggaze` (decision #30).
+
+## C. Image decode strategy
+- Rely on GdkPixbuf loaders for the common case, or link libjpeg-turbo /
+ libpng directly from the start for the progressive low-res preview feature?
+- **Lean:** GdkPixbuf first; add direct libs in M5/M6.
+
+## D. Thumbnail grid view — in scope (decided)
+- Two views per window: a thumbnail grid (overview) and a large single-image
+ view. `Enter`/`Esc` switch between them; cursor stays in sync.
+- Trashed/deleted items stay listed but dimmed (with a hide toggle).
+- **Lean:** grid view is a core feature, M7. Not "a different app" after all.
+
+## E. Single instance?
+- `GApplication` single-instance means a second `ggaze img.jpg` reuses the
+ window and loads the new image. Convenient; small risk of state confusion.
+- **Decision:** single instance, replace on new `open` (decision #32).
+
+## F. Recursive directory walking
+- `ggaze folder/` → recurse into subdirs, or just flat siblings?
+- **Lean:** flat by default; add `--recursive` later.
+
+## G. Color management
+- Ignore sRGB-only for now; plan a later milestone for lcms2 + ICC.
+- Confirm target displays are sRGB-ish (most are).
+- **Update:** if GEGL is enabled (M9), color-managed decode/export comes via
+ babl + LCMS (`gegl:icc-file-loader`, `gegl:lcms-from-profile`,
+ `gegl:convert-color-space`) — no separate lcms2 wiring. Without GEGL, stay
+ sRGB-only.
+
+## H. Scroll behavior default
+- Scroll = zoom (feh-style `--scale-zoom`) vs scroll = next/prev.
+- **Lean:** zoom; expose in settings since it divides users.
+
+## I. Trash vs delete (decided)
+- `d` moves the file to a local `<folder>/.Trash/` directory (created lazily,
+ collision-suffixed), undoable with `u`. This is **not** the system trash.
+- `D` permanently deletes (unlink), no undo.
+- **Lean:** confirmed; `./Trash` lives with the shoot for easy inspection/emptying.
+
+## J. Packaging targets
+- RPM first (Fedora native). Flatpak too? Copr repo?
+- **Lean:** RPM + AppStream; Flatpak later.
+
+## K. Camera-dump specifics
+- **RAW + JPEG pairs.** Many cameras shoot both. Show only the JPEG and hide
+ the matching `.RAF/.CR3/.NEF`? Or show RAW via embedded preview? Hide-pairs
+ is the culling-friendly choice.
+- **Burst grouping.** Auto-detect burst sequences (EXIF burst ID or
+ sub-second capture time clustering) and collapse them into a group, letting
+ `j`/`k` step group-by-group with an expand for within-burst? Big UX win for
+ the stated use case, but scope creep — decide whether it's M-something or
+ "later".
+- **Default sort.** Capture time (EXIF `DateTimeOriginal`) vs filename. Camera
+ dumps are usually already named in shot order, so filename sort ≈ capture
+ order; but capture-time sort is more robust after a burst of edits.
+- **Import folder.** Any integration with the camera-download location, or just
+ "whatever path you point it at"? Lean: just a path.
+- **Decision:** burst grouping deferred to "later"; hide RAW sidecars by
+ default (toggle to reveal); default sort = filename (capture-time as a menu
+ option); import folder = just a path (decision #33).
+
+## L. Custom viewer widget vs GtkPicture
+- `GtkPicture` is simplest but limited zoom/pan. A custom `GtkWidget` gives
+ cursor-centered zoom, pan clamping, animated transitions.
+- **Decision:** custom viewer widget (decision #31).
+
+## M. Destination configuration storage
+- GSettings `a(ss)` (ordered name→path) is simplest and integrates with
+ `gsettings`/dconf. Alternative: a small TOML/ini under
+ `~/.config/ggaze/destinations.conf` for hand editing.
+- **Lean:** GSettings `a(ss)` via the Preferences dialog; revisit if users want
+ to hand-edit.
+
+## N. Move vs copy, and collision policy
+- `g_file_move` (rename / copy+delete) by default; a copy mode ("send a copy
+ without removing") could be a modifier (`M` for copy?).
+- Collision: suffix `-1`, `-2`, … (never overwrite).
+- **Lean:** move + suffix; copy as a later option.
+
+## O. Auto-hotkey scheme past 10 destinations
+- `1`-`9`, `0`, then `a`-`z` gives 36 slots — plenty. Beyond that, a scrollable
+ list navigable by arrows + `Enter` (no single-key shortcut).
+- **Lean:** digits then letters; cap at a sane number.
+
+## P. Undo depth
+- One level (`u` undoes the last `d` or `m`) is enough to start; a small stack
+ (10) is a cheap upgrade later.
+- **Lean:** one level now, stack later.
+
+## Q. Marks vs re-sort / view switch / trash
+- Marks are path-based and held by the navigator: a re-sort reflows but keeps
+ marks; a view switch preserves them; trashing a marked item clears its mark.
+- **Lean:** confirm during implementation.
+
+## R. External programs — command format & launch
+- Store `name → command` pairs; command uses freedesktop `Exec` placeholders
+ (`%f` single file, `%F` multiple). Start with `%f` only; `%F` (marked set)
+ later.
+- Launch via `GSubprocess` detached (non-blocking), or `g_app_info`?
+ GSubprocess is simpler for raw commands; `g_app_info` is better if reusing
+ `.desktop` entries.
+- **Lean:** raw command + `%f` + GSubprocess; revisit `.desktop` reuse later.
+- Should `e` apply to marks (`%F`)? **Lean:** current image first; marks later.
+
+## S. Shell scripts — execution model
+- Run via `/bin/sh -c "<cmd>"` (POSIX sh) or `bash -c`? Use the user's
+ `$SHELL`? **Lean:** `/bin/sh -c` for portability; revisit for bash-isms.
+- Async, non-blocking; toast while running and on completion. On exit,
+ rescan the directory (scripts may add/remove/move files). A destructive
+ script could rename the current file away — rescan handles it (cursor falls
+ back to nearest).
+- Placeholders: `%f` (current image), `%d` (current folder); `%F` (marked
+ set) later. **Shell injection:** single-quote substituted paths (filenames
+ can contain spaces, `$`, backticks) — or pass paths via env/argv instead of
+ `sh -c`.
+- **Lean:** `/bin/sh -c`, single-quote paths, rescan on exit, `%f`/`%d` now.
+
+## T. Thumbnail size — range, step, and cache
+- freedesktop TMS defines only 128 (normal) and 256 (large) cached sizes.
+ For larger grid thumbnails, decode a custom size on demand (downscale the
+ full image or the `large` cache entry), cached in a separate bucket. Range
+ ~64–512px, step ~32px. Confirm.
+- Persist `thumbnail-size` (int) in GSettings; restore on launch.
+- **Lean:** 64–512px, ±32px step, custom cache bucket for non-TMS sizes.
+
+## U. GEGL integration
+- **Hard or optional dep?** Lean: optional meson `feature`; core viewer works
+ without it. Confirm RPM splits a `ggaze-gegl` subpackage or keeps it in.
+- **Preset format:** store `gegl-graph` text (parsed via `gegl:gegl` /
+ `gegl_node_new_from_xml`) or build programmatically per known preset? Lean:
+ built-in presets built programmatically; user presets as graph text.
+- **Apply timing:** only when paused on an image (not during `h`/`l` scrub);
+ disable the preset during rapid navigation, reapply on settle. Confirm.
+- **Viewer path:** import decoded pixels → GeglBuffer (GdkPixbuf-source op or
+ babl), process, render output buffer → GdkTexture. Measure overhead; maybe
+ show a subtle "enhanced" badge in the header.
+- **Export naming:** `<stem>-enhanced.<ext>`; collision → suffix `-1`. Same dir
+ as original by default; configurable later.
+- **gegl-gtk?** No — keep the custom viewer, render to GdkTexture.
+- **Save flow:** `s` = save enhanced copy; no auto-save; navigate-away (or
+ quit, or `d`/`D`/`m`) with a dirty preview prompts Save/Discard/Cancel.
+ Slideshow moved to `S` to free `s` for save. Confirm the prompt also fires
+ on `d`/`D`/`m` of a dirty image (Lean: yes).
+- **Decision:** optional meson feature; built-in presets programmatic, user
+ presets as `gegl-graph` text; apply only when settled (not during scrub);
+ "enhanced" badge; export `<stem>-enhanced.<ext>` same dir, collision suffix
+ `-1`; dirty-prompt fires on `d`/`D`/`m`; no gegl-gtk (decision #34).
+
+## V. Clipboard — pixels vs URIs
+- Single image → `image/png` pixels (paste as image into chat apps); marks →
+ `text/uri-list` (+ `text/plain` paths). Verify Katogram paste accepts image
+ pixels (some apps want URIs even for one file).
+- Offer both at once via `gdk_content_provider_new_union` (PNG + uri-list) when
+ one file, so the target picks. Lean: yes.
+- Decode-for-PNG-copy runs in a `GTask` thread; cap size (downscale very
+ large images?) — Lean: copy full-res, note the memory cost.
+- `Ctrl+Shift+c` to force copy-as-path (text) — later.
+
+## W. Crop, straighten & rotate tools
+- **Crop rect UI:** overlay rectangle with handles; keyboard move
+ (`h`/`l`/`j`/`k`) + resize (`H`/`L`/`J`/`K`); aspect presets `1`-`4` + `0`
+ free. Tool mode grabs keys until `Enter`/`Esc` so they don't clash with
+ pan/zoom.
+- **Straighten:** drag-a-horizon-line vs angle nudge; ±0.5° step; grid overlay.
+ Auto-crop rotated corners? Lean: offer as a toggle, default on.
+- **Rotate 90°:** one-shot `[`/`]`; repeat to 180°/270°; non-destructive. No
+ overlay.
+- All are GEGL ops in the same preview graph as enhance; `s` exports. If GEGL
+ off, toast. Confirm compose order (crop after rotate, or user order).
+- **Compare:** hold `Space` (momentary key-release event) vs a toggle; GUI uses
+ a menu *Show original* toggle. Confirm momentary doesn't fight the
+ navigate-away dirty prompt.
+- **Decision:** compose order load→enhance(color)→rotate→straighten→crop→
+ export; straighten auto-crop default on (decision #35).
+
+## X. Enhance — fixed presets vs tunable parameters
+- Ship one-shot presets with sensible fixed strengths (brightness/contrast/
+ saturation/etc.). Strength is editable in the `enhance-presets` gegl-graph
+ text (Preferences / `gsettings`) — no slider UI, keeps KISS.
+- Later: a "fine adjust" mode that nudges the active preset's main parameter
+ with keys (which keys? `+`/`-` clash with zoom; maybe `H`/`L` or a sub-mode).
+ Lean: presets first; nudging only if asked.
+- **Curves:** GEGL has `gegl:contrast-curve` and `gegl:curve`; confirm the
+ exact op name and how to embed a curve shape in the graph text. Interactive
+ curve editing is out of scope (GIMP hand-off via `e`).
+- **Decision:** one active color preset (replace); crop/straighten/rotate
+ stack; reset preview clears all; combine color presets via one `gegl-graph`
+ entry; curves via `gegl:contrast-curve`; no fine-adjust nudging in v1
+ (decision #36).
+
+## Y. EXIF orientation
+- Source: GdkPixbuf's `gdk_pixbuf_apply_embedded_orientation` covers JPEG/TIFF
+ via GdkPixbuf; for direct-lib backends (libjpeg-turbo, libjxl, libavif,
+ libheif) read the orientation tag (libexif or the format's own metadata) and
+ rotate/flip. Confirm a single code path (normalize to identity orientation
+ before producing the `GdkTexture`).
+- Manual `[`/`]` and straighten compose **on top** of the EXIF-corrected image.
+- On `s` export, the pixels are already upright → write the EXIF Orientation
+ tag as 1 (normal) to avoid double-rotation in other apps. Confirm.
+
+## Z. Opening files, folders & drag-drop
+- **Folder arg vs file arg:** `ggaze dir/` → grid of dir; `ggaze file.jpg` →
+ parent dir as navigator, file current (large view). Confirm.
+- **Drop semantics:** drop folder → grid; drop one file → open it; drop many
+ files → open the first file's folder in grid with the first selected (or
+ treat the dropped set as the navigator's universe?). Lean: first-file's
+ folder, first selected.
+- **`o` dialog:** use `GtkFileDialog` (GTK4) with folder selection allowed as
+ well as files.
+- **Single-instance:** a new `open` (arg or drop) replaces the current
+ folder/image (per open-question E).
+
+## AA. Folder monitoring
+- `GFileMonitor` on the current directory; debounce bursts (usbimport writes
+ many files quickly) — e.g. 250 ms coalesce before emitting `changed`.
+- Removed current file → fall back to nearest neighbor (or stay on a
+ placeholder)? Lean: nearest.
+- Recurse into subdirs? No (flat; matches open-question F). Watch only the
+ current dir.
+- Pause monitoring during rapid `h`/`l` scrubbing? Probably unnecessary;
+ debounce handles it. \ No newline at end of file