【问题标题】:X11 JNA Bad Window (invalid Window parameter) causes JVM exitX11 JNA Bad Window(无效的Window参数)导致JVM退出
【发布时间】:2016-08-19 19:06:28
【问题描述】:

使用 JNA 4.2.2 的以下 JNA 崩溃 - 如果您在最小化和最大化窗口的同时运行它,JVM 将退出并跟随。在 Ubuntu 16.04 上发生,但在 Redhat 6u2 上更常见。

X error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 20 (X_GetProperty)
...

我猜窗口 ID 在从 XQueryTree 返回时是有效的,但在调用 XGetWMName 之前变得无效。问题是这会导致 JVM 退出,而不仅仅是我可以很好地处理的异常。我该如何避免这个问题?

public class X11WindowFinder {

    private X11 x11;

    public X11WindowFinder() {
        x11 = X11.INSTANCE;
    }

    public List<Window> find(Pattern title) {
        Display display = x11.XOpenDisplay(null);
        Window root = x11.XDefaultRootWindow(display);
        List<Window> windows = recurse(x11, display, root, title);
        x11.XCloseDisplay(display);
        return windows;
    }

    private synchronized List<Window> recurse(X11 x11, Display display, Window root, Pattern pattern) {
        List<Window> windows = new ArrayList<>(1);
        X11.WindowByReference windowRef = new X11.WindowByReference();
        X11.WindowByReference parentRef = new X11.WindowByReference();
        PointerByReference childrenRef = new PointerByReference();
        IntByReference childCountRef = new IntByReference();

        x11.XQueryTree(display, root, windowRef, parentRef, childrenRef, childCountRef);
        if (childrenRef.getValue() == null) {
            return Collections.emptyList();
        }


        long[] ids = {};

        if (Native.LONG_SIZE == Long.BYTES) {
            ids = childrenRef.getValue().getLongArray(0, childCountRef.getValue());
        } else if (Native.LONG_SIZE == Integer.BYTES) {
            int[] intIds = childrenRef.getValue().getIntArray(0, childCountRef.getValue());
            ids = new long[intIds.length];
            for (int i = 0; i < intIds.length; i++) {
                ids[i] = intIds[i];
            }
        }

        for (long id : ids) {
            Window child = new Window(id);
            X11.XTextProperty name = new X11.XTextProperty();
            x11.XGetWMName(display, child, name);
            String value = name.value;
            if (value != null) {
                System.out.println(String.format("Found window %s free %s", value, name));
            }
            if (value != null && pattern.matcher(value).matches()) {
                windows.add(child);
            }
            windows.addAll(recurse(x11, display, child, pattern));
        }
        return windows;
    }

    public static void main(String[] args) {
        X11WindowFinder finder = new X11WindowFinder();
        while (true) {
            finder.find(Pattern.compile(".*Firefox.*"));
        }
    }
}

【问题讨论】:

    标签: java x11 jna


    【解决方案1】:

    看起来默认的错误处理程序会导致退出,但可以被覆盖。例如

    x11.XSetErrorHandler(new XErrorHandler() {
    
        @Override
        public int apply(Display display, XErrorEvent errorEvent) {
            System.err.println("bad fish " + errorEvent);
            return 0;
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多