From d4c4361b4a36a5e397d76bb01511f6812c701926 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 5 Oct 2026 22:43:23 +0700 Subject: [PATCH 1/3] M14.1: long menus scroll inside the window and use all the height they have Menu bar menus, their submenus, panel menus, the effects menu groups and library submenus are as tall as their items down to the window's bottom edge, and scroll only past that (widgets::menu_scroll), instead of running off screen. Co-Authored-By: Claude Opus 5.5 --- ROADMAP.md | 2 +- crates/ui-egui/src/menus.rs | 48 +++++++++++++++++++--- crates/ui-egui/src/panels/appearance.rs | 12 +++--- crates/ui-egui/src/panels/library_panel.rs | 8 ++-- crates/ui-egui/src/panels/mod.rs | 6 ++- crates/ui-egui/src/widgets.rs | 13 ++++++ 6 files changed, 73 insertions(+), 16 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 7c39a1ba..25a23133 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -150,7 +150,7 @@ grade by behaviour against `plan/illustrator/`, not by whether a menu item exist | M11 | Artboards & views (artboard panel/tool, Trim View, middle-button pan and print tiling done; multiple windows, presentation polish) | 🟡 | 15–25 | | M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (12 presets, 18 ms/1k² image), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, regenerate in place) done; graph Design/Column/Marker designs pending | 6–10 | | M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 | 18–27 | -| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux and content-sized dialogs and menus done; accessibility, Windows/Linux packaging pending | 18–28 | +| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux, content-sized dialogs and menus that scroll when longer than the window done; accessibility, Windows/Linux packaging pending | 18–28 | | — | Interaction fidelity pass (every tool's modifiers, Properties panel per context, isolation, nuance) | ⬜ | 60–90 | | — | Hardening at scale (big-file corpus, fuzzing, cross-platform + browser QA) | 🟡 | 50–80 | | | **Total to full parity** (one agent; re-derived from the [Parity estimate](#parity-estimate) table) | | **~335–520** | diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index e7fcc540..103fe999 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -13,6 +13,7 @@ use crate::VectorcraftApp; use crate::io; use crate::state::{DockTab, ICON_PANELS, next_zoom}; use crate::theme::{self, Brightness, Tokens}; +use crate::widgets; #[derive(Clone, Debug)] pub enum Item { @@ -1860,10 +1861,13 @@ pub fn menu_bar(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> f32 { end } -/// A top-level menu's popup: as wide as its widest item (label plus shortcut), at least 230 pt. +/// A top-level menu's popup: as wide as its widest item (label plus shortcut), at least 230 pt; +/// it scrolls when it is taller than the window. fn menu_body(app: &VectorcraftApp, ui: &mut egui::Ui, items: &[Item], clicked: &mut Option<(String, Value)>) { - ui.set_min_width(230.0); - render_items(app, ui, items, clicked); + widgets::menu_scroll(ui, |ui| { + ui.set_min_width(230.0); + render_items(app, ui, items, clicked); + }); } fn render_items(app: &VectorcraftApp, ui: &mut egui::Ui, items: &[Item], clicked: &mut Option<(String, Value)>) { @@ -1878,8 +1882,10 @@ fn render_items(app: &VectorcraftApp, ui: &mut egui::Ui, items: &[Item], clicked } Item::Sub(label, children) => { ui.menu_button(*label, |ui| { - ui.set_min_width(200.0); - render_items(app, ui, children, clicked); + widgets::menu_scroll(ui, |ui| { + ui.set_min_width(200.0); + render_items(app, ui, children, clicked); + }); }); } Item::Todo(label, sc) => { @@ -2428,4 +2434,36 @@ mod tests { let w = ctx.memory(|m| m.area_rect(id)).unwrap().width(); assert!((230.0..340.0).contains(&w), "File menu is {w} pt wide"); } + + #[test] + fn long_menus_scroll_inside_a_short_window() { + // The Window menu is taller than a 600 pt window: it stops above the bottom edge and + // scrolls instead of running off screen. + let app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default()); + let ctx = egui::Context::default(); + crate::theme::install_fonts(&ctx); + let tree = menu_tree(); + let (_, window) = tree.iter().find(|(t, _)| *t == "Window").unwrap(); + let id = egui::Id::new("test-long-menu"); + let rect = |height: f32| { + let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1200.0, height)); + for _ in 0..3 { + let input = egui::RawInput { screen_rect: Some(screen), ..Default::default() }; + let mut out = ctx.run_ui(input, |ui| { + egui::Area::new(id).fixed_pos(egui::pos2(300.0, 30.0)).show(ui.ctx(), |ui| { + egui::containers::menu::menu_style(ui.style_mut()); + ui.with_layout(egui::Layout::top_down_justified(egui::Align::Min), |ui| menu_body(&app, ui, window, &mut None)); + }); + }); + out.textures_delta.clear(); + } + ctx.memory(|m| m.area_rect(id)).unwrap() + }; + let short = rect(600.0); + assert!(short.bottom() <= 600.0, "Window menu ends at {} in a 600 pt window", short.bottom()); + // With room to spare it shows whole, taller than the short window allowed. + let tall = rect(3000.0); + assert!(tall.height() > short.height() + 100.0, "{} vs {}", tall.height(), short.height()); + assert!(tall.bottom() < 3000.0); + } } diff --git a/crates/ui-egui/src/panels/appearance.rs b/crates/ui-egui/src/panels/appearance.rs index 8c5b6423..bab72d90 100644 --- a/crates/ui-egui/src/panels/appearance.rs +++ b/crates/ui-egui/src/panels/appearance.rs @@ -870,12 +870,14 @@ pub(crate) fn fx_menu(app: &mut VectorcraftApp, ui: &mut Ui) { } for (g, items) in groups { ui.menu_button(g, |ui| { - for (id, label) in items { - if ui.button(format!("{label}…")).clicked() { - app.run("effect.dialog", json!({"effect": id})).ok(); - ui.close(); + crate::widgets::menu_scroll(ui, |ui| { + for (id, label) in items { + if ui.button(format!("{label}…")).clicked() { + app.run("effect.dialog", json!({"effect": id})).ok(); + ui.close(); + } } - } + }); }); } } diff --git a/crates/ui-egui/src/panels/library_panel.rs b/crates/ui-egui/src/panels/library_panel.rs index f57e97b3..2affee13 100644 --- a/crates/ui-egui/src/panels/library_panel.rs +++ b/crates/ui-egui/src/panels/library_panel.rs @@ -374,9 +374,11 @@ pub(crate) fn library_items(ui: &mut Ui, libs: &[LibraryRef], current: Option<&s } for s in subs { ui.menu_button(s, |ui| { - for l in libs.iter().filter(|l| l.submenu == Some(s)) { - item(ui, l); - } + crate::widgets::menu_scroll(ui, |ui| { + for l in libs.iter().filter(|l| l.submenu == Some(s)) { + item(ui, l); + } + }); }); } chosen diff --git a/crates/ui-egui/src/panels/mod.rs b/crates/ui-egui/src/panels/mod.rs index 521db16b..055732d8 100644 --- a/crates/ui-egui/src/panels/mod.rs +++ b/crates/ui-egui/src/panels/mod.rs @@ -158,8 +158,10 @@ pub fn panel_menu(app: &mut VectorcraftApp, ui: &mut Ui, id: &str, rect: Rect) { icons::paint(ui, "menu", rect.shrink(1.0), if resp.hovered() { t.text_strong } else { t.text_dim }); let resp = resp.on_hover_text("Panel menu"); egui::Popup::menu(&resp).show(|ui| { - ui.set_min_width(220.0); - panel_menu_items(app, ui, id); + crate::widgets::menu_scroll(ui, |ui| { + ui.set_min_width(220.0); + panel_menu_items(app, ui, id); + }); }); } diff --git a/crates/ui-egui/src/widgets.rs b/crates/ui-egui/src/widgets.rs index 3faaa7e3..4d8bcc12 100644 --- a/crates/ui-egui/src/widgets.rs +++ b/crates/ui-egui/src/widgets.rs @@ -426,6 +426,19 @@ fn combo( .inner } +/// The body of a menu or popup list: as tall as its items up to the bottom of the window, and +/// scrolling only past that, so long menus (Window, Effect, a panel's menu) stay reachable on +/// small windows. +pub fn menu_scroll(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R { + // Room left below the popup's first item, less the popup frame and a small gap. + const BOTTOM_GAP: f32 = 12.0; + const MIN_HEIGHT: f32 = 120.0; + let room = (ui.ctx().content_rect().bottom() - ui.next_widget_position().y - BOTTOM_GAP).max(MIN_HEIGHT); + // The minimum lets the list grow past a popup's default 400 pt size; it still shrinks to + // its items when they need less. + egui::ScrollArea::vertical().max_height(room).min_scrolled_height(room).show(ui, add_contents).inner +} + /// Whether the blend-mode list draws a separator above `BlendMode::ALL[i]`: where a /// [`BlendMode::group`] starts. pub fn blend_separator_before(i: usize) -> bool { From 258337cf7c5117ea1d597191d872acd7d96be708 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 5 Oct 2026 22:43:26 +0700 Subject: [PATCH 2/3] M14.3: the Home button shows the Home screen over open documents It used to open the New Document dialog. Now it runs the new app.home UI command: the Home screen replaces the canvas while the documents stay open as tabs; choosing a tab, or a document opening, closing or becoming active, returns. Co-Authored-By: Claude Opus 5.5 --- ROADMAP.md | 2 +- crates/ui-egui/src/canvas.rs | 6 ++++- crates/ui-egui/src/chrome.rs | 9 ++++--- crates/ui-egui/src/lib.rs | 2 ++ crates/ui-egui/src/menus.rs | 11 +++++++++ crates/ui-egui/src/state.rs | 6 +++++ crates/ui-egui/src/tests_home.rs | 40 ++++++++++++++++++++++++++++++++ 7 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 crates/ui-egui/src/tests_home.rs diff --git a/ROADMAP.md b/ROADMAP.md index 25a23133..7efd344a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -150,7 +150,7 @@ grade by behaviour against `plan/illustrator/`, not by whether a menu item exist | M11 | Artboards & views (artboard panel/tool, Trim View, middle-button pan and print tiling done; multiple windows, presentation polish) | 🟡 | 15–25 | | M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (12 presets, 18 ms/1k² image), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, regenerate in place) done; graph Design/Column/Marker designs pending | 6–10 | | M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 | 18–27 | -| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux, content-sized dialogs and menus that scroll when longer than the window done; accessibility, Windows/Linux packaging pending | 18–28 | +| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux with a Home button, content-sized dialogs and menus that scroll when longer than the window done; accessibility, Windows/Linux packaging pending | 18–28 | | — | Interaction fidelity pass (every tool's modifiers, Properties panel per context, isolation, nuance) | ⬜ | 60–90 | | — | Hardening at scale (big-file corpus, fuzzing, cross-platform + browser QA) | 🟡 | 50–80 | | | **Total to full parity** (one agent; re-derived from the [Parity estimate](#parity-estimate) table) | | **~335–520** | diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 86ea9d13..4b9dde39 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -127,7 +127,11 @@ pub fn fit(app: &mut VectorcraftApp, how: &str) { pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) { let t = Tokens::get(ui.ctx()); let full = ui.available_rect_before_wrap(); - if app.session.active().is_none() { + // A document that opened, closed or became active since Home was chosen replaces it. + if app.ui.home.is_some_and(|k| k != crate::menus::home_key(app)) { + app.ui.home = None; + } + if app.session.active().is_none() || app.ui.home.is_some() { home(app, ui, full); return; } diff --git a/crates/ui-egui/src/chrome.rs b/crates/ui-egui/src/chrome.rs index 42fceecb..5126897f 100644 --- a/crates/ui-egui/src/chrome.rs +++ b/crates/ui-egui/src/chrome.rs @@ -27,8 +27,9 @@ pub fn app_bar(app: &mut VectorcraftApp, ui: &mut Ui) { let (r, _) = ui.allocate_exact_size(vec2(22.0, 22.0), Sense::hover()); crate::brand::paint_mark(ui, r); ui.add_space(4.0); - if widgets::icon_button(ui, "house", "Home", false, 24.0).clicked() { - crate::dialogs::open_new_document(app); + let on_home = app.ui.home.is_some() || app.session.active().is_none(); + if widgets::icon_button(ui, "house", "Home", on_home, 24.0).clicked() { + app.run("app.home", json!({})).ok(); } ui.add_space(2.0); let menus_end = if app.native_menu { @@ -237,7 +238,8 @@ pub fn doc_tabs(app: &mut VectorcraftApp, ui: &mut Ui) { for (i, d) in app.session.documents().iter().enumerate() { let zoom = app.views.get(i).map(|v| v.zoom).unwrap_or(1.0); let title = tab_title(d, zoom, app.ui.view.outline); - let is_active = Some(i) == active; + // On the Home screen no tab is the current one. + let is_active = Some(i) == active && app.ui.home.is_none(); let galley = ui.painter().layout_no_wrap(title, theme::semibold(12.5), if is_active { t.text_strong } else { t.text_dim }); let w = galley.size().x + 50.0; let r = egui::Rect::from_min_size(egui::pos2(x, strip.top()), vec2(w, strip.height() - 1.0)); @@ -265,6 +267,7 @@ pub fn doc_tabs(app: &mut VectorcraftApp, ui: &mut Ui) { app.status(e); } } else if let Some(i) = activate { + app.ui.home = None; app.session.set_active(i); } // Isolation mode breadcrumb bar. diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 1befbd13..70a26f24 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -46,6 +46,8 @@ mod tests_clipboard; #[cfg(test)] mod tests_docsetup; #[cfg(test)] +mod tests_home; +#[cfg(test)] mod tests_labels; #[cfg(test)] mod tests_nativeoptions; diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 103fe999..81341c9e 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -111,6 +111,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[ ), ("file.documentSetup", "Document Setup…", "Cmd+Alt+P", "{}"), ("file.newDialog", "New…", "Cmd+N", "{} opens the New Document dialog"), + ("app.home", "Home", "", "{} shows the Home screen (new file presets, Open) over the open documents; choosing a document tab returns to it"), ("edit.preferences", "Preferences…", "Cmd+K", "{category?} open Preferences (engine: prefs.get / prefs.set / prefs.list)"), ("edit.keyboardShortcuts", "Keyboard Shortcuts…", "Cmd+Alt+Shift+K", "{}"), ("shortcuts.set", "Set Keyboard Shortcut", "", "{id: command id or tool:, shortcut: \"Cmd+Shift+K\" | \"\" (none) | null (default), force?}"), @@ -549,6 +550,10 @@ pub fn run_ui_command(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option { + app.ui.home = Some(home_key(app)); + Ok(Value::Null) + } "file.open" => match s("path") { Some(path) => io::open_path(app, &path).map(|_| Value::Null), None => io::open_dialog(app).map(|_| Value::Null), @@ -1919,6 +1924,12 @@ fn render_items(app: &VectorcraftApp, ui: &mut egui::Ui, items: &[Item], clicked } } +/// What the Home screen remembers when it opens (`app.home`): the active document and the +/// document count. When either changes, the Home screen gives way to the document. +pub(crate) fn home_key(app: &VectorcraftApp) -> (Option, usize) { + (app.session.active().map(|d| d.uid), app.session.documents().len()) +} + fn label_of(it: &Item) -> &'static str { match it { Item::Cmd(l, _, _) => l, diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index 7a7d1303..4c7c3153 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -298,6 +298,11 @@ pub struct UiState { /// never used). #[serde(default)] pub dxf_import: Value, + /// The Home screen is shown over the open documents (`app.home`): the active document's uid + /// and the document count when it opened. Choosing a tab, or a document opening, closing or + /// becoming active, leaves it. + #[serde(skip)] + pub home: Option<(Option, usize)>, } impl UiState { @@ -359,6 +364,7 @@ impl Default for UiState { dxf_options: Value::Null, eps_options: Value::Null, dxf_import: Value::Null, + home: None, } } } diff --git a/crates/ui-egui/src/tests_home.rs b/crates/ui-egui/src/tests_home.rs new file mode 100644 index 00000000..c3208f53 --- /dev/null +++ b/crates/ui-egui/src/tests_home.rs @@ -0,0 +1,40 @@ +//! The Home icon shows the Home screen over open documents. + +use serde_json::json; + +use crate::{VectorcraftApp, canvas}; + +fn app_with_doc() -> VectorcraftApp { + let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default()); + app.run("file.new", json!({})).unwrap(); + app +} + +/// Draw one canvas frame; whether it drew the document (else the Home screen). +fn shows_document(app: &mut VectorcraftApp) -> bool { + app.canvas_rect = None; + let ctx = egui::Context::default(); + crate::theme::install_fonts(&ctx); + let raw = egui::RawInput { screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(800.0, 600.0))), ..Default::default() }; + let mut out = ctx.run_ui(raw, |ui| canvas::show(app, ui)); + out.textures_delta.clear(); + app.canvas_rect.is_some() +} + +#[test] +fn home_shows_over_open_documents_until_a_document_is_chosen() { + let mut app = app_with_doc(); + assert!(shows_document(&mut app)); + app.run("app.home", json!({})).unwrap(); + assert!(!shows_document(&mut app), "Home replaces the canvas"); + assert_eq!(app.session.documents().len(), 1, "the document stays open"); + assert!(app.ui.dialog.is_none(), "Home is not the New Document dialog"); + // Choosing the document's tab returns to it. + app.ui.home = None; + assert!(shows_document(&mut app)); + // A new document (from Home's presets, New… or Open) replaces Home too. + app.run("app.home", json!({})).unwrap(); + app.run("file.new", json!({})).unwrap(); + assert!(shows_document(&mut app)); + assert!(app.ui.home.is_none()); +} From d0d934bfda252296c7d42dca165b0ea8e122c2b7 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 5 Oct 2026 22:43:28 +0700 Subject: [PATCH 3/3] M14.7: Cmd/Ctrl+N opens the New Document dialog The engine's file.new also claimed Cmd+N and engine commands win shortcut lookups, so the shortcut made a blank document. file.newDialog now owns it, as the docs already said; file.new stays the headless command. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/cmd/edit.rs | 2 +- crates/ui-egui/src/tests_home.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/edit.rs b/crates/engine/src/cmd/edit.rs index c230b009..fa58a619 100644 --- a/crates/engine/src/cmd/edit.rs +++ b/crates/engine/src/cmd/edit.rs @@ -17,7 +17,7 @@ pub fn specs() -> Vec { "file.new", "New…", ["File"], - Some("Cmd+N"), + None, "{preset?: a name from file.newPresets (start from it; the other params change it), name?|title?: document name (default Untitled-N), width?: pt=612|\"210 mm\", height?: pt=792, units?: \"Pixels\"|\"Points\"|\"Picas\"|\"Inches\"|\"Millimeters\"|\"Centimeters\"|\"Feet\"|\"Yards\"|\"Meters\"|\"Feet & Inches\" (default: prefs unitsGeneral, as print presets; screen presets: Pixels), orientation?: \"portrait\"|\"landscape\" (swaps width and height to match), artboards?: n (1–1000), artboardLayout?: {layout?: \"gridByRow\"|\"gridByColumn\"|\"row\"|\"column\", columns?: n (default: all in one row), spacing?: pt=20, rightToLeft?: bool}, bleed?: pt|[top, bottom, left, right]|{top?, …} (0–72 pt), backgroundContents?: \"transparent\"|\"white\" (a white artboard background, not an object), colorMode?: \"rgb\"|\"cmyk\" (a CMYK document starts with CMYK swatches and stores the colours applied to it as CMYK), rasterEffectsPpi?: 72|150|300 (1–2400), previewMode?: \"default\"|\"pixel\"|\"overprint\" (overprint turns Overprint Preview on, pixel Pixel Preview in the app; default leaves both), created?: Unix seconds|null (File Info's created date; default now, recorded in the journal so a replay matches)} → {index, previewMode}; the size is remembered in file.newPresets' Recent", always, super::newdoc::file_new diff --git a/crates/ui-egui/src/tests_home.rs b/crates/ui-egui/src/tests_home.rs index c3208f53..0fd8f0ca 100644 --- a/crates/ui-egui/src/tests_home.rs +++ b/crates/ui-egui/src/tests_home.rs @@ -1,4 +1,4 @@ -//! The Home icon shows the Home screen over open documents. +//! The Home icon shows the Home screen over open documents; Cmd+N opens the New Document dialog. use serde_json::json; @@ -38,3 +38,12 @@ fn home_shows_over_open_documents_until_a_document_is_chosen() { assert!(shows_document(&mut app)); assert!(app.ui.home.is_none()); } + +#[test] +fn cmd_n_opens_the_new_document_dialog() { + assert_eq!(crate::shortcut_editor::command_for_key("Cmd+N"), Some("file.newDialog")); + let mut app = app_with_doc(); + app.run("file.newDialog", json!({})).unwrap(); + assert_eq!(app.ui.dialog.as_ref().map(|d| d.kind.as_str()), Some("newDocument")); + assert_eq!(app.session.documents().len(), 1, "no document is made until the dialog's OK"); +}