Linux get notification on focused gui window change

前端 未结 2 2035
情话喂你
情话喂你 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 <X11/Xlib.h>
    #include <cstring>
    #include <iostream>
    #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<unsigned long>(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;
    }
    
    
    0 讨论(0)
  • 2021-02-09 10:26

    Example in JavaScript using node-x11:

    var x11 = require('x11');
    x11.createClient(function(err, display) {
      var X = display.client;
      X.ChangeWindowAttributes(display.screen[0].root, { eventMask: x11.eventMask.PropertyChange });
      X.on('event', function(ev) {
        if(ev.name == 'PropertyNotify') {
          X.GetAtomName(ev.atom, function(err, name) {
            if (name == '_NET_ACTIVE_WINDOW') {
              X.GetProperty(0, ev.window, ev.atom, X.atoms.WINDOW, 0, 4, function(err, prop) {
                console.log('New active window:' + prop.data.readUInt32LE(0));
              });
            }
          });
        }
      });
    });
    
    0 讨论(0)
提交回复
热议问题