java-native-access/jna · error · X11Exception

Can't query subwindows

Error message

Can't query subwindows

What it means

Window.getSubwindows calls XQueryTree to enumerate child windows; a return value of 0 indicates the query failed, so "Can't query subwindows" is thrown. The most common underlying cause is an invalid window id (the window no longer exists) rather than a permission issue.

Solutions

  1. Re-resolve the Window before querying; skip windows that vanish (catch X11Exception per window)
  2. Check the display connection with a lightweight call before batch operations
  3. Filter candidate windows (e.g. via XQueryTree from root) freshly each time rather than caching ids
  4. Catch X11Exception in enumeration loops so one dead child doesn't abort listing

Example fix

// before
Window[] kids = win.getSubwindows();
// after
Window[] kids;
try {
    kids = win.getSubwindows();
} catch (X11Exception e) {
    kids = new Window[0]; // window likely destroyed
}
Defensive patterns

Strategy: try-catch

Validate before calling

// skip windows that no longer exist before querying children
// cheap liveness probe:
try { win.getParent(); } catch (X11Exception e) { /* window gone: skip */ }

Try / catch

try {
    Window[] kids = win.getSubwindows();
    process(kids);
} catch (X11Exception e) {
    log.debug("window vanished before XQueryTree: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling getSubwindows() on a Window whose x11Window id is stale/destroyed, or when the X connection is broken.

Common situations: Enumerating windows in a loop where targets get destroyed (apps closing) mid-iteration; screensaver/lock switching displays; X server restarts invalidating all window ids.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/3cda9ae58cd0d4c5. Report an issue: GitHub.

Appendix: source

Thrown at contrib/x11/src/jnacontrib/x11/api/X.java:1127

            X11.XEvent e = new X11.XEvent();
            e.setTypedValue(event);

            if (x11.XSendEvent(display.x11Display, display.getRootWindow().x11Window, 0, mask, e) != 0) {
                return X11.Success;
            } else {
                throw new X11Exception("Cannot send " + msg + " event.");
            }
        }

        public Window[] getSubwindows() throws X11Exception {
            WindowByReference root = new WindowByReference();
            WindowByReference parent = new WindowByReference();
            PointerByReference children = new PointerByReference();
            IntByReference childCount = new IntByReference();

            if (x11.XQueryTree(display.x11Display, x11Window, root, parent, children, childCount) == 0){
                throw new X11Exception("Can't query subwindows");
            }

            if( childCount.getValue() == 0 ){
                return null;
            }

            Window[] retVal = new Window[ childCount.getValue() ];
            //Depending on if we're running on 64-bit or 32-bit systems,
            //the Window ID size may be different; we need to make sure that
            //we get the data properly no matter what
            if (X11.XID.SIZE == 4) {
                int[] windows = children.getValue().getIntArray( 0, childCount.getValue() );
                for( int x = 0; x < retVal.length; x++ ){
                    X11.Window win = new X11.Window( windows [ x ] );
                    retVal[ x ] = new Window( display, win );
                }
            }
            else {

View on GitHub (pinned to d036ad9781)