如何在Ubuntu和Mac实现类似Windows下JNA获取活跃应用窗口标题的功能?
无额外依赖获取活跃窗口标题(Ubuntu + Mac)
Ubuntu (X11 环境)
直接通过JNA对接X11原生库,无需预装任何第三方工具:
定义X11的JNA接口并实现获取逻辑:
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; public interface X11 extends Library { X11 INSTANCE = Native.load("X11", X11.class); Pointer XOpenDisplay(String display); void XGetInputFocus(Pointer display, IntByReference focus_return, IntByReference revert_to_return); String XFetchName(Pointer display, long window); void XCloseDisplay(Pointer display); } public class UbuntuActiveWindow { public static String getActiveWindowTitle() { Pointer display = X11.INSTANCE.XOpenDisplay(null); if (display == null) return null; IntByReference focusWindow = new IntByReference(); IntByReference revert = new IntByReference(); X11.INSTANCE.XGetInputFocus(display, focusWindow, revert); String title = X11.INSTANCE.XFetchName(display, focusWindow.getValue()); X11.INSTANCE.XCloseDisplay(display); return title; } public static void main(String[] args) { System.out.println(getActiveWindowTitle()); } }
注:若系统使用Wayland而非X11,需对接Wayland API,X11仍是Ubuntu桌面默认主流环境
MacOS
通过JNA对接CoreGraphics框架,无需额外依赖,仅需确保JNA依赖包含jna-platform:
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.platform.mac.CoreFoundation; public interface CoreGraphics extends Library { CoreGraphics INSTANCE = Native.load("CoreGraphics", CoreGraphics.class); int kCGWindowListOptionOnScreenOnly = 1; int kCGWindowListExcludeDesktopElements = 2; int kCGNullWindowID = 0; Pointer CGWindowListCopyWindowInfo(int options, int relativeToWindow); void CFRelease(Pointer cf); } public class MacActiveWindow { public static String getActiveWindowTitle() { Pointer windowList = CoreGraphics.INSTANCE.CGWindowListCopyWindowInfo( CoreGraphics.kCGWindowListOptionOnScreenOnly | CoreGraphics.kCGWindowListExcludeDesktopElements, CoreGraphics.kCGNullWindowID ); if (windowList == null) return null; try { CoreFoundation.CFArrayRef array = new CoreFoundation.CFArrayRef(windowList); int count = CoreFoundation.CFArrayGetCount(array); for (int i = 0; i < count; i++) { Pointer dictPtr = CoreFoundation.CFArrayGetValueAtIndex(array, i); CoreFoundation.CFDictionaryRef dict = new CoreFoundation.CFDictionaryRef(dictPtr); Pointer isActive = CoreFoundation.CFDictionaryGetValue(dict, CoreFoundation.CFStringRef.createCFString("kCGWindowIsOnscreen")); if (isActive != null && CoreFoundation.CFBooleanGetValue(isActive)) { Pointer titlePtr = CoreFoundation.CFDictionaryGetValue(dict, CoreFoundation.CFStringRef.createCFString("kCGWindowName")); if (titlePtr != null) { return CoreFoundation.CFStringGetJavaString(new CoreFoundation.CFStringRef(titlePtr)); } } } } finally { CoreGraphics.INSTANCE.CFRelease(windowList); } return null; } public static void main(String[] args) { System.out.println(getActiveWindowTitle()); } }
内容的提问来源于stack exchange,提问作者gpsingh
相关产品推荐
相关产品推荐

