Package limn.testing

Class StubWindow

java.lang.Object
limn.testing.StubWindow
All Implemented Interfaces:
AutoCloseable, NativeWindow, WindowPeer

public class StubWindow extends Object implements WindowPeer
A NativeWindow that does nothing except answer questions: enough of a window for the components that ask one whether they may open a window of their own, without a backend, a display server or GL.

backend() throws rather than returning null. A component that reached it has decided to create a real window, which is the one thing no headless test can do, and an AssertionError naming that says so where a NullPointerException three frames down would not.

  • Field Details

    • framesRequested

      public int framesRequested
      Frames the scene has asked for: what an idle scene must stop adding to.
    • screenX

      public int screenX
      Where this window claims to be, and how many native units one logical point is.

      Both answered a fixed zero and a fixed one until the accessible tree needed them: a tree publishes scene-local boxes plus the window's own origin and scale, and no headless test could assert a real screen rectangle against two constants. Settable, so one can.

    • screenY

      public int screenY
    • logicalToScreenFactor

      public float logicalToScreenFactor
    • accessibility

      public AccessibilityBridge accessibility
      The bridge this window hands its scene. AccessibilityBridge.NONE unless a test sets one, which is the answer that keeps every other component test free of the accessible walk: with no bridge the scene never runs it.
    • lastSize

      public int[] lastSize
      The last setSize(int, int) a scene or a test asked for, null before any.
    • sizeLimits

      public SizeLimits sizeLimits
      What setSizeLimits(int, int, int, int) last set, read back by sizeLimits().
    • fullscreen

      public boolean fullscreen
      Whether this window claims to be fullscreen: set by enterFullscreen(int, int, int), cleared by exitFullscreen(), and settable directly. It is the other question a popup asks before it opens a window of its own, since a fullscreen owner is given none, so a test of that fallback needs a window that can answer yes.

      The two calls also tell a bound scene of the change, as a backend does, through WindowInput.windowFullscreenChanged(boolean); a test ends the batch to have it acted on, with SceneDriver.drive(scene).inputBatchEnded(). Setting the field tells nothing, which is how a test starts with a window that was fullscreen before anything opened over it.

    • modalBlocked

      public boolean modalBlocked
      Whether this window claims a native modal is open over it, as a dialog's owner does.
  • Constructor Details

    • StubWindow

      public StubWindow()
      A window on a platform that places windows where it is told, which is most of them.
    • StubWindow

      public StubWindow(boolean canPosition)
      Parameters:
      canPosition - what supportsAbsolutePositioning() answers; false reproduces Wayland, where nothing outside a window can be lined up with anything inside it
  • Method Details

    • supportsAbsolutePositioning

      public boolean supportsAbsolutePositioning()
      Description copied from interface: WindowPeer
      Whether NativeWindow.screenX(), NativeWindow.screenY() and NativeWindow.setScreenPosition(int, int) actually work on this platform. When false the getters report a placeholder and the setter is ignored: a window is placed by the desktop and never learns where it went.

      Ask this before drawing anything outside a window that has to line up with something inside it: a dropdown's list, a menu cascade, a tooltip. Those are not windows in their own right; they are the owner's content, escaping the frame because most desktops offer no other way to overflow it. Where the answer is false there is no such way, and the content has to be drawn in the scene instead, clipped to the owner.

      A window that is genuinely a window (a document, a dialog, a palette) needs no such check. It has no position to agree with, so letting the desktop place it is the right outcome rather than a fallback.

      No default. It answered true until 2026-09-22, which is the unsafe answer: a backend that said nothing claimed a power Wayland does not have, and a popup that trusted it opened wherever the compositor put it. Absolute window position is absent from that protocol by design, so a backend has to say.

      Specified by:
      supportsAbsolutePositioning in interface WindowPeer
    • setCloseRequestHandler

      public void setCloseRequestHandler(@Nullable CloseRequestHandler handler)
      Description copied from interface: NativeWindow
      Sets the handler asked whether this window may close: when the user closes it (the OS close button, Alt-F4, Cmd-W), and when the application is ending (Backend.requestQuit()). It answers through the CloseRequest it is handed, at once or later, so an "unsaved changes" dialog can decide. With no handler, the window agrees. A program's NativeWindow.requestClose() bypasses it. null clears. UI thread only.

      A window created with an owner (WindowConfig.popup(NativeWindow, int, int) or WindowConfig.ownedBy(limn.backend.NativeWindow): a native dialog, a menu) is not asked when the application ends: its owner speaks for it, and it closes with it.

      No default: a backend that ignored it lost an application's "unsaved changes" veto silently. A backend with no close gesture of its own (headless, embedded) keeps the handler, asks it only when the application ends, and says so in its implementation.

      Specified by:
      setCloseRequestHandler in interface NativeWindow
      Parameters:
      handler - the handler, or null for none
    • closeRequestHandler

      public @Nullable CloseRequestHandler closeRequestHandler()
      Specified by:
      closeRequestHandler in interface NativeWindow
      Returns:
      the close handler a scene or an application registered, for a test to ask
    • setClosePolicy

      public void setClosePolicy(ClosePolicy policy)
      Description copied from interface: NativeWindow
      Sets what a user's close does once it is allowed: dispose the window (the default), hide it, or end the application. A program's NativeWindow.requestClose() disposes whatever this says. UI thread only.
      Specified by:
      setClosePolicy in interface NativeWindow
      Parameters:
      policy - the policy; never null
    • closePolicy

      public ClosePolicy closePolicy()
      Specified by:
      closePolicy in interface NativeWindow
      Returns:
      what a user's close does; ClosePolicy.DISPOSE unless set
    • fileDialogs

      public FileDialogs fileDialogs()
      No chooser here: every dialog answers empty, as if cancelled.
      Specified by:
      fileDialogs in interface NativeWindow
      Returns:
      the platform's file and folder choosers, owned by this window; FileDialogs.NONE for a window with none (headless, embedded). No default: a backend that answered NONE by omission made every "Open…" in an application silently do nothing. UI thread only.
    • launcher

      public Launcher launcher()
      Specified by:
      launcher in interface NativeWindow
      Returns:
      what hands an address or a file to the system this window is on; Launcher.NONE for a window with no desktop under it (headless, embedded). No default, for the reason NativeWindow.fileDialogs() has none: a link that silently opens nothing. UI thread only.
    • printer

      public Printer printer()
      Specified by:
      printer in interface NativeWindow
      Returns:
      what prints a PDF through the system's own print dialog, owned by this window; Printer.NONE for a window with no printing under it (headless, embedded). No default, for the reason NativeWindow.launcher() has none: a "Print…" that silently prints nothing. UI thread only.
    • setTextInput

      public void setTextInput(TextInput input)
      Description copied from interface: WindowPeer
      Says what text this window wants from the platform: none, typed characters with the input method off, or characters and the input method's composition. The scene asks for composition while a text-editing widget holds focus and for characters otherwise, so composition keys never leak into a control that is not text, and a list's type-ahead still hears letters. UI thread only.

      No default, nor for the two IME methods below: a backend that ignored them broke Chinese, Japanese and Korean input without a word. A backend with no input method (headless) implements them as no-ops, on purpose and in writing.

      Specified by:
      setTextInput in interface WindowPeer
      Parameters:
      input - what the window wants; never null
    • setPreeditCaretRect

      public void setPreeditCaretRect(float x, float y, float width, float height)
      Description copied from interface: WindowPeer
      Positions the IME candidate/composition window at the caret, so it follows the text being edited. x/y/width/height are in logical points relative to the window's content area (the scene feeds the focused widget's caretRect). UI thread only.
      Specified by:
      setPreeditCaretRect in interface WindowPeer
    • resetPreedit

      public void resetPreedit()
      Description copied from interface: WindowPeer
      Cancels any in-progress IME composition held by the platform for this window. The scene calls it when focus leaves a text-editing widget, so a composition started there can never commit into whatever is focused next. A no-op when nothing is being composed. UI thread only.
      Specified by:
      resetPreedit in interface WindowPeer
    • display

      public Display display()
      A single 400×300 display at the origin, so the whole window is inside its work area.
      Specified by:
      display in interface NativeWindow
      Returns:
      the Display this window currently sits on (the monitor containing the window's centre), or null when headless/embedded. Its Display.workArea() is what external popups clamp against to stay on screen. UI thread only.
    • backend

      public Backend backend()
      Specified by:
      backend in interface NativeWindow
      Returns:
      the backend that owns this window (popup creation, shutdown)
    • requestFrame

      public void requestFrame()
      Description copied from interface: NativeWindow
      Marks the window dirty so the loop renders a frame for it. UI thread only: from a background thread, hop with Ui.post(window::requestFrame).
      Specified by:
      requestFrame in interface NativeWindow
    • setFrameCallback

      public void setFrameCallback(FrameCallback callback)
      Description copied from interface: WindowPeer
      Registers the per-frame render callback.
      Specified by:
      setFrameCallback in interface WindowPeer
    • setInput

      public void setInput(WindowInput newInput)
      Description copied from interface: WindowPeer
      Registers the input sink (usually the scene). See WindowInput.
      Specified by:
      setInput in interface WindowPeer
    • title

      public String title()
      Specified by:
      title in interface NativeWindow
      Returns:
      the current title
    • setTitle

      public void setTitle(String title)
      Description copied from interface: NativeWindow
      Sets the native title bar text.
      Specified by:
      setTitle in interface NativeWindow
    • logicalWidth

      public float logicalWidth()
      Specified by:
      logicalWidth in interface NativeWindow
      Returns:
      width in logical points (framebuffer width ÷ content scale)
    • logicalHeight

      public float logicalHeight()
      Specified by:
      logicalHeight in interface NativeWindow
      Returns:
      height in logical points (framebuffer height ÷ content scale)
    • framebufferWidth

      public int framebufferWidth()
      Specified by:
      framebufferWidth in interface NativeWindow
      Returns:
      framebuffer width in physical pixels
    • framebufferHeight

      public int framebufferHeight()
      Specified by:
      framebufferHeight in interface NativeWindow
      Returns:
      framebuffer height in physical pixels
    • contentScale

      public float contentScale()
      Specified by:
      contentScale in interface NativeWindow
      Returns:
      the content scale in effect for this window: the monitor's, or the forced one. Fractional values (1.25, 1.5, 1.75) are first-class citizens, never assume integer
    • overrideContentScale

      public void overrideContentScale(float scale)
      Description copied from interface: NativeWindow
      Forces the rendering content scale, ignoring the monitor's. Screenshot scenes use it to validate 1.0/1.25/1.5/2.0 rendering on any monitor. Pass 0 to return to the monitor scale.
      Specified by:
      overrideContentScale in interface NativeWindow
    • setSize

      public void setSize(int width, int height)
      Description copied from interface: NativeWindow
      Resizes the window to the given size in logical points.
      Specified by:
      setSize in interface NativeWindow
    • setSizeLimits

      public void setSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight)
      Description copied from interface: NativeWindow
      Constrains user resizing to the given bounds in logical points; pass <= 0 for any bound to leave it unconstrained. Only affects interactive resizes; NativeWindow.setSize(int, int) is not clamped. A window made from a WindowConfig with WindowConfig.minSize(int, int) or WindowConfig.maxSize(int, int) starts with those. The default implementation ignores it (headless/embedding). UI thread only.
      Specified by:
      setSizeLimits in interface NativeWindow
    • sizeLimits

      public SizeLimits sizeLimits()
      Specified by:
      sizeLimits in interface NativeWindow
      Returns:
      the bounds the user may resize this window within, as its configuration or the last NativeWindow.setSizeLimits(int, int, int, int) set them; SizeLimits.NONE where the implementation keeps none (headless, embedding)
    • show

      public void show()
      Specified by:
      show in interface NativeWindow
    • hide

      public void hide()
      Specified by:
      hide in interface NativeWindow
    • focus

      public void focus()
      Description copied from interface: NativeWindow
      Brings this window to the front and gives it input focus. UI thread only.
      Specified by:
      focus in interface NativeWindow
    • isVisible

      public boolean isVisible()
      Specified by:
      isVisible in interface NativeWindow
      Returns:
      whether the window is currently visible on screen
    • setOpacity

      public void setOpacity(float value)
      Description copied from interface: NativeWindow
      Sets the whole-window opacity in [0..1] at the compositor level, the fade primitive behind Scene.fadeWindow(float, double, java.lang.Runnable). Affects the entire window uniformly, decorations included. A no-op where the platform's compositor does not support per-window opacity, and under Wayland, which gives a program none; the default implementation ignores it (headless/embedding). UI thread only.
      Specified by:
      setOpacity in interface NativeWindow
    • setCursor

      public void setCursor(@Nullable Cursor value)
      Description copied from interface: NativeWindow
      Sets the mouse cursor shown while the pointer is over this window. The scene calls this as the hovered widget changes; null or Cursor.DEFAULT restores the plain arrow. A shape the platform cannot provide falls back to the arrow. The default implementation ignores it (headless/embedding). UI thread only.
      Specified by:
      setCursor in interface NativeWindow
    • isClosed

      public boolean isClosed()
      Specified by:
      isClosed in interface NativeWindow
      Returns:
      whether this window has already been closed/destroyed
    • requestClose

      public void requestClose()
      Description copied from interface: NativeWindow
      Asks the window to close (processed by the event loop). Any-thread safe.
      Specified by:
      requestClose in interface NativeWindow
    • close

      public void close()
      Description copied from interface: NativeWindow
      Same as NativeWindow.requestClose(); actual destruction happens in the loop/backend.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface NativeWindow
    • enterFullscreen

      public void enterFullscreen(int width, int height, int refreshRate)
      Description copied from interface: NativeWindow
      Makes the window fullscreen on the monitor it occupies, in one of two ways, chosen by whether the call names a display mode.

      Naming no mode, width, height and refreshRate all ≤ 0 as NativeWindow.enterFullscreen() passes them, leaves the display in the mode it is in, which is the fullscreen a document, a dashboard or any application that is not a game wants:

      • macOS: native fullscreen, what the green button and Control-Command-F do. The window moves to a Space of its own with an animation of most of a second, the menu bar and the title bar slide in when the pointer reaches the top of the screen, and the person can leave it the way they leave any application's. This call returns before the animation ends, and the window reports its new size when AppKit resizes it.
      • Windows and X11: a borderless window covering the monitor at the mode it is in, on X11 through the window manager's fullscreen state where it has one.
      • Wayland: the compositor's fullscreen.

      Naming a mode, a size or a refresh rate or both, is the exclusive fullscreen a game asks for: the display is switched to the mode it lists nearest to the one named, which holds the application for a noticeable moment each way (more than half a second on a Mac), and is switched back by NativeWindow.exitFullscreen(). A dimension ≤ 0 beside a named one is the current one. The size is in screen coordinates, as a Resolution's is: pixels on Windows, X11 and Wayland, points on macOS. On macOS the window covers the menu bar and the Dock and has no Space of its own; the mode a Retina display is in is usually not one it can be switched to, so naming the current mode switches to another. Wayland lets no application change the display's mode, and there the window is fullscreen at the compositor's whatever is named.

      Losing the focus tells the two apart. A window at a named mode is minimized when another window takes the focus, on every platform, and a switched mode is switched back until the window is restored, which is what a game wants when the person switches away from it. A window at the mode the display is in is not: on Windows, X11 and Wayland it stays fullscreen behind the window that took the focus, as a browser's fullscreen does, and the person comes back to it as they left it; on macOS the person moves to another Space and back.

      A window already fullscreen one way and asked for the other leaves the first: a switched mode is switched back before native fullscreen begins, and native fullscreen is left, with its animation, before the mode is switched. The windowed position and size are remembered for NativeWindow.exitFullscreen(). UI thread only.

      Specified by:
      enterFullscreen in interface NativeWindow
      Parameters:
      width - width in screen coordinates, or ≤ 0 to name none
      height - height in screen coordinates, or ≤ 0 to name none
      refreshRate - refresh rate in Hz, or ≤ 0 to name none
    • exitFullscreen

      public void exitFullscreen()
      Description copied from interface: NativeWindow
      Leaves fullscreen of either kind, and does nothing for a window that is not fullscreen. A switched mode is switched back and the windowed position and size asked for before this returns, and given back as the window had them: where the window manager answers later, as on X11, a window it gives back maximized when it was not, or elsewhere or at another size, is asked once more when the answer comes. macOS native fullscreen is left with its animation, after this returns, and is left whether the application or the person entered it. UI thread only.
      Specified by:
      exitFullscreen in interface NativeWindow
    • isFullscreen

      public boolean isFullscreen()
      Description copied from interface: NativeWindow
      Whether the window is fullscreen, of either kind. On macOS that includes native fullscreen the person entered with the green button, Control-Command-F or the menu, and the answer is where the window is going rather than where its animation has got to: true from the moment NativeWindow.enterFullscreen() returns or the person starts the animation, false from the moment NativeWindow.exitFullscreen() returns or the person starts leaving. Elsewhere it is whether this window was made fullscreen and has not been told to leave.

      Each change of this answer is told to the window's input, through WindowInput.windowFullscreenChanged(boolean), including the changes the person makes on macOS. A window that can never be fullscreen never tells it.

      Specified by:
      isFullscreen in interface NativeWindow
      Returns:
      whether the window is, or is going to be, fullscreen
    • isModalBlocked

      public boolean isModalBlocked()
      Specified by:
      isModalBlocked in interface NativeWindow
      Returns:
      whether this window is currently locked by an active modal (its input is ignored); the scene dims it while true
    • isModal

      public boolean isModal()
      Specified by:
      isModal in interface WindowPeer
      Returns:
      whether this window is itself an active modal: one the backend registered through BackendPeer.pushModal(limn.backend.NativeWindow, limn.backend.NativeWindow), blocking the window it was opened over, or every other window when it was opened over none. The other end of NativeWindow.isModalBlocked(): that is the owner's bit and this is the dialog's, and it is this one an accessible tree publishes on the window's own node, because a client asks a window whether it blocks what it owns and never whether something else blocks it
    • registerChildPopup

      public void registerChildPopup(NativeWindow child, WindowPeer.PopupKind kind)
      Description copied from interface: WindowPeer
      Registers a child popup and says what it is; see WindowPeer.PopupKind, which is the whole reason this overload exists.
      Specified by:
      registerChildPopup in interface WindowPeer
    • unregisterChildPopup

      public void unregisterChildPopup(NativeWindow child)
      Description copied from interface: WindowPeer
      Unregisters a child popup that closed on its own.
      Specified by:
      unregisterChildPopup in interface WindowPeer
    • clipboard

      public Clipboard clipboard()
      A clipboard that holds nothing, and not null.

      Scene#clipboard() promises its callers a clipboard and keeps that promise by handing over the window's, so a window answering null makes the scene break a contract it states in its own javadoc. Nothing noticed until a text field's context menu was raised headlessly and asked what was on the clipboard to decide whether Paste is enabled.

      Specified by:
      clipboard in interface NativeWindow
      Returns:
      the system clipboard
    • screenX

      public int screenX()
      Specified by:
      screenX in interface NativeWindow
      Returns:
      window x in native screen coordinates
    • screenY

      public int screenY()
      Specified by:
      screenY in interface NativeWindow
      Returns:
      window y in native screen coordinates
    • setScreenPosition

      public void setScreenPosition(int x, int y)
      Description copied from interface: NativeWindow
      Moves the window (native screen coordinates; see NativeWindow.logicalToScreenFactor()).
      Specified by:
      setScreenPosition in interface NativeWindow
    • logicalToScreenFactor

      public float logicalToScreenFactor()
      Specified by:
      logicalToScreenFactor in interface NativeWindow
      Returns:
      multiplier from logical points to native screen coordinates (1.0 on macOS, the monitor scale on Windows/X11), for positioning popups relative to widget bounds
    • captureNextFrame

      public void captureNextFrame(Consumer<Image> sink)
      Description copied from interface: NativeWindow
      Captures the next rendered frame (post-flush, pre-swap) and hands the pixels to sink: a per-window screenshot without touching the frame callback, and without a file. Requests a frame, so it works on an idle window. sink runs on the UI thread inside that frame.

      The image is display-referred: it is what the composite produced, not scene-referred content awaiting a display transform. See GpuRenderer.captureFramebuffer(java.util.function.Consumer).

      Specified by:
      captureNextFrame in interface NativeWindow
    • setContentScaleListener

      public void setContentScaleListener(NativeWindow.ContentScaleListener listener)
      Description copied from interface: NativeWindow
      Registers a listener for runtime monitor/content-scale changes.
      Specified by:
      setContentScaleListener in interface NativeWindow
    • accessibility

      public AccessibilityBridge accessibility()
      Specified by:
      accessibility in interface NativeWindow
      Returns:
      the platform accessibility bridge for this window, or AccessibilityBridge.NONE when it has none.

      default on the merits rather than as a compatibility dodge: none is the correct behaviour for a window with no accessibility — a test double, an embedded surface, any future backend on its first day — and getting exactly zero cost by writing nothing is better than getting it by writing the same stub in each.