Class StubWindow
- All Implemented Interfaces:
AutoCloseable,NativeWindow,WindowPeer
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.
-
Nested Class Summary
Nested classes/interfaces inherited from interface limn.backend.NativeWindow
NativeWindow.ContentScaleListenerNested classes/interfaces inherited from interface limn.backend.spi.WindowPeer
WindowPeer.PopupKind -
Field Summary
FieldsModifier and TypeFieldDescriptionThe bridge this window hands its scene.intFrames the scene has asked for: what an idle scene must stop adding to.booleanWhether this window claims to be fullscreen: set byenterFullscreen(int, int, int), cleared byexitFullscreen(), and settable directly.int[]The lastsetSize(int, int)a scene or a test asked for,nullbefore any.floatbooleanWhether this window claims to be an active modal, as a dialog's own native window is.booleanWhether this window claims a native modal is open over it, as a dialog's owner does.intWhere this window claims to be, and how many native units one logical point is.intWhatsetSizeLimits(int, int, int, int)last set, read back bysizeLimits(). -
Constructor Summary
ConstructorsConstructorDescriptionA window on a platform that places windows where it is told, which is most of them.StubWindow(boolean canPosition) -
Method Summary
Modifier and TypeMethodDescriptionbackend()voidcaptureNextFrame(Consumer<Image> sink) Captures the next rendered frame (post-flush, pre-swap) and hands the pixels tosink: a per-window screenshot without touching the frame callback, and without a file.A clipboard that holds nothing, and notnull.voidclose()Same asNativeWindow.requestClose(); actual destruction happens in the loop/backend.@Nullable CloseRequestHandlerfloatdisplay()A single 400×300 display at the origin, so the whole window is inside its work area.voidenterFullscreen(int width, int height, int refreshRate) Makes the window fullscreen on the monitor it occupies, in one of two ways, chosen by whether the call names a display mode.voidLeaves fullscreen of either kind, and does nothing for a window that is not fullscreen.No chooser here: every dialog answers empty, as if cancelled.voidfocus()Brings this window to the front and gives it input focus.intintvoidhide()booleanisClosed()booleanWhether the window is fullscreen, of either kind.booleanisModal()booleanbooleanlauncher()floatfloatfloatvoidoverrideContentScale(float scale) Forces the rendering content scale, ignoring the monitor's.printer()voidregisterChildPopup(NativeWindow child, WindowPeer.PopupKind kind) Registers a child popup and says what it is; seeWindowPeer.PopupKind, which is the whole reason this overload exists.voidAsks the window to close (processed by the event loop).voidMarks the window dirty so the loop renders a frame for it.voidCancels any in-progress IME composition held by the platform for this window.intscreenX()intscreenY()voidsetClosePolicy(ClosePolicy policy) Sets what a user's close does once it is allowed: dispose the window (the default), hide it, or end the application.voidsetCloseRequestHandler(@Nullable CloseRequestHandler handler) 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()).voidRegisters a listener for runtime monitor/content-scale changes.voidSets the mouse cursor shown while the pointer is over this window.voidsetFrameCallback(FrameCallback callback) Registers the per-frame render callback.voidsetInput(WindowInput newInput) Registers the input sink (usually the scene).voidsetOpacity(float value) Sets the whole-window opacity in[0..1]at the compositor level, the fade primitive behindScene.fadeWindow(float, double, java.lang.Runnable).voidsetPreeditCaretRect(float x, float y, float width, float height) Positions the IME candidate/composition window at the caret, so it follows the text being edited.voidsetScreenPosition(int x, int y) Moves the window (native screen coordinates; seeNativeWindow.logicalToScreenFactor()).voidsetSize(int width, int height) Resizes the window to the given size in logical points.voidsetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) Constrains user resizing to the given bounds in logical points; pass<= 0for any bound to leave it unconstrained.voidsetTextInput(TextInput input) 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.voidSets the native title bar text.voidshow()booleanWhetherNativeWindow.screenX(),NativeWindow.screenY()andNativeWindow.setScreenPosition(int, int)actually work on this platform.title()voidunregisterChildPopup(NativeWindow child) Unregisters a child popup that closed on its own.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface limn.backend.NativeWindow
bounds, captureNextFrame, cursorX, cursorY, enterFullscreen, enterFullscreen, isMaximized, isMinimized, maximize, minimize, nativeHandle, observeState, pointerMode, restore, setAboveSystemChrome, setAccessibility, setCursorPosition, setIcon, setImageCursor, setMousePassthrough, setPointerMode, state, toFrontMethods inherited from interface limn.backend.spi.WindowPeer
dragAnswerChanged, publishAccessibilityElsewhere, registerChildPopup, startDrag, supportsDrag
-
Field Details
-
framesRequested
public int framesRequestedFrames the scene has asked for: what an idle scene must stop adding to. -
screenX
public int screenXWhere 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
The bridge this window hands its scene.AccessibilityBridge.NONEunless 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[] lastSizeThe lastsetSize(int, int)a scene or a test asked for,nullbefore any. -
sizeLimits
WhatsetSizeLimits(int, int, int, int)last set, read back bysizeLimits(). -
fullscreen
public boolean fullscreenWhether this window claims to be fullscreen: set byenterFullscreen(int, int, int), cleared byexitFullscreen(), 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, withSceneDriver.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. -
modal
public boolean modalWhether this window claims to be an active modal, as a dialog's own native window is. -
modalBlocked
public boolean modalBlockedWhether 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- whatsupportsAbsolutePositioning()answers;falsereproduces Wayland, where nothing outside a window can be lined up with anything inside it
-
-
Method Details
-
supportsAbsolutePositioning
public boolean supportsAbsolutePositioning()Description copied from interface:WindowPeerWhetherNativeWindow.screenX(),NativeWindow.screenY()andNativeWindow.setScreenPosition(int, int)actually work on this platform. Whenfalsethe 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
falsethere 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
trueuntil 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:
supportsAbsolutePositioningin interfaceWindowPeer
-
setCloseRequestHandler
Description copied from interface:NativeWindowSets 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 theCloseRequestit is handed, at once or later, so an "unsaved changes" dialog can decide. With no handler, the window agrees. A program'sNativeWindow.requestClose()bypasses it.nullclears. UI thread only.A window created with an owner (
WindowConfig.popup(NativeWindow, int, int)orWindowConfig.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:
setCloseRequestHandlerin interfaceNativeWindow- Parameters:
handler- the handler, ornullfor none
-
closeRequestHandler
- Specified by:
closeRequestHandlerin interfaceNativeWindow- Returns:
- the close handler a scene or an application registered, for a test to ask
-
setClosePolicy
Description copied from interface:NativeWindowSets what a user's close does once it is allowed: dispose the window (the default), hide it, or end the application. A program'sNativeWindow.requestClose()disposes whatever this says. UI thread only.- Specified by:
setClosePolicyin interfaceNativeWindow- Parameters:
policy- the policy; nevernull
-
closePolicy
- Specified by:
closePolicyin interfaceNativeWindow- Returns:
- what a user's close does;
ClosePolicy.DISPOSEunless set
-
fileDialogs
No chooser here: every dialog answers empty, as if cancelled.- Specified by:
fileDialogsin interfaceNativeWindow- Returns:
- the platform's file and folder choosers, owned by this window;
FileDialogs.NONEfor a window with none (headless, embedded). No default: a backend that answeredNONEby omission made every "Open…" in an application silently do nothing. UI thread only.
-
launcher
- Specified by:
launcherin interfaceNativeWindow- Returns:
- what hands an address or a file to the system this window is on;
Launcher.NONEfor a window with no desktop under it (headless, embedded). No default, for the reasonNativeWindow.fileDialogs()has none: a link that silently opens nothing. UI thread only.
-
printer
- Specified by:
printerin interfaceNativeWindow- Returns:
- what prints a PDF through the system's own print dialog, owned by this window;
Printer.NONEfor a window with no printing under it (headless, embedded). No default, for the reasonNativeWindow.launcher()has none: a "Print…" that silently prints nothing. UI thread only.
-
setTextInput
Description copied from interface:WindowPeerSays 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:
setTextInputin interfaceWindowPeer- Parameters:
input- what the window wants; nevernull
-
setPreeditCaretRect
public void setPreeditCaretRect(float x, float y, float width, float height) Description copied from interface:WindowPeerPositions the IME candidate/composition window at the caret, so it follows the text being edited.x/y/width/heightare in logical points relative to the window's content area (the scene feeds the focused widget'scaretRect). UI thread only.- Specified by:
setPreeditCaretRectin interfaceWindowPeer
-
resetPreedit
public void resetPreedit()Description copied from interface:WindowPeerCancels 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:
resetPreeditin interfaceWindowPeer
-
display
A single 400×300 display at the origin, so the whole window is inside its work area.- Specified by:
displayin interfaceNativeWindow- Returns:
- the
Displaythis window currently sits on (the monitor containing the window's centre), ornullwhen headless/embedded. ItsDisplay.workArea()is what external popups clamp against to stay on screen. UI thread only.
-
backend
- Specified by:
backendin interfaceNativeWindow- Returns:
- the backend that owns this window (popup creation, shutdown)
-
requestFrame
public void requestFrame()Description copied from interface:NativeWindowMarks the window dirty so the loop renders a frame for it. UI thread only: from a background thread, hop withUi.post(window::requestFrame).- Specified by:
requestFramein interfaceNativeWindow
-
setFrameCallback
Description copied from interface:WindowPeerRegisters the per-frame render callback.- Specified by:
setFrameCallbackin interfaceWindowPeer
-
setInput
Description copied from interface:WindowPeerRegisters the input sink (usually the scene). SeeWindowInput.- Specified by:
setInputin interfaceWindowPeer
-
title
- Specified by:
titlein interfaceNativeWindow- Returns:
- the current title
-
setTitle
Description copied from interface:NativeWindowSets the native title bar text.- Specified by:
setTitlein interfaceNativeWindow
-
logicalWidth
public float logicalWidth()- Specified by:
logicalWidthin interfaceNativeWindow- Returns:
- width in logical points (framebuffer width ÷ content scale)
-
logicalHeight
public float logicalHeight()- Specified by:
logicalHeightin interfaceNativeWindow- Returns:
- height in logical points (framebuffer height ÷ content scale)
-
framebufferWidth
public int framebufferWidth()- Specified by:
framebufferWidthin interfaceNativeWindow- Returns:
- framebuffer width in physical pixels
-
framebufferHeight
public int framebufferHeight()- Specified by:
framebufferHeightin interfaceNativeWindow- Returns:
- framebuffer height in physical pixels
-
contentScale
public float contentScale()- Specified by:
contentScalein interfaceNativeWindow- 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:NativeWindowForces 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. Pass0to return to the monitor scale.- Specified by:
overrideContentScalein interfaceNativeWindow
-
setSize
public void setSize(int width, int height) Description copied from interface:NativeWindowResizes the window to the given size in logical points.- Specified by:
setSizein interfaceNativeWindow
-
setSizeLimits
public void setSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) Description copied from interface:NativeWindowConstrains user resizing to the given bounds in logical points; pass<= 0for any bound to leave it unconstrained. Only affects interactive resizes;NativeWindow.setSize(int, int)is not clamped. A window made from aWindowConfigwithWindowConfig.minSize(int, int)orWindowConfig.maxSize(int, int)starts with those. The default implementation ignores it (headless/embedding). UI thread only.- Specified by:
setSizeLimitsin interfaceNativeWindow
-
sizeLimits
- Specified by:
sizeLimitsin interfaceNativeWindow- 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.NONEwhere the implementation keeps none (headless, embedding)
-
show
public void show()- Specified by:
showin interfaceNativeWindow
-
hide
public void hide()- Specified by:
hidein interfaceNativeWindow
-
focus
public void focus()Description copied from interface:NativeWindowBrings this window to the front and gives it input focus. UI thread only.- Specified by:
focusin interfaceNativeWindow
-
isVisible
public boolean isVisible()- Specified by:
isVisiblein interfaceNativeWindow- Returns:
- whether the window is currently visible on screen
-
setOpacity
public void setOpacity(float value) Description copied from interface:NativeWindowSets the whole-window opacity in[0..1]at the compositor level, the fade primitive behindScene.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:
setOpacityin interfaceNativeWindow
-
setCursor
Description copied from interface:NativeWindowSets the mouse cursor shown while the pointer is over this window. The scene calls this as the hovered widget changes;nullorCursor.DEFAULTrestores 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:
setCursorin interfaceNativeWindow
-
isClosed
public boolean isClosed()- Specified by:
isClosedin interfaceNativeWindow- Returns:
- whether this window has already been closed/destroyed
-
requestClose
public void requestClose()Description copied from interface:NativeWindowAsks the window to close (processed by the event loop). Any-thread safe.- Specified by:
requestClosein interfaceNativeWindow
-
close
public void close()Description copied from interface:NativeWindowSame asNativeWindow.requestClose(); actual destruction happens in the loop/backend.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceNativeWindow
-
enterFullscreen
public void enterFullscreen(int width, int height, int refreshRate) Description copied from interface:NativeWindowMakes 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,heightandrefreshRateall ≤ 0 asNativeWindow.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 aResolution'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:
enterFullscreenin interfaceNativeWindow- Parameters:
width- width in screen coordinates, or ≤ 0 to name noneheight- height in screen coordinates, or ≤ 0 to name nonerefreshRate- refresh rate in Hz, or ≤ 0 to name none
-
exitFullscreen
public void exitFullscreen()Description copied from interface:NativeWindowLeaves 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:
exitFullscreenin interfaceNativeWindow
-
isFullscreen
public boolean isFullscreen()Description copied from interface:NativeWindowWhether 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:truefrom the momentNativeWindow.enterFullscreen()returns or the person starts the animation,falsefrom the momentNativeWindow.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:
isFullscreenin interfaceNativeWindow- Returns:
- whether the window is, or is going to be, fullscreen
-
isModalBlocked
public boolean isModalBlocked()- Specified by:
isModalBlockedin interfaceNativeWindow- 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:
isModalin interfaceWindowPeer- 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 ofNativeWindow.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
Description copied from interface:WindowPeerRegisters a child popup and says what it is; seeWindowPeer.PopupKind, which is the whole reason this overload exists.- Specified by:
registerChildPopupin interfaceWindowPeer
-
unregisterChildPopup
Description copied from interface:WindowPeerUnregisters a child popup that closed on its own.- Specified by:
unregisterChildPopupin interfaceWindowPeer
-
clipboard
A clipboard that holds nothing, and notnull.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:
clipboardin interfaceNativeWindow- Returns:
- the system clipboard
-
screenX
public int screenX()- Specified by:
screenXin interfaceNativeWindow- Returns:
- window x in native screen coordinates
-
screenY
public int screenY()- Specified by:
screenYin interfaceNativeWindow- Returns:
- window y in native screen coordinates
-
setScreenPosition
public void setScreenPosition(int x, int y) Description copied from interface:NativeWindowMoves the window (native screen coordinates; seeNativeWindow.logicalToScreenFactor()).- Specified by:
setScreenPositionin interfaceNativeWindow
-
logicalToScreenFactor
public float logicalToScreenFactor()- Specified by:
logicalToScreenFactorin interfaceNativeWindow- 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
Description copied from interface:NativeWindowCaptures the next rendered frame (post-flush, pre-swap) and hands the pixels tosink: a per-window screenshot without touching the frame callback, and without a file. Requests a frame, so it works on an idle window.sinkruns 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:
captureNextFramein interfaceNativeWindow
-
setContentScaleListener
Description copied from interface:NativeWindowRegisters a listener for runtime monitor/content-scale changes.- Specified by:
setContentScaleListenerin interfaceNativeWindow
-
accessibility
- Specified by:
accessibilityin interfaceNativeWindow- Returns:
- the platform accessibility bridge for this window, or
AccessibilityBridge.NONEwhen it has none.defaulton 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.
-