Package limn.testing

Class HeadlessBackend

java.lang.Object
limn.testing.HeadlessBackend
All Implemented Interfaces:
AutoCloseable, Backend, BackendPeer

public final class HeadlessBackend extends Object implements BackendPeer
A backend that mints HeadlessWindows and remembers them, so that a dialog, a menu or a popup which opens as a window of its own opens somewhere a test can read. Install it with a HeadlessUi's runtime: new HeadlessBackend(ui.runtime()).

Modality is the two bits the toolkit asks a window about and nothing more: the modal's own bit and its owner's blocked bit, set and cleared exactly as a platform would.

  • Constructor Details

    • HeadlessBackend

      public HeadlessBackend(UiRuntime runtime)
      Parameters:
      runtime - the runtime the test installed, which is what uiRuntime() answers
  • Method Details

    • setCompositorShadowsPopups

      public void setCompositorShadowsPopups(boolean casts)
      Says whether this backend's system casts a shadow around an undecorated window, which it does by default. Told it does not, the toolkit makes such a window larger than its panel and draws the shadow in the margin, as on a desktop whose compositor casts none: what a test of a frameless dialog or popup on such a desktop sets first.
      Parameters:
      casts - whether the compositor casts the shadow
    • compositorShadowsPopups

      public boolean compositorShadowsPopups()
      Description copied from interface: Backend
      Whether the system's compositor casts a shadow around an undecorated window of this backend's (a menu, the list of a combo box, a dialog with no frame). Where it does the toolkit draws none of its own, or there would be two; where it does not, the toolkit makes such a window larger than its panel and draws the shadow in the margin.
      Specified by:
      compositorShadowsPopups in interface Backend
      Returns:
      true (the default) where the compositor casts it, and for a backend with no desktop under it, which then draws nothing extra
    • open

      public HeadlessWindow open(String title, int width, int height)
      Opens the application's own window, the one a demo scene binds to.
      Parameters:
      title - what the window is called, which is the tree's root name
      width - logical width
      height - logical height
      Returns:
      the window
    • windows

      public List<HeadlessWindow> windows()
      Returns:
      every window this backend created that has not closed, in the order it created them; a live view, whose iteration walks the windows there were when it began. A window leaves it as it closes, so that a test is not what keeps a closed window, its scene and what that scene held alive (a native popup's page looked leaked); a test that needs a window after it closed keeps its own reference, which still answers HeadlessWindow.isClosed()
    • uiRuntime

      public UiRuntime uiRuntime()
      Specified by:
      uiRuntime in interface Backend
      Returns:
      the concurrency runtime owned by this backend
    • createWindow

      public WindowPeer createWindow(WindowConfig config)
      Description copied from interface: BackendPeer
      Creates (but does not necessarily show) a native window, as its peer. UI thread only.
      Specified by:
      createWindow in interface Backend
      Specified by:
      createWindow in interface BackendPeer
    • ended

      public @Nullable LoopEnd ended()
      Returns:
      why the application ended: LoopEnd.QUIT once a requestQuit() was agreed to and every window closed, and null until then. What runEventLoop() would have returned, for a backend that has no loop.
    • runEventLoop

      public LoopEnd runEventLoop()
      Description copied from interface: Backend
      Runs the event/render loop on the calling (UI) thread. Returns when the last window closes (under LoopLifetime.UNTIL_LAST_WINDOW), when a Backend.requestQuit() was agreed to and every window has closed, or when Backend.stop() is invoked.
      Specified by:
      runEventLoop in interface Backend
      Returns:
      why it returned
    • setLoopLifetime

      public void setLoopLifetime(LoopLifetime newLifetime)
      Description copied from interface: Backend
      Sets how long Backend.runEventLoop() runs: until the last window closes (the default) or until the application ends it, which lets an application live with no window open. UI thread only.
      Specified by:
      setLoopLifetime in interface Backend
      Parameters:
      newLifetime - the lifetime; never null
    • loopLifetime

      public LoopLifetime loopLifetime()
      Specified by:
      loopLifetime in interface Backend
      Returns:
      how long Backend.runEventLoop() runs; LoopLifetime.UNTIL_LAST_WINDOW unless set
    • requestQuit

      public void requestQuit()
      Asks the quit handler and then each window, front to back, as a desktop backend does.
      Specified by:
      requestQuit in interface Backend
    • setQuitHandler

      public void setQuitHandler(@Nullable QuitHandler handler)
      Description copied from interface: Backend
      Sets the handler Backend.requestQuit() asks before any window, for what belongs to no window. null clears. UI thread only.
      Specified by:
      setQuitHandler in interface Backend
      Parameters:
      handler - the handler, or null for none
    • setSystemMenuBar

      public void setSystemMenuBar(@Nullable SystemMenuBar bar)
      Gives this backend a menu bar outside its windows, which it has none of, for a test of what a MenuBar does where the system keeps the bar: it is asked for the bar as a real backend is on such a system.
      Parameters:
      bar - what answers for the system's bar, or null for none again
    • systemMenuBar

      public @Nullable SystemMenuBar systemMenuBar()
      Description copied from interface: BackendPeer
      The menu bar the system keeps outside the windows, where it keeps one and the application may have it.

      The default is the answer of every system but one: null, and a menu bar is drawn in its window.

      Specified by:
      systemMenuBar in interface BackendPeer
    • pushModal

      public void pushModal(NativeWindow modal, @Nullable NativeWindow parent)
      Description copied from interface: BackendPeer
      Registers modal as an active modal window and pushes it on the modal stack. Only the topmost modal receives input; every window it locks ignores input until it closes.

      Modality scope: a non-null parent makes it window-modal, so it locks only parent (and parent's owned popups), leaving unrelated windows interactive. A null parent makes it toolkit-modal, so it locks every other window. Modals stack: with several open, only the top one is usable and the non-modal windows are released only after the whole modal stack closes. UI thread only.

      Specified by:
      pushModal in interface BackendPeer
    • popModal

      public void popModal(NativeWindow modal)
      Description copied from interface: BackendPeer
      Removes modal from the modal stack, releasing what it locked. UI thread only.
      Specified by:
      popModal in interface BackendPeer
    • pushSceneModal

      public BackendPeer.SceneModalHandle pushSceneModal(NativeWindow owner, boolean toolkitScope)
      Description copied from interface: BackendPeer
      Registers an in-scene (overlay) modal hosted by owner. Unlike BackendPeer.pushModal(limn.backend.NativeWindow, limn.backend.NativeWindow), there is no separate modal window: the overlay blocks owner's own content, so owner stays interactive, while this call blocks the same sibling windows a native modal would. toolkitScope true locks every other window; false locks only owner's owned popups. Release the returned handle when the overlay closes. UI thread only.
      Specified by:
      pushSceneModal in interface BackendPeer
    • signalModalBlocked

      public void signalModalBlocked()
      Description copied from interface: BackendPeer
      Gives the modal-blocked feedback (the alert sound plus a re-raise of the top modal) for an interaction the active modal ignores. The backend already does this for clicks on blocked native windows; call it for an in-scene modal's scrim so internal and native modals feel identical. UI thread only.
      Specified by:
      signalModalBlocked in interface BackendPeer
    • stop

      public void stop()
      Description copied from interface: Backend
      Asks the loop to exit. Safe to call from any thread.
      Specified by:
      stop in interface Backend
    • close

      public void close()
      Description copied from interface: Backend
      Destroys all windows and releases native resources. UI thread only.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Backend