Adds support for XMP D&D in the darkroom.#21403
Open
masterpiga wants to merge 1 commit into
Open
Conversation
Collaborator
Author
Member
|
Love this ! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for dropping
.xmpsidecar files onto the darkroom to apply their edit history to the current image.Fixes #21359.
Behavior
Drop hints While an external file drag hovers the darkroom, an overlay hint is shown on the center view ("drop XMP sidecar files here…") and on the filmstrip ("drop image files here…", the existing import target). Internal drags (thumbnail/module reordering) don't trigger it.
Screen.Recording.2026-06-23.at.08.34.33.mp4
Implementation notes
The change touches two files:
src/views/darkroom.c(the feature) andsrc/common/history.c(a deadlock fix it exposed).Drop target, scoped to the darkroom. The center drawing area is shared across views, so the
text/uri-listdrag destination and its handlers are registered inenter()and torn down inleave()rather than at construction — this keeps the behavior darkroom-only and avoids leaking handlers onto a widget other views reuse. Only external URIs are accepted, so dropping a filmstrip thumbnail on the canvas is unaffected. The drop is filtered to existing.xmpfiles; everything else is ignored.Reuse over reinvention. The feature is mostly glue over existing machinery:
dt_history_load_and_apply()to read a sidecar into an image's history,dt_image_duplicate()to spawn duplicates, and theXmp.darktable.version_namemetadata (the same per-duplicate caption the duplicate module writes) to label them. Applying to the current image relies ondt_history_load_and_apply()'s built-in darkroom reload; duplicates are non-current, so they don't reload and we switch to the single one explicitly so the result is visible.Deadlock fix (
history.c).dt_history_load_and_apply()grabbed the image-cache write lock and then, for the current darkroom image, calleddt_dev_reload_history_items()while still holding it. The reload re-entersdt_image_cache_get()for the same image (e.g. from a module'sreload_defaults), and that entry lock is non-recursive → hard hang. The fix moves the reload to after the cache lock is released. This was latent: existing callers (lighttable's "load sidecar file") only ever apply to non-current images, so the reload branch never fired — this PR is the first to apply a sidecar to the current darkroom image.Drag hints without a global hook. We can't see the drag at the moment it starts (the app isn't focused yet), so the hint is driven by the
drag-motion/drag-leavesignals of the two drop targets (center + filmstrip thumbtable), which fire as soon as the pointer enters them. To distinguish a Finder drag from an internal reorder, we testgtk_drag_get_source_widget(context) == NULL— an in-app drag has a source widget, an external one doesn't. (An earlier attempt inspected the offered targets, but macOS's Quartz backend doesn't resolve those until drop time, so the hint never armed; the source-widget test is backend-agnostic and phase-agnostic.) A short timeout ondrag-leavedebounces the hand-off when the drag moves between the center and the filmstrip so the overlay doesn't flicker. The center hint is painted at the end of the view'sexpose(); the filmstrip hint via adraw-after handler on the thumbtable — so no changes to the sharedthumbtable.c.Smaller things. A shared
_darkroom_dnd_dialog_new()builds the parented, centered, macOS-fullscreen-safe dialog used by both branches; the multi-duplicate loop is wrapped in one undo group (matchingdt_history_load_and_apply_on_list) so the batch undoes in a single step; and batch results report how many succeeded.Co-authored with Claude.