Package limn.backend

Interface Backend

All Superinterfaces:
AutoCloseable
All Known Subinterfaces:
BackendPeer
All Known Implementing Classes:
HeadlessBackend, LwjglBackend

public sealed interface Backend extends AutoCloseable permits BackendPeer
Service-provider interface for a native platform backend (windows, input, GPU rendering, clipboard). The only shipped implementation is limn-backend-lwjgl (GLFW + OpenGL 3.3 core); the abstraction exists so ANGLE/Vulkan (or SDL) backends can replace it without touching any module above.

Lifecycle: construct on the process main thread (which becomes the UI thread), create windows, then runEventLoop() until the last window closes, an agreed requestQuit() or stop(), as the lifetime says. The loop is event-driven: it sleeps in the native event wait and is woken by input, window damage or Ui.post(java.lang.Runnable).

This is the application's view of a backend, which the 1.0 contract freezes. What the toolkit asks of it below that (the modal stack) is BackendPeer's, in the incubating layer; every backend is one, which is why this interface is sealed.

  • Method Details

    • uiRuntime

      UiRuntime uiRuntime()
      Returns:
      the concurrency runtime owned by this backend
    • setApplicationName

      default void setApplicationName(String name)
      Names this application where the desktop's accessibility tree lists applications by name.

      On Linux, AT-SPI2 shows one application object per process with every window beneath it, and a screen reader says that name when the user moves into the application; left unset, a backend uses the title of the first window it created, which is right for a one-window program and wrong for one whose first window is a splash or a login. Windows names an application from the process itself and reads nothing here. Call it before the first window for the name to be there from the start; a later call renames the application for the next client that asks.

      On macOS the name is also what the toolkit writes in the items of the application's menu (About, Hide, Quit). It is not what the system writes in bold at the head of its menu bar: the system reads that once, as the windowing library starts, from the application's package, and for an application that is not packaged from the name the backend was made with. A backend that takes a name at its construction says so there.

      Parameters:
      name - what the desktop should call this application; never null
      Throws:
      NullPointerException - if name is null
    • createWindow

      NativeWindow createWindow(WindowConfig config)
      Creates (but does not necessarily show) a native window. UI thread only.
    • runEventLoop

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

      void setLoopLifetime(LoopLifetime lifetime)
      Sets how long 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.
      Parameters:
      lifetime - the lifetime; never null
      Throws:
      NullPointerException - if lifetime is null
    • loopLifetime

      LoopLifetime loopLifetime()
      Returns:
      how long runEventLoop() runs; LoopLifetime.UNTIL_LAST_WINDOW unless set
    • requestQuit

      void requestQuit()
      Asks to end the application. The quit handler is asked first, then every open top-level window's handler, front to back (the window used last first), one at a time; a window with no handler agrees. A refusal anywhere ends the request and every window stays open. When all have agreed, every window closes, owned ones included, and runEventLoop() returns LoopEnd.QUIT.

      A request made while one is being answered joins it. On macOS the system's Quit command for the application (Cmd-Q, the application menu, the Dock) makes this request. UI thread only.

    • setQuitHandler

      void setQuitHandler(@Nullable QuitHandler handler)
      Sets the handler requestQuit() asks before any window, for what belongs to no window. null clears. UI thread only.
      Parameters:
      handler - the handler, or null for none
    • renderStats

      default RenderStats renderStats()
      Returns:
      aggregate GPU resource usage across all windows (texture count + estimated bytes), for diagnostics. Default: RenderStats.EMPTY. UI thread only.
    • render3DStats

      default Render3DStats render3DStats()
      Returns:
      aggregate 3D-subsystem GPU usage across all windows (meshes, textures, render targets, bytes, and last-frame draw calls/triangles), for diagnostics. Default: Render3DStats.EMPTY. UI thread only.
    • graphicsInfo

      default GraphicsInfo graphicsInfo()
      Returns:
      which graphics context this backend obtained and which optional capabilities it has: the report a bug about a machine that will not start, or that renders slowly, has to carry. The strings live on the context, so this is only answerable once createWindow(limn.backend.WindowConfig) has succeeded at least once; before that, and on a machine where it never does, the result carries the windowing platform and a GraphicsInfo.failure() instead. Default: GraphicsInfo.NONE. UI thread only.
    • compositorShadowsPopups

      default boolean compositorShadowsPopups()
      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.
      Returns:
      true (the default) where the compositor casts it, and for a backend with no desktop under it, which then draws nothing extra
    • displays

      default List<Display> displays()
      Returns:
      every connected Display, in the platform's order (index 0 is usually the primary). Empty when headless/embedded. UI thread only.
    • primaryDisplay

      default @Nullable Display primaryDisplay()
      Returns:
      the primary Display, or null when headless. Default: the display that reports Display.isPrimary(), else the first of displays(). UI thread only.
    • stop

      void stop()
      Asks the loop to exit. Safe to call from any thread.
    • close

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