Package limn.testing

Class HeadlessWindow.CapturingBridge

java.lang.Object
limn.testing.HeadlessWindow.CapturingBridge
All Implemented Interfaces:
AccessibilityBridge
Enclosing class:
HeadlessWindow

public static final class HeadlessWindow.CapturingBridge extends Object implements AccessibilityBridge
A bridge that listens, keeps the newest tree and every event it was handed, and does nothing else.
  • Field Details

    • events

      public final List<AccessibleEvent> events
      Every event handed over, in order, across every publish.
    • publishes

      public int publishes
      How many trees were handed over.
    • host

      public volatile @Nullable AccessibilityBridge.Host host
      The scene-side half this bridge holds, through which a test performs a verb.
  • Constructor Details

    • CapturingBridge

      public CapturingBridge()
  • Method Details

    • attach

      public void attach(AccessibilityBridge.Host newHost)
      Description copied from interface: AccessibilityBridge
      Hands the bridge the scene-side half, replacing any host it already held.

      A scene can be bound over a live window and the outgoing one never learns it was, so the bridge is the only object that knows there was a tree to close. That is why the window pair is raised here rather than by the caller: an implementation empties its element registry and raises a window-closed for the host it is replacing, if there was one, then raises a window-opened for the incoming one. On a first attach only the second is raised.

      It builds and pushes no tree, on any platform. At this moment the scene has never laid out, so every box in it would be a zero-size rectangle at the origin.

      Specified by:
      attach in interface AccessibilityBridge
      Parameters:
      newHost - what the scene answers with
    • detach

      public void detach()
      Description copied from interface: AccessibilityBridge
      The window is going away: raises a window-closed, then empties whatever it was holding.
      Specified by:
      detach in interface AccessibilityBridge
    • isListening

      public boolean isListening()
      Description copied from interface: AccessibilityBridge
      Whether any assistive technology is listening.

      Asked once per frame on the publish path, and on the two rare paths that have to know whether spending a frame is worth it at all. It must therefore be cheap: one platform call, or a flag the bridge already keeps.

      It is never "did a client ask us something recently." A gate of that shape inverts the contract on all three platforms, because a platform event is a push a client waits on: one of the three screen readers registers for a focus change and then calls nothing at all until it fires. Tab twice quickly with such a gate and the toolkit goes silent — the client only asks after an event, and the event only fires after the client asks.

      Specified by:
      isListening in interface AccessibilityBridge
      Returns:
      whether anything is reading this window
    • publish

      public void publish(AccessibleTree published, boolean reentrant)
      Description copied from interface: AccessibilityBridge
      Hands over a fresh whole-window snapshot. User-interface thread.

      reentrant is true when the scene built this tree from inside the platform's own callback, with the platform on the stack holding elements this bridge vended. A reentrant publish stores the tree and answers from it, and does nothing else: it must not destroy or release anything in its element registry, must not re-push the top of its tree, and must not drain its event queue — each of those would act on the objects the caller is standing on. Everything it defers is owed by the next ordinary frame, which the scene has already asked for.

      Specified by:
      publish in interface AccessibilityBridge
      Parameters:
      published - the window as it now stands
      reentrant - whether the platform is on the stack
    • emit

      public void emit(AccessibleEvent event)
      Description copied from interface: AccessibilityBridge
      One coalesced event, naming a node in the tree just published. User-interface thread.

      Enqueue it; do not raise it. A difference between two frames of a scrolling list or a dragged slider can be hundreds of nodes wide, and every raise is a cross-process call: a bridge that raised them here would spend the frame budget inside the platform, which is precisely the stall that makes a window unreadable to the user it is being read to.

      Specified by:
      emit in interface AccessibilityBridge
      Parameters:
      event - what happened
    • tree

      public AccessibleTree tree()
      Returns:
      the newest tree the scene published, or the empty one
    • eventsOf

      public List<AccessibleEvent> eventsOf(AccessibleEvent.Type type)
      Parameters:
      type - the kind to look for
      Returns:
      every event of that kind handed over so far, in order