繁体   English   中英

如何使用 C/C++ 在 linux 上操作应用程序窗口

[英]How to manipulate application windows on linux with C/C++

我对 C 没有很多经验,如果这是一个愚蠢的问题,我很抱歉。 我正在编写一个将监视和操作应用程序窗口的应用程序,我需要弄清楚如何执行以下操作:

  • 获取所有应用程序窗口的列表
  • 调整窗口大小时收到通知
  • 当用户最大化/最小化窗口时收到通知
  • 设置应用程序窗口的大小和位置。

我花了很长时间搜索谷歌,但没有找到任何有用的东西。 语言并不重要,因为我可以使这个项目使用 C 或 C++ 甚至 C# 任何帮助将不胜感激。

在 linux windows 上由X11 (X Window System https://en.wikipedia.org/wiki/X_Window_Systemhttps://en.wikipedia.org/wiki/X.Org_Server )和 X Window Managers 如Enlightenment 处理https: //en.wikipedia.org/wiki/Comparison_of_X_window_managers ),以及像xdotoolXlib这样的工具和库( https://www.lemoda.net/c/xlib-resize/ ...)。

X11 是 linux 上的低(est)级应用程序窗口处理

在此 X11 基础上,您通常使用 Qt 或 GTK+ 框架编写包含窗口的程序,在这两个框架中都实现了执行您提到的所有任务的方法( 我应该选择什么:GTK+ 或 Qt?

重要的是已安装的 X windows 管理器 ( https://en.wikipedia.org/wiki/Comparison_of_X_window_managers )。 在覆盖的 Qt 和 GTK+ 框架中,只能使用由底层 X 窗口管理器实现的函数

在 Qt 和 GTK 中调整窗口事件捕获的大小:

可以使用Xlib库中的XQueryTree函数查询所有打开的 X 窗口的列表

如何从 xserver 获取打开的窗口列表

xwininfo ( https://linux.die.net/man/1/xwininfo ) 可用于收集有关打开窗口的信息

编辑:当我第一次回答这个问题时,我只是在想别的事情。 其实你要求的很简单。

这是一个潜在的解决方案。

  1. 注册创建/销毁/调整窗口事件 (XCB_EVENT_MASK_STRUCTURE_NOTIFY),以便您可以跟上新添加/销毁/调整大小的窗口。 根据您的设置,您可能想要添加 XCB_EVENT_MASK_PROPERTY_CHANGE,以便您可以判断是否设置了“最小化”或“最大化”属性。

  2. 查询 _NET_CLIENT_LIST(即通过 xcb_ewmh_get_client_list)或使用XQueryTree获取所有(应用程序)窗口。 前者会给你一个过滤列表,它可能是“应用程序窗口”的超集。 后者将为您提供每个窗口,这些窗口可能比您想要的更多。

  3. 发送配置请求以调整窗口大小。 就像其他人所说的,xdotool 可用于发送这些请求。 请注意,一般来说,这些请求很可能会被 WM 阻止/修改。 如果您不拥有该窗口,则除非您的 WM 允许,否则没有什么好方法可以解决此问题。 如果您确实拥有该窗口,则可以在窗口上设置覆盖重定向字段。

下面是有关如何侦听事件的代码示例(符合 -lxcb)。 请注意,这只是一个示例,您可能希望在 switch 语句中过滤事件(即您不需要所有属性)

void main(){
//create connection using default display
xcb_connection_t* dis = xcb_connect(NULL, NULL);
if(xcb_connection_has_error(dis))
    exit(1);

xcb_screen_t*screen=xcb_setup_roots_iterator(xcb_get_setup(dis)).data;
int root = screen->root;
int mask = XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE;
if(xcb_request_check(dis,xcb_change_window_attributes_checked(dis, root,XCB_CW_EVENT_MASK, &mask)))
    exit(1);//an error occured

while(1){
    xcb_generic_event_t *event;
    event = xcb_wait_for_event(dis);
    switch(event->response_type){
        case XCB_CREATE_NOTIFY:
            printf("New window\n");
            break;
        case XCB_DESTROY_NOTIFY:
            printf("Window deleted\n");
            break;
        case XCB_PROPERTY_NOTIFY:
            printf("Window property change\n");
            break;
        case XCB_CONFIGURE_NOTIFY:
            printf("Window size has changed\n");
            break;
    }
}

}

如果你是 X11 的新手,我个人推荐xcb而不是 Xlib,因为它更容易调试,但这只是个人喜好。 您可以使用其中一个或两者。 还要记住,X11 api 已经被移植到许多语言,比如 python,所以你不会被 C 困住。

查看您的评论,是的 DE/WM 会影响您的代码。 不确定你的用例或你想要多深,但你可以

  • 切换WM(有很多可供选择)
  • 在没有 WM 运行的沙箱中运行
  • 查看您的 WM 是否可以将某些窗口列入白名单,以便您可以直接修改它们,或者查看您的 WM 是否可编写脚本/允许您在运行某些事件时添加挂钩
  • 编写自己的 WM。 您可以收到有关您关心的每个事件的通知,但您必须做您想做的所有其他事情,因此工作量很大

我承认 X 编程可能有一点学习曲线,但它会变得更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM