2

我正在制作一个程序,我需要在屏幕上锁定窗口的位置,有人会认为最简单的方法是使用 _NET_WM_ALLOWED_ACTIONS 但显然没有用,或者我不知道它是如何工作的 xD.. . 我试图发送一个事件,像这样:

def getatom (atom):
    return self.display.intern_atom(atom)

data = [getatom("_NET_WM_ACTION_ABOVE"),getatom("_NET_WM_ACTION_CLOSE"),
        getatom("_NET_WM_ACTION_BELOW"),getatom("_NET_WM_ACTION_CHANGE_DESKTOP"),
        getatom("_NET_WM_ACTION_SHADE")]
state = getatom("_NET_WM_ALLOWED_ACTIONS")
event = Xlib.protocol.event.ClientMessage(window = window, client_type = state, data = (32, data))
root.send_event(event, X.SubstructureRedirectMask)
self.display.sync()

那什么也没做,如果我使用 xprop 允许的操作是 _NET_WM_ACTION_ABOVE、_NET_WM_ACTION_CLOSE、_NET_WM_ACTION_BELOW、_NET_WM_ACTION_CHANGE_DESKTOP 和 _NET_WM_ACTION_SHADE 但我仍然可以移动窗口,我真的不知道该怎么做/它是如何工作的,如果有人能澄清我的话给我一个例子会很感激。

4

2 回答 2

3

这是一个老问题,但我有一个类似的问题,所以,这就是我最终使用的:Motif-compatible,非官方,但大多数窗口管理器都支持_MOTIF_WM_HINTS。定义来自旧的 Motif 代码(应该在 中Xm/MwmUtil.h),但每个人都在克隆它们,所以:

struct MwmHints {
    unsigned long flags;
    unsigned long functions;
    unsigned long decorations;
    long input_mode;
    unsigned long status;
};
enum {
    MWM_HINTS_FUNCTIONS = (1L << 0),
    MWM_HINTS_DECORATIONS =  (1L << 1),

    MWM_FUNC_ALL = (1L << 0),
    MWM_FUNC_RESIZE = (1L << 1),
    MWM_FUNC_MOVE = (1L << 2),
    MWM_FUNC_MINIMIZE = (1L << 3),
    MWM_FUNC_MAXIMIZE = (1L << 4),
    MWM_FUNC_CLOSE = (1L << 5)
};

代码将是这样的:

struct MwmHints hints;
Atom wm = XInternAtom(display, "_MOTIF_WM_HINTS", False);
hints.functions = MWM_FUNC_RESIZE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE;
hints.flags = MWM_HINTS_FUNCTIONS;
XChangeProperty(display, window, wm, XA_ATOM, 32, PropModeReplace, (unsigned char*)&hints, 5);

既然我们省略了MWM_FUNC_MOVE,窗户应该是不可移动的。

在我的(有限的)测试中,这些大部分都有效,但MWM_FUNC_RESIZE大多数情况下都不起作用。

将这些移植到 Python 应该不难,但我在 Python 中不需要它,我更喜欢共享工作代码。

于 2016-07-03T23:11:36.087 回答
2

_NET_WM_ALLOWED_ACTIONS似乎根本不是你想要的:

窗口管理器必须保持更新此属性以反映当前对窗口“活动”或“敏感”的操作 [...] 窗口管理器在最初管理窗口时应该忽略 _NET_WM_ALLOWED_ACTIONS 的值。该值可能是以前具有不同策略的窗口管理器遗留下来的。

在 freedesktop 扩展中,_NET_WM_WINDOW_TYPE最接近您想要的:指定特定的窗口类型以推荐特定的行为。但是,没有机会得到您想要的确切东西(例如,带有装饰的不可移动的窗户),也不能保证 WM 会完全遵守这个提示。

您可能想使用OverrideRedirect属性:在映射窗口之前设置它时,WM 不会干预窗口映射过程。这意味着该窗口没有装饰,没有重新父级,也没有用户发起的操作:您承诺自己管理它。它将是不可移动的(除非提供拖动它的工具)它也将(也许很不幸)没有装饰。

于 2013-01-21T15:54:03.257 回答