fix(windows): start 32-bit builds on OpenGL so launch no longer exits (#839)

* fix(windows): start 32-bit builds on OpenGL so launch no longer exits

DirectX 12 graphics pipeline creation fails on 32-bit Windows, so the app quit before the window appeared.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add @odedigo to the contributor names list

The About window credits this username; no real name or display name was chosen.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
authored and GitHub committed 2026-10-12 09:20:53 -04:00
1 parent 912d49f38f
commit 0acf6bd512
7 files changed
+63 -26

No files matched your search

+4
View File
@@ -235,6 +235,10 @@ Remove-Item Env:WGPU_BACKEND # restore the default for later
An explicit `gl` override can bring the driver crash back on affected systems. The macOS, Linux An explicit `gl` override can bring the driver crash back on affected systems. The macOS, Linux
and web backend defaults are unchanged. and web backend defaults are unchanged.
The **32-bit** build uses OpenGL even when a DirectX 12 graphics card is present. On 32-bit
Windows, creating a DirectX 12 graphics pipeline fails immediately and the app exits before the
window appears. `WGPU_BACKEND=vulkan` (or `dx12`) still overrides that.
**If the app quits right after its window appears with "Parent device is lost" in the log:** **If the app quits right after its window appears with "Parent device is lost" in the log:**
WordCraft compiles DirectX 12 shaders with FXC, the compiler built into Windows, so it needs no WordCraft compiles DirectX 12 shaders with FXC, the compiler built into Windows, so it needs no
`dxcompiler.dll`/`dxil.dll` and ignores any copy another program put on `PATH` (#603). `dxcompiler.dll`/`dxil.dll` and ignores any copy another program put on `PATH` (#603).
+2 -1
View File
@@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away **Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** trivial (Turkish interface catalog completed, #774; previously trivial: Hungarian interface landed; previously trivial: Quick Access Toolbar KeyTips and a saved enable/disable option, #620; previously trivial: new documents follow the system region, #838; previously minor: Polish interface and Polish proofing; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** trivial (32-bit Windows starts on OpenGL so launch no longer exits; previously trivial: every measurement follows the Options unit, #755; previously trivial: Insert › SmartArt landed, #497: catalog 429/451 → 437/458 (95.4%); previously trivial: Turkish interface landed; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
WordCraft aims for complete parity with Microsoft Word, then goes further on speed, openness and WordCraft aims for complete parity with Microsoft Word, then goes further on speed, openness and
agent control. This page is the summary; the assessment is agent control. This page is the summary; the assessment is
@@ -132,6 +132,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
## Progress log ## Progress log
| Date | What landed | | Date | What landed |
| 2026-10-12 | 32-bit Windows starts on OpenGL. DirectX 12 graphics pipeline creation returns "The parameter is incorrect" and the app exited before the window appeared |
| 2026-10-12 | New documents follow the system region (#838): A4 and centimetres outside the US (Letter in the CLDR Letter territories, inches in the US), lengths written with the region's decimal separator (`2,54 cm`) and typed with either; an explicit Measurement units choice wins; `file.options {"region"}` for agents | | 2026-10-12 | New documents follow the system region (#838): A4 and centimetres outside the US (Letter in the CLDR Letter territories, inches in the US), lengths written with the region's decimal separator (`2,54 cm`) and typed with either; an explicit Measurement units choice wins; `file.options {"region"}` for agents |
| 2026-10-12 | Paste from other programs keeps their formatting (#687): Ctrl+V and Home › Paste read the system clipboard's HTML (and RTF on Windows and Wayland); Merge Formatting takes the destination's font and paragraph and keeps bold, italic, underline and strikethrough; Paste Special lists what the system clipboard holds (HTML, RTF, picture, text). Linux: pictures copied in a browser or Spectacle paste on KDE and other Wayland desktops (data-control clipboard), and a paste that finds nothing usable names what the clipboard holds instead of "empty" (#833) | | 2026-10-12 | Paste from other programs keeps their formatting (#687): Ctrl+V and Home › Paste read the system clipboard's HTML (and RTF on Windows and Wayland); Merge Formatting takes the destination's font and paragraph and keeps bold, italic, underline and strikethrough; Paste Special lists what the system clipboard holds (HTML, RTF, picture, text). Linux: pictures copied in a browser or Spectacle paste on KDE and other Wayland desktops (data-control clipboard), and a paste that finds nothing usable names what the clipboard holds instead of "empty" (#833) |
| 2026-10-12 | PDF export of long documents with many internal links (a linked table of contents) is linear: NIH's 67-page protocol template 10.6 s → 0.9 s | | 2026-10-12 | PDF export of long documents with many internal links (a linked table of contents) is linear: NIH's 67-page protocol template 10.6 s → 0.9 s |
+46 -19
View File
@@ -20,18 +20,28 @@ pub struct Dx12Adapter {
/// The backends to initialize on Windows. /// The backends to initialize on Windows.
/// ///
/// An explicit `backend_override` (normally `Backends::from_env()`, i.e. `WGPU_BACKEND`) always /// An explicit `backend_override` (normally `Backends::from_env()`, i.e. `WGPU_BACKEND`) always
/// wins. Otherwise DirectX 12 only, as long as `dx12_adapters` (what a DirectX 12-only probe found) /// wins. Otherwise DirectX 12 only, as long as `dx12_graphics` is set and `dx12_adapters` (what a
/// contains a usable hardware GPU. Without one, OpenGL is the way to the GPU: graphics chips whose /// DirectX 12-only probe found) contains a usable hardware GPU. Without one, OpenGL is the way to
/// driver has no DirectX 12 support (Intel 4th generation on Windows 11, #316) still have an /// the GPU: graphics chips whose driver has no DirectX 12 support (Intel 4th generation on Windows
/// OpenGL driver, and GL can't reach the AMD driver crash described in [`configure_backends`], /// 11, #316) still have an OpenGL driver, and GL can't reach the AMD driver crash described in
/// because an AMD GPU with a driver shows up as a DirectX 12 adapter and keeps us on DirectX 12. /// [`configure_backends`], because an AMD GPU with a driver shows up as a DirectX 12 adapter and
/// When DirectX 12 offers only WARP, it stays enabled next to GL as a last resort for machines /// keeps us on DirectX 12. When DirectX 12 offers only WARP, it stays enabled next to GL as a last
/// without an OpenGL driver either (virtual machines): wgpu prefers any GPU over a software /// resort for machines without an OpenGL driver either (virtual machines): wgpu prefers any GPU
/// adapter, so it's only picked when GL has nothing better. /// over a software adapter, so it's only picked when GL has nothing better.
pub fn choose_backends(backend_override: Option<Backends>, dx12_adapters: &[Dx12Adapter]) -> Backends { ///
/// `dx12_graphics` is false on 32-bit Windows. wgpu creates the graphics pipeline through
/// `ID3D12Device2::CreatePipelineState`, and that stream is aligned to 8 bytes. The 32-bit runtime
/// expects pointer alignment (4), so creation returns `E_INVALIDARG` ("The parameter is incorrect")
/// and the process exits before the first frame. Compute pipelines use the older API and succeed,
/// which is why startup gets as far as the egui pipeline and then quits. OpenGL does not use that
/// stream.
pub fn choose_backends(backend_override: Option<Backends>, dx12_adapters: &[Dx12Adapter], dx12_graphics: bool) -> Backends {
if let Some(backends) = backend_override { if let Some(backends) = backend_override {
return backends; return backends;
} }
if !dx12_graphics {
return Backends::GL;
}
let hardware = |a: &&Dx12Adapter| a.device_type != DeviceType::Cpu; let hardware = |a: &&Dx12Adapter| a.device_type != DeviceType::Cpu;
if dx12_adapters.iter().filter(hardware).any(|a| a.meets_limits) { if dx12_adapters.iter().filter(hardware).any(|a| a.meets_limits) {
Backends::DX12 Backends::DX12
@@ -94,9 +104,16 @@ pub fn configure(options: &mut NativeOptions, backend_override: Option<Backends>
backends backends
} }
None => { None => {
let adapters = probe_dx12(options); // 32-bit: skip the DirectX 12 probe. A capable GPU would be selected, then
let backends = choose_backends(None, &adapters); // CreatePipelineState fails and the app exits with no window.
log::info!("graphics: {} DirectX 12 adapter(s) {adapters:?}, backends {backends:?}", adapters.len()); let dx12_graphics = cfg!(not(target_arch = "x86"));
let adapters = if dx12_graphics { probe_dx12(options) } else { Vec::new() };
let backends = choose_backends(None, &adapters, dx12_graphics);
if dx12_graphics {
log::info!("graphics: {} DirectX 12 adapter(s) {adapters:?}, backends {backends:?}", adapters.len());
} else {
log::info!("graphics: 32-bit Windows uses OpenGL; DirectX 12 graphics pipeline creation fails");
}
backends backends
} }
}; };
@@ -157,7 +174,7 @@ mod tests {
}; };
assert!(eframe_default.instance_descriptor.backends.contains(Backends::GL)); assert!(eframe_default.instance_descriptor.backends.contains(Backends::GL));
let gpu = [adapter(DeviceType::IntegratedGpu, true)]; let gpu = [adapter(DeviceType::IntegratedGpu, true)];
assert_eq!(configured_backends(choose_backends(None, &gpu)), Backends::DX12); assert_eq!(configured_backends(choose_backends(None, &gpu, true)), Backends::DX12);
} }
#[test] #[test]
@@ -165,8 +182,8 @@ mod tests {
let warp_only = [adapter(DeviceType::Cpu, true)]; let warp_only = [adapter(DeviceType::Cpu, true)];
for backends in [Backends::VULKAN, Backends::GL, Backends::DX12, Backends::VULKAN | Backends::DX12, Backends::empty()] { for backends in [Backends::VULKAN, Backends::GL, Backends::DX12, Backends::VULKAN | Backends::DX12, Backends::empty()] {
// Whatever the probe would have found, the override wins (the probe doesn't run then). // Whatever the probe would have found, the override wins (the probe doesn't run then).
assert_eq!(choose_backends(Some(backends), &[]), backends); assert_eq!(choose_backends(Some(backends), &[], true), backends);
assert_eq!(choose_backends(Some(backends), &warp_only), backends); assert_eq!(choose_backends(Some(backends), &warp_only, true), backends);
assert_eq!(configured_backends(backends), backends); assert_eq!(configured_backends(backends), backends);
} }
} }
@@ -192,13 +209,23 @@ mod tests {
fn gl_when_dx12_has_no_usable_gpu() { fn gl_when_dx12_has_no_usable_gpu() {
// #316: no DirectX 12 driver, so DirectX 12 offers only WARP (or nothing) and lags. // #316: no DirectX 12 driver, so DirectX 12 offers only WARP (or nothing) and lags.
let warp_only = [adapter(DeviceType::Cpu, true)]; let warp_only = [adapter(DeviceType::Cpu, true)];
assert_eq!(choose_backends(None, &warp_only), Backends::GL | Backends::DX12); assert_eq!(choose_backends(None, &warp_only, true), Backends::GL | Backends::DX12);
assert_eq!(choose_backends(None, &[]), Backends::GL); assert_eq!(choose_backends(None, &[], true), Backends::GL);
// A GPU that can't create eframe's device: GL alone, so it isn't picked over the GL one. // A GPU that can't create eframe's device: GL alone, so it isn't picked over the GL one.
let weak_gpu = [adapter(DeviceType::IntegratedGpu, false), adapter(DeviceType::Cpu, true)]; let weak_gpu = [adapter(DeviceType::IntegratedGpu, false), adapter(DeviceType::Cpu, true)];
assert_eq!(choose_backends(None, &weak_gpu), Backends::GL); assert_eq!(choose_backends(None, &weak_gpu, true), Backends::GL);
// Any usable GPU keeps DirectX 12 only, next to WARP or a weaker GPU. // Any usable GPU keeps DirectX 12 only, next to WARP or a weaker GPU.
let mixed = [adapter(DeviceType::Cpu, true), adapter(DeviceType::IntegratedGpu, false), adapter(DeviceType::DiscreteGpu, true)]; let mixed = [adapter(DeviceType::Cpu, true), adapter(DeviceType::IntegratedGpu, false), adapter(DeviceType::DiscreteGpu, true)];
assert_eq!(choose_backends(None, &mixed), Backends::DX12); assert_eq!(choose_backends(None, &mixed, true), Backends::DX12);
}
/// 32-bit Windows: a usable DirectX 12 GPU still starts on OpenGL. `WGPU_BACKEND` still wins.
#[test]
fn x86_uses_opengl_even_with_a_usable_gpu() {
let gpu = [adapter(DeviceType::IntegratedGpu, true)];
assert_eq!(choose_backends(None, &gpu, false), Backends::GL);
assert_eq!(choose_backends(Some(Backends::DX12), &gpu, false), Backends::DX12);
assert_eq!(choose_backends(Some(Backends::VULKAN), &[], false), Backends::VULKAN);
assert_eq!(configured_backends(choose_backends(None, &gpu, false)), Backends::GL);
} }
} }
+2 -2
View File
@@ -274,8 +274,8 @@ fn main() -> eframe::Result {
options.viewport = options.viewport.with_icon(icon); options.viewport = options.viewport.with_icon(icon);
} }
// Before eframe creates the wgpu instance: default Windows to DirectX 12 only, or OpenGL when // Before eframe creates the wgpu instance: default Windows to DirectX 12 only, or OpenGL when
// DirectX 12 has no GPU driver, and compile DirectX 12 shaders with FXC, which needs no // DirectX 12 has no GPU driver or this is a 32-bit build, and compile DirectX 12 shaders with
// DLL of ours (#603; see graphics.rs). // FXC, which needs no DLL of ours (#603; see graphics.rs).
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
graphics::configure(&mut options, eframe::wgpu::Backends::from_env()); graphics::configure(&mut options, eframe::wgpu::Backends::from_env());
load_user_fonts(); load_user_fonts();
+3
View File
@@ -64,3 +64,6 @@ sync_github_name = false
[people.alexanderalber] [people.alexanderalber]
real_name = "Alexander Alber" real_name = "Alexander Alber"
[people.edurbs] [people.edurbs]
sync_github_name = true
[people.odedigo]
+3 -2
View File
@@ -1,6 +1,6 @@
# Where WordCraft falls short of Word # Where WordCraft falls short of Word
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** trivial (formatted paste from other programs and Wayland clipboard pictures, #687, #833; previously trivial: DOCX complex-script formatting inheritance fixed; broader RTL work remains; previously trivial: #24 narrowed: Customize Keyboard and Customize Ribbon landed; previously trivial: formatting revisions landed, #41; previously trivial: Draw Table and Eraser landed, #303; previously minor: beta distance restated: ~15 points, ~150–230 h; previously: first version; every known shortfall from the 2026-10-10 re-measure, ranked) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** trivial (32-bit Windows no longer exits at launch on DirectX 12; previously trivial: Word XML Document and Word 2003 XML landed, #548) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
The work list. One entry per shortfall, ranked by how much it stops a Word user from switching The work list. One entry per shortfall, ranked by how much it stops a Word user from switching
(**B** = blocks beta). Each says what's missing, the evidence, who it hurts, an Opus 5.5 agent (**B** = blocks beta). Each says what's missing, the evidence, who it hurts, an Opus 5.5 agent
@@ -15,7 +15,7 @@ Native save reliability: synthetic cases on macOS reproduced loss through the pr
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| 1 | **DOCX never tested on real-world files.** No corpus of files from Word, Google Docs, LibreOffice and Pages has been opened, rendered and round-tripped and compared with Word page by page | B | No corpus in the repo; `crates/docx/tests` are synthetic fixtures (including omitted/empty paragraph defaults and imported TOC range preservation); "DOCX fidelity corpus: not started" since 2026-10-06 | Everyone: the files people receive are the files that break | 30–50 | [file-format-parity.md](file-format-parity.md) | | 1 | **DOCX never tested on real-world files.** No corpus of files from Word, Google Docs, LibreOffice and Pages has been opened, rendered and round-tripped and compared with Word page by page | B | No corpus in the repo; `crates/docx/tests` are synthetic fixtures (including omitted/empty paragraph defaults and imported TOC range preservation); "DOCX fidelity corpus: not started" since 2026-10-06 | Everyone: the files people receive are the files that break | 30–50 | [file-format-parity.md](file-format-parity.md) |
| 2 | **Remaining native ink forms are dropped on open and lost on save, silently**; OLE objects show only their picture | B | Drawing-level native ink is preserved with its optional picture fallback; direct run-level content parts and ink nested in groups/canvases remain unsupported. Drawing canvases are read and written (#344); group shapes (`wpg`) read and written (#267). Charts and SmartArt are drawn (#292) and, with OLE objects, written back with all their parts on save (#319) | Documents with diagrams drawn in Word or pen notes lose content without warning | 4–8 to preserve remaining native ink forms; 45–70 to render and edit charts and SmartArt (#13) | [file-format-parity.md](file-format-parity.md) | | 2 | **Remaining native ink forms are dropped on open and lost on save, silently**; OLE objects show only their picture | B | Drawing-level native ink is preserved with its optional picture fallback; direct run-level content parts and ink nested in groups/canvases remain unsupported. Drawing canvases are read and written (#344); group shapes (`wpg`) read and written (#267). Charts and SmartArt are drawn (#292) and, with OLE objects, written back with all their parts on save (#319) | Documents with diagrams drawn in Word or pen notes lose content without warning | 4–8 to preserve remaining native ink forms; 45–70 to render and edit charts and SmartArt (#13) | [file-format-parity.md](file-format-parity.md) |
| 3 | **Crashes and freezes in the field**: startup crash on Intel UHD Graphics (#170) (lag on GPUs without a DirectX 12 driver fixed, #316), freezes (#77, #59 Thai fonts, #31 font selector), no writes without admin on Windows 11 (#218), broken shape tool (#142), images can't be moved (#82) | B | 62 open issues, ~15 of them crashes, hangs or data-path failures | Anyone hit loses work or trust; the never-crash standard covers panics, not hangs or GPU driver faults | 20–30 | [target-app-parity.md](target-app-parity.md) (Stability) | | 3 | **Crashes and freezes in the field**: startup crash on Intel UHD Graphics (#170) (lag on GPUs without a DirectX 12 driver fixed, #316; 32-bit Windows exited at launch because DirectX 12 graphics pipeline creation failed, now OpenGL), freezes (#77, #59 Thai fonts, #31 font selector), no writes without admin on Windows 11 (#218), broken shape tool (#142), images can't be moved (#82) | B | 62 open issues, ~15 of them crashes, hangs or data-path failures | Anyone hit loses work or trust; the never-crash standard covers panics, not hangs or GPU driver faults | 20–30 | [target-app-parity.md](target-app-parity.md) (Stability) |
| 4 | **Pagination differs from Word**: Aptos has no metric-matched substitute; legacy compatibility options ignored; no page-by-page comparison harness | B | [layout-parity.md](layout-parity.md); [typing-parity.md](typing-parity.md) Known gaps | Page counts and line breaks differ, which matters for forms, legal and academic work | 30–50 + owner (font) | [layout-parity.md](layout-parity.md) | | 4 | **Pagination differs from Word**: Aptos has no metric-matched substitute; legacy compatibility options ignored; no page-by-page comparison harness | B | [layout-parity.md](layout-parity.md); [typing-parity.md](typing-parity.md) Known gaps | Page counts and line breaks differ, which matters for forms, legal and academic work | 30–50 + owner (font) | [layout-parity.md](layout-parity.md) |
| 5 | **Content controls** landed (#381): `w:sdt` kept, shown and edited (Developer tab, Design Mode, Properties). Move tracking landed (#400): `w:moveFrom`/`w:moveTo` with their named ranges round-trip, a tracked cut and paste of a paragraph or sentence records a move, either end accepts/rejects both, green double strike/underline markup and "Moved from/to" balloons; still missing: drag-and-drop moves (no text drag yet) and move options in Track Changes Options. Formatting revisions landed (#41): `w:rPrChange`/`w:pPrChange`/`w:tblPrChange`/`w:trPrChange`/`w:tcPrChange`/`w:sectPrChange`/`w:numberingChange` round-trip, are recorded while tracking, accepted/rejected and shown in balloons; still missing: tracked style-definition changes and table/section changes made in WordCraft. Opaque custom XML backing stores now survive saves; binding evaluation remains absent. | B | Issues #41, #400; source grep | Legal and editorial review workflows; templates with form controls | 5–8 | [file-format-parity.md](file-format-parity.md) | | 5 | **Content controls** landed (#381): `w:sdt` kept, shown and edited (Developer tab, Design Mode, Properties). Move tracking landed (#400): `w:moveFrom`/`w:moveTo` with their named ranges round-trip, a tracked cut and paste of a paragraph or sentence records a move, either end accepts/rejects both, green double strike/underline markup and "Moved from/to" balloons; still missing: drag-and-drop moves (no text drag yet) and move options in Track Changes Options. Formatting revisions landed (#41): `w:rPrChange`/`w:pPrChange`/`w:tblPrChange`/`w:trPrChange`/`w:tcPrChange`/`w:sectPrChange`/`w:numberingChange` round-trip, are recorded while tracking, accepted/rejected and shown in balloons; still missing: tracked style-definition changes and table/section changes made in WordCraft. Opaque custom XML backing stores now survive saves; binding evaluation remains absent. | B | Issues #41, #400; source grep | Legal and editorial review workflows; templates with form controls | 5–8 | [file-format-parity.md](file-format-parity.md) |
| 6 | **No native printing** on desktop: File › Print opens the PDF in the system viewer, which prints (#286); File › Print has a preview, page range, odd/even, copies and collate (#641); printer choice, duplex and pages per sheet are still the system's; web prints through the browser (#209) | B | `ui.print` → `apps/wordcraft/src/print.rs`; issue #15 | Everyone who prints | 5–8 | [hardware-parity.md](hardware-parity.md) | | 6 | **No native printing** on desktop: File › Print opens the PDF in the system viewer, which prints (#286); File › Print has a preview, page range, odd/even, copies and collate (#641); printer choice, duplex and pages per sheet are still the system's; web prints through the browser (#209) | B | `ui.print` → `apps/wordcraft/src/print.rs`; issue #15 | Everyone who prints | 5–8 | [hardware-parity.md](hardware-parity.md) |
@@ -72,6 +72,7 @@ The same gaps grouped the way the parity documents are, for agents working in on
| Date | Change | Summary | | Date | Change | Summary |
|---|---|---| |---|---|---|
| 2026-10-12 | trivial | #3: 32-bit Windows no longer exits at launch; DirectX 12 graphics pipelines fail to create, so that build starts on OpenGL |
| 2026-10-12 | trivial | Custom dictionary persists across sessions (`custom-dictionary.txt` in the settings folder; #40) | | 2026-10-12 | trivial | Custom dictionary persists across sessions (`custom-dictionary.txt` in the settings folder; #40) |
| 2026-10-11 | trivial | #8 narrowed: runs in a proofing language without a dictionary are skipped instead of flagged against the English dictionary (#100); dictionaries still English-only | | 2026-10-11 | trivial | #8 narrowed: runs in a proofing language without a dictionary are skipped instead of flagged against the English dictionary (#100); dictionaries still English-only |
| 2026-10-11 | trivial | #16: DOCX open/save preserves independent complex-script formatting inheritance; RTL sections, tables and typography remain open | | 2026-10-11 | trivial | #16: DOCX open/save preserves independent complex-script formatting inheritance; RTL sections, tables and typography remain open |
+3 -2
View File
@@ -1,6 +1,6 @@
# Hardware parity with Microsoft Word # Hardware parity with Microsoft Word
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (first version) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 and Word for Windows > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** trivial (32-bit Windows starts on OpenGL; previously major: first version) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 and Word for Windows
Word is not a hardware-heavy app, but a few devices matter to its users: printers above all, then Word is not a hardware-heavy app, but a few devices matter to its users: printers above all, then
pens, microphones (Dictate) and speakers (Read Aloud), and displays. pens, microphones (Dictate) and speakers (Read Aloud), and displays.
@@ -11,7 +11,7 @@ pens, microphones (Dictate) and speakers (Read Aloud), and displays.
| Hardware | Word | WordCraft macOS | Windows | Linux / BSD | Web | Parity | Hours | | Hardware | Word | WordCraft macOS | Windows | Linux / BSD | Web | Parity | Hours |
|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|
| Printers: native print dialog, printer choice, copies, duplex, page ranges, tray, scaling | ✅ (`WordPDE.plugin` print-dialog extension on Mac) | 🟡 PDF opens in Preview to print (#286) | 🟡 PDF opens in the default viewer (#286) | 🟡 PDF opens in the default viewer (#286) | ✅ browser print dialog (#209) | 35% | 5–8 | | Printers: native print dialog, printer choice, copies, duplex, page ranges, tray, scaling | ✅ (`WordPDE.plugin` print-dialog extension on Mac) | 🟡 PDF opens in Preview to print (#286) | 🟡 PDF opens in the default viewer (#286) | 🟡 PDF opens in the default viewer (#286) | ✅ browser print dialog (#209) | 35% | 5–8 |
| GPU rendering, HiDPI/Retina, pixel-aligned text | ✅ | ✅ wgpu + vello_cpu rasteriser, whole-pixel text (#110, #165) | ✅ DirectX 12 default (#50), OpenGL when DirectX 12 has no GPU driver (#316); startup crash on Intel UHD (#170) | ✅ (soft text on KDE at some zooms, #140) | ✅ | 80% | 3–5 (bugs) | | GPU rendering, HiDPI/Retina, pixel-aligned text | ✅ | ✅ wgpu + vello_cpu rasteriser, whole-pixel text (#110, #165) | ✅ DirectX 12 default (#50), OpenGL when DirectX 12 has no GPU driver (#316) or on 32-bit; startup crash on Intel UHD (#170) | ✅ (soft text on KDE at some zooms, #140) | ✅ | 80% | 3–5 (bugs) |
| Multiple monitors, per-monitor DPI, remembered window position | ✅ | ✅ (#38, #76) | ✅ (winit DPI fix pending, #155) | ✅ | — | 85% | 1 | | Multiple monitors, per-monitor DPI, remembered window position | ✅ | ✅ (#38, #76) | ✅ (winit DPI fix pending, #155) | ✅ | — | 85% | 1 |
| Pen / stylus: ink, pressure, eraser, ink to shape/math | ✅ (Draw tab, `InkRender.bundle`) | ❌ | ❌ | ❌ | ❌ | 0% | (Draw tab, 15–25) | | Pen / stylus: ink, pressure, eraser, ink to shape/math | ✅ (Draw tab, `InkRender.bundle`) | ❌ | ❌ | ❌ | ❌ | 0% | (Draw tab, 15–25) |
| Microphone: Dictate | ✅ (cloud speech service) | ❌ | ❌ | ❌ | ❌ | 0% | 8–15 + owner (speech model choice) | | Microphone: Dictate | ✅ (cloud speech service) | ❌ | ❌ | ❌ | ❌ | 0% | 8–15 + owner (speech model choice) |
@@ -23,6 +23,7 @@ pens, microphones (Dictate) and speakers (Read Aloud), and displays.
| Date | Change | Summary | | Date | Change | Summary |
|---|---|---| |---|---|---|
| 2026-10-12 | trivial | 32-bit Windows starts on OpenGL: DirectX 12 graphics pipeline creation returns "The parameter is incorrect" and the app exited before the window appeared |
| 2026-10-10 | trivial | Windows falls back to OpenGL when DirectX 12 offers only the software adapter (#316) | | 2026-10-10 | trivial | Windows falls back to OpenGL when DirectX 12 offers only the software adapter (#316) |
| 2026-10-10 | trivial | Desktop File › Print opens the PDF in the system viewer (#286) | | 2026-10-10 | trivial | Desktop File › Print opens the PDF in the system viewer (#286) |
| 2026-10-10 | trivial | Inertial touchpad scrolling landed (#252) | | 2026-10-10 | trivial | Inertial touchpad scrolling landed (#252) |