feat: image tool — insert and paste images into the screenshot - #563
Open
rokokol wants to merge 8 commits into
Open
feat: image tool — insert and paste images into the screenshot#563rokokol wants to merge 8 commits into
rokokol wants to merge 8 commits into
Conversation
Member
|
Thank you for the PR, this will be a great addition to Satty. But it's also going to take a bit to review :) Just a heads up, I think we may merge #555, #561 and #562 to main first. The former definitely overlaps because it changes how shortcut keybindings work and would require some editing here. The other two might or might not cause a conflict. |
Move the crop tool's handle drawing into drag_box and turn the renderer-private background upload into a reusable create_image_from_pixbuf, so other tools can draw handles and upload pixbufs to the canvas.
Selecting the tool opens a file chooser and places the chosen image in the center of the screenshot, scaled down to at most half of its size. The image is edited with the familiar 8-handle frame plus a rotate handle: dragging inside moves it, corner handles resize it keeping the aspect ratio, edge handles stretch it along one axis and dragging a handle across the opposite side mirrors the image. Shift snaps the rotation to 15 degree steps and the handle under the cursor is highlighted. Enter or switching to another tool renders the image into the screenshot, Escape discards it.
If the clipboard contains an image, Ctrl+V switches to the image tool and inserts it, without opening the file chooser. Text editing keeps its own Ctrl+V handling since the text tool stops propagation.
gdk-pixbuf only handles webp when the external webp-pixbuf-loader is installed. Route all image decoding through a shared helper that tries gdk-pixbuf first and falls back to the image crate, which is already in the dependency tree via femtovg, with only the pure-Rust webp decoder enabled. This covers the input file, stdin and the image tool alike.
Accept file and texture drops on the sketch board and insert them through the same path as clipboard paste, centering the image on the drop position.
On Wayland the drag position arrives as (0,0) until the first motion event and gtk picks the drop widget chain there, which is usually the tools toolbar. With the drop target on the sketch board area the drop never got accepted and the compositor cancelled the drag before any motion arrived. Move the target to the window, which is part of every pick chain, translate the drop position into canvas coordinates and clamp it to the image so a drop released over a toolbar stays visible. The explicit enter/motion handlers are required as well: the default ones report no action before the data is available, which equally cancels the drag.
Copying a file in a file manager puts a uri list on the clipboard, not image data, so Ctrl+V silently did nothing; fall back to reading the clipboard as a file list through the same loader the drop path uses. The pasted image now also centers on the last pointer position instead of the middle of the screenshot, falling back to the center when the pointer is outside the window.
Contributor
Author
|
Thank you! :D I've merged with my other PR #565 and added some enhancements like drag & drop and webp processing |
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.
Closes #233
This adds a new Image tool that makes it possible to insert pictures into the screenshot, addressing the concern raised in the issue: the pasted image is fully controllable (position, scale, rotation, mirroring) before it is rendered into the annotation stack.
2026-07-03.00-48-28.mp4
Usage
Configuration
o, configurable via[keybinds] image = "…".imageis accepted by--initial-tool/initial-tool.config.tomlupdated, new options markedNEXTRELEASE.Implementation notes
Imagedrawable +ImageToolimplementingTool, committed viaToolUpdateResult::Commitlike the text tool.SketchBoardInput::ImageSelected(Pixbuf)→ToolEvent::ImageSelectedmessage, mirroring how text commit events are routed. On paste the image is handed to the tool before activation so that activation does not open the file chooser.drag_box(now shared, with an optional highlight), and the renderer-private background upload became a reusablecreate_image_from_pixbuf.PointerPosevents now get converted to image coordinates like the other mouse events (needed for hover tracking); the renderer keeps using the raw position via the already existingscreen_posfield.FileChooserNativeis stored in the tool until the response arrives — GTK does not hold a reference to native dialogs, and dropping the wrapper while the dialog is open crashes deep inside the file chooser internals.Testing
cargo fmt,cargo clippy --all-targets --all-features -- -D warningsandcargo testare clean.Note: building currently requires a newer toolchain than the pinned
rust-overlayinflake.lockprovides (rustc ≥ 1.92 for relm4 0.10.1 and friends) — that predates this PR; I built withnix develop --override-input rust-overlay github:oxalica/rust-overlay.