Repository navigation
Add keyboard input from the focused visualizer window - #8158
Conversation
d78dfca to
a82dd1e
Compare
|
run-ci |
|
There was a problem hiding this comment.
Isaac Lab Review Bot
Needs attention: Scope and over-engineering (2), Implementation (3), Style consistency (2), Test quality (2). Other reviewed categories look good.
- PR description: The body falsely claims a Viser implementation although the diff and capability table return
None; remove that claim and the emptyFixes #, then list focused validation commands. - Design and architecture: Architecture looks good.
- Scope and over-engineering: Minimal implementation: extend BaseVisualizer, KitVisualizer, and NewtonVisualizer; keep key_event_source.py, keep kit_key_event_source.py but inline its one-use
_kit()wrapper, and keep newton_key_event_source.py for pyglet mapping and capture. Delete both redundant_key_input_closedflags; retain lazy creation, backend hooks, event delivery, and visualizer-owned cleanup. Scope is cohesive; no split recommended. - API: API changes look good.
- Compatibility and deprecation: No breaking changes identified.
- Implementation: Backend cleanup is not failure-safe: Kit can remain marked listening after losing hooks, and Newton can retain its frame callback after unhook failure; preserve consistent state and clear callbacks during release.
- Style consistency: The new property and capabilities declaration violate required class organization: move properties before public methods and annotate backend-shared
capabilitieswithClassVar[KeyboardCapabilities]. - Test quality: The added suites cover distinct lifecycle and backend behavior, but capability-literal assertions and mirrored shift-order rows duplicate stronger behavioral coverage; remove those cases.
Minor fixes needed. Posted 9 inline findings.
Automated review; human maintainers own approval decisions.
a82dd1e to
5811c22
Compare
|
@greptile |
5811c22 to
773a726
Compare
|
@greptile |
|
run-ci |
773a726 to
1c1d547
Compare
|
The goal makes sense, but I’m concerned about how much responsibility is going into Could we first connect this to I’d expect the ownership to be roughly:
The shared source may need some bookkeeping to deliver reliable events, and focus-loss handling is important. But which actual callers need subscription/cleanup from different threads and multiple independent keyboard capture handles? Would requiring operations on the visualizer thread and providing a simple camera-keyboard toggle cover the current use case? I’d like us to validate those boundaries with one real controller before committing to the larger public API. |
Thanks Octi, agreed on validating against a real controller. There is one: the follow-up branch The ownership you describe matches how that branch splits it:
On your questions, the real caller doesn't need everything this PR provides:
That reduces the public API to |
|
Yes, that matches what I had in mind. Thanks for clarifying. Let's simplify this PR as you described: keep key/focus events and a closable subscription, remove the locks and per-listener held-key tracking, and replace capture handles with a camera-keyboard toggle. Please open the controller integration as a follow-up draft PR so we can review both together. That should make the ownership much clearer. |
1c1d547 to
3699be9
Compare
BaseVisualizer.key_event_source exposes keys typed into a visualizer's own window, or None when it has none. A KeyEventSource reports each press and release as a W3C KeyboardEvent.code string, plus a focus loss when the window stops delivering keys (blur, the visualizer's UI taking the keyboard, or close). add_key_listener returns a KeyboardSubscription, an idempotent handle the caller closes. Events are forwarded as the window reports them, so a listener tracks the keys it holds. Subscribing, closing and callbacks all happen on the thread that steps the visualizer. Closing the source is terminal: every listener gets one final focus loss. BaseVisualizer.set_camera_keys_enabled lets a keyboard consumer turn off the visualizer's keyboard camera movement while it uses those keys; it does nothing by default.
KitVisualizer reports physical keys from the Kit app window and a focus loss on window blur. Kit has no Python query for UI keyboard ownership, so keys typed into its UI are reported too. Its viewport camera keys only act while the right mouse button is held, so it keeps the default set_camera_keys_enabled. NewtonGLVisualizer and NewtonRTXVisualizer report layout-mapped keys from their shared pyglet viewer window. They withhold presses typed into its ImGui widgets, checking ImGui's keyboard ownership after every frame. set_camera_keys_enabled(False) stops the window's WASD/QE and arrow-key camera movement, including for a window opened later. Each visualizer closes its keyboard source first in its teardown, while the window is still open, and finishes that teardown when the source fails to close. Headless runs and the Viser and Rerun visualizers have no keyboard source.
3699be9 to
d4fb5e8
Compare
|
run-ci |
Kit and Newton visualizers now connect keyboard input when their window initializes. Keyboard input is optional, so a failure there is logged and key_event_source stays None instead of stopping the visualizer from starting.
Keep the deleted helper out of the direct rendering test architecture and check keyboard availability in the existing scene test. Preserve all production changes from the author branch, including optional keyboard initialization.
|
run-ci |
|
run-ci |
Description
Adds a keyboard input API to visualizers, so code can read the keys pressed in a visualizer's window, e.g. for keyboard teleoperation or script hotkeys, independent of Kit/carb.
BaseVisualizer.key_event_sourcereturns aKeyEventSourcefor the visualizer's window, orNonewhen it has none (the default; also before initialization, after close, and headless). It is createdon first access and closed with the visualizer.
KeyEventSource.add_key_listener(on_key, on_focus_lost)returns a closableKeyboardSubscription. Presses and releases arrive as W3CKeyboardEvent.codestrings ("KeyW"), forwarded as the windowreports them;
on_focus_lostruns on blur, when the visualizer's UI takes the keyboard, and on close. Subscribing, closing and callbacks all happen on the visualizer's thread.BaseVisualizer.set_camera_keys_enabled(enabled)lets the caller turn off keyboard camera movement (Newton WASD/QE and arrow keys) while it uses those keys; a no-op by default.typed into the ImGui UI are withheld). Viser, Rerun and headless runs return
None.close(), while the window is still open; a failure there is logged and the rest of the teardown still runs.Opt-in: nothing is hooked until a listener subscribes, and existing visualizer behavior is unchanged.
Used by #8797 (keyboard, gamepad and SpaceMouse teleop through Isaac Capture) and #8798 (remaining scripts and deprecation of the
isaaclab.deviceskeyboard, gamepad and SpaceMouse devices).Fixes # (issue)
Type of change
Release backport
developChecklist
Docker and GPU tests run on demand. Push the commits you want tested, then
comment
run-cion the pull request.pre-commitchecks withuv run isaaclab --formatsource/<pkg>/changelog.d/for every touched package (do not editCHANGELOG.rstor bump package versions — CI handles that)CONTRIBUTORS.mdor my name already exists there