Commit Graph
4930 Commits
Author SHA1 Message Date
Martín Lucas Golini ee8f560bde Add native Wayland file dragging for SDL2 and SDL3
- Load Wayland APIs dynamically and track genuine pointer press serials.
- Serve file URI lists on a dedicated queue and transfer thread.
- Render native drag icons with Copy, rejected and pending feedback.
- Use memfd_create on Linux with a portable temporary-file fallback.
- Suppress synthetic gesture releases and clean up on cancellation,
  window destruction and process exit.
- Add isolated Weston integration tests and document API requirements.
2026-10-15 10:58:58 -03:00
Martín Lucas Golini ad69ee977e Fix project encoding test scanning downloaded SDL3 SDKs
Skip versioned SDL2 and SDL3 SDK directories before recursing,
preventing bundled libraries and debug symbols from being treated
as project text files.
2026-10-15 00:07:27 -03:00
Martín Lucas Golini 0b182de93e Fix Windows MSVC build. 2026-10-14 22:01:18 -03:00
Martín Lucas Golini b53ea69258 Fixed the missing SDL3 startup wrappers. Premake now adds sdl3_main.cpp (src/eepp/main/sdl3_main.cpp) once per MSVC executable to supply main/WinMain, while preserving the accessibility harness’s own wmain. 2026-10-14 20:38:57 -03:00
Martín Lucas Golini 60f025fde2 Fix SDL backend isolation in platform helpers
Include only the selected backend in Engine and guard both platform helper
classes and the SDL2 implementation. This prevents MSVC SDL3 builds from
exporting SDL2 vtables and failing with unresolved helper methods.
2026-10-14 19:16:26 -03:00
Martín Lucas Golini 45f11f6816 Add native file dragging on macOS
- Implement a Cocoa drag source on NSDraggingSession for SDL2 and SDL3.
- Use the offered snapshot as the drag image, or each file's Finder icon,
  with AppKit's own count badge and copy cursor.
- Offer Generic alongside Copy only within the application, so SDL2's
  Cocoa windows accept drops while other apps still see a copy-only offer.
- Report cancellation immediately and refuse the drop, since AppKit cannot
  abort a running session.
- Fix macOS SDL3 builds: use pkg-config instead of the removed sdl3-config
  and keep EE_SDL3_FROM_ROOTPATH for framework builds only.
- Build the native drag tests on macOS, add the Android drag sources, and
  avoid the windows.h max macro in the Win32 source.
- Document macOS behavior and platform support.
2026-10-14 18:37:08 -03:00
Martín Lucas Golini 6e38945211 Add native file dragging on X11 and Windows
- Introduce DragAndDrop with capability queries, copy-only file offers,
  image previews, cancellation, and completion callbacks.
- Implement XDND and OLE sources with safe input recovery and window teardown.
- Keep SDL2 and SDL3 presentation and input handling in their own backends.
- Load X11 dynamically without adding a link dependency.
- Reuse Image, URI, and timing APIs; fix Image::fillWithColor().
- Add a manual playground, integration tests, and consumer documentation.
- Migrate SDK builds and packaging to SDL3 and fix bundled runtime lookup.
2026-10-14 17:24:56 -03:00
Martín Lucas Golini 5833344902 refactor(scene): unify current scene and window context binding
Move Context and makeCurrent() from UISceneNode to SceneNode, allowing
scene drawing, updates, and input/IME dispatch to use the same scoped
binding without UI-specific branches.

Replace SceneManager's cached UI scene and scoped scene pointers with
one persistent SceneNode binding. Add setCurrentSceneNode() and make
getUISceneNode() return nullptr when the current scene is not a UI scene,
removing implicit fallback searches.

Establish the default binding during initialization and select a
surviving application scene when the current native window closes.
Use scoped binding in UICodeEditor::showFindReplace() and migrate
existing callers of the UI-specific setter.

Add regression coverage for nested and moved contexts, strict UI lookup,
cross-window restoration, scene removal, find/replace, and window closing.
2026-10-13 01:29:35 -03:00
Martín Lucas Golini d1ea03f420 fix(ui): clear stale dirty queues when widgets change scenes
Remove pending layout, style and style-state entries from the old
scene during rebinding without invalidating shared accessibility
identities. Requeue dirty layouts in the destination scene while
preserving their invalidation reasons.

Fix a use-after-free exposed by TabFocus.WidgetCreatorDefaultsAreIntentional
after deleting a WebView.

Add regression coverage for WebView deletion, subtree and reverse
rebinding, and coalesced layout work.
2026-10-13 00:17:21 -03:00
Martín Lucas Golini c59920c72c feat(a11y): expose basic HTML accessibility semantics
- Expose source text, heading levels, links, lists/items and image alt text
- Keep formatting wrappers transparent and nested controls accessible
- Route link activation through existing navigation and interception
- Project passive fragment focus to links while preserving control focus
- Notify clients of text, href, alt text and semantic role changes
- Map HTML semantics to AT-SPI, UIA and macOS accessibility APIs
- Avoid advertising selection capabilities for static HTML lists
- Preserve dormant allocation behavior without new per-widget caches
- Fix MinGW harness compatibility with both TreeScope enum spellings
- Add unit/native regression coverage and update accessibility docs
2026-10-12 23:33:46 -03:00
Martín Lucas Golini 28cc1e528f fix(a11y): restore compatibility with older macOS and MinGW SDKs
- Use the native AX navigation-order attribute name on older AppKit SDKs
- Supply missing UIA declarations with compatible COM signatures and UUID
- Generate missing x86/x64 UIAutomationCore import libraries for older MinGW
- Keep fallback library paths consistent across Premake 4 and 5
- Add native navigation-order and UIA event-advice ABI regression coverage
2026-10-12 20:00:57 -03:00
Martín Lucas Golini ddbec94c2f Merge branch 'feature/a11y' into develop 2026-10-12 13:38:35 -03:00
Martín Lucas Golini 7044db3038 Update docs. 2026-10-12 12:27:44 -03:00
Martín Lucas Golini edf0ab26f0 Fix build warnings. 2026-10-12 11:06:50 -03:00
Martín Lucas Golini 20cef23920 Fixed an HTML input regression:
- focusable now targets the native control, without making the host another Tab stop.
- Overrides survive type changes, including transitions through hidden.
- Added regression coverage and updated documentation.
2026-10-12 02:52:53 -03:00
Martín Lucas Golini 1aa874d766 feat(ui): introduce intentional tab-focus defaults
- Make generic widgets non-tabbable and opt interactive controls in
- Keep composite controls and model views from exposing duplicate stops
- Fix reverse traversal and list-row focus navigation
- Complete keyboard activation and popup navigation for affected controls
- Preserve explicit focus policies and ecode search navigation callbacks
- Align accessibility focus semantics with effective keyboard targets
- Add tab-navigation regressions and document custom-widget migration
2026-10-12 02:38:25 -03:00
Martín Lucas Golini a06826ee72 refactor(a11y): expose virtual widget semantics and encapsulate hierarchy bridge
- Make UIWidget accessibility queries and actions virtual while retaining
  centralized resolver defaults for built-in widgets.
- Honor custom semantics in hierarchy, focus, auditing, action validation,
  and relation names while preserving one-hop relation resolution.
- Remove obsolete parent-change forwarding methods and test notifications
  through actual scene operations.
- Restrict SceneNode's hierarchy observer to the internal accessibility bridge.
- Add custom-widget and dormant-construction regression tests and update docs.
2026-10-12 01:16:35 -03:00
Martín Lucas Golini 2a2bbea989 refactor(a11y): move scene-rebinding cleanup into UIWidget
- Add a protected UINode rebinding hook with a no-op default.
- Move widget identity invalidation into the UIWidget override.
- Remove the UINode self-downcast and AccessibilityManager dependency.
- Preserve child-first cleanup before updating the local scene pointer.
- Extend regression coverage to verify rebinding and invalidation order
2026-10-11 23:50:01 -03:00
Martín Lucas Golini 273abed43d test(a11y): cover dormant reparenting and reentrant indexed insertion
- Verify semantic references survive same-scene reparenting through plain
  nodes and are invalidated when moving between scene owners.
- Check text references and semantic hierarchy without native clients.
- Verify indexed insertion reports the final semantic index when a
  child-count callback reorders destination siblings.
- Assert stable identities and exactly one ordered removal/arrival pair.
2026-10-11 19:56:02 -03:00
Martín Lucas Golini 87d50eb177 perf(a11y): reduce dormant overhead and decouple scene notifications
- Move process-wide client activity tracking into Accessibility
- Remove UI dependencies from Node through an optional hierarchy observer
- Inline dormant manager checks and avoid redundant subtree cleanup
- Preserve invalidation of identities retained by explicit semantic queries
- Skip idle AT-SPI atomic exchanges and async-resource queue locking
- Avoid empty-set style lookups and redundant dispatcher lookups
- Add lifecycle, multi-scene activity and async-delivery regression tests
- Update accessibility architecture documentation
2026-10-11 18:48:53 -03:00
Martín Lucas Golini 866851c061 fix(a11y): track plain-node subtree moves and fix MSVC build
- Report semantic subtree removals and arrivals through plain nodes,
  preserving identities and avoiding duplicate embedded-scene notifications.
- Add regression coverage for direction changes, reparenting, focus,
  selection, event ordering and mirrored-layout hit testing.
- Extend macOS password-mode tests to verify retained element identity,
  protected text access and native transition notifications.
- Qualify the event-loop wake-up call to resolve MSVC's Window ambiguity.
- Document accessibility notifications for plain-node subtree moves.
2026-10-11 15:12:31 -03:00
Martín Lucas Golini 4112805706 Fix debug build. 2026-10-11 14:08:29 -03:00
Martín Lucas Golini 218c634bf2 Merge branch 'develop' into feature/a11y 2026-10-11 14:08:11 -03:00
Martín Lucas Golini 48b0ce6db6 Should fix MSVC build. 2026-10-11 14:07:18 -03:00
Martín Lucas Golini f380cd7630 Merge branch 'develop' into feature/a11y 2026-10-11 13:08:33 -03:00
Martín Lucas Golini 15f76e4872 Fix MSVC build. 2026-10-11 13:08:12 -03:00
Martín Lucas Golini b79b4444d6 Merge branch 'develop' into feature/a11y 2026-10-11 12:59:47 -03:00
Martín Lucas Golini ccb03a3b8e Add inherited RTL direction and logical UI layout support
- Cache effective direction and skip unchanged subtree propagation.
- Add logical alignment, box edges, and relative positioning.
- Mirror layouts and controls while preserving logical node order.
- Apply inherited base direction to UI text and editing.
- Keep logical-edge storage lazy and compact.
- Add regression tests, an isolated WebView demo, and RTL documentation.
- Document RichText bidi limitations and plan paragraph-level support.
2026-10-11 12:29:16 -03:00
Martín Lucas Golini 32a9b7084d fix(ui): preserve LSP tooltip highlighting on repeated hover responses
Restore the tooltip source when its text cache has been transformed,
even if the incoming tooltip text is unchanged. This prevents repeated
Markdown highlighting from losing fenced-code syntax colors.

Keep accessibility notifications gated on actual source-text changes.
Add a regression test covering repeated hover responses and rendered
color retention.
2026-10-11 11:54:25 -03:00
Martín Lucas Golini 925053484d Fixed all review items:
- Password-mode changes immediately clear/restore the Inspector preview and notify native clients.
- Added regression tests without artificial focus events.
- Verified full-value copying and password privacy using an in-memory clipboard.
- Updated incremental-index documentation.
2026-10-11 11:10:31 -03:00
Martín Lucas Golini 64e13cc80b perf(ui): bound accessibility Inspector value refreshes
- Replace full editor values with bounded 1024-code-point previews.
- Reuse previews when document identity and revision are unchanged.
- Use proportional column widths and borrowed model strings.
- Add explicit full-value copying with loading-state safeguards.
- Safely defer worker-originated refreshes to the main thread.
- Add regression tests and Inspector allocation benchmarks.
- Document preview behavior and text revision assumptions.
2026-10-11 03:05:18 -03:00
Martín Lucas Golini cc2097f854 Fixed the test’s recursive callback with std::exchange(nested, nullptr) and added assertions that it runs exactly once and remains cleared. 2026-10-11 01:31:38 -03:00
Martín Lucas Golini a154e1c9f9 perf(a11y): reduce cold text indexing overhead
- Build text indexes using a bulk line-length read under one lock scope,
  reusing storage and returning the document revision.
- Avoid requesting unused text offsets in the Accessibility Inspector.
- Add cold first-edit/focus benchmarks and regression tests for unqueried
  edits, Inspector updates, Unicode lengths, and buffer reuse.
- Document the remaining O(lines) initialization cost and measurements.

Reduce million-line cold edits from ~29.2 ms to ~5.7 ms without changing
allocation counts, class sizes, or dormant-path work.
2026-10-11 00:58:03 -03:00
Martín Lucas Golini e8e0a26727 perf(a11y): incrementally index text and bound AT-SPI dispatch
- Replace global line caches with lazy, per-manager document indexes
- Update affected line lengths without allocations on ordinary edits
- Preserve indexes across muted edits and recover ambiguous nested changes
- Count semantic children without materializing node identities
- Add a 2 ms AT-SPI dispatch budget while preserving backlog wakeups
- Add opt-in AT-SPI/UIA profiling and active performance benchmarks
- Cover shared documents, lifecycle, Unicode and nested-edit regressions
- Document measurements, scalability limits and native-host follow-ups
2026-10-10 23:59:58 -03:00
Martín Lucas Golini df541930bf Merge remote-tracking branch 'origin/develop' into develop 2026-10-10 23:56:39 -03:00
Martín Lucas Golini 340d879677 Fix shaped text vertex colors, glyph blur and RTL caret mapping
Text sized its per-vertex color array with getTotalVertices(), which
assumed one quad per non-space character. Shaped text does not follow
that rule (clusters, ligatures, marks, zero-sized glyphs and fallback
fonts change the glyph count), so the color array could be shorter than
the geometry. The draw then read past the end of the array for the last,
visually rightmost glyphs: they disappeared or showed up as stray glyphs
in mixed Latin/Hebrew/Arabic strings.

- Size fill and outline colors from the generated geometry and rebuild
  them whenever the vertex counts change. Remove getTotalVertices().
- Never read past the color array in draw(), and draw the outline pass
  with its own vertex count instead of the fill count.
- Share one shaped glyph walker (forEachShapedGlyphQuad) between both
  setFillColor() overloads and keep it in sync with
  ensureGeometryUpdate(): same layout parameters and the same fill
  visibility test. The per-character overload advanced its vertex index
  only when a color was present, which misaligned the remaining colors.

TextLayout snapped complex-script glyph positions to whole pixels, but
simple-script glyphs used the pen position as-is. After a Hebrew or
Arabic run the pen is fractional (HarfBuzz 26.6 advances), so the Latin
glyphs that followed were drawn at sub-pixel positions and blurred. Round
simple-script positions as well. Pure Latin text is unchanged.

Caret mapping:
- Text::findCharacterPos() and findCharacterFromPos() now use the text's
  own base direction instead of TextDirection::Unspecified, so caret
  positions and hit testing agree with rendering.
- In a right-to-left paragraph, place the end-of-text caret at the left
  end of the last line instead of after the rightmost glyph.

Add TextLayout::getFirstStrongDirection(), which returns the direction of
the first strong bidi character (UAX #9 P2/P3), for upcoming
right-to-left layout support.

Update the textedit Arabic and Hebrew reference images: only punctuation
that follows RTL runs moves, now aligned to whole pixels.
2026-10-10 22:03:24 -03:00
Martín Lucas Golini 1e0ed08d25 Fix accessibility hierarchy routing and table column invalidation
- Invalidate virtual table children when the visible column set changes.
- Route accessibility events through plain nodes to the nearest exposed widget.
- Extend regression tests for column visibility, stable cell identities,
  and semantic-parent event routing.
2026-10-10 21:47:52 -03:00
Martín Lucas Golini cae7595773 Fix accessibility hierarchy invalidation and tree expansion events
- Refresh virtual children when column visibility or main column changes
- Notify semantic parents when widget roles change tree exposure
- Report expansion state changes for queried tree rows
- Use scalar native queries without building full node metadata
- Add Linux CI coverage for deferred policy changes
- Add hierarchy, expansion-event and UIA scalar-query regressions
- Fix multiline control-statement braces and update architecture docs
2026-10-10 21:21:36 -03:00
Martín Lucas Golini c27425887f Fix accessibility dispatch safety, selection reporting and tree updates
- Defer policy changes during native dispatch and guard re-entrant updates.
- Correct container hit testing and semantic subtree identities and indices.
- Avoid duplicate indexed-reparent events and skip no-op sibling moves.
- Keep child insertion linear and avoid registering unseen nodes unnecessarily.
- Add lightweight role/state queries and reduce node-info overhead.
- Implement AT-SPI selection queries, actions and event-maintained snapshots.
- Release AT-SPI session-bus resources and unify event-loop wakeups.
- Fix Windows harness executable discovery and expand regression coverage.
- Document lifecycle safeguards and selection snapshot requirements.
2026-10-10 20:52:02 -03:00
Martín Lucas Golini d4b751bf83 Fixed six findings, with regression coverage and documentation updates:
- Windows selection teardown crash and cross-window text-range identity.
- Manager invalidation during setId() callbacks.
- Unused UIA/macOS text-edit allocations.
- Hidden-subtree event leaks, preserving label relations.
- Disabled virtual-row states and actions.
2026-10-10 14:48:37 -03:00
Martín Lucas Golini af9449aaa0 Fix macOS build? 2026-10-10 13:59:52 -03:00
Martín Lucas Golini 67660d4c13 Add accessible text, relations and live regions; keep dormant a11y free
Text:
- Ranged text access in code points (length, range, line bounds) that
  never copies more than requested, plus a text revision (document UUID
  and modification) so UIA and macOS cache their UTF-16 copies.
- Report document edits as exact change records, up to four per widget
  and frame, then collapse to one whole-text change. Resets, loads and
  document swaps report a whole-text change.
- The removed text is available only while an edit is being notified
  (TextDocument::getNotifiedRemovedText()); DocumentContentChange stays
  { range, text }, so queued records (LSP) copy nothing extra.
- Suppressed text changes are keyed by node ref, so a document shared
  with another window still reports its edits.
- UITextView reports NameChanged; UITextInput overrides onTextChanged()
  to report ValueChanged.

Relations, live regions and shortcuts:
- aria-labelledby, aria-describedby and aria-live (API and CSS). Ids a
  client has read are remembered; renaming, adding or removing their
  widgets notifies the dependents. setId() copies the old id only when
  it is remembered.
- Live regions and UISceneNode::announceForAccessibility(). A newer
  change from the same widget replaces its pending announcement, and
  hidden sources are dropped.
- Menu item shortcuts (std::string text and key) exposed as AT-SPI key
  bindings, the UIA accelerator key and macOS command characters.
- ScrollTo for anything inside a scroll view
  (UIScrollView::scrollIntoView()). Icon-only buttons are named from
  their tooltip.

Dormant path (no client attached):
- Widget notifications are inline: one relaxed atomic load of a
  process-wide count of active root scenes, no call.
- Scene destruction and scene or host changes never create a manager.
  Without a client, notify() queues nothing and widget deletion does
  not register parents to announce it. While only the root has an
  identity, deletion skips the ancestor walk unless a remembered
  relation target may be affected.
- When the last client disconnects, model-view sources release their
  queried rows. Persistent handles count their registrations, so
  handles held elsewhere survive (PersistentModelIndex::release()).
- Spin boxes no longer hide their input explicitly, and
  AccessibilityProperties shrinks from 144 to 136 bytes.

Backends:
- AT-SPI: object:announcement, word and line granularity, ranged
  reads, SetTextContents reported as its minimal diff. Watch
  disconnects per client (NameOwnerChanged arg0 plus a non-blocking
  NameHasOwner check) instead of for every bus name. Without a scene
  thread pool, initialize on a detached thread that shares ownership,
  so teardown never waits on D-Bus timeouts.
- UIA: notification events (resolved at runtime, Windows 10 1709+),
  text ranges served from the revision cache, and a per-frame provider
  drain that skips the lock when nothing is queued.
- macOS: announcements, a UTF-16 text cache per revision, and command
  key attributes.
- EEPP_ACCESSIBILITY_TRACE=1 logs client activity transitions.

Fixes:
- UICodeEditor::isType() no longer dispatches to a subclass's
  getType(), so a UITextEdit is a code editor again.
- ecode: dropped files open only in document editors, not in other
  code editors such as a commit message box.

Tools, tests and docs:
- Widget inspector: role names, shortcut, relation and live rows, and
  an accessibility audit (unnamed controls, broken relations).
- Accessibility example: live status, an icon-only button, and edit and
  reset actions that test_atspi.py checks end to end.
- Regression tests for text records, relations, live regions,
  disconnect and reconnect, scene lifecycle and id changes.
- Add the AccessibilityDormant benchmark (C++ new/new[] counted on the
  measuring thread) and benchmark_accessibility_dormant.py, which fails
  on missing measurements and compares against other builds with
  --compare LABEL=PATH.
- Document the dormant-path rules, what survives a disconnection, and
  the remaining platform limitations.
2026-10-10 02:01:52 -03:00
Martín Lucas Golini 1dd0870187 Harden accessibility review fixes and make macOS de-dup linear
macOS:
- Check each notification against a hash set of (event, element,
  related element) instead of scanning the whole pending queue. The
  ordered queue still drives delivery, so a burst of distinct events
  (e.g. 10,000 label changes) stays linear. Created/Destroyed are never
  de-duplicated.
- Track the pending focus change by its index instead of scanning for it.

Core:
- SceneManager::update: also bound the loop by the live scene count, so
  a scene removed during the pass can't cause an out-of-range read.
- Accessibility setters (role, label, description, hidden) return early
  on unchanged values. Re-applying CSS no longer allocates the
  properties block or notifies clients.

API cleanup:
- Remove AccessibilityRelation, AccessibilityRelationInfo and
  AccessibilityNodeInfo::relations. Nothing populated them. Remove the
  inspector row and the macOS linked-elements attribute that read them.
  AT-SPI GetRelationSet still answers with an empty set.
- Drop unused includes in uiroot.cpp and accessibility.hpp.

Docs:
- Architecture guide: UIA and macOS queue events until update(); AT-SPI
  emits right away except for per-frame text diffs. Describe each
  backend's per-frame batching, including the macOS de-dup.

Tests:
- Add UnchangedAccessibilityPropertiesStaySilent.
2026-10-09 10:47:43 -03:00
Martín Lucas Golini 4baa4ae4b1 Split accessibility backends, fix CI regressions and document architecture
CI fixes for the previous commit:
- Windows: announce one BoundsChanged on the window root when the scene
  resizes, so UIA raises LayoutInvalidated again. Widgets still do not
  report their own bounds changes.
- macOS: collapse identical pending notifications per element within one
  update, so one text selection change posts a single
  AXSelectedTextChanged. Created/Destroyed keep every occurrence, in order.
- MinGW: link the UIA test harness with -municode and uuid, which fixes
  the nightly MinGW build.

Backends:
- Split the AT-SPI backend into a private header plus connection, events,
  tree/marshalling and method files. Break the 600-line D-Bus dispatcher
  into one handler per interface.
- Split the UIA backend into a private header plus core, element provider
  and text range files.
- Share hasState/hasAction in accessibilitybackend.hpp instead of three
  per-backend copies.

CI and docs:
- Run test_atspi.py --multi-window on Linux: closing a secondary window
  while an AT-SPI client stays connected.
- Add docs/articles/uiaccessibilityarchitecture.md (layer map, files,
  invariants, per-backend layout, common tasks, test matrix) and link it
  from the articles index and the accessibility guide.
- Add a unit test for the single layout notification on scene resize.
2026-10-09 01:02:11 -03:00
@greweb 14b67cfcca Use bezier-easing 3.2 closed-form solver in cubicBezierInterpolation (#189)
Replace the sample table + Newton-Raphson + bisection search, which was
rebuilt on every call, with the closed-form solver of bezier-easing 3.2:
exact, no backward jump on steep curves such as (1, 0, 0, 1), and no
table to build per call.

t outside [0, 1] now saturates to 0 / 1 instead of going through the
old search, which returned arbitrary values there.
2026-10-09 00:58:56 -03:00
Martín Lucas Golini d27eae5927 Harden accessibility lifecycle, events and native backends
Teardown and identity:
- Detach native backends before scene children are destroyed and clear
  mRoot afterwards, fixing a use-after-free when an AT-SPI client is
  connected while a window closes.
- Invalidate a deleted widget's subtree once, top-down, before OnClose
  handlers run (NODE_FLAG_DESTROYING). Descendants never walk into
  destroyed parents, and deleted identities cannot be re-registered.
- Closing scenes expose no accessibility manager through either accessor.
- Deleting widgets no client has seen allocates no identity and emits no
  events.
- Ignore events from widgets not yet attached to a scene.

Events:
- Keep the order of state and structural events; coalesce only adjacent
  query-again hints.
- Stop emitting per-widget BoundsChanged; bounds are queried on demand.
- Report the Focused state and keyboard focus only on the projected focus
  owner, through a shared helper used by both paths.

Model views:
- Lazy child count and child queries, cached sibling indexes, selection
  and hit testing without enumerating rows.
- Row identities follow inserted and removed rows; removed rows are
  pruned from native wrapper caches.
- Expose the active cell editor as the child of the row or cell it edits.

AT-SPI:
- Correct state bits (EXPANDABLE/EXPANDED, SENSITIVE, CHECKABLE,
  SELECTABLE, READ_ONLY, SINGLE/MULTI_LINE, SELECTABLE_TEXT) and the
  password-text and panel roles.
- Emit text-changed insert/delete, caret-moved and selection-changed
  events, diffed once per frame. Support line granularity,
  SetCaretOffset and selection editing.
- Track clients by bus name so the active flag clears on disconnect.
- Fix the I/O thread busy-spin and stranded dispatch backlog, flush
  queued signals, and type-check Properties.Set values.

UIA:
- Raise focus only for the focused element.
- Defer UiaDisconnectProvider out of widget destruction.
- Keep providers alive for in-flight cross-thread requests.
- Reject unknown interfaces without a UI-thread round trip.
- Require window-specific client activity.

macOS:
- Avoid repeated full node info builds.
- Use sibling indexes and lazy child access.
- Fix label/value deduplication for list items.

Tests and docs:
- Add regression tests for focus ownership, teardown, event ordering,
  lazy model identities, nested scenes and cell editors.
- Extend the AT-SPI validation scripts and document the current
  performance characteristics and limitations.
2026-10-09 00:06:36 -03:00
Martín Lucas Golini 51b1059996 Fix accessibility ownership and native backend lifecycle
- Prevent dense-map iterator invalidation during widget deletion.
- Invalidate widget and model references when scene ownership changes.
- Expose nested-scene controls through the host accessibility manager.
- Preserve identities when reparenting within the same host.
- Synchronize AT-SPI state access with asynchronous initialization.
- Wake the shared SDL event loop without retaining window-owned Input pointers.
- Add lifecycle regression tests and hidden multi-window AT-SPI validation.
- Ensure test-bus failures cannot skip child-process cleanup.
2026-10-08 21:20:14 -03:00
Martín Lucas Golini 5a4fb936f0 Merge branch 'develop' into feature/a11y 2026-10-08 10:04:08 -03:00
Martín Lucas Golini 9d8ec467cf Modernize UI Editor with isolated previews and UIApplication
- Reimplement previews using nested UISceneNodes with isolated styles
  and resources.
- Preserve live XML/CSS editing, unsaved buffer previews, external file
  watching, and project resource loading.
- Use UIApplication for initialization, font resolution, and offscreen
  rendering support.
- Enable Breeze by default, add a menu toggle, and replace
  --use-app-theme with --disable-app-theme.
- Automatically preserve declared project viewport dimensions, with
  an optional override to use the preview split size.
- Support embedded HTML documents inside WebView XML elements.
- Fix fading window shadows and shutdown with visible modal dialogs.
- Update documentation and add regression coverage.
2026-10-07 14:02:56 -03:00
Martín Lucas Golini 66d2c9d4d2 eproc: improve startup memory collection and tab navigation
Publish the base process snapshot without waiting for PSS collection.
Leave Family Memory blank until startup accounting completes.

- Derive PSS policy from saved column visibility before startup.
- Collect Linux startup PSS with four temporary workers and seed the cache.
- Apply completed samples only to matching process identities without
  advancing performance history or aging ended processes.
- Preserve live cache entries while memory columns are hidden and
  invalidate entries on PID reuse.
- Share table-state parsing and validation; remove unused migrations.
- Add next-tab and previous-tab commands with Mod+Tab and Mod+Shift+Tab.
- Remember and restore each tab's last focused widget.
- Add coverage for startup collection, cache lifetime, saved visibility,
  and asynchronous family-memory updates.
2026-10-07 02:27:25 -03:00