首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Xlib通过JNA移动窗口

使用Xlib通过JNA移动窗口
EN

Stack Overflow用户
提问于 2010-03-06 01:47:03
回答 2查看 3.4K关注 0票数 1

我使用JNA通过发送Xlib消息来操作Linux上的应用程序窗口,但似乎无法移动窗口。

我最初的实现是在shell上执行wmctrl来移动窗口,并且成功地移动了窗口。不幸的是,与从Java调用shell程序相关的开销很大,所以现在我尝试使用JNA进行直接API调用。我正在使用来自JNA网站的X11示例,可以成功地执行一些技巧,例如枚举窗口is和读取窗口属性,因此我知道JNA+Xlib至少部分工作。

首先,我尝试使用XMoveWindow()直接移动窗口,但是窗口管理器显然阻止了这些调用。

我遇到了一个提示我需要使用XSendMessage()发送客户端消息的线程,所以我已经在下面这样做了,但是显然XSendMessage()失败了,因为窗口没有移动,我得到了0的返回值。我想我漏掉了一些显而易见的东西,但却搞不清楚。有什么建议吗?

注意,就本例而言,main方法有一个硬编码的窗口ID。这是我要移动的窗口的窗口ID (在控制台上使用wmctrl -l获得)。

代码语言:javascript
复制
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.examples.unix.X11;
import com.sun.jna.examples.unix.X11.Atom;
import com.sun.jna.examples.unix.X11.AtomByReference;
import com.sun.jna.examples.unix.X11.Display;
import com.sun.jna.examples.unix.X11.Window;
import com.sun.jna.examples.unix.X11.WindowByReference;
import com.sun.jna.examples.unix.X11.XEvent;
import com.sun.jna.examples.unix.X11.XTextProperty;
import com.sun.jna.examples.unix.X11.XWindowAttributes;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.NativeLongByReference;
import com.sun.jna.ptr.PointerByReference;

private static final int FALSE = 0; /** C-style boolean "false" */
private static final int TRUE  = 1; /** C-style boolean "true" */

public static void main(String[] args) {
    setWindowPos(new Window(0x01300007), 100, 100, 600, 400); // update the Window constructor with the appropriate ID given by wmctrl -l
}


public static boolean setWindowPos(Window window, int x, int y, int w, int h) {
    final X11 x11 = X11.INSTANCE;
    Display display = x11.XOpenDisplay(null);

    NativeLong mask = new NativeLong(X11.SubstructureRedirectMask | X11.SubstructureNotifyMask | X11.ResizeRedirectMask);

    XEvent event = new XEvent();

    String msg = "_NET_MOVERESIZE_WINDOW"; //$NON-NLS-1$

    long grflags = 0l; // use the default gravity of the window
    if (x != -1) grflags |= (1 << 8);
    if (y != -1) grflags |= (1 << 9);
    if (w != -1) grflags |= (1 << 10);
    if (h != -1) grflags |= (1 << 11);

    event.xclient.type = X11.ClientMessage;
    event.xclient.serial = new NativeLong(0l);
    event.xclient.send_event = TRUE;
    event.xclient.message_type = x11.XInternAtom(display, msg, false);
    event.xclient.window = window;
    event.xclient.format = 32;
    event.xclient.data.l[0] = new NativeLong(grflags); // gravity flags
    event.xclient.data.l[1] = new NativeLong(x);
    event.xclient.data.l[2] = new NativeLong(y);
    event.xclient.data.l[3] = new NativeLong(w);
    event.xclient.data.l[4] = new NativeLong(h);

    int status = x11.XSendEvent(display, x11.XDefaultRootWindow(display), FALSE, mask, event);
    x11.XFlush(display); // need to XFlush if we're not reading X events

    if (status == 0) { // 0 indicates XSendEvent failed
        logger.error("setWindowPos: XSendEvent failed (" + msg + ")"); //$NON-NLS-1$
        return false;
    }

    return true;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-22 11:16:03

这可能有点晚了,但无论如何.

当您试图移动窗口时,窗口(称为“客户端”)向窗口管理器发送一个XConfigureRequest。这是因为窗口管理器告诉X服务器他是boss (通过在客户端的父服务器上设置子结构覆盖标志)。

绕过这种情况的唯一方法是在客户端上设置重写重定向标志,进行移动,并禁用重写重定向标志(这样一切都回到了“正常”状态)。

gl & hf

票数 3
EN

Stack Overflow用户

发布于 2010-03-13 06:50:08

你看过XConfigureWindow吗?

我还没有真正测试过这一点,因为我今晚刚刚实现了它,我正在Windows上进行开发,但值得一试.

代码语言:javascript
复制
public static interface X11Ext extends Library
    {
        public static X11Ext INSTANCE = (X11Ext)Native.loadLibrary("X11", X11Ext.class);

        public int XConfigureWindow(X11.Display display, X11.Window window, int value_mask, XWindowChanges changes);

        /**
         * Use value_mask flags:
         * CWX
         * CWY
         * CWWidth
         * CWHeight
         * CWBorderWidth
         * CWSibling
         * CWStackMode
         */
        public class XWindowChanges extends Structure
        {
            public int x;
            public int y;
            public int width;
            public int height;
            public int border_width;
            public X11.Window sibling;
            public int stack_mode;
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2391043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档