简体   繁体   English

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

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

I dont have a lot of experience with C so sorry if this is a dumb question.我对 C 没有很多经验,如果这是一个愚蠢的问题,我很抱歉。 I'm writing an application that will monitor and manipulate application windows and i need to figure out how to do the following:我正在编写一个将监视和操作应用程序窗口的应用程序,我需要弄清楚如何执行以下操作:

  • Get a list of all application windows获取所有应用程序窗口的列表
  • Be notified when a window is resized调整窗口大小时收到通知
  • Be notified when the a user maximises/minimises a window当用户最大化/最小化窗口时收到通知
  • Set the size and position of an application window.设置应用程序窗口的大小和位置。

I spent quite a while searching google but did not find anything useful.我花了很长时间搜索谷歌,但没有找到任何有用的东西。 The language is not to important as i could make this project work with C or C++ maybe even C# Any help would be appreciated.语言并不重要,因为我可以使这个项目使用 C 或 C++ 甚至 C# 任何帮助将不胜感激。

on linux windows are handled by X11 ( X Window System https://en.wikipedia.org/wiki/X_Window_System , https://en.wikipedia.org/wiki/X.Org_Server ) and X Window Managers like Enlightenment ( https://en.wikipedia.org/wiki/Comparison_of_X_window_managers ), and tools and libraries like xdotool or Xlib ( https://www.lemoda.net/c/xlib-resize/ ...).在 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 is low(est)-level application window handling on linux X11 是 linux 上的低(est)级应用程序窗口处理

on this X11 basis you normally write programs that contain windows using Qt or GTK+ framework, in both frameworks are implemented methods to do all your mentioned tasks ( What should I choose: GTK+ or Qt? )在此 X11 基础上,您通常使用 Qt 或 GTK+ 框架编写包含窗口的程序,在这两个框架中都实现了执行您提到的所有任务的方法( 我应该选择什么:GTK+ 或 Qt?

important is the installed X windows manager ( https://en.wikipedia.org/wiki/Comparison_of_X_window_managers ).重要的是已安装的 X windows 管理器 ( https://en.wikipedia.org/wiki/Comparison_of_X_window_managers )。 In the overlying Qt and GTK+ frameworks only functions can be used that are implemented by the underlying X window manager在覆盖的 Qt 和 GTK+ 框架中,只能使用由底层 X 窗口管理器实现的函数

resize window event capturing in Qt and GTK :在 Qt 和 GTK 中调整窗口事件捕获的大小:

A list of all open X windows can be queried with XQueryTree function from the Xlib library可以使用Xlib库中的XQueryTree函数查询所有打开的 X 窗口的列表

( How to get the list of open windows from xserver ) 如何从 xserver 获取打开的窗口列表

xwininfo ( https://linux.die.net/man/1/xwininfo ) can be used to collect information about open windows xwininfo ( https://linux.die.net/man/1/xwininfo ) 可用于收集有关打开窗口的信息

EDIT: I was just thinking of something else when I answered the question the first time.编辑:当我第一次回答这个问题时,我只是在想别的事情。 In fact what you are asking for is pretty simple.其实你要求的很简单。

Here is a potential solution.这是一个潜在的解决方案。

  1. Register for Create/Destroy/Resize window events (XCB_EVENT_MASK_STRUCTURE_NOTIFY) so you can keep up with newly added/destroyed/resized windows.注册创建/销毁/调整窗口事件 (XCB_EVENT_MASK_STRUCTURE_NOTIFY),以便您可以跟上新添加/销毁/调整大小的窗口。 Depending on your setup you may want to add the XCB_EVENT_MASK_PROPERTY_CHANGE so you can tell if the "minimized" or "maximized" property is set.根据您的设置,您可能想要添加 XCB_EVENT_MASK_PROPERTY_CHANGE,以便您可以判断是否设置了“最小化”或“最大化”属性。

  2. Query _NET_CLIENT_LIST (ie via xcb_ewmh_get_client_list) or use XQueryTree to get all (application) windows.查询 _NET_CLIENT_LIST(即通过 xcb_ewmh_get_client_list)或使用XQueryTree获取所有(应用程序)窗口。 The former will give you a filtered list that will probably be a superset of "application windows".前者会给你一个过滤列表,它可能是“应用程序窗口”的超集。 The latter will give you every single window which will probably be more than what you want.后者将为您提供每个窗口,这些窗口可能比您想要的更多。

  3. Send configure request to resize the window.发送配置请求以调整窗口大小。 Like others have said, xdotool can be used to send these requests.就像其他人所说的,xdotool 可用于发送这些请求。 Note that, in general, these requests are likely to be blocked/modified by the WM.请注意,一般来说,这些请求很可能会被 WM 阻止/修改。 If you don't own the window, there is no good way around this unless your WM allows it.如果您不拥有该窗口,则除非您的 WM 允许,否则没有什么好方法可以解决此问题。 If you do own the window, you could set the override redirect field on the window.如果您确实拥有该窗口,则可以在窗口上设置覆盖重定向字段。

Below is a code sample on how you might listen for events (complied with -lxcb).下面是有关如何侦听事件的代码示例(符合 -lxcb)。 Note that this is just a sample and you would probably want to filter events in the switch statement (ie you don't want all properties)请注意,这只是一个示例,您可能希望在 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;
    }
}

} }

If you are new to X11, I personally recommend xcb instead of Xlib because its easier to debug, but its just a personal preference.如果你是 X11 的新手,我个人推荐xcb而不是 Xlib,因为它更容易调试,但这只是个人喜好。 You could use either or both.您可以使用其中一个或两者。 Also keep in mind that X11 api has been ported to many languages like python so you are not stuck with C.还要记住,X11 api 已经被移植到许多语言,比如 python,所以你不会被 C 困住。

Looking through your comments, yes DE/WM can impact your code.查看您的评论,是的 DE/WM 会影响您的代码。 Not sure of your use case or how deep you want to go but you can不确定你的用例或你想要多深,但你可以

  • switch WM (there are a lot to choose from)切换WM(有很多可供选择)
  • Run in a sandbox where no WM is running在没有 WM 运行的沙箱中运行
  • See if your WM can white list certain windows so you can modify them directly or see if you WM is scriptable/allows you to add hooks when certain events are run查看您的 WM 是否可以将某些窗口列入白名单,以便您可以直接修改它们,或者查看您的 WM 是否可编写脚本/允许您在运行某些事件时添加挂钩
  • Write your own WM.编写自己的 WM。 You can get notified of every event you care about but you'd have to do everything else you'd ever want so it would be a lot of work您可以收到有关您关心的每个事件的通知,但您必须做您想做的所有其他事情,因此工作量很大

I will admit that X programming can have a bit of a learning curve but it gets better.我承认 X 编程可能有一点学习曲线,但它会变得更好。

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

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