2016-08-19 12 views
1

JNA 4.2.2を使用しているJNAの次の部分は、ウィンドウを最小化し最大化しながらJVMを終了するとJVMを終了します。 Ubuntu 16.04で起こりますが、Redhat 6u2ではより頻繁に起こります。X11 JNA Bad Window(無効なWindowパラメータ)によりJVM出口が発生する

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

私は、彼らがXQueryTreeから返されたが、XGetWMNameへの呼び出しの前に無効になっているとき、ウィンドウIDが有効である推測しています。この問題は、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.*")); 
     } 
    } 
} 

答えて

1

デフォルトのエラーハンドラのように見えますが、exitが発生しますが、上書きすることができます。例えば、

x11.XSetErrorHandler(new XErrorHandler() { 

    @Override 
    public int apply(Display display, XErrorEvent errorEvent) { 
     System.err.println("bad fish " + errorEvent); 
     return 0; 
    } 
}); 
関連する問題