DeckCraft forces X11 whenever DISPLAY is set. A stale DISPLAY (an ended ssh -X session, or
Xwayland turned off) made start-up fail with "failed to open display" while a Wayland
compositor was running. A local DISPLAY whose /tmp/.X11-unix socket is missing now starts on
Wayland when WAYLAND_DISPLAY is set; remote displays and live servers keep X11. Forcing Wayland
without a compositor keeps X11, and with no display at all the error says so plainly.
Co-authored-by: Cursor <cursoragent@cursor.com>
Same fix as storytold/gridcraft#117 (storytold/gridcraft#316): eframe drops
the window while AppKit's run loop still runs, AccessKit restores the
content view's class and AppKit's Touch Bar KVO observer throws on the
next display cycle. on_exit now ends the process on macOS once the
preferences are saved.
wgpu's default DX12 compiler (Auto) loads whichever dxcompiler.dll the DLL
search path finds. DeckCraft ships none, and without a matching dxil.dll the
unsigned-DXIL warning fails wgpu's indirect-validation pipeline, the device
is lost and the app exits before the first frame. Pin the compiler to FXC,
which is part of Windows; WGPU_DX12_COMPILER still overrides it.
Fixes#153
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three causes, each making links look like they "don't save":
- With the caret at a word boundary (end of text, empty paragraph),
insert.hyperlink formatted an empty range and changed nothing. It now
inserts the address (or the slide's title, or `text`) as linked text, as
PowerPoint does. Typing right after a link no longer extends it.
- The slide show ignored hyperlinks and shape actions. A click on one now
follows it (ShowState::follow): slides, next/previous/first/last, Last
Slide Viewed, End Show, and URLs; the pointer turns into a hand over links.
- The desktop app was built without eframe's `links` feature, so
ctx.open_url did nothing natively (also the ribbon's app page link).
Enabled as in DesignCraft, EffectCraft and PrintCraft.
Saving was fine: links round-trip through .deckcraft and .pptx.
generated with Claude Code
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
eframe's default wgpu instance enables PRIMARY | GL on Windows. Creating
the OpenGL backend can crash inside AMD's atio6axx.dll before the window
appears, so the app exits silently at launch. When WGPU_BACKEND is not
set, the Windows instance now enables only DirectX 12; an explicit
WGPU_BACKEND is still honoured. macOS, Linux and web are unchanged.
Same fix as storytold/designcraft#168 and storytold/filmcraft#179.
Claude-Session: https://claude.ai/code/session_01LyVbT6Vv4BwWZ4hY8973qD
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The desktop app installed no logger, so every log::warn!/log::error! in
the workspace was discarded: the crash guard's panic report, a failed
crash-recovery save, PowerPoint parts skipped on import, audio output
problems. A launch from a desktop menu has no terminal either, so there
was nothing to attach to a bug report.
apps/deckcraft/src/logging.rs (no new dependency):
- standard error plus <settings dir>/logs/deckcraft.log (beside ui.json
and prefs.json); each launch rotates the previous log to
deckcraft.1.log and .2.log, so the log of a run that crashed survives
the next start; the file is capped at 16 MiB
- records logged before the settings directory is known are buffered
(bounded) and written once the file is attached
- default levels: info for deckcraft*, warn for everything else;
RUST_LOG replaces them with env_logger-style directives
- never panics: an unusable directory or a failed write leaves standard
error as the only sink; a poisoned lock is tolerated
- a record holds the lock for one write of an already formatted line
The cpal error callback runs on the realtime audio thread (on ALSA in a
loop while the device stays broken), so it no longer logs: it keeps the
first error without blocking, and the UI thread logs it when the stream
stops.
The logger is installed first in main (before the engine's panic hook)
and the file is opened after argument parsing (--version leaves no
file). The settings directory moves out of prefs_path into config_dir.
The start-up eprintln!s (sample, files that fail to open, control
server) now go through the logger. Documented in README.md (Getting
started > Logs).
Co-authored-by: Brandon Thomas <echelon@gmail.com>