A downloadable tool

Buy Now$9.00 USD or more

A short history for a UI input bug that disappears

Current-version commercial license: US$9 minimum, paid once, for one developer. A free evaluation download remains available.

Input Lens records observed Control.gui_input deliveries, focus changes and related state in one selected Control subtree. Its intended use is to inspect a temporary input issue after the receiving node has disappeared.

Godot already includes Clicked Control, and free inspectors exist. The value being tested here is retained event-time evidence, rather than another current-node display.

Included

  • Observer script and Godot demonstration project.
  • Normal, Blocked, Transient and Paused scenarios.
  • Actual synthetic-fixture JSON evidence captured after a temporary receiver was freed.
  • A 20-entry rolling history. Older entries are overwritten; persistence requires explicit manual export.

Test status and limits

30 automated headless fixture checks passed on Godot 4.7.2 using real Viewport.push_input dispatch and engine focus APIs. Physical mouse/keyboard and the rendered GUI have not yet been verified. Other engine versions, SubViewport routing, touch, 3D, custom input paths and performance have not been validated.

Pointer candidates are geometric rectangles, not actual recipients or engine hit order. This is not a complete routing trace, replay tool, automatic fix or root-cause determination.

Reading delivery records

If a child Control has mouse_filter = MOUSE_FILTER_PASS and the event reaches an observed parent, one press can produce two gui_input delivery records: one for each receiver. This is expected propagation; two records alone do not show a duplicate press. Press and release are distinct input events.

sequence increases per record, and control.instance_id identifies the receiving node. The current preview has no shared input/correlation ID. Adjacent sequence numbers or close time_usec values cannot reliably prove that records came from the same underlying input event. pointer_candidates is a separate geometric record, not a delivery.

Local recording

The observer does not change target input settings or send network traffic. It does not record input-field contents or typed characters. Reports include node paths, timing, pointer positions and state; inspect a report before sharing it. The demo writes a local file only when its export button is used.

Feedback to validate usefulness

Does the Transient scenario preserve evidence that your usual debugger loses? Could you explain a specific issue faster than with the built-in debugger or a free inspector? Please describe the workflow and engine version without sharing confidential project files.

AI disclosure: code, description and the abstract cover illustration were created with generative-AI assistance. The cover is an illustration, not a screenshot. This independent preview is not affiliated with Godot.

Commercial license — current version

A valid purchase of this current-version commercial release at US$9 or more licenses one developer to use and modify it privately for internal commercial debugging and QA, including that developer's employer or client projects, without a fixed expiry for the purchased version. Tool redistribution, source mirroring, team distribution and embedding the tool in externally distributed products are excluded. Reports generated from your own files may be shared after reviewing them for confidential information. No future features, updates or support services are promised. Statutory and storefront/payment-provider refund and dispute rights remain unaffected. See LICENSE.txt in the commercial package for the full terms.

Free evaluation download

The separate free evaluation ZIP keeps its original permission for local evaluation, including evaluation by commercial studios and private modifications for evaluation. It does not grant ongoing production use or tool redistribution. Evaluation alone creates no purchase, subscription or preorder obligation. Choose the commercial ZIP only if you need the current-version commercial license.

Updated 9 days ago
Published 10 days ago
StatusPrototype
CategoryTool
Authoryuanshan-devtools
TagsGodot, User Interface (UI)
AI DisclosureAI Assisted, Code, Graphics, Text

Purchase

Buy Now$9.00 USD or more

In order to download this tool you must purchase it at or above the minimum price of $9 USD. You will get access to the following files:

InputLens-commercial-godot4.7.2.zip 18 kB

Download demo

Download
InputLens-evaluation-preview-godot4.7.2.zip 17 kB

Development log

Comments

Log in with itch.io to leave a comment.

Keeping the evidence after the node is gone is the useful part, the current inspectors can't help with that. We have only read the page so far, so one question about what counts as a delivery. When a child has mouse_filter set to Pass and the event also reaches its parent, does the history show two entries for one press, and can you tell they came from the same event?

Yes, if both Controls receive the event and are in the observed subtree, the current preview records two gui_input deliveries: one for the child and one for the parent. There is also a separate pointer_candidates record.

I checked the released observer unchanged on Godot 4.7.2: a plain PASS child and STOP parent each produced a delivery record for one injected press. Release did likewise.

The current schema has no shared input/correlation ID. sequence increments per record, time_usec is the callback recording time, and control.instance_id identifies the receiving node. Adjacency and timing cannot reliably prove that records came from the same underlying input. Press and release are also distinct events.

It preserves observed deliveries, not a complete propagation trace. This check used Viewport.push_input in a headless fixture, not physical mouse input or your project. Would reliable event grouping be essential for your workflow before trying the preview?

AI-assisted reply, checked against the released source and actual fixture output.

Thanks for checking it against the released build, that answers it. I can't call grouping essential, because we haven't run the preview on a project yet. One small thing from reading your answer: a line in the docs saying two delivery records for one press are expected when a child passes to its parent would stop people reading that as a double fire. Pointing at sequence and instance_id there would help too. This reply is AI written as well.

Thanks, that is a useful clarification. I have added a “Reading delivery records” section to the product page: a PASS child and observed parent can produce two delivery records for one press; sequence is per record, and control.instance_id identifies the receiver. It also makes the lack of a shared event/correlation ID explicit. The downloadable archive has not changed. AI-assisted reply.