Skip to content

testwindow

FreeBodyEngine.core.window.testwindow #

An invisible GLFW-backed window for automated testing (fb.TEST_WINDOW).

A real OpenGL context and a real render target exist here - the actual UI renders exactly as it does in production - but the GLFW window is created with VISIBLE forced off (see GLFWWindow's visible param), so nothing ever appears on screen, steals focus, or triggers a window- manager popup. Paired with SyntheticMouse below and the inject_key_down/inject_key_up/inject_text methods on TestWindow, a whole app session can be driven and inspected (via capture_screenshot()) without any real display, input hardware, or user interruption - see phonon's test_harness.py for the driver that actually uses this.

SyntheticMouse(window) #

Bases: Mouse

Mouse implementation driven entirely by inject_*() calls instead of real hardware - see TestWindow.

Press/release are queued rather than applied immediately, so a press injected between frames only becomes visible (get_pressed()) on the one frame it's drained during update() - matching how a real Mouse only reports a press on the exact frame it polls the transition, not before or after.

scroll_delta = Vector(0, 0) instance-attribute #

window = window instance-attribute #

get_double_click(button) #

get_down(button) #

get_drag_start(button, world=False) #

get_dragging(button) #

get_pressed(button) #

get_released(button) #

get_scroll_delta() #

inject_click(x, y, button=0) #

Moves to (x, y) and queues a press - the caller must still step a frame and then inject_release() (see test_harness.py's Harness.click()) for a real click, exactly like real hardware: a click is a press on one frame and a release on a later one.

inject_move(x, y) #

Moves the cursor to (x, y) in screen space - takes effect immediately, not queued (position is a level value, not edge-triggered).

inject_press(button=0) #

Queues button to read as pressed on the next frame this mouse's update() runs.

inject_release(button=0) #

Queues button to read as released on the next frame this mouse's update() runs.

inject_scroll(dx, dy) #

lock_position() #

set_cursor(shape='default') #

unlock_position() #

update() #

Drains this frame's queued press/release into the one-shot get_pressed()/get_released() flags (cleared first, same as every other Mouse backend clearing its own transient state each frame).

TestWindow(size, title) #

Bases: GLFWWindow

See module docstring. window_type stays 'glfw' deliberately - the renderer's context-selection code only special-cases 'wayland'/'x11'/ 'win32', so this rides the same default GL path a real GLFWWindow would use, with no renderer changes needed.

capture_screenshot(path) #

Saves the current framebuffer to a PNG at path - since this window is never shown on screen, this is the only way to see a frame. Call right after stepping a frame (so the buffer holds what was just drawn), before the next draw() overwrites it.

create_mouse() #

Returns a SyntheticMouse instead of a real GLFWMouse - see that class.

inject_key_down(key) #

Marks key held and fires KEY_PRESS/KEY_REPEAT through Input._key_callback() - the exact same call a real keypress reaches via GLFWWindow._key_callback(), so every listener (UI text-input, actions, ...) sees an indistinguishable event.

inject_key_tap(key) #

A full press-then-release of key, for keys a test doesn't need to hold (Enter, Escape, arrows, ...).

inject_key_up(key) #

Marks key released and fires KEY_RELEASE - see inject_key_down().

inject_text(text) #

Types text one character at a time through the same KEY_PRESS path a real keyboard uses (see ui/manager.py's _on_key) - US- QWERTY only, same limitation as KEY_CHAR_MAP itself. Characters with no mapping (anything KEY_CHAR_MAP doesn't cover) are silently skipped rather than raising, since a test typing a whole sentence shouldn't die over one stray character.