This commit is contained in:
Brandon Thomas
2026-10-14 22:05:11 -04:00
3 changed files with 15 additions and 4 deletions
+1
View File
@@ -169,6 +169,7 @@ Newest first.
- **2026-10-13** · An explicit recovery folder (`file.recovery.save` with `dir`) never overwrites or deletes another running app's checkpoints. Document uids start at 1 in every process, so two apps saving recovery to one chosen folder replaced or removed each other's `<uid>.designcraft`. A run replaces or removes only the entries it wrote or recovered there, refuses an occupied uid, and refuses a folder whose run lock another app holds. No readiness percentage change.
- **2026-10-13** · Path edits (`path.setAnchor`, `path.moveAnchors`, `path.appendAnchor`, `path.reverse`, `path.close`, anchor add/delete/convert, Erase, Smooth and Scissors) refuse a path that is locked, sits in a locked group or on a locked layer (#735). Properties links to the Stroke, Character, Paragraph, Effects, Text Wrap and Info panels open them in a customized panel layout too (#736). No readiness percentage change.
- **2026-10-13** · IDML export keeps parent item overrides: each page lists its overridden parent items and the local copy keeps its link to the parent item, so a reopened IDML file shows only the local copy (#725). No readiness percentage change.
- **2026-10-13** · macOS: a command chosen with the mouse in the menu bar runs at once. It used to wait for the next mouse move or key press over the window, so File › Open, Place and Save As seemed to take 10–20 seconds to open their dialogs. No readiness percentage change.
- **2026-10-12** · macOS Dock Quit uses the same unsaved-document prompts as window and menu Quit. Repeated requests keep the current answers; Cancel retains every tab and unsaved recovery checkpoint, and completed Save/Don't Save answers exit through the ordinary event loop. No readiness percentage change.
- **2026-10-12** · Text strokes can sit behind the fill: the stroke lies wholly outside the letters at its full weight on screen, in PNG and in PDF, set from the Properties panel or Character Style Options. IDML `StrokeAlignment` on text imports and exports as this setting, so imported text with outside-aligned strokes keeps its letter shapes (#619). No readiness percentage change.
- **2026-10-12** · Placed Word documents keep their bullets and numbering (#626): `numbering.xml` levels become bullet or numbered paragraphs with Word's number formats, label text, start numbers, restarts and list indents, also when a paragraph style carries the list. No readiness percentage change.
+1 -1
View File
@@ -45,7 +45,7 @@ impl eframe::App for App {
#[cfg(target_os = "macos")]
{
if self.menu.is_none() && std::env::var_os("DESIGNCRAFT_NO_NATIVE_MENU").is_none() {
self.menu = Some(native_menu::NativeMenu::install(&mut self.app));
self.menu = Some(native_menu::NativeMenu::install(&mut self.app, ctx));
}
if let Some(m) = &mut self.menu {
m.poll(&mut self.app, ctx);
+13 -3
View File
@@ -4,6 +4,7 @@
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::mpsc::{Receiver, channel};
use designcraft_ui_egui::DesignApp;
use designcraft_ui_egui::menus::{self, Item};
@@ -19,6 +20,7 @@ enum Handle {
pub struct NativeMenu {
_menu: Menu,
items: HashMap<String, (String, Value, Handle)>,
events: Receiver<MenuEvent>,
last_refresh: f64,
}
@@ -31,7 +33,15 @@ fn accel(sc: &str) -> Option<Accelerator> {
}
impl NativeMenu {
pub fn install(app: &mut DesignApp) -> Self {
pub fn install(app: &mut DesignApp, ctx: &egui::Context) -> Self {
// A click in the menu bar reaches the app with no input over the window, so nothing would
// draw the frame that runs the command until the pointer or a key comes back: wake egui.
let (tx, events) = channel();
let repaint = ctx.clone();
MenuEvent::set_event_handler(Some(move |e: MenuEvent| {
let _ = tx.send(e);
repaint.request_repaint();
}));
let menu = Menu::new();
let mut items = HashMap::new();
let mut counter = 0usize;
@@ -72,11 +82,11 @@ impl NativeMenu {
(p.is_null() && accel(sc).is_some()).then(|| id.clone())
})
.collect();
Self { _menu: menu, items, last_refresh: 0.0 }
Self { _menu: menu, items, events, last_refresh: 0.0 }
}
pub fn poll(&mut self, app: &mut DesignApp, ctx: &egui::Context) {
while let Ok(ev) = MenuEvent::receiver().try_recv() {
while let Ok(ev) = self.events.try_recv() {
if let Some((cmd, params, _)) = self.items.get(ev.id.as_ref()) {
menus::activate_native(app, ctx, &cmd.clone(), &params.clone());
}