Linux get notification on focused gui window change

前端 未结 2 2039
情话喂你
情话喂你 2021-02-09 09:52

In linux, is it possible to get notifications when the currently focused GUI app changes? I\'m writing an app that tracks how long a user stays on each GUI app(per process, not

2条回答
  •  逝去的感伤
    2021-02-09 10:23

    Finally I got it.
    compile: g++ ./a.cpp -lX11

    #include 
    #include 
    #include 
    #define MAXSTR 1000
    using namespace std;
    
    Display* display;
    unsigned char *prop;
    
    void check_status(int status, Window window)
    {
        if (status == BadWindow)
        {
            printf("window id # 0x%lx does not exists!", window);
        }
    
        if (status != Success)
        {
            printf("XGetWindowProperty failed!");
        }
    }
    
    unsigned char *get_string_property(const char *property_name, Window window)
    {
        Atom actual_type, filter_atom;
        int actual_format, status;
        unsigned long nitems, bytes_after;
    
        filter_atom = XInternAtom(display, property_name, True);
        status = XGetWindowProperty(display, window, filter_atom, 0, MAXSTR, False, AnyPropertyType,
                                    &actual_type, &actual_format, &nitems, &bytes_after, &prop);
        check_status(status, window);
        return prop;
    }
    
    unsigned long get_long_property(const char *property_name, Window window)
    {
        if (window == 0)
            return 0;
        get_string_property(property_name, window);
        unsigned long long_property = static_cast(prop[0] + (prop[1] << 8) + (prop[2] << 16) + (prop[3] << 24));
        return long_property;
    }
    
    unsigned long getActiveWindowPID(Window root_window)
    {
        unsigned long window;
        window = get_long_property("_NET_ACTIVE_WINDOW", root_window);
        return get_long_property(("_NET_WM_PID"), window);
    }
    
    int main()
    {
        Display * d;
        Window w;
        XEvent e;
    
        d = XOpenDisplay( 0 );
        if ( !d ) {
            cerr << "Could not open display" << endl;
            return 1;
        }
        display = d;
    
        w = DefaultRootWindow( d );
        XSelectInput( d, w, PropertyChangeMask );
    
        pid_t window_pid;
    
        for ( ;; ) {
            XNextEvent( d, &e );
            if ( e.type == PropertyNotify ) {
                if ( !strcmp( XGetAtomName( d, e.xproperty.atom ), "_NET_ACTIVE_WINDOW" ) ) {
                    window_pid = getActiveWindowPID(w );
                    cout << window_pid << endl;
                }
            }
        }
    
        return 0;
    }
    
    

提交回复
热议问题