Commit graph

653 commits

Author SHA1 Message Date
Admin
bff75eb694 fix 2026-04-10 21:14:32 +02:00
Admin
69aa615947 mlx 5x->2x 2026-04-10 14:46:22 +02:00
Kevin Boos
17f2ef553c Batch/buffer tooltip hover in/out actions to avoid flicker (#1029) 2026-04-10 08:12:50 +02:00
Kevin Boos
aed71d2b14 Smooth scroll the tab bar to the selected tab, if not visible (#1016)
* Dock: add touch support for Tab/Tab bar interactions (scroll, drag/drop)

Details below:

1. **Finger-based tab drag-and-drop via long press** (tab.rs, android.rs, ios.rs):
   - On touch devices, tab dragging now requires a long press before moving,
     distinguishing it from scroll gestures.
   - Added internal drag-and-drop support for Android and iOS backends,
     synthesizing Drag/Drop/DragEnd events from touch move/up, matching the
     existing Linux X11/Wayland approach.

2. **Finger-based drag-scrolling through the tab bar** (tab.rs, tab_bar.rs):
   - A finger down + move (without long press) on a tab now scrolls the tab bar
     horizontally instead of initiating a tab drag.
   - Includes flick-to-scroll with velocity and decay for natural momentum.
   - Touch tab selection is deferred to finger-up and only fires on a clean tap
     (no long press, no scroll gesture), so scrolling/dragging doesn't
     accidentally select tabs.

3. **Horizontal scroll input for tab bar** (scroll_bar.rs):
   - When `use_vertical_finger_scroll` is enabled on a horizontal scroll bar,
     both horizontal (trackpad) and vertical (mouse wheel) scroll inputs are
     accepted, so trackpad users can scroll the tab list in either direction.

* fix drag/drop on macOS by using internal drag logic.

Fix ghost tab on dock to be much cleaner in terms of behavior

* Cleanup dock tab drag&drop behavior

Make platforms consistent. Switch macOS to internal drag item tracking
instead of OS-native (just for the dock for now).

Ensure ghost tab that gets drawn is consistently hidden (instantly)
upon being dropped in an invalid target zone.

* Smooth scroll the tab bar to the selected tab, if not visible

This animation does a lot to help the user track where tabs are.
Previously, without this, tabs would get lost in a lengthy tab bar
because you could select a tab and not realize which one was selected
as there was no visual indication that a non-visible tab was chosen.
This was especially strange when a new tab is programmatically selected,
as you couldn't tell where you were in the tab bar.

Now, if you select a tab that is far beyond the visible bounds of the
dock tab bar, it will auto-scroll to it with a smooth animation.
Also, if you click on a tab that is partially visible, it'll scroll
just enough to make that tab fully within the tab bar view.
Basically it's just like any IDE's tab bar now.
2026-04-06 23:00:23 +02:00
Kevin Boos
8d356ec85d Show "ghost" dock tab during drag animation. Fix drag-n-drop rules, target zones, etc (#1015)
* Dock: add touch support for Tab/Tab bar interactions (scroll, drag/drop)

Details below:

1. **Finger-based tab drag-and-drop via long press** (tab.rs, android.rs, ios.rs):
   - On touch devices, tab dragging now requires a long press before moving,
     distinguishing it from scroll gestures.
   - Added internal drag-and-drop support for Android and iOS backends,
     synthesizing Drag/Drop/DragEnd events from touch move/up, matching the
     existing Linux X11/Wayland approach.

2. **Finger-based drag-scrolling through the tab bar** (tab.rs, tab_bar.rs):
   - A finger down + move (without long press) on a tab now scrolls the tab bar
     horizontally instead of initiating a tab drag.
   - Includes flick-to-scroll with velocity and decay for natural momentum.
   - Touch tab selection is deferred to finger-up and only fires on a clean tap
     (no long press, no scroll gesture), so scrolling/dragging doesn't
     accidentally select tabs.

3. **Horizontal scroll input for tab bar** (scroll_bar.rs):
   - When `use_vertical_finger_scroll` is enabled on a horizontal scroll bar,
     both horizontal (trackpad) and vertical (mouse wheel) scroll inputs are
     accepted, so trackpad users can scroll the tab list in either direction.

* fix drag/drop on macOS by using internal drag logic.

Fix ghost tab on dock to be much cleaner in terms of behavior

* Cleanup dock tab drag&drop behavior

Make platforms consistent. Switch macOS to internal drag item tracking
instead of OS-native (just for the dock for now).

Ensure ghost tab that gets drawn is consistently hidden (instantly)
upon being dropped in an invalid target zone.
2026-04-06 23:00:13 +02:00
Kevin Boos
3a030e88a5 Add ellipsis text truncation support (text_overflow + max_lines) (#1014)
* Add ellipsis text truncation support (text_overflow + max_lines)

Re-implement ellipsis truncation for text that overflows its container,
following conventions from CSS (text-overflow), Android (TextOverflow), and
Flutter (TextOverflow). This was supported in Makepad 1.0 but removed in 2.0.

Full summary below:

-----------------------

- Add `max_rows: Option<usize>` and `ellipsis: bool` fields to `LayoutOptions`
- Implement `apply_ellipsis_truncation()` post-processing step that:
  - Detects when text was truncated (by max_rows or single-line overflow)
  - Shapes the "…" (U+2026) glyph using the same font family
  - Removes trailing glyphs from the last visible row to make room
  - Trims trailing whitespace before the ellipsis for clean appearance
  - Appends the ellipsis glyph(s) to the last row
  - Recalculates the text bounding box
- Add early-exit in `layout_by_word()` and `layout_by_grapheme()` when
  `max_rows` is exceeded, avoiding unnecessary layout work for long texts
- Add `is_truncated: bool` field to `LaidoutText` for consumer detection
- Fix pre-existing bugs in `LayoutOptions` Hash/PartialEq: `wrap` and
  `line_spacing_scale` were missing, which could cause stale cache hits

- Add `TextOverflow` enum with `Clip` (default) and `Ellipsis` variants
- Add `max_lines: usize` and `text_overflow: TextOverflow` live properties
  on `DrawText`, passed through to `LayoutOptions`
- Register `TextOverflow` in the script module for DSL access
- Resolve `Fit` width max bounds when ellipsis/max_lines is active, so
  text layout knows the width constraint even for Fit-sized containers

- **Label** (widgets/src/label.rs): Add top-level `max_lines` and
  `text_overflow` properties, forwarded to `draw_text` in `draw_walk()`
- **TextFlow** (widgets/src/text_flow.rs): Same top-level properties,
  forwarded before each text draw call
- **Html / Markdown**: Inherit from TextFlow via `#[deref]` automatically
- Add `..mod.text` to widget prelude (widgets/src/lib.rs) so `Ellipsis`
  and `Clip` are accessible in all widget DSL

- Make `FitBound::eval_width()` and `eval_height()` public (draw/src/turtle.rs)
  so DrawText can resolve Fit max bounds during layout

```rust
// Simple single-line ellipsis
Label {
    width: Fill
    max_lines: 1
    text_overflow: Ellipsis
    text: "Long text gets truncated…"
}

// Multi-line with ellipsis
Label {
    width: Fill
    max_lines: 3
    text_overflow: Ellipsis
    text: "Wraps up to 3 lines, then truncates…"
}

// Also works via draw_text for any widget with DrawText
Button {
    draw_text +: { max_lines: 1, text_overflow: Ellipsis }
}
```

See the demos I newly added to the `uizoo` example too.

* Fix TextFlow widget-level ellipsis for multi-run styled text (like Html)

The per-run forwarding of max_lines/text_overflow to DrawText caused each
styled run (bold, italic, etc.) to independently truncate with its own
ellipsis, producing double "……" artifacts in Html/Markdown content.

- Add `lines_drawn` and `content_truncated` fields to track visual lines
  across all text runs within a single TextFlow
- Compute per-run `max_rows` based on remaining visual lines instead of
  blindly forwarding the widget's `max_lines` to every DrawText call
- Handle continuation runs (starting mid-line) correctly: they get +1
  row allowance since their first row shares the current visual line
- Skip further text runs once a run reports `is_truncated` (ellipsis drawn)
- Skip non-continuation runs when no visual lines remain

- `draw_walk_resumable_with` now returns `(usize, bool)`: row count and
  whether the layout was truncated, so TextFlow can track state across runs

- Add three Html ellipsis examples: 1-line, 2-line styled, and emoji+styled
2026-04-06 16:29:24 +02:00
Kevin Boos
07c55f65a9 Dock: add touch support for Tab/Tab bar interactions (scroll, drag/drop) (#1013)
Details below:

1. **Finger-based tab drag-and-drop via long press** (tab.rs, android.rs, ios.rs):
   - On touch devices, tab dragging now requires a long press before moving,
     distinguishing it from scroll gestures.
   - Added internal drag-and-drop support for Android and iOS backends,
     synthesizing Drag/Drop/DragEnd events from touch move/up, matching the
     existing Linux X11/Wayland approach.

2. **Finger-based drag-scrolling through the tab bar** (tab.rs, tab_bar.rs):
   - A finger down + move (without long press) on a tab now scrolls the tab bar
     horizontally instead of initiating a tab drag.
   - Includes flick-to-scroll with velocity and decay for natural momentum.
   - Touch tab selection is deferred to finger-up and only fires on a clean tap
     (no long press, no scroll gesture), so scrolling/dragging doesn't
     accidentally select tabs.

3. **Horizontal scroll input for tab bar** (scroll_bar.rs):
   - When `use_vertical_finger_scroll` is enabled on a horizontal scroll bar,
     both horizontal (trackpad) and vertical (mouse wheel) scroll inputs are
     accepted, so trackpad users can scroll the tab list in either direction.
2026-04-06 16:29:13 +02:00
Kevin Boos
f36f2e58ad TextInput: support single-line horizontal scrolling when text overflows (#1012)
* TextInput: support single-line horizontal scrolling when text overflows

When a single-line TextInput's text content is wider than its visible area
(due to Fill, Fixed, or parent-constrained Fit width), the text now
automatically scrolls horizontally to keep the cursor visible.

- Add `scroll_x` tracking with auto-scroll-to-cursor logic
- Push a clip rect for all TextInput modes (not just multiline) to prevent
  text from bleeding outside widget bounds
- Layout single-line text without max_width constraint so overflow is
  detectable via `size_in_lpxs.width`
- Handle mouse wheel/trackpad scroll events for single-line horizontal
  scrolling (maps both axes to horizontal)
- Account for `scroll_x` in IME position and selection rect calculations
- Add `Turtle::set_width()` and `Cx2d::compute_max_width_from_ancestors()`
  (width counterparts to existing height methods)
- Add UIZoo examples: Fill width, Fixed width, and Fit-in-container

* a bit more cleanup, no need for clip size to be an option
2026-04-06 16:28:35 +02:00
Kevin Boos
99bcff6dbf TextInput: explicitly support multiline mode with parent-relative max height (#1011)
* TextInput: support multiline mode with proper scrolling

* ScrollBar integration with mouse wheel, scrollbar handle drag,
  and the correct way of dealing with `handled_y` propagation,
  which basically means that scrolling can be handled by the TextInput
  as a child, or not and left to the parent.
* Only auto-scroll to the cursor when it actually moves, not on every redraw
* `is_multiline` controls wrapping too, which makes more sense.
   Now a single-line mode TextINput shouldn't wrap the text
* Allow setting `text` in the Splash DSL (make it `#[live]`)

Also added some examples to the uizoo demo: empty, pre-filled, read-only, toggle
between multi and single line.

* minor cleanup for TextInput multiline/scrolling

* Explicitly support multiline TextInput with Relative max height bounds

* more cleanup

* TextInput: support cascading parent-relative max height bounds

This was needed in Robrix, specifically a fairly common case in which
a TextInput should expand to Fit its content, but should not exceed
a certain percentage of the height of its parent.

This builds on the initial relative min/max Fit bounds that Eddy added
a while back, but weren't directly handled by TextInput, whcih itself
has special demands because it has to start internally
wrapping/scrolling.

* fix merge artifacts
2026-04-03 19:17:15 +02:00
Kevin Boos
0c5d39e2bc TextInput: support multiline mode with proper scrolling (#1010)
* TextInput: support multiline mode with proper scrolling

* ScrollBar integration with mouse wheel, scrollbar handle drag,
  and the correct way of dealing with `handled_y` propagation,
  which basically means that scrolling can be handled by the TextInput
  as a child, or not and left to the parent.
* Only auto-scroll to the cursor when it actually moves, not on every redraw
* `is_multiline` controls wrapping too, which makes more sense.
   Now a single-line mode TextINput shouldn't wrap the text
* Allow setting `text` in the Splash DSL (make it `#[live]`)

Also added some examples to the uizoo demo: empty, pre-filled, read-only, toggle
between multi and single line.

* minor cleanup for TextInput multiline/scrolling

* Explicitly support multiline TextInput with Relative max height bounds

* more cleanup
2026-04-03 19:09:48 +02:00
Kevin Boos
9379d01e21 TextInput: reflow text upon widget resize (width changes) (#1009)
Fixes a minor bug in which the entered text within a TextInput widget
would not get its layout recalculated if the width changed, meaning
that text could get cutoff on the right side of the widget.

Now we ensure that the text layout gets re-done (and the cached value
is not incorrectly used) if the width has changed since the last layout.
2026-04-03 11:30:25 +02:00
Kevin Boos
a45b505cbe Fix PortalList smooth scroll to handle all possible cases, and support scroll offset (#1008)
* Fix PortalList smooth scroll once and for all

* more cleanup, another small fix
2026-04-02 10:16:23 +02:00
Kevin Boos
8e1d9c8a72 Fix behavior of PortalList::at_end() to be fully correct (#1007)
* Fix behavior of `PortalList::at_end()` to be fully correct

This has been buggy for a long time, now it is flawless.

* cleanup, add some clarifying comments
2026-04-02 08:31:33 +02:00
Kevin Boos
95b4a3dbcc Properly animate caption bar when entering/exiting macOS fullscreen (#1005)
add handlers for "will enter/exit fullscreen" instead of just handling
"did" enter/exit, in order to properly animate. Otherwise it looks
janky for a split second where the traffic light buttons are on top of
the old app content before it refreshes.
2026-04-02 08:31:10 +02:00
Kevin Boos
39fee955e3 Expose window chrome button bounding box in WindowGeom (#1001)
* Expose window chrome button bounding box in `WindowGeom`

This allows apps that wanna draw something in the title/caption bar
to do so in a proper way without potentially drawing over the native
window chrome buttons (on macOS, the traffic light buttons).
Without this it'd be pretty tough to figure that out.

This also auto-sets the caption bar height to be tall enough such that
the window chrome / traffic light buttons are perfectly vertically-centered
in the middle of the caption bar. This was needed on macOS to prevent
things from looking janky as hell on newer macOS versions, which changed
the default size of the traffic chrome buttons.
It'll also be useful for drawing things in the caption bar on linux
or windows too.

Full change set:

- `widgets/src/window.rs`: Hide the caption bar on `LinuxWindow` when
  `!custom_window_chrome` (X11 — WM provides native decorations) directly in
  `sync_caption_bar_state`, removing the need for apps to do this manually.
- `event/window.rs`: Add `window_chrome_buttons: Rect` to `WindowGeom` —
  the bounding box of the OS/app-drawn window chrome buttons in logical window
  coordinates (top-left origin). Non-zero on macOS (traffic lights), Windows
  (min/max/close), and Wayland with `custom_window_chrome`. Zero on all other
  platforms (X11, LinuxDirect, mobile, web). Documented with per-platform
  details and guidance on how to use it for caption-bar layout margins.
- `macos_window.rs`: Add `traffic_lights_geom()` — queries all three
  traffic-light buttons via `standardWindowButton:`, converts their frames
  to Makepad's coordinate system via `convertRect:fromView:`, and returns
  the bounding box as a `Rect`.
- `win32_window.rs`: Populate `window_chrome_buttons` with the right-aligned
  138×29 px bounding box of the three Makepad-drawn caption buttons.
- `linux_wayland.rs`: Populate `window_chrome_buttons` in the
  `WindowGeomChange` handler when `custom_window_chrome: true`, using the
  same right-aligned 138×29 px layout.
- `cx_api.rs`: Add `update_caption_bar_height_script_value()` to push a
  measured height into `mod.widgets.CAPTION_BAR_HEIGHT` on the script heap.
- `window.rs` (DSL): Declare `mod.widgets.CAPTION_BAR_HEIGHT = 27.0` in the
  `script_mod!` block and change `caption_bar.height` from the hardcoded `27`
  to `(mod.widgets.CAPTION_BAR_HEIGHT)`. On `WindowGeomChange`, derive the
  default caption bar height from `window_chrome_buttons` using equal
  top/bottom padding (`pos.y * 2 + size.y`) and trigger a script reapply.
- `platform/src/lib.rs`: Export `LinuxWindowParams`, `WindowGeom`,
  and `SafeAreaInsets`.

* Fix calculation of title bar height based on buttons

ensure dynamic override actually propagates via Rust code

* clearly define system-calculated caption bar height vs manual override

* Fix window drag move bounds to match the caption bar area

remove excess debug logs
2026-04-01 23:11:37 +02:00
Admin
f94a3f36fa variable weight fonts 2026-04-01 12:19:03 +02:00
Admin
d134df9f06 xr llama and slug 2026-04-01 12:19:03 +02:00
Kevin Boos
af7712a406 PortalList: fix drag scrolling over widgets that handle events/hits (#1002)
Previously, PortalList's drag scrolling straight up didn't work
when the initial FingerDown event (touch/tap/click) landed on a widget
that is "interactive", meaning it could handle events. Not sure when that
concept was introduced, but it's kinda flawed given that all widgets
just defaulted to being `true` (always interactive). But imo that goes
against the ethos of simple event handling based on ordering of calls to
`handle_event()`, not to mention the whole `capture_overload` thing.

I think this is the solution that we've always wanted. The PortalList itself
now tracks when it is scrolling (and only starts a scroll once it is sure
enough finger/mouse movement has occurred, `TAP_COUNT_DISTANCE`),
and it does not deliver these interactive events to child widgets
while it is scrolling. This will make things a lot easier for the app dev too,
since that's how iOS and Android work too.

Details of changes to `portal_list.rs`:

- Always enter `ScrollState::Drag` on FingerDown regardless of whether
  the touch point is over an interactive widget. A `committed` flag and
  `drag_scroll_threshold` (defaulting to `TAP_COUNT_DISTANCE`) gate
  when scroll deltas actually apply, preventing micro-scrolling during
  taps/clicks on interactive items.
- Suppress event forwarding to child widgets once a drag scroll commits
  (finger moves past threshold), so children don't receive stale
  interaction events during scrolling.
- Suppress event forwarding when a finger-down/click arrives while a
  scroll animation (flick, pulldown, etc.) is in progress, so tapping
  to stop a scroll doesn't also activate a child widget.
- Add configurable `drag_scroll_threshold` property to PortalList.
2026-04-01 08:40:06 +02:00
Kevin Boos
e8d1b217da Choose sane defaults for platform-specific title/caption bar config (#1000)
Primarily on Linux, ensure that we show the title/caption bar
and draw it within Makepad (i.e., client-side drawing) if the
DE/WM doesn't show it by default.
This should make things behave as expected on Linux X11 and Wayland
both.
2026-04-01 00:42:29 +02:00
Kevin Boos
f99b1d875a Fix title bar, captions label centering, and windows buttons (#999)
no app-level overrides are needed now.

1. on Windows, the windows buttons now behave and are drawn
   just like all other apps -- proper bg coloring on hover and down,
   and the right sizing.

2. and for the caption label, it is centered properly (by accounting
   for the size of the windows_buttons button set), and then when the
   window is too narrow, it is left-aligned in the remaining space
   to ensure that it stil looks good.
2026-03-31 08:58:06 +02:00
Kevin Boos
fec9bb6f2e Introduce knowledge of device screen bounds/"safe inset areas" (#990)
* Introduce knowledge of device screen bounds/cutous/"safe inset areas"

Tested working on iOS, implemented for Android but not yet tested.

The approach may need to be improved, because it currently restricts
the whole app window to being fully within the safe areas.
We may not necessarily want that, or if we do, then we probably also
need to support setting the base color of the reserved system areas
(beneath the app bounds and above in the notification bar area).

* Use metal scissor rect to prevent SVGs/icons from being mis-drawn in safe areas

This prevents anything from being accidentally drawn in the safe
inset areas when the pass clear_color is transparent. Of course,
we can still draw the pass clear_color in those areas.

* Workaround: apply a scissor rect within safe inset area

Only apply it to clip any DrawSvg/DrawVector-specific draw calls
within the safe inset area.

This is unfortunately still just a hacky solution, because if we
actually do want to draw svg/vectors within that safe inset area,
then we won't be able to.

* Properly fix gpu artifacts when rendering SVGs

The `DrawSvg` vertex shader had a GPU fringe expansion pass designed for `fill_gpu()` mode, where fringe vertices encode per-vertex normals in the `v` and `stroke_dist` fields. SVG rendering used `fill_gpu()`, which produces **coincident-vertex fringe triangles** (body and outer fringe at the same CPU position, expanded on the GPU). These zero-area triangles caused **Metal GPU rasterization artifacts** — stray fragments appearing at unexpected screen positions.

**`draw/src/svg/render.rs`** — Switch SVG fill from `fill_gpu()` to `fill()`. Pre-computed fringe produces vertices at physically different positions (no coincident vertices).

**`draw/src/shader/draw_svg.rs`** — Remove the GPU fringe expansion code from the vertex shader. With pre-computed fringe, the `v` and `stroke_dist` fields are constants (`1.0` and `0.0`), not per-vertex normals. The expansion code was misinterpreting `v=1.0` as a horizontal normal, corrupting vertex positions.

**`libs/apple_sys/src/lib.rs`** — Added `MTLScissorRect` struct (unused now but available for future use).

**`src/home/rooms_sidebar.rs`** — Changed shadow offset from `vec2(1.0, 0.0)` to `vec2(0.0, 10.0)` so the `RoundedShadowView` shadow only draws below the header, eliminating the gray line at the top of the screen (issue 1).

* Expose safe area inset padding to app, don't forcibly apply it to root window

* Fixed safe area insets padding, with support for rotation

We now make these values available to the app dev (see below)
instead of forcibly inserting them as padding on all root windows.

This will allow each app to choose how and when they want to apply said pad values
(or if they want to at all) in an easy way, both at the Splash level
or more dynamically/programmatically at the Rust level.

Required quite a few changes to how things work in the iOS platform plumbing,
also described below in the generated summary:

On iOS and Android, Makepad apps render content behind device cutouts (Dynamic Island, camera notch), home indicators, and rounded screen corners because the framework has no awareness of safe area insets.

Added platform-level safe area inset querying on iOS and Android, exposed the values through both the Splash DSL (`mod.widgets.SAFE_INSET_PAD_*`) and Rust (`cx.display_context.safe_area_insets`), and ensured they update correctly on device rotation.

**New types:**
- `UIEdgeInsets` struct in `libs/apple_sys` for Objective-C interop
- `SafeAreaInsets` struct in `platform/src/event/window.rs` (top/right/bottom/left in logical points)
- Added `safe_area_insets` field to `WindowGeom` and `DisplayContext`

**iOS (`platform/src/os/apple/ios/`):**
- Query `[UIView safeAreaInsets]` from the MTKView in `check_window_geom()`
- Added `viewSafeAreaInsetsDidChange` callback on `MakepadViewController` to detect inset changes on rotation
- Populate `display_context` before `Event::Startup` so values are available during app script initialization
- Fixed MTKView setup: removed redundant `addSubview:` (conflicted with `setRootViewController:`) and added autoresizing mask — both required for safe area propagation on rotation

**Android (`platform/src/os/linux/android/`):**
- Added `SafeAreaInsets` variant to `FromJavaMessage` and corresponding JNI function
- Java side (`ResizingLayout.onApplyWindowInsets`): queries `WindowInsets.Type.systemBars() | displayCutout()` and sends insets to Rust (converted from px to dp)
- Added `safe_area_insets` field to `CxOs`, populated on `SafeAreaInsets` message and included in `WindowGeom` construction
- Added `surfaceOnSafeAreaInsets` native method to `MakepadNative.java`

**Splash DSL variables (`widgets/src/lib.rs`):**
- `mod.widgets.SAFE_INSET_PAD_TOP`
- `mod.widgets.SAFE_INSET_PAD_BOTTOM`
- `mod.widgets.SAFE_INSET_PAD_LEFT`
- `mod.widgets.SAFE_INSET_PAD_RIGHT`
- Values read from `display_context` at widget module initialization (during `Event::Startup`)
- Updated on the script heap via `Cx::update_safe_inset_script_values()` on `WindowGeomChange`

**Rotation support:**
- Added `pending_script_reapply` flag on `Cx` — set when safe area insets change, checked at the end of the platform event loop iteration
- Fires a deferred `LiveEdit` event to re-evaluate and re-apply all Splash widget definitions with updated inset values
- Implemented in both iOS and Android event loops

**StackNavigationView fix (`widgets/src/stack_navigation.rs`):**
- Full-screen stack views now position at `max(safe_area_insets.top, parent_rect.pos.y)` instead of hardcoded `y: 0`, respecting both mobile safe areas and desktop title bars

**All other platforms:**
- Added `..Default::default()` to all `WindowGeom` constructors (macOS, Windows, Linux X11/Wayland/Direct, web, tvOS, OpenHarmony) so the new `safe_area_insets` field defaults to zeros
2026-03-31 08:57:36 +02:00
Admin
cf46675a32 xr room mapping 2026-03-27 13:51:54 +01:00
Admin
9b9a35ea7c better physics 2026-03-25 17:39:00 +01:00
Admin
1bbc4b6791 finally 2026-03-25 17:38:59 +01:00
Sabin Regmi
81034607d7 ft makepad_test (#974)
* ft makepad_test

* Improve run handling, manifest parsing, and stdout newline

Replace dynamic free-port lookup with an ephemeral localhost SocketAddr in test runtime and remove the unused find_free_listen_address helper. Ensure headless stdout messages end with a newline. Simplify send_to_app error handling and add a test that queued bootstrap messages are delivered once an app socket connects. Substantially enhance process_manager: unify cargo flag parsing, parse Cargo.toml to determine package/bin targets, resolve the correct binary name for direct stdio runs, and build the cargo/build+exec script from the resolved args. Add unit tests for manifest parsing and script generation and adjust related call sites.

* test harness

* Preserve test attrs; return Vec for gateway binds

In the test macro (libs/makepad_test/macros/src/lib.rs) preserve wrapper-only attributes (ignore and should_panic) on the generated wrapper test while removing them from the inner function. Added Attribute import, is_wrapper_only_test_attr helper, adjusted attribute filtering and emission, and added unit tests to verify attribute placement and expansion.

In the hub (studio/hub/src/hub.rs) change gateway_bind_candidates to return a Vec<SocketAddr> instead of an iterator and special-case ephemeral port 0 to preserve ephemeral binding; otherwise collect the range of candidate ports into a Vec. Added tests to validate candidate behavior. Also minor formatting/whitespace tweaks and a small IPv6 formatting adjustment.

* Add visible Studio mode and remote client

Enable running UI tests visibly through a running Makepad Studio. Adds a new makepad-network dependency and studio_remote client (libs/makepad_test/src/studio_remote.rs) and integrates it into the runtime via a TestConnection enum. Introduces visible-mode tooling: env vars (MAKEPAD_TEST_VISIBLE, MAKEPAD_TEST_STUDIO, MAKEPAD_TEST_STUDIO_MOUNT, MAKEPAD_TEST_STARTUP_DELAY_MS, MAKEPAD_TEST_ACTION_DELAY_MS, MAKEPAD_TEST_KEEP_OPEN_MS), pacing/delays after actions, and pause-before-shutdown. Splits startup into start_headless_app/start_visible_app, clears existing visible builds before launching, and updates tests, docs (GUIDE.md, README.md), and selector/runtime minor cleanups/formatting.
2026-03-25 16:09:03 +01:00
Sabin Regmi
5f97452a00 Redraw overlay draw_list on open/close (#978)
Explicitly redraw the overlay widget draw_list when opening and closing Modal and PopupNotification. This makes the overlay visible immediately on the first open (before the overlay content has refreshed or established a reusable draw area) and ensures the previous frame isn't left visible too long on close. Keeps existing background redraws intact.
2026-03-25 15:17:41 +01:00
Sabin Regmi
33dea86646 Small Studio UX Nits (#982)
* Add animated sidebar toggle and splitter APIs

Add an animated, persistent sidebar toggle and supporting splitter APIs/UI.

- New icon resource: studio/desktop/resources/icons/icon_sidebar_toggle.svg
- UI: replace hidden caption bar with a visible caption that includes a sidebar toggle button (CaptionSidebarToggle), layout adjustments and related controls.
- App behavior: add SidebarAnimation struct and App fields to track animation state and next-frame. Handle button actions, next-frame stepping, and window drag queries to avoid initiating window drag over the toggle.
- Add App methods to query/set the workspace root splitter position, start/step sidebar animations, toggle sidebar (remember/restore width), and sync tab-bar visibility for mounts.
- Persist mount sidebar restore width by adding sidebar_restore_width to MountState and initializing default.
- Make save_state pub(super) so App can save when animation finishes.
- Widgets: expose splitter position and set_splitter_align on Dock and Splitter to allow programmatic width changes and redrawing.

These changes improve UX by providing a smooth animated sidebar hide/show, remembering user width per mount, and ensuring the dock UI updates correctly during mount/tab changes.

* Persist sidebar_restore_width in mount state

Add an Option<f64> sidebar_restore_width to PersistedMountStateRon and wire it through loading and collection so the sidebar width is saved and restored. Include tests to verify a round-trip serialization/deserialization preserves the value and that missing legacy data defaults to None for backward compatibility.

* Sync run preview splitter state

Hide and restore the Run preview column based on whether run tabs exist. Added run_panel_split_restore to AppData to remember the last editor_split ratio per mount, plus a helper (run_preview_splitter_is_collapsed) and a new method sync_run_preview_splitter that collapses the preview when there are no runs and restores the previous ratio when runs reappear (defaults to Weighted(0.62)). Called sync_run_preview_splitter from relevant places: after creating/ensuring run tabs, when clearing build tabs, when closing run tabs, and at startup to initialize each mount. Also added /.cocoindex_code/ to .gitignore.

* Add bottom panel toggle with animation

Introduce a bottom panel toggle UI and animation support. Adds a new icon resource and CaptionPanelToggle button in the caption bar, moves/adjusts caption layout, and wires the button to toggle the bottom panel. Adds a TerminalShellPane, bottom_terminal_tab, and integrates bottom_panel_tabs into the workspace layout. Implements BottomPanelAnimation, animation helpers (panel_animation_progress, start/step logic), workspace splitter height getters/setters, and toggle/select helpers (toggle_bottom_panel, select_bottom_terminal_panel). Persists mount bottom_panel_restore_height in MountState and persisted state with tests updated. Also updates drag/tab behavior to account for the new bottom terminal tab and routes animation next-frame events.

* Refactor reflow_resize and add wrap test

Rewrite reflow_resize to simplify reflow logic and improve handling of growing/shrinking rows and scrollback. The change always captures the old grid state, builds logical (re-wrapped) scrollback lines, and then branches on whether the new height is greater, less, or equal to the old height. On growth it may pull rows from the logical scrollback when the terminal was full, preserve content when a custom scroll region is present, and correctly update cursor, high-water, saved cursor and bottom_trimmed_rows. On shrink it chooses how many bottom rows to push into scrollback based on cursor position, trimmed rows, and content below the cursor, and trims scrollback to max_scrollback. Also adjust cursor bounds and pending_wrap handling. Add a test (visible_wrapped_prompt_rows_do_not_reflow_on_width_growth) to ensure visible wrapped prompt rows do not get reflowed when the width increases.
2026-03-25 14:12:57 +01:00
Kevin Boos
2c91c12dbf Fix stack nav to make it more like a true stack (#980)
* Removed `remove_all(view_id)` from `push_view()` to allow
  the same view ID on the stack multiple times. Most apps will
  need somethin like this, otherwise they'd have to have a weird
  statically-known set of fixed views that are eligible to be
  on the stack. Robrix, at the least, doesn't have that.
* Fixed `show()` to force-reset the animator state, which was needed
  to make a fresh animation always play (even when animating in "reused" views)
* Reset `state` to `Inactive` in `show()`, otherwise it'll never transition to `Active`
2026-03-24 19:52:37 +01:00
Admin
ab3c57436d xr otw 2026-03-23 22:26:41 +01:00
Admin
6d38bc52be compiles 2026-03-23 12:56:39 +01:00
Admin
a169260390 cleanup 2026-03-23 10:12:37 +01:00
Admin
8a13941776 android borked 2026-03-22 17:28:18 +01:00
Admin
e5e3ddbdec fix xr lib 2026-03-21 15:24:19 +01:00
Admin
b2b31cce5b demo 2026-03-21 11:39:27 +01:00
Sabin Regmi
0ef3e2d9ee Some small web nits from my crazy experiement (#972)
* Schedule loader removal after presented frame

Introduce loader_after_presented_frame_id and add schedule/cancel helpers to remove the canvas loader after a presented animation frame. Cancel any pending requestAnimationFrame when the loader is removed or conditions change, and update update_startup_loader to use the new scheduling logic (remove loader only after seen animation frame and quiet frames threshold). This prevents premature removal and visual glitches while preserving the existing fallback timer.

* small fonts should be used when --profile=small

* dont include large fonts on small profile + fix compress serving

* Refactor window initialization and caption sync

Extract sync_caption_bar_state and sync_caption_title from ensure_initialized and call them before the initialized early-return so caption bar state and title are kept in sync even when the widget is re-applied. ensure_initialized still performs the original one-time setup (pass, depth texture, demo frame), but runtime chrome (VR button and caption visibility/title) is now updated up-front to avoid stale UI state.

* fix --bindgen

* Set imports.env in wasm import patches

Add additional string replacements to ensure imports.env = env is injected into generated JS for different formatting variants of the __wbg_get_imports(...) call. This makes the patch robust to variations like missing const or spacing so the env object is always attached to the wasm imports.

* Revert "Set imports.env in wasm import patches"

This reverts commit 37933234d36b4ee867690cf167474638e81febf7.

* Revert "fix --bindgen"

This reverts commit cb236b202b92a46eda3cb1ee4c678bdf6507081a.

* Reapply "fix --bindgen"

This reverts commit 27df4175bd1889222b928ffb68213aa865d1c839.

* Reapply "Set imports.env in wasm import patches"

This reverts commit 23695b4fa646d8f1b7a31a3fc27eb92f5bce0cf8.

* fix xr compilation error
2026-03-21 11:23:16 +01:00
Admin
0b4ee8860d fix android screencap to studio 2026-03-20 09:03:50 +01:00
Kevin Boos
3a263956c8 Restore optional serde derives that were removed in Makepad 2.0 (#973) 2026-03-19 20:07:45 +01:00
Kevin Boos
95090bbc0a Ensure that the Html <br> tag obeys current line spacing settings (#971)
Without this, Html blocks that have both `<br>` and `\n` newlines
(or even just soft line wraps) look quite janky, with poor vertical spacing.
2026-03-19 20:07:28 +01:00
Kevin Boos
9977202cfa Fixed several issue in text drawing, layout, and text flow. (#970)
These are needed to support better formatting of Html code
that mixes multiple different styles together, e.g., inline code
next to normal code, or inline code within a blockquote or a heading.

Full summary of changes:

**File:** `draw/src/shader/draw_text.rs`

Added `#[live(0.0)] pub top_drop: f32` to `TextStyle`. This is a vertical offset expressed as a fraction of font size — positive values shift text downward. It's useful for aligning baselines when mixing fonts with different vertical metrics (e.g., a code font rendered inline with regular text).

**File:** `draw/src/shader/draw_text.rs`

When `temp_y_shift != 0`, the extra shift pixels are now added to `allocate_height()` and the emitted walk rect. This prevents containers (blockquotes, etc.) from clipping the descenders (g, p, q, y) of vertically-shifted text.

**File:** `widgets/src/text_flow.rs`

After selecting the appropriate text style (normal/bold/italic/fixed), `draw_text.temp_y_shift` is now set from that style's `top_drop` value. This allows each style variant to specify its own vertical offset, since `TextFlow` uses a single shared `DrawText` instance for all text rendering.

**File:** `draw/src/turtle.rs`

New public method to mutate `layout.padding.left` after a turtle has been created.

**File:** `widgets/src/text_flow.rs`

After drawing the bullet/number marker, the actual cursor position is now measured and `set_padding_left()` is called so that wrapped continuation lines align with the text after the marker, rather than being over-indented by the estimated `font_based_padding` (which was `2.5 * font_size`).

Additionally, the hardcoded `draw_text(cx, " ")` spacer after the marker was replaced with `walk_margin(cx, self.list_item_marker_pad)` for precise pixel-based control.

**File:** `widgets/src/text_flow.rs`

Added `#[live(5.0)] list_item_marker_pad: f64` — a configurable spacing (in pixels) between the list item marker (bullet/number) and the content text that follows it.
2026-03-19 20:07:13 +01:00
Admin
9f445a6c69 cleanup 2026-03-19 10:16:38 +01:00
Admin
059f8a123c helmet with real envmap 2026-03-18 01:29:59 +01:00
Admin
99bd8d38d4 vulkan debugging 2026-03-17 23:59:07 +01:00
Admin
62a7fd33f4 cef 2026-03-17 19:00:28 +01:00
Admin
c4064cef6a vulkan video textures 2026-03-17 19:00:28 +01:00
Kevin Boos
b376a3c447 Proper widget tree fix (#956)
* Fix macos platform build failures related to PR#946

* Properly fix the new breadth-first widget tree lookup
2026-03-16 19:27:32 +01:00
Admin
98bc76b705 vulkan back 2026-03-15 13:20:49 +01:00
Admin
0cfd9f36e0 otw 2026-03-15 09:52:45 +01:00
Sabin Regmi
747d04c898 ft floating panel on macos (#945) 2026-03-14 12:12:35 +01:00
offline-ant
2e94536b28 platform: rework custom MSE playback sessions (#946)
Co-authored-by: ant <ant@offline.click>
2026-03-14 12:12:21 +01:00
Kevin Boos
682592c214 Fix HtmlLink attribute init to handle any attr order (#948) 2026-03-14 12:11:42 +01:00