Xlib:如何检查特定 window 是否已最小化?

Xlib: How to check if a specific window is minimized or not?

我想判断具体window是否最小化。但坐标与未最小化相同。如何判断window是否最小化? 我发现标记为已解决的问题,但它不起作用。

Xlib:如何检查 window 是否被最小化?

根据您上面的评论,试试这个:

//try to get the atoms, don't create it if it does not exist
Atom wm_state = XInternAtom(dpy, "_NET_WM_STATE", True);
Atom wm_hidden = XInternAtom(dpy, "_NET_WM_HIDDEN", True);

//test if the atoms do exists
if (wm_state == None) { /*does not exist*/ }
if (wm_hidden == None) { /*does not exist*/ }

然后调用XGetWindowProperty函数:

long max_length = 1024;
Atom actual_type;
int actual_format;
unsigned long bytes_after, num_states = 0;
Atom* states = NULL;

if (XGetWindowProperty(
    dpy, //your display handle
    id, //your windows handle
    wm_state, //the atom you received earlier
    0l,  //no offset
    max_length,
    False, //do not delete
    XA_ATOM, //requested type
    &actual_type, //atom identifier that defines the actual type
    &actual_format, //actual format of the property
    &num_states, //actual number of items stored in the states data
    &bytes_after, //number of bytes remaining on a partial read
    (unsigned char**) &states //data in the specified format
) == Success) {
    //iterate over the returned list of atoms
    for (unsigned long i = 0; i < num_states; ++i) {
        //test if the list contains the 'hidden' state
        if (states[i] == wm_hidden) { /* state is set */ }
    }
}

参考:


示例(基于讨论):

/* window states */

typedef enum {
    WINDOW_STATE_NONE               = 0,
    WINDOW_STATE_MODAL              = (1 << 0),
    WINDOW_STATE_STICKY             = (1 << 1),
    WINDOW_STATE_MAXIMIZED_VERT     = (1 << 2),
    WINDOW_STATE_MAXIMIZED_HORZ     = (1 << 3),
    WINDOW_STATE_MAXIMIZED          = (WINDOW_STATE_MAXIMIZED_VERT | WINDOW_STATE_MAXIMIZED_HORZ),
    WINDOW_STATE_SHADED             = (1 << 4),
    WINDOW_STATE_SKIP_TASKBAR       = (1 << 5),
    WINDOW_STATE_SKIP_PAGER         = (1 << 6),
    WINDOW_STATE_HIDDEN             = (1 << 7),
    WINDOW_STATE_FULLSCREEN         = (1 << 8),
    WINDOW_STATE_ABOVE              = (1 << 9),
    WINDOW_STATE_BELOW              = (1 << 10),
    WINDOW_STATE_DEMANDS_ATTENTION  = (1 << 11),
    WINDOW_STATE_FOCUSED            = (1 << 12),
    WINDOW_STATE_SIZE               = 13,
} window_state_t;

/* state names */

static char* WINDOW_STATE_NAMES[] = {
    "_NET_WM_STATE_MODAL",
    "_NET_WM_STATE_STICKY",
    "_NET_WM_STATE_MAXIMIZED_VERT",
    "_NET_WM_STATE_MAXIMIZED_HORZ",
    "_NET_WM_STATE_SHADED",
    "_NET_WM_STATE_SKIP_TASKBAR",
    "_NET_WM_STATE_SKIP_PAGER",
    "_NET_WM_STATE_HIDDEN",
    "_NET_WM_STATE_FULLSCREEN",
    "_NET_WM_STATE_ABOVE",
    "_NET_WM_STATE_BELOW",
    "_NET_WM_STATE_DEMANDS_ATTENTION",
    "_NET_WM_STATE_FOCUSED"
};

/* some window struct */

typedef struct {

    Display *dpy;
    Window id;

    struct {
        Atom NET_WM_STATE;
        Atom NET_WM_STATES[WINDOW_STATE_SIZE];
    } atoms;

} window_t;

window_t win;

/* in window initialization function */

win->atoms.NET_WM_STATE = XInternAtom(win->dpy, "_NET_WM_STATE", False);

for (i=0; i < WINDOW_STATE_SIZE; ++i) {
    win->atoms.NET_WM_STATES[i] = XInternAtom(win->dpy, WINDOW_STATE_NAMES[i], False);
}

/* a function to retrieve the current state of the window */

window_state_t get_window_state(window_t *win)
{
    long max_length = 1024;
    Atom actual_type;
    int actual_format;
    unsigned long bytes_after, i, num_states = 0;
    Atom* states = NULL;
    window_state_t state = WINDOW_STATE_NONE;

    if (XGetWindowProperty(win->dpy,
                           win->id,
                           win->atoms.NET_WM_STATE,
                           0l,
                           max_length,
                           False,
                           XA_ATOM,
                           &actual_type,
                           &actual_format,
                           &num_states,
                           &bytes_after,
                           (unsigned char**) &states) == Success)
    {
        //for every state we get from the server
        for (i = 0; i < num_states; ++i) {

            //for every (known) state
            for (int n=0; n < WINDOW_STATE_SIZE; ++n) {
            
                //test the state at index i
                if (states[i] == win->atoms.NET_WM_STATES[n]) {
                    state |= (1 << n);
                    break;
                }
                
            }

        }

        XFree(states);
    }

    return state;
}