Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ The v0.9.23+ prebuilt `wayscriber` packages require glibc 2.39 and GTK 4.12. See

### Drawing and editing
- Freehand pen, highlighter, eraser (circle/rect)
- Shape pen: draw naturally and confident strokes preview and become editable lines, circles, ovals, rectangles, or triangles; other strokes remain freehand. Choose **Live Shaping Tool** in the command palette or the toolbar's Shapes picker. Adjust recognition with `[drawing] shape_recognition_sensitivity` (0-4) or the configurator's Drawing page.
- Shape Pen: draw naturally and confident strokes preview and become editable lines, circles, ovals, rectangles, or triangles; other strokes remain freehand, and one undo turns a recognized shape back into its ink. Press `S`, click it next to Pen on the toolbar (in the Shapes picker in simple mode), or choose **Shape Pen Tool** in the command palette. Adjust recognition with the toolbar's **Sensitivity** stepper, `[drawing] shape_recognition_sensitivity` (0-4), or the configurator's Drawing page; the level is remembered with the session.
- Pen smoothing: finished pen and marker strokes are cleaned up on release, so the live line never lags the cursor (`[drawing] pen_smoothing`, 0-6, or the toolbar's **Smoothing** stepper); tablet pressure values are preserved, and the level is remembered with the session
- Shapes: lines, rectangles, ellipses, polygons (with fill toggle)
- Arrows in four styles - standard, pointy, curved (drag its handle to route around what is in the way), and double-ended - with optional auto-numbered labels; step markers for walkthroughs
Expand Down
27 changes: 20 additions & 7 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ decrease_marker_opacity = ["Ctrl+Alt+ArrowDown"]
# Tool selection shortcuts (optional; keep empty to rely on modifiers)
select_selection_tool = ["V"]
select_pen_tool = ["F"]
select_live_shape_tool = []
select_live_shape_tool = ["S"]
select_marker_tool = ["H"]
select_step_marker_tool = []
select_eraser_tool = ["D"]
Expand All @@ -129,6 +129,9 @@ open_font_picker = []
# Step stroke smoothing up and down (unbound by default)
increase_pen_smoothing = []
decrease_pen_smoothing = []
# Step Shape Pen recognition sensitivity up and down (unbound by default)
increase_shape_recognition_sensitivity = []
decrease_shape_recognition_sensitivity = []
# Select the spotlight tool (unbound by default)
select_spotlight_tool = []
# Step the blur tool through blur/pixelate/secure/black-out (unbound by default)
Expand Down Expand Up @@ -479,7 +482,8 @@ show_capabilities_warning = true
# The guided tour remains available manually when this is false.
show_onboarding_hints = true

# Show rectangle and ellipse preview dimensions in logical board pixels.
# Show rectangle and ellipse preview dimensions in logical board pixels, and
# the shape Shape Pen has recognized with its size (a line shows its length).
# This is separate from capture.region.show_size_readout.
show_shape_size_readout = true

Expand Down Expand Up @@ -1118,11 +1122,20 @@ font_cycle = ["Sans", "Monospace", "Serif"]
# A session remembers the level it was saved at; this is the starting value.
pen_smoothing = 3

# Shape Pen recognition sensitivity (0 - 4): 0 is precise, 2 is balanced,
# and 4 accepts rougher lines and closed shapes. Applies to lines, ellipses,
# rectangles, and triangles; it does not change the dedicated shape tools or
# grid spacing.
shape_recognition_sensitivity = 2
# Shape Pen recognition sensitivity (0 - 4): 0 is precise, 3 (the default)
# is forgiving, and 4 accepts the roughest lines and closed shapes. Applies to
# lines, ellipses, rectangles, and triangles; it does not change the dedicated
# shape tools or grid spacing.
#
# Also on the toolbar as the "Sensitivity" stepper while Shape Pen is up.
# A session remembers the level it was saved at; this is the starting value.
shape_recognition_sensitivity = 3

# Snap Shape Pen results to board paper: lines to nearby grid lines,
# rectangle and oval edges to Cartesian lines, and triangle corners to
# Cartesian lines or isometric points. Set to false to keep recognized shapes
# exactly where you drew them.
shape_recognition_grid_snap = true

# Default fill state for fill-capable shapes
default_fill_enabled = false
Expand Down
6 changes: 6 additions & 0 deletions configurator/src/app/pages/drawing/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ pub(super) fn build(page: &mut PageBuilder) {
)
},
)
.switch_row(
"Snap Shape Pen to board paper",
"Recognized lines, rectangles, ovals, and triangles line up with nearby grid lines and points",
|app| app.draft.drawing_shape_recognition_grid_snap,
|value| Message::ToggleChanged(ToggleField::DrawingShapeRecognitionGridSnap, value),
)
.entry_row_validated(
"Undo stack limit",
|app| app.draft.drawing_undo_stack_limit.clone(),
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/app/pages/ui/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub(super) fn build(sender: &ComponentSender<ConfiguratorApp>) -> BuiltPage {
)
.switch_row(
"Show shape size readout",
"Shows rectangle and ellipse preview dimensions in logical board pixels. Separate from the region-capture size readout.",
"Shows rectangle and ellipse preview dimensions in logical board pixels, and the shape Shape Pen has recognized. Separate from the region-capture size readout.",
|app| app.draft.ui_show_shape_size_readout,
|value| Message::ToggleChanged(ToggleField::UiShowShapeSizeReadout, value),
)
Expand Down
2 changes: 2 additions & 0 deletions configurator/src/app/search/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub(super) const DRAWING_DEFAULT_TERMS: &[&str] = &[
"shape pen sensitivity",
"shape recognition",
"recognition sensitivity",
"snap shape pen to board paper",
"grid snap",
"marker",
"marker opacity",
"fill",
Expand Down
1 change: 1 addition & 0 deletions configurator/src/models/config/draft/from_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl ConfigDraft {
.drawing
.shape_recognition_sensitivity
.to_string(),
drawing_shape_recognition_grid_snap: config.drawing.shape_recognition_grid_snap,
drawing_font_cycle: FontCycleDraft::from_entries(config.drawing.font_cycle.clone()),
drawing_hit_test_tolerance: format_float(config.drawing.hit_test_tolerance),
drawing_hit_test_linear_threshold: config.drawing.hit_test_linear_threshold.to_string(),
Expand Down
1 change: 1 addition & 0 deletions configurator/src/models/config/draft/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct ConfigDraft {
pub drawing_marker_opacity: String,
pub drawing_pen_smoothing: String,
pub drawing_shape_recognition_sensitivity: String,
pub drawing_shape_recognition_grid_snap: bool,
/// Families `Shift+T` steps through, in order. A list rather than a
/// comma-separated line: a family name can contain a comma, and the row
/// editor picks from what is installed instead of asking for exact text.
Expand Down
3 changes: 3 additions & 0 deletions configurator/src/models/config/setters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ impl ConfigDraft {
ToggleField::DrawingFillEnabled => {
self.drawing_default_fill_enabled = value;
}
ToggleField::DrawingShapeRecognitionGridSnap => {
self.drawing_shape_recognition_grid_snap = value;
}
ToggleField::PerformanceVsync => {
self.set_performance_bool(PerformanceFieldId::EnableVsync, value);
}
Expand Down
19 changes: 19 additions & 0 deletions configurator/src/models/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ fn shape_pen_sensitivity_round_trips_and_rejects_invalid_drafts() {
assert_eq!(draft.drawing_shape_recognition_sensitivity, "5");
}

#[test]
fn shape_pen_grid_snap_round_trips() {
let mut config = Config::default();
assert!(config.drawing.shape_recognition_grid_snap);
config.drawing.shape_recognition_grid_snap = false;

let mut draft = ConfigDraft::from_config(&config);
assert!(!draft.drawing_shape_recognition_grid_snap);

draft.set_toggle(ToggleField::DrawingShapeRecognitionGridSnap, true);
assert!(
draft
.to_config(&config)
.expect("valid draft")
.drawing
.shape_recognition_grid_snap
);
}

#[test]
fn board_grid_draft_preserves_patterns_and_rejects_invalid_spacing() {
let mut config = Config::default();
Expand Down
1 change: 1 addition & 0 deletions configurator/src/models/config/to_config/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl ConfigDraft {
config.drawing.text_background_enabled = self.drawing_text_background_enabled;
config.drawing.text_halo_enabled = self.drawing_text_halo_enabled;
config.drawing.default_fill_enabled = self.drawing_default_fill_enabled;
config.drawing.shape_recognition_grid_snap = self.drawing_shape_recognition_grid_snap;
config.drawing.drag_tool = legacy_tool(
self.drawing_drag_tools.left.drag_tool,
DragBindableTool::Pen,
Expand Down
1 change: 1 addition & 0 deletions configurator/src/models/fields/toggles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub enum ToggleField {
DrawingTextBackground,
DrawingTextHalo,
DrawingFillEnabled,
DrawingShapeRecognitionGridSnap,
PerformanceVsync,
UiShowStatusBar,
UiStatusBarInteractive,
Expand Down
4 changes: 2 additions & 2 deletions configurator/src/models/fields/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl ToolOption {
match self {
Self::Select => "Select",
Self::Pen => "Pen",
Self::LiveShape => "Shape pen",
Self::LiveShape => "Shape Pen",
Self::Line => "Line",
Self::Rect => "Rectangle",
Self::Ellipse => "Ellipse",
Expand Down Expand Up @@ -222,7 +222,7 @@ impl DragToolOption {
Self::Default => "Button default",
Self::Select => "Select",
Self::Pen => "Pen",
Self::LiveShape => "Shape pen",
Self::LiveShape => "Shape Pen",
Self::Line => "Line",
Self::Rect => "Rectangle",
Self::Ellipse => "Ellipse",
Expand Down
2 changes: 2 additions & 0 deletions configurator/src/models/keybindings/field/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const PREFERRED_ORDER: &[KeybindingField] = &[
KeybindingField::OpenFontPicker,
KeybindingField::IncreasePenSmoothing,
KeybindingField::DecreasePenSmoothing,
KeybindingField::IncreaseShapeRecognitionSensitivity,
KeybindingField::DecreaseShapeRecognitionSensitivity,
KeybindingField::SelectMarkerTool,
KeybindingField::SelectStepMarkerTool,
KeybindingField::SelectLineTool,
Expand Down
17 changes: 11 additions & 6 deletions docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,10 @@ font_cycle = ["Sans", "Monospace", "Serif"]
# Smoothing applied to a finished freehand or marker stroke (0 - 6)
pen_smoothing = 3

# Shape Pen: 0 precise, 2 balanced (default), 4 more forgiving
shape_recognition_sensitivity = 2
# Shape Pen: 0 precise, 3 forgiving (default), 4 most forgiving
shape_recognition_sensitivity = 3
# Snap Shape Pen results to nearby board-paper lines and points
shape_recognition_grid_snap = true

# Default fill state for fill-capable shape tools
default_fill_enabled = false
Expand Down Expand Up @@ -381,7 +383,7 @@ drag_tool = "default"
- **Arrow style**: Run **Cycle Arrow Style** from the command palette to step through standard → pointy → curved → double (unbound by default; bind `cycle_arrow_style`). With arrows selected it restyles those in one undo step; with nothing selected it sets the style for the next arrow
- **Marker opacity**: Use <kbd>Ctrl+Alt</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd>
- **Pen smoothing**: Run **Increase / Decrease Pen Smoothing** from the command palette, or bind `increase_pen_smoothing` / `decrease_pen_smoothing` (see [Pen smoothing](#pen-smoothing))
- **Live shaping**: Choose **Shape pen** from the Shapes picker or **Live Shaping Tool** from the command palette; bind `select_live_shape_tool` for a shortcut. Confident lines, circles, ovals, axis-aligned rectangles, and triangles preview as shapes and commit as editable shapes. Set `[drawing] shape_recognition_sensitivity` from 0 (precise) to 4 (forgiving), with 2 as the default, or edit **Shape Pen sensitivity** on the configurator's Drawing page. Reopen the overlay after changing it. The setting affects recognition by Shape Pen, not the dedicated shape tools. Lines close to Cartesian or isometric board-paper lines snap to them; without a nearby grid line, nearly horizontal or vertical strokes align to that axis and skew lines keep their angle. Nearly horizontal or vertical triangle sides align the same way. Other ink stays freehand.
- **Shape Pen**: Press `S` (`select_live_shape_tool`), click **Shape Pen** next to Pen on the toolbar (in the Shapes picker in simple mode), or choose **Shape Pen Tool** from the command palette. Confident lines, circles, ovals, rectangles, and triangles preview as shapes over a faint copy of the stroke and commit as editable shapes. Recognized ovals, rectangles, and triangles follow the Fill toggle, like the dedicated shape tools. If a stroke should have stayed ink, undo once to get the original stroke back; undo again to remove it. Set `[drawing] shape_recognition_sensitivity` from 0 (precise) to 4 (most forgiving), with 3 as the default, or edit **Shape Pen sensitivity** on the configurator's Drawing page. While Shape Pen is active, the toolbar's **Sensitivity** stepper changes it at once; so do **Increase / Decrease Shape Pen Sensitivity** in the command palette, or bind `increase_shape_recognition_sensitivity` / `decrease_shape_recognition_sensitivity`. A session remembers the level it was saved at; the config value is the starting level. The setting affects recognition by Shape Pen, not the dedicated shape tools. Lines close to Cartesian or isometric board-paper lines snap to them; without a nearby grid line, nearly horizontal or vertical strokes align to that axis and skew lines keep their angle. Nearly horizontal or vertical triangle sides align the same way. Rectangle and oval edges also snap to nearby Cartesian lines, and triangle corners to nearby Cartesian lines or isometric points. Set `[drawing] shape_recognition_grid_snap = false`, or turn off **Snap Shape Pen to board paper** in the configurator, to keep recognized shapes exactly where you drew them; axis alignment still applies. Rectangles drawn quickly, with leaning or skewed sides, are squared up to the average position of each side. Other ink stays freehand.
- **Text font**: <kbd>Shift+T</kbd> steps through `font_cycle`; **Font Picker** in the command palette opens the full list (see [Font cycle](#font-cycle) and [Font picker](#font-picker))
- **Regular polygon sides**: Use the Shapes popover Sides control (range: 3-12)
- **Font size**: Use <kbd>Ctrl+Shift++</kbd>/<kbd>Ctrl+Shift+-</kbd> or <kbd>Shift</kbd> + scroll (range: 8-72px)
Expand Down Expand Up @@ -925,7 +927,8 @@ show_capabilities_warning = true
# appearances. The guided tour remains available manually when this is false.
show_onboarding_hints = true

# Show rectangle and ellipse preview dimensions in logical board pixels.
# Show rectangle and ellipse preview dimensions in logical board pixels, and
# the shape Shape Pen has recognized with its size (a line shows its length).
# This is separate from capture.region.show_size_readout.
show_shape_size_readout = true

Expand Down Expand Up @@ -1401,7 +1404,7 @@ top_controls = [
- **Context-aware UI**: `context_aware_ui` shows/hides tool-specific controls (colors, thickness, arrow labels, etc.) based on the active tool; disable to always show all controls.
- **Preset toasts**: `show_preset_toasts` enables toast confirmations for preset apply/save/clear.
- **Automatic guidance**: `show_onboarding_hints` controls first-run cards, discovery tips, and shortcut coaching. Discovery and coaching tips offer **Got it** (permanently acknowledge that tip) and **Tip settings…** (acknowledge it, then open the Configurator at this setting); the toolbar-hidden recovery tip keeps **Show** as its primary control and offers the same settings route. Using the board picker, bottom-right zoom controls, or Canvas popover also acknowledges the matching tip. Clicking the message body dismisses a tip only for the current run; an unattended tip stops after three appearances. Set this option to `false` to disable all automatic tutorials on later overlay launches; the running overlay does not live-reload this Configurator change. The guided tour remains available manually, and capability, safety, and configuration warnings are unaffected. Completed profiles migrated from onboarding versions before v6 are not enrolled in the later status-bar, Canvas, and zoom tip series. If onboarding progress cannot be saved, automatic guidance is disabled for that run and an actionable persistence warning is shown.
- **Shape size readout**: `show_shape_size_readout` controls the live rectangle and ellipse preview dimensions, measured in logical board pixels. Ellipse values match the diameter that will be committed, so an odd drag span rounds down to the nearest even diameter. It defaults to `true` and is separate from `capture.region.show_size_readout`, which describes a region-capture selection.
- **Shape size readout**: `show_shape_size_readout` controls the live rectangle and ellipse preview dimensions, measured in logical board pixels. With Shape Pen it names the shape that release will commit, such as "Triangle 120 × 90" or "Line 140", and stays hidden while the stroke is still ink. Ellipse values match the diameter that will be committed, so an odd drag span rounds down to the nearest even diameter. It defaults to `true` and is separate from `capture.region.show_size_readout`, which describes a region-capture selection.
- **Capability warnings**: `show_capabilities_warning` independently controls compositor limitation warnings; disabling tutorials does not hide safety, configuration, or capability diagnostics.
- **Tool preview**: `show_tool_preview` toggles the cursor bubble.
- **Offsets**: `top_offset` and `top_offset_y` are the authored default top-toolbar position. Dragging the strip saves its position as a runtime preference in `runtime-ui.toml` and leaves these untouched; editing one here again takes over from the saved drag.
Expand Down Expand Up @@ -2168,7 +2171,7 @@ decrease_marker_opacity = ["Ctrl+Alt+ArrowDown"]
# Tool selection shortcuts (optional; keep empty to rely on modifiers)
select_selection_tool = ["V"]
select_pen_tool = ["F"]
select_live_shape_tool = [] # draw ink that snaps to lines and shapes
select_live_shape_tool = ["S"] # draw ink that snaps to lines and shapes
select_marker_tool = ["H"]
select_step_marker_tool = []
select_eraser_tool = ["D"]
Expand All @@ -2177,6 +2180,8 @@ cycle_font_family = ["Shift+T"] # step the text font through drawing.font_cyc
open_font_picker = [] # pick from every installed family
increase_pen_smoothing = [] # clean up finished strokes more
decrease_pen_smoothing = [] # keep more of the drawn path
increase_shape_recognition_sensitivity = [] # Shape Pen: recognize rougher strokes
decrease_shape_recognition_sensitivity = [] # Shape Pen: keep more strokes as ink
cycle_blur_style = [] # blur -> pixelate -> secure -> black out
cycle_arrow_style = [] # standard -> pointy -> curved -> double
select_spotlight_tool = [] # dim everything except a region
Expand Down
1 change: 1 addition & 0 deletions src/backend/wayland/session/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ fn sample_tool_state() -> stored_session::ToolStateSnapshot {
blur_style: Default::default(),
recent_colors: Vec::new(),
pen_smoothing: None,
shape_recognition_sensitivity: None,
marker_opacity: Some(0.32),
spotlight_magnification: None,
fill_enabled: Some(false),
Expand Down
3 changes: 2 additions & 1 deletion src/backend/wayland/state/render/canvas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,8 @@ fn provisional_point_count(stroke: &crate::input::tool::ProvisionalToolStroke<'_
crate::input::tool::ProvisionalToolStroke::BorrowedFreehand { points, .. }
| crate::input::tool::ProvisionalToolStroke::BorrowedPressureFreehand { points, .. }
| crate::input::tool::ProvisionalToolStroke::BorrowedMarker { points, .. }
| crate::input::tool::ProvisionalToolStroke::EraserPreview { points, .. } => points.len(),
| crate::input::tool::ProvisionalToolStroke::EraserPreview { points, .. }
| crate::input::tool::ProvisionalToolStroke::Recognized { ink: points, .. } => points.len(),
crate::input::tool::ProvisionalToolStroke::Shape(_)
| crate::input::tool::ProvisionalToolStroke::BlurReplayPreview(_)
| crate::input::tool::ProvisionalToolStroke::None => 0,
Expand Down
Loading
Loading