Commit graph

1,863 commits

Author SHA1 Message Date
admin
e76019a9f4 fix slides 2026-05-05 10:00:39 +02:00
admin
621c7dfee4 Fix todo input styling and studio build env 2026-05-05 07:50:38 +02:00
admin
5ebbe29850 cad 2026-05-04 18:34:29 +02:00
admin
245d47ef5a Fix and restyle todo example 2026-05-04 17:37:21 +02:00
admin
9df7c778f3 Add local AI talk slide 2026-05-04 17:05:19 +02:00
admin
4eef5a1cb0 Tighten realtime CAD demo wording 2026-05-04 17:02:46 +02:00
admin
84c634ac32 Add Robrix opening demo 2026-05-04 17:01:23 +02:00
Kevin Boos
4c3093a39b
Fix virtual/soft keyboard shift on both iOS & Android (#1079)
This normalizes the IME geometry calcs across iOS and Android.
The main difference is to make KeyboardView shift the content based on
the focused TExtInput instance instead of trying to shrink the viewport.

Also make sure that StackNavigation widget properly handles the
keyboard shift, even when it is drawing in full-screen mode.
2026-05-04 16:58:44 +02:00
admin
fdcf33e167 Clarify realtime CAD demo 2026-05-04 16:58:37 +02:00
Kevin Boos
ee39df2089
Windows: properly catch sigquit and actually exit (#1077) 2026-05-04 16:58:11 +02:00
admin
b377e6b9e4 Update AI talk demo sequence 2026-05-04 16:57:16 +02:00
admin
2a7e59ac84 Wrap AI talk title slide 2026-05-04 16:54:24 +02:00
admin
17ca8cf9ce Refine AI talk slide content 2026-05-04 16:53:04 +02:00
admin
ba1ba116c3 Add slides example to splash run items 2026-05-04 16:42:27 +02:00
admin
48612ea771 Add AI Makepad talk slides example 2026-05-04 16:25:03 +02:00
Admin
30dc2e621e aichat 2026-05-04 13:50:02 +02:00
Admin
1dfae4654b fix cad 2026-05-04 11:35:36 +02:00
Admin
77208b237e ai chat working 2026-05-04 08:48:38 +02:00
Codex
c2fb2c4b06 Fix Linux RunView DPI propagation 2026-05-03 23:52:29 +02:00
Admin
a5992d3fb2 xr 2026-05-03 23:45:59 +02:00
Admin
fe7cc8babc gauss ok 2026-05-03 23:45:59 +02:00
Admin
55db1be071 gauss blurs 2026-05-03 23:45:59 +02:00
Kevin Boos
20b6c53b6f
App menu bar: restore Quit option, use proper app name (#1076)
* App menu bar: restore Quit option, use proper app name

The menu bar shows "MakepadStdInLoop" by default, which is really strange
especially for published apps. This fixes that and also allows the app
to set the name, as well as using a sensible default for it if the app
didn't specify it.

We also now restore the previous Makepad 1.0 behavior of having a default
"Quit" entry in the main app's first menu bar entry.

* ensure Exit flow actually makes it out, on macOS
2026-05-02 09:35:44 +02:00
Kevin Boos
e0549dc502
iOS: don't always prompt the user for camera/mic access on app startup (#1075)
* WIP: adding full app lifecycle event support, and Ctrl+C/signal catch

* iOS: don't always prompt the user for camera/mic access on app startup

This fixes two unrelated but similar-structure issues, both on iOS:

- `Cx::handle_repaint` ran a 32-slot encoder-capture sweep every frame,
  which lazy-created `AvCaptureAccess` and fired
  `requestAccessForMediaType:AVMediaTypeVideo` — i.e. the camera prompt —
  on every Makepad app, even ones that never touch the camera. Gate the
  loop on `av_capture.is_some()` and stop the three `video_encoder_*`
  methods in `apple_media.rs` from lazy-creating it; they now return
  `EncoderNotStarted` (or no-op for `push_frame`) when no encoder exists.

- `AudioUnitAccess::new()` unconditionally activated the shared
  `AVAudioSession` with category `PlayAndRecord` + `VoiceChat` mode,
  which is wrong for playback-only apps (mic prompt + forced VPIO).
  Defer session config to a new `ensure_ios_session(for_input)` helper,
  called from `use_audio_inputs` (PlayAndRecord) and `use_audio_outputs`
  (Playback). Idempotent, never downgrades.

* Added fuller lifecycle event support, plus ability to catch sigquit

Tested working well on every platform except web/wasm, as I don't have
a working setup able to test that.
2026-05-01 22:30:33 +02:00
Kevin Boos
5ec03ff0ad
Add full app lifecycle event support, and Ctrl+C/signal catch (#1074)
* WIP: adding full app lifecycle event support, and Ctrl+C/signal catch

* Added fuller lifecycle event support, plus ability to catch sigquit

Tested working well on every platform except web/wasm, as I don't have
a working setup able to test that.
2026-05-01 22:30:24 +02:00
Kevin Boos
ecff7b816b
Don't duplicate fonts in Android/iOS app bundles (#1073)
* Fix portallist alignment handling so centering actually works

Now, alignment on PortalLists now only applies to the "cross-axis"
of each item, not the main axis.
So when you center a portallist itself, it won't add weird space
on the leading side of the list

* Fix text not drawing on top of a background, e.g., `<code>` tags

This worked in *most* but not all cases, e.g., if you had a ton of
inline code tags, some of them would rarely but deterministically
not show the actual text glyphs, but just an empty background.

* Avoid large margin on the left of `<code>` if it's on a new line

* Add a separate "touch" margin; use it on dock splitter and tab close

Without this, those dock UI elements are nearly impossible to grab
and press on a real touch screen device, even on my iPad.

Also, tweak cargo-makepad iOS and Android builds to use a polished
display name for the app (uppercase first character) by default.

* Don't duplicate fonts in Android/iOS app bundles
2026-04-30 08:33:33 +02:00
Kevin Boos
3fe61b3ed0
Add separate touch margin; use it on dock splitter and tab close (#1072)
* Fix portallist alignment handling so centering actually works

Now, alignment on PortalLists now only applies to the "cross-axis"
of each item, not the main axis.
So when you center a portallist itself, it won't add weird space
on the leading side of the list

* Fix text not drawing on top of a background, e.g., `<code>` tags

This worked in *most* but not all cases, e.g., if you had a ton of
inline code tags, some of them would rarely but deterministically
not show the actual text glyphs, but just an empty background.

* Avoid large margin on the left of `<code>` if it's on a new line

* Add a separate "touch" margin; use it on dock splitter and tab close

Without this, those dock UI elements are nearly impossible to grab
and press on a real touch screen device, even on my iPad.

Also, tweak cargo-makepad iOS and Android builds to use a polished
display name for the app (uppercase first character) by default.
2026-04-30 08:33:04 +02:00
Kevin Boos
1a2453e7e4
Misc fixes for PortalList alignment and inline <code> tags (#1071)
* Fix portallist alignment handling so centering actually works

Now, alignment on PortalLists now only applies to the "cross-axis"
of each item, not the main axis.
So when you center a portallist itself, it won't add weird space
on the leading side of the list

* Fix text not drawing on top of a background, e.g., `<code>` tags

This worked in *most* but not all cases, e.g., if you had a ton of
inline code tags, some of them would rarely but deterministically
not show the actual text glyphs, but just an empty background.

* Avoid large margin on the left of `<code>` if it's on a new line
2026-04-30 08:32:51 +02:00
Admin
9d3d0e4450 ai mgr update 2026-04-28 18:25:08 +02:00
Admin
a3294c3c99 profiler 2026-04-28 12:33:37 +02:00
Admin
d8d6a7d971 profiler 2026-04-28 12:33:05 +02:00
Admin
61a3f53c5c ai manager otw 2026-04-28 12:24:40 +02:00
Admin
30385ae3c6 cleanup 2026-04-27 14:52:45 +02:00
Admin
614e203f17 aimgr 2026-04-27 14:51:24 +02:00
Kevin Boos
b32022a7d5
Stack nav now handles script reapply for previously-pushed views (#1070)
* Simplify tooltip logic, fix positioning to respect safe inset areas

And other misc positioning/formatting fixes, like wrapping
after a hard line break, as well as ensuring that the callout
arrow thing itself is centered (to the fullest extent possible)
w.r.t. the rest of the tooltip body.

Basically, now it looks good again.

* Fix CheckBox/Toggle `set_active` to animate like others

All other widgets allow you to pass an `animate` arg when setting
them as active, except CheckBox (and by proxy, its wrapper Toggle).
This is necessary for proper non-animated thigns like restoring the
state of a toggle from persistent storage, or other similar examples
where you don't really want the animation to occur (because that'll
look like the user did it accidentally or some kind of phantom movement).

* PortalList: pass "touch stop" (FingerUp) events to children, always

I had recently implemented a feature where PortalList would not pass
events down to its children if those events were being direclty handled
by the PortalList as part of its scroll-action. That was generally correct,
but it missed one rare case where a child widget was waiting on a
finger up (touch stop/release) for something like stopping a hover/down
animation.

So the child, like a button, could capture the initial FingerDown
but never the FingerUp, so they'd get stuck on the hover or down
animation. This fixes that issue by passing FingerUp-causing events
down to the child widgets.

Note that the children must use `was_tap()` on the FingerUp in order
to handle a regular click -- but they should have already been doing that.
So this doesn't break anything, it's just strictly a proper fix
for something that i should've covered previously.

* Separate apply-reload and script-reapply into different concepts

The goal here is to differentiate between "applies" that change the actual
Splash script "DSL" (i.e., the template) from a "re-apply" that doesn't
change the DSL template but does change runtime heap objects.

Mostly, we want to ensure that LiveEdit (the former) is different from
things that require heap updates (the latter), such as changing a theme
value or doing screen rotation that changes safe inset areas on mobile.

I don't know that I love this approach as a permanent solution,
but it's a good stepping stone until we can redesign LiveEdit/Apply
to funnel all of these various events through the same singular system.
We probably want to use different attributes on widget fields in order
to have more fine-grained control over what happens on an Apply action.

Generated list of brief details here:

* `Apply::ScriptReapply` variant + `is_script_reapply` /
  `is_live_edit_reload` predicates; `Event::ScriptReapply` now applies
  via `Apply::ScriptReapply`.
* `String` / `ArcStringMut` `script_apply` early-return on
  `ScriptReapply`.
* Codegen: `#[deref]` runs before `#[apply_default]`'s recursive call
  so animator state wins over template defaults.
* `Animator::script_apply_default` returns `state_object` on
  `ScriptReapply`; new `current_state_apply()` helper for
  `on_after_apply` hooks.

* `Cx::request_live_edit()` + `pending_live_edit_request` for primitive
  heap mutations (safe-area insets baked into `script_mod!`
  expressions).
* `handle_live_edit()` returns `LiveEditTrigger {None, FileChange,
  Manual}`; `run_live_edit_if_needed` skips shader-cache reset and
  same-tick `ScriptReapply` follow-up for `Manual` (fixes ~1s rotation
  lag).
* iOS/Android post-event hook now drains both flags via
  `run_live_edit_if_needed` (was firing `LiveEdit` indiscriminately).
* `Window` `WindowGeomChange` uses `request_live_edit()` for
  safe-area.

* `StackNavigationView` gains `runtime_title` field re-asserted in
  `on_after_apply`; new `StackNavigation::set_title` API.
* `app_main!` collapses 4 duplicate platform branches into a shared
  `_app_main_event_closure!` macro.

* Stack nav now handles script reapply for previously-pushed views

`StackNavigation`'s `_after_apply` only restored the currentt view,
but skipped all the pushed view, making their visibility false.

Now, `on_after_apply` sets all pushed views as visible, and also
that the offset (for the slide animation) gets properly re-set
2026-04-27 09:23:42 +02:00
Kevin Boos
cd6d2e78cd
Separate apply-reload and script-reapply into different concepts (#1069)
* Simplify tooltip logic, fix positioning to respect safe inset areas

And other misc positioning/formatting fixes, like wrapping
after a hard line break, as well as ensuring that the callout
arrow thing itself is centered (to the fullest extent possible)
w.r.t. the rest of the tooltip body.

Basically, now it looks good again.

* Fix CheckBox/Toggle `set_active` to animate like others

All other widgets allow you to pass an `animate` arg when setting
them as active, except CheckBox (and by proxy, its wrapper Toggle).
This is necessary for proper non-animated thigns like restoring the
state of a toggle from persistent storage, or other similar examples
where you don't really want the animation to occur (because that'll
look like the user did it accidentally or some kind of phantom movement).

* PortalList: pass "touch stop" (FingerUp) events to children, always

I had recently implemented a feature where PortalList would not pass
events down to its children if those events were being direclty handled
by the PortalList as part of its scroll-action. That was generally correct,
but it missed one rare case where a child widget was waiting on a
finger up (touch stop/release) for something like stopping a hover/down
animation.

So the child, like a button, could capture the initial FingerDown
but never the FingerUp, so they'd get stuck on the hover or down
animation. This fixes that issue by passing FingerUp-causing events
down to the child widgets.

Note that the children must use `was_tap()` on the FingerUp in order
to handle a regular click -- but they should have already been doing that.
So this doesn't break anything, it's just strictly a proper fix
for something that i should've covered previously.

* Separate apply-reload and script-reapply into different concepts

The goal here is to differentiate between "applies" that change the actual
Splash script "DSL" (i.e., the template) from a "re-apply" that doesn't
change the DSL template but does change runtime heap objects.

Mostly, we want to ensure that LiveEdit (the former) is different from
things that require heap updates (the latter), such as changing a theme
value or doing screen rotation that changes safe inset areas on mobile.

I don't know that I love this approach as a permanent solution,
but it's a good stepping stone until we can redesign LiveEdit/Apply
to funnel all of these various events through the same singular system.
We probably want to use different attributes on widget fields in order
to have more fine-grained control over what happens on an Apply action.

Generated list of brief details here:

* `Apply::ScriptReapply` variant + `is_script_reapply` /
  `is_live_edit_reload` predicates; `Event::ScriptReapply` now applies
  via `Apply::ScriptReapply`.
* `String` / `ArcStringMut` `script_apply` early-return on
  `ScriptReapply`.
* Codegen: `#[deref]` runs before `#[apply_default]`'s recursive call
  so animator state wins over template defaults.
* `Animator::script_apply_default` returns `state_object` on
  `ScriptReapply`; new `current_state_apply()` helper for
  `on_after_apply` hooks.

* `Cx::request_live_edit()` + `pending_live_edit_request` for primitive
  heap mutations (safe-area insets baked into `script_mod!`
  expressions).
* `handle_live_edit()` returns `LiveEditTrigger {None, FileChange,
  Manual}`; `run_live_edit_if_needed` skips shader-cache reset and
  same-tick `ScriptReapply` follow-up for `Manual` (fixes ~1s rotation
  lag).
* iOS/Android post-event hook now drains both flags via
  `run_live_edit_if_needed` (was firing `LiveEdit` indiscriminately).
* `Window` `WindowGeomChange` uses `request_live_edit()` for
  safe-area.

* `StackNavigationView` gains `runtime_title` field re-asserted in
  `on_after_apply`; new `StackNavigation::set_title` API.
* `app_main!` collapses 4 duplicate platform branches into a shared
  `_app_main_event_closure!` macro.
2026-04-26 22:11:31 +02:00
Kevin Boos
07354753b1
PortalList: pass "touch stop" (FingerUp) events to children, always (#1068)
* Simplify tooltip logic, fix positioning to respect safe inset areas

And other misc positioning/formatting fixes, like wrapping
after a hard line break, as well as ensuring that the callout
arrow thing itself is centered (to the fullest extent possible)
w.r.t. the rest of the tooltip body.

Basically, now it looks good again.

* Fix CheckBox/Toggle `set_active` to animate like others

All other widgets allow you to pass an `animate` arg when setting
them as active, except CheckBox (and by proxy, its wrapper Toggle).
This is necessary for proper non-animated thigns like restoring the
state of a toggle from persistent storage, or other similar examples
where you don't really want the animation to occur (because that'll
look like the user did it accidentally or some kind of phantom movement).

* PortalList: pass "touch stop" (FingerUp) events to children, always

I had recently implemented a feature where PortalList would not pass
events down to its children if those events were being direclty handled
by the PortalList as part of its scroll-action. That was generally correct,
but it missed one rare case where a child widget was waiting on a
finger up (touch stop/release) for something like stopping a hover/down
animation.

So the child, like a button, could capture the initial FingerDown
but never the FingerUp, so they'd get stuck on the hover or down
animation. This fixes that issue by passing FingerUp-causing events
down to the child widgets.

Note that the children must use `was_tap()` on the FingerUp in order
to handle a regular click -- but they should have already been doing that.
So this doesn't break anything, it's just strictly a proper fix
for something that i should've covered previously.
2026-04-26 22:11:17 +02:00
Kevin Boos
93aaca16fe
Fix CheckBox/Toggle set_active to animate like others (#1067)
* Simplify tooltip logic, fix positioning to respect safe inset areas

And other misc positioning/formatting fixes, like wrapping
after a hard line break, as well as ensuring that the callout
arrow thing itself is centered (to the fullest extent possible)
w.r.t. the rest of the tooltip body.

Basically, now it looks good again.

* Fix CheckBox/Toggle `set_active` to animate like others

All other widgets allow you to pass an `animate` arg when setting
them as active, except CheckBox (and by proxy, its wrapper Toggle).
This is necessary for proper non-animated thigns like restoring the
state of a toggle from persistent storage, or other similar examples
where you don't really want the animation to occur (because that'll
look like the user did it accidentally or some kind of phantom movement).
2026-04-26 22:11:07 +02:00
Kevin Boos
5d214947d7
Simplify tooltip logic, fix positioning to respect safe inset areas (#1066)
And other misc positioning/formatting fixes, like wrapping
after a hard line break, as well as ensuring that the callout
arrow thing itself is centered (to the fullest extent possible)
w.r.t. the rest of the tooltip body.

Basically, now it looks good again.
2026-04-26 22:10:54 +02:00
Kevin Boos
18669f5a58
Support runtime changes to script-level heap objects (#1063)
* Support runtime-reassigned module templates and app-wide events

- Dock/PortalList: add `refresh_widgets_mod_template()` so callers can
  re-capture a content template from `mod.widgets.*` after reassigning
  it at runtime via `script_eval!`. Dock's variant takes a separate
  template_key and mod_widgets_name since local DSL names (e.g.
  `room_screen`) don't always match the module entry (`RoomScreen`).
- PortalList: add `all_items_and_pool()` iterator so callers can walk
  every live and pooled item (e.g. to push a new property across the
  whole list on a preference change).
- StackNavigation: forward non-visibility events (`Event::Actions`) to
  all child stack views, not just visible ones. Inactive views need
  global state updates too; `View::handle_event` still gates on each
  child's own `visible` flag for events that require visibility.
- TextInput: add `submit_on_enter` so callers can opt into Cmd/Ctrl+
  Enter submit semantics, plus a `key_focus_lost` helper for commit-
  on-blur inputs.
- Image: honor `Size::Fit { max }` when `peek_walk_turtle` returns NaN
  so `Fit{max: Abs(..)}` caps image height without clipping.
- FlatList: derive `Default` on the shared `WidgetItem` struct.
- draw: re-export `Base` and `FitBound` from turtle.

* Add Event::ScriptReapply + preserve Dock state on reload

- `Event::ScriptReapply`: new event signalling a widget-tree Apply::Reload
  that does NOT re-run `script_mod!`. Fires from `run_live_edit_if_needed`
  when `Cx::pending_script_reapply` is set (previously the flag was never
  observed on desktop). The AppMain macro caches the app's script root as
  a rooted `ScriptObjectRef` and re-applies the tree with it — so runtime
  heap mutations (e.g. `script_eval!` overriding a user preference) stay
  intact. If a file-driven `LiveEdit` handler then sets the flag again, a
  bounded follow-up `ScriptReapply` pass runs in the same tick.

- Dock: on `Apply::Reload`, preserve existing runtime `dock_items` (open
  tabs, selected indices, splitter positions). Only insert DSL-defined
  items for IDs that don't already exist — so a source hot-reload no
  longer wipes the user's opened tabs.

* cleanup, remove unnecessary crap from prior approaches

the whole `refresh_widgets_mod_template` was a misguided approach,
and now that we have script reload/re-apply working and we have fixed
LiveEdit for most widgets, we just don't need it

* cleanup, remove more unused functions
2026-04-22 23:36:56 +02:00
Admin
ea993f30c4 Batch Qwen CUDA prefill MoE 2026-04-20 13:48:29 +02:00
Admin
92eee25a4c Optimize Qwen CUDA routing and exact decode 2026-04-20 13:48:29 +02:00
Admin
2325f23dbe Optimize Qwen CUDA MoE decode path 2026-04-20 13:48:29 +02:00
Admin
8049779c0b Checkpoint Qwen CUDA exact progress 2026-04-20 13:48:29 +02:00
Kevin Boos
2faaf7b16b
Implement the <details>/<summary> widget within Html (#1052)
* draw_text: adopt outer many_instances batch on linux/windows

CodeEditor opens an outer raster batch via DrawText::begin_many_instances
before its glyph loop. The linux/windows branch of DrawText::draw_text
ignored self.many_instances and opened its own nested batch, which
resolved (via find_appendable_drawcall) to the same draw_item whose
`instances` Vec was already swapped out by the outer open, panicking on
unwrap in Cx2d::begin_many_instances.

Mirror what the other platform branch (and draw_rasterized_glyphs_abs)
already do: take self.many_instances on entry, track whether the active
raster batch is the outer one, and hand it back on exit so the caller's
end_many_instances finalizes it. Skip the !drew_raster_this_frame area
clear when the outer batch is still live.

* Html/Markdown fixes: sub/superscript, table outlines/alignment, etc

- **Sub/sup in HTML**: added a `y_shift_scales` stack on `TextFlow`, composed onto `temp_y_shift` in `draw_text`. `<sub>` pushes `+0.55`, `<sup>` pushes `-0.2` in html.rs
- **Sub/sup in Markdown**: now handles `MdEvent::InlineHtml` for `<sub>`/`<sup>` (case-insensitive), using the same stacks.
- **Space after `&amp;` (and other entities)**: the HTML lib's entity decoder now resets `last_non_whitespace` after truncate+push, so the whitespace-collapse check no longer drops the next real space.
- **Table column alignment (Markdown)**: `begin_table_cell` takes `align_x: f64`; tracks `Tag::Table` alignments and a per-row column index, passing each cell's `Alignment` through.
- **Table column alignment (HTML)**: `<td>`/`<th>` now honor `align="…"` and inline `style="text-align: …"` via new `cell_align_x` / `align_keyword_to_x` helpers in html.rs.
- **Per-row text alignment plumbing**: new `layout_align` field on `DrawText` is passed to the layouter, which already supports per-row alignment. `TextFlow` propagates a `cell_text_align_x` into it. This is the actual fix that makes cell alignment visible.
- **Wrap-flow alignment scaffolding**: implemented the previously-stubbed `Flow::Right { wrap: true }` branch in the turtle logic. Useful for non-text wrapping walks; text goes through the layouter path above.
- Add examples to uizoo: three new tables in both markdown and html tab -- a plain one, a left/center/right aligned one, and a numeric all-right-aligned one. They cover bold/italic/code/links/sub-sup/emoji/entities/strikethrough inside cells.

* minor cleanup; prefer `style` over `align` HTML tag

* Implement the `<details>`/`summary` widget within Html

* cleanup/improvement

* spacing and size consistency for details/summary header
2026-04-19 10:13:49 +02:00
Kevin Boos
047e9cba21
Add RowAlign::Center, per-row FinishedWalk support, and inline widget alignment (#1053)
* Add RowAlign::Center, per-row FinishedWalk support, and inline widget alignment

Closes #712

turtle.rs:
- Add RowAlign::Center variant for vertically centering walks within a row
- Add finish_row_center() that shifts shorter walks to the row's vertical midline
- Fix finish_row's current_row_walks_start() to use last finished row (not first)
- Add Cx2d::align_list_len(), shift_align_entries(), emit_turtle_walk_with_metrics()

draw_text.rs (draw_walk_resumable_with):
- Per-row path: multi-row wrapped text now emits one FinishedWalk per visual row
  with separate glyph instance batches, enabling RowAlign::Center per row
- Between rows: call turtle_new_line_with_spacing to trigger finish_row at each
  visual-row boundary
- Wrapped rows draw glyphs at turtle position (not layouter position) so glyph
  positions stay in sync with turtle tracking when pills inflate row height
- Remove shift_extra_height from allocation (caused turtle/glyph position divergence)

text_flow.rs:
- Fix wrap check to use matches!(Flow::Right { wrap: true, .. }) instead of
  equality against Flow::right_wrap() (broke wrapping with non-Top RowAlign)
- Account for inline_code padding in turtle allocation (fixes overlap bug)

* fix build for Linux / Windows
2026-04-18 10:30:04 +02:00
Kevin Boos
c7d7202551
Html/Markdown fixes: sub/superscript, table outlines/alignment, etc (#1051)
* draw_text: adopt outer many_instances batch on linux/windows

CodeEditor opens an outer raster batch via DrawText::begin_many_instances
before its glyph loop. The linux/windows branch of DrawText::draw_text
ignored self.many_instances and opened its own nested batch, which
resolved (via find_appendable_drawcall) to the same draw_item whose
`instances` Vec was already swapped out by the outer open, panicking on
unwrap in Cx2d::begin_many_instances.

Mirror what the other platform branch (and draw_rasterized_glyphs_abs)
already do: take self.many_instances on entry, track whether the active
raster batch is the outer one, and hand it back on exit so the caller's
end_many_instances finalizes it. Skip the !drew_raster_this_frame area
clear when the outer batch is still live.

* Html/Markdown fixes: sub/superscript, table outlines/alignment, etc

- **Sub/sup in HTML**: added a `y_shift_scales` stack on `TextFlow`, composed onto `temp_y_shift` in `draw_text`. `<sub>` pushes `+0.55`, `<sup>` pushes `-0.2` in html.rs
- **Sub/sup in Markdown**: now handles `MdEvent::InlineHtml` for `<sub>`/`<sup>` (case-insensitive), using the same stacks.
- **Space after `&amp;` (and other entities)**: the HTML lib's entity decoder now resets `last_non_whitespace` after truncate+push, so the whitespace-collapse check no longer drops the next real space.
- **Table column alignment (Markdown)**: `begin_table_cell` takes `align_x: f64`; tracks `Tag::Table` alignments and a per-row column index, passing each cell's `Alignment` through.
- **Table column alignment (HTML)**: `<td>`/`<th>` now honor `align="…"` and inline `style="text-align: …"` via new `cell_align_x` / `align_keyword_to_x` helpers in html.rs.
- **Per-row text alignment plumbing**: new `layout_align` field on `DrawText` is passed to the layouter, which already supports per-row alignment. `TextFlow` propagates a `cell_text_align_x` into it. This is the actual fix that makes cell alignment visible.
- **Wrap-flow alignment scaffolding**: implemented the previously-stubbed `Flow::Right { wrap: true }` branch in the turtle logic. Useful for non-text wrapping walks; text goes through the layouter path above.
- Add examples to uizoo: three new tables in both markdown and html tab -- a plain one, a left/center/right aligned one, and a numeric all-right-aligned one. They cover bold/italic/code/links/sub-sup/emoji/entities/strikethrough inside cells.

* minor cleanup; prefer `style` over `align` HTML tag
2026-04-18 10:29:50 +02:00
Admin
87863fe42f Add Qwen runtime and Windows CUDA build support 2026-04-17 11:44:43 +02:00
Kevin Boos
4a576a7add
draw_text: adopt outer many_instances batch on linux/windows (#1049)
CodeEditor opens an outer raster batch via DrawText::begin_many_instances
before its glyph loop. The linux/windows branch of DrawText::draw_text
ignored self.many_instances and opened its own nested batch, which
resolved (via find_appendable_drawcall) to the same draw_item whose
`instances` Vec was already swapped out by the outer open, panicking on
unwrap in Cx2d::begin_many_instances.

Mirror what the other platform branch (and draw_rasterized_glyphs_abs)
already do: take self.many_instances on entry, track whether the active
raster batch is the outer one, and hand it back on exit so the caller's
end_many_instances finalizes it. Skip the !drew_raster_this_frame area
clear when the outer batch is still live.
2026-04-17 08:25:28 +02:00
Kevin Boos
85fbea9b0f
Switch to SLUG/DrawGlyph font drawing stack (#1042)
* Switch to SLUG/DrawGlyph font drawing stack (via Codex)

* Improve same-frame new glyph caching and SLUG packed instances

* avoid performance regression by batch updating slug atlas cache

* TextFlow: separate SLUG glyph batches to avoid interleaving HTML text drawing

* SLUG optimization: append instead of a full clone each generation

* trying out codex perf fix for linux wayland

* Disable SLUG glyps on Linux for now

* Fix Linux SLUG rendering, warmup, and promotion behavior

- re-enable Linux SLUG through a separate Linux-only DrawText helper
  instead of bloating the normal DrawText shader path
- preserve widget text styling on Linux SLUG by syncing common DrawText
  state into the helper, including base colors, gradients, and interactive
  states such as hover, focus, down, active, pressed, drag, empty, and
  disabled
- keep normal Linux UI text on the raster/MSDF path and only switch to
  SLUG above the Linux cutoff, while still falling back cleanly when SLUG
  data is unavailable
- fix Linux SLUG glyph placement so promoted text uses the correct glyph
  origin, layout position, and atlas packing
- add progressive SLUG warmup on Linux by budgeting glyph generation and
  uploads across redraws and falling back to raster/MSDF until SLUG data
  is actually ready
- lazily register and prewarm the shared Linux SLUG helper so app startup
  and first-use latency stay low
- opt only the Linux SLUG helper into async GL shader compilation and use
  parallel shader compile support when available, avoiding the large
  startup and first-tab stalls seen before
- fix Linux runtime shader issues caused by copied widget text shaders and
  custom get_color logic by using a shared helper shader with the expected
  text-state inputs
- stabilize Linux SLUG promotion by preventing stale retained areas,
  cleaning up raster/helper ownership correctly during draw, and
  shadow-promoting the first ready SLUG frame before making it visible
- eliminate the visible SLUG handoff flicker so Linux text now switches
  from raster/MSDF to SLUG without freezes or noticeable visual artifacts
- add a dedicated UIZoo SLUG tab with side-by-side below-cutoff and
  above-cutoff examples, plus diagnostic cases for plain labels,
  gradients, custom text shaders, and glyph/color probes
- keep the final diff focused by removing unrelated formatting-only churn
  from the worktree during cleanup

* Tighten Linux SLUG promotion and helper sync

- make Linux SLUG promotion state local to each DrawText instance
  instead of using a global per-redraw gate
- cache Linux SLUG helper shader field intersections so helper state
  syncing avoids repeated per-draw allocations and linear membership checks
- harden the shadow-promotion fallback path so failed helper batching
  only takes a single raster fallback path
- preserve DrawText memory alignment after adding Linux SLUG bookkeeping

* try to fix emoji on Android

* emoji fix take 2

* uizoo example: allow touch/drag scroll. Don't panic in FileTree demo

* Fix emoji on Android

* Windows: async HLSL shader compile + extend SLUG helper path to Windows

Fixes two major performance issues on Windows that made uizoo unusable on
first launch:

1. **60-75s startup stall** caused by synchronous `D3DCompile` of ~30+
   SLUG-bearing text shader variants on the UI thread before the window
   could present.
2. **3-4s hang when opening the SLUG tab** caused by synchronous compile
   of the fat DrawTextSlug helper shader the first time a SLUG glyph was
   needed.

Also fixes a latent HLSL-only `CreateInputLayout` E_INVALIDARG crash
triggered by shaders with >26 instance inputs (exposed by DrawTextSlug).

`DrawTextLinuxSlug` → `DrawTextSlug` and all `linux_slug_*` /
`LinuxSlug*` symbols dropped their `Linux` prefix. Cfg guards expanded
from `target_os = "linux"` to `any(target_os = "linux", target_os = "windows")`
so Windows now:

- uses the same lean base `DrawText` shader (SDF/MSDF only, no SLUG
  curve-solver HLSL inlined)
- uses a separate `DrawTextSlug` helper shader for the SLUG path
- has the same progressive glyph-build budget and DPI cutoff
  (`default_slug_new_glyphs_per_redraw`, `default_slug_min_dpxs_per_em`
  in `fonts.rs` now match `OsType::Windows` alongside the Linux variants)
- falls back to raster/MSDF while the SLUG helper shader or its glyph
  data isn't yet ready

macOS/iOS/Android/WASM paths are untouched — they still use the fat
all-in-one `DrawText` shader via `cfg(not(any(linux, windows)))`.

Added `AsyncHlslCompile` in `d3d11.rs` and an `async_hlsl_compile` field
on `CxOs`. Shaders flagged `async_compile: true` (the SLUG helper) now
dispatch to a background thread per shader via `std:🧵:Builder`
(named `hlsl-compile-<id>` for debugging). Workers call `D3DCompile`
off the UI thread, write the resulting DXBC to the on-disk cache, and
send only a status result (not the bytes themselves — SLUG is ~240 KB
and ferrying it through the channel is wasteful) back via an mpsc
channel guarded by a `Mutex`.

`hlsl_compile_shaders` drains completed results at the top of each
call, constructs `CxOsDrawShader` objects on the main thread (the
bytes come from the cache-hit path in `CxOsDrawShader::new`), and
triggers `redraw_all()` so widgets whose shaders just became ready
get re-rendered. The existing `sh.os_shader_id.is_none()` guard in
`render_view` handles skipping the draw call while a shader is
pending.

Added `Cx::is_draw_shader_window_ready()` on Windows for the SLUG
helper's readiness check; on Windows it's simply
`os_shader_id.is_some()` since HLSL compile is either synchronous
(cache hit) or tracked via the async path.

Cold-start still compiled 30+ shaders synchronously (parallelized via
`std:🧵:scope`) which took ~5-10s because FXC's per-call speed is
the bottleneck and parallelism helps less than expected. Now
`hlsl_compile_shaders` partitions queued shaders by cache state:

- cache hit → sync path: disk read + D3D11 object creation, a few ms
- cache miss OR `async_compile: true` → async path: worker thread

On a fully cold cache, every shader is a cache miss → the window
presents on the first frame with no compile work on the UI thread.
Widgets fill in over the next ~1-2s as their shaders become ready.
On a warm cache every shader is a hit → instant startup as before.

Added `shader_bytes_cached()` for cheap existence checking of the
cache entries.

`d3d_compile_hlsl` now passes `D3DCOMPILE_SKIP_OPTIMIZATION`. FXC's
optimizer is what makes individual compiles burn hundreds of ms to
seconds on text shaders with loops; UI shaders don't benefit enough
from it to justify the cold-cache cost. If a specific shader is later
shown to be a runtime hotspot, the fix is to recompile it optimized
on a background thread and hot-swap, not to pay the cost upfront for
every shader.

Bumped `CACHE_KEY_VERSION` to 2 so pre-existing `.dxbc` blobs compiled
with the old flags are invalidated cleanly on upgrade.

`d3d11.rs` used its own `index_to_char(i) = i + 'A'` which produced
invalid HLSL semantic names (`[`, `\`, `]`, …) past 26 inputs, while
the HLSL generator in `shader_hlsl.rs` already used a correct
multi-character scheme (`A..Z, AA..AZ, BA..`). `CreateInputLayout`
returned E_INVALIDARG because the names didn't match. Replaced with
`makepad_script::shader_hlsl::index_to_semantic` so both sides of
the binding agree.

This was a latent bug — no existing shader had >26 instance inputs
until `DrawTextSlug` (which inherits many interactive-state fields
from Label-derived shaders). Linux/GLSL is unaffected because GLSL
binds by identifier, not semantic name.

- Hoisted `d3d_compile_hlsl`, `hlsl_cache_key`, and
  `get_or_compile_shader_bytes` out of `CxOsDrawShader::new` to module
  scope so they can be shared with the async worker.
- Compute `hlsl_cache_key` once per shader during partition and reuse
  at dispatch instead of recomputing.
- Scoped borrows in the async drain loop eliminate mapping/bindings
  clones.

- `platform/src/os/windows/d3d11.rs` — compile pipeline, async infra,
  semantic-name fix
- `platform/src/os/windows/windows.rs` — `async_hlsl_compile` field on
  `CxOs`
- `draw/src/shader/draw_text.rs` — rename `LinuxSlug*` → `Slug*`,
  expand cfg gates
- `draw/src/text/fonts.rs` — extend SLUG cutoff/budget defaults to
  Windows

No changes to macOS, iOS, Android, or WASM paths.
2026-04-16 22:50:48 +02:00