简体   繁体   中英

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. 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.

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/ ...).

X11 is low(est)-level application window handling on linux

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? )

important is the installed X windows manager ( 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

resize window event capturing in Qt and GTK :

A list of all open X windows can be queried with XQueryTree function from the Xlib library

( How to get the list of open windows from xserver )

xwininfo ( https://linux.die.net/man/1/xwininfo ) can be used to collect information about open windows

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. 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.

  2. Query _NET_CLIENT_LIST (ie via xcb_ewmh_get_client_list) or use XQueryTree to get all (application) windows. 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. Note that, in general, these requests are likely to be blocked/modified by the WM. If you don't own the window, there is no good way around this unless your WM allows it. 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). 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)

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. 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.

Looking through your comments, yes DE/WM can impact your code. 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)
  • Run in a sandbox where no WM is running
  • 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
  • Write your own 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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