You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:55:27