【问题标题】:Move Window Linux C移动窗口 Linux C
【发布时间】:2013-03-29 16:27:21
【问题描述】:

我想制作一个函数,可以通过其 PID 在 C++ 中移动 Linux 中的窗口。所以我在Windows下试过了。但是我很难为 Linux 编译它。 有没有办法用 Qt 做到这一点?由于我没有找到,所以我尝试为 Linux 编译。

我正在使用 MoveWindow 函数,它是 Windows API 的一部分。是否有任何 Linux 等价物?

【问题讨论】:

    标签: c++ linux window


    【解决方案1】:

    如果您不想这样做,则不必手动执行此操作,因为已经有很多工具可以执行诸如移动、调整大小、最大化和任何窗口等任务。

    即使您不打算使用,您可能想要仔细研究的一个工具名称为wmctrl,也许通过查看源代码您会发现一些有趣的技巧。

    移动只有创建窗口的客户端的 pid 知道的窗口的任务可能不是最简单的任务,原因有几个。

    • 首先,您真的不应该尝试这样做,因为在 X Windows 哲学中,窗口管理器的工作是在屏幕上排列窗口。

      以及 ICCCM(参见:http://de.wikipedia.org/wiki/Inter-Client_Communication_Conventions_Manual)和 EWM 规范(参见:http://standards.freedesktop.org/wm-spec/wm-spec-latest.html)强烈劝阻任何客户端尝试自行调整大小或其他任何内容。最有可能移动由另一个客户“拥有”的窗口可能被认为是更大的邪恶。

    • 您可能面临的第二个问题是,X 11 协议没有任何 pid 概念。

      由于它是为通过网络使用而设计的,因此您永远无法真正确定该程序与您当前所坐的机器在同一台机器上运行。因此,像 pid 这样的东西没有多大意义,因为如果它们在不同的机器上运行,可能会有任意数量的具有相同 pid 的客户端在同一个 X 服务器上显示窗口。

    幸运的是,它并没有那么糟糕,因为 EWMH 规范鼓励任何客户端在其顶级窗口上设置 _NET_WM_PID 属性,即创建该窗口的客户端的 pid。

    再次遵守 EWMH 规范并不是 X 服务器以任何方式强制执行的,因此虽然几乎所有客户端都会设置它,但仍然不能保证您会找到属于特定 pid 的窗口。

    可能性

    虽然在此之前提到的所有要点可能看起来相当有限,但实际上很可能恰恰相反。即使实际上完全搞乱在 X 会话中运行的任何其他客户端相对容易,也引入了有关如何在 X 词中成为好公民的整套规则。

    由于 X11 协议本身是一种网络协议(当然不是 100% 正确,因为本地运行的客户端很可能会通过 UNIX 域套接字与 X 服务器进行通信),因此不需要任何特定的库来与 X服务器。

    谈到您的问题中提到的 C,Xlib 长期以来一直是广泛使用的唯一一个实现,但还有另一种称为 xcb 的绑定。与 Xlib 相比,API 略有变化。

    Xlib

    说到Xlib 到现在为止我还没有用过任何xcb,所以我不能告诉你太多关于它可能是以下可能有用的方法。

    • XOpenDisplay - 打开与 X 服务器的连接
    • XQueryTree - 获取服务器上当前活动的窗口树
    • XInternAtom - 不用担心它不危险。只需在手册中阅读它,因为您需要将“原子”映射到上面提到的 _NET_WM_PID
    • XListProperties - 使用您要查找的值搜索 _NET_WM_PID 属性

    • XConfigureWindow, XMoveWindow, XResizeWindow, ... - 最终执行您想做的任何事情。

    上述所有功能都应记录在手册页中。以man XOpenDisplay 为例。

    哦,一定要了解您可以使用的所有其他工具,以进一步研究 X Window 世界。运行xlsatoms,检查xwininfoxprop 的输出中报告的内容,仅针对一个(!)窗口。试着给自己设置一些,看看会发生什么xprop 如果你有礼貌地问,甚至会为你做这件事。

    【讨论】:

    • tldr:X 窗口系统很烂
    • 示例:我正在制作桌面应用程序,在调试版本中,我希望 UI 窗口在启动时始终移动到某个位置。并将同一应用程序的控制台输出窗口移到其正下方。事实上,我无法通过类似于单个 MoveWindow 调用的方式在 linux 上可靠地执行此操作,这绝对是完全愚蠢的。
    • 可能取决于观点。恕我直言,它应该是我的作为用户的选择,作为用户的选择,而不是开发人员硬编码他或她对放置它的“正确”位置的看法的决定。在这种特殊情况下,X 哲学意味着不多或少:普通只是让用户自己决定,你会吗?我所知道的几乎所有 WindowManager 都让用户有机会明确指定应该在哪里弹出哪个窗口以及以什么大小弹出。所以至少对我来说,有一些工具忽略我的任何选择将是真正的麻烦。
    • 确切地说,用户应该始终能够通过调用 OS API MoveWindow 调用来手动(使用键盘或鼠标)或以编程方式将窗口定位在任何他想要的位置。 X 窗口系统没有可靠的方法来做到这一点——因为它已经无法修复了。希望 Wayland(或将替换 X 的人)不会遇到同样的问题。
    • 换句话说 - 对放置窗口的位置的一致、直接控制从用户手中夺走了。并给予 Stupid-Piece-Of-Software - AKA - 窗口管理器。用户唯一的选择是 1) 编写自己的窗口管理器或 2) 在没有窗口管理器的情况下使用 X11。多么美好的世界啊!