Пример #1
0
void map_client(client_t *c)
{
    XWindowAttributes attr;
    strut_t s = { 0, 0, 0, 0 };
    XWMHints *hints;
    int btn, want_raise = 1;

    XGrabServer(dpy);

    XGetWindowAttributes(dpy, c->win, &attr);
    collect_struts(c, &s);

    if (attr.map_state == IsViewable) {
        c->ignore_unmap++;
        reparent(c, &s);
        if (get_wm_state(c->win) == IconicState) {
            c->ignore_unmap++;
            XUnmapWindow(dpy, c->win);
        } else {
            set_wm_state(c, NormalState);
            do_map(c, want_raise);
        }
    } else {
        if ((hints = XGetWMHints(dpy, c->win))) {
            if (hints->flags & StateHint)
                set_wm_state(c, hints->initial_state);
            XFree(hints);
        } else {
            set_wm_state(c, NormalState);
        }
        if (!init_geom(c, &s) && opt_imap) {
            btn = sweep(c, map_curs, recalc_map, SWEEP_DOWN, &s);
            if (btn == Button2)
                btn = sweep(c, resize_curs, recalc_resize, SWEEP_UP, &s);
            if (btn == Button3)
                want_raise = 0;
        }
#ifdef DEBUG
        dump_geom(c, "set to");
        dump_info(c);
#endif
        reparent(c, &s);
        if (get_wm_state(c->win) == NormalState)
            do_map(c, want_raise);
    }

    XSync(dpy, False);
    c->name = get_wm_name(c->win); // horrible kludge
    XUngrabServer(dpy);
}
Пример #2
0
static void
pager_propertynotify(pager *p, XEvent *ev)
{
    Atom at = ev->xproperty.atom;
    Window win = ev->xproperty.window;
    task *t;

    ENTER;
    if ((win == GDK_ROOT_WINDOW()) || !(t = g_hash_table_lookup(p->htable, &win)))
        RET();

    /* The property is deleted */
    if( ((XPropertyEvent*)ev)->state == 1 )
        return;

    DBG("window=0x%x\n", t->win);
    if (at == a_WM_STATE)    {
        DBG("event=WM_STATE\n");
        t->ws = get_wm_state (t->win);
    } else if (at == a_NET_WM_STATE) {
        DBG("event=NET_WM_STATE\n");
        get_net_wm_state(t->win, &t->nws);
    } else if (at == a_NET_WM_DESKTOP) {
        DBG("event=NET_WM_DESKTOP\n");
        desk_set_dirty_by_win(p, t); // to clean up desks where this task was
        t->desktop = get_net_wm_desktop(t->win);
    } else {
        RET();
    }
    desk_set_dirty_by_win(p, t);
    RET();
}
Пример #3
0
void snprint_wm_name(char *buf, size_t len, Window w)
{
    char *n;

    if ((n = get_wm_name(w))) {
        if (get_wm_state(w) == NormalState) {
            if (snprintf(buf, len, "%s", n) > len)
                strcpy(buf+len-4, "...");
        } else {
            if (snprintf(buf, len, "[%s]", n) > len)
                strcpy(buf+len-5, "...]");
        }
        XFree(n);
    } else {
        snprintf(buf, len, "%#lx", w);
    }
}
Пример #4
0
/* Handle PropertyNotify event.
 * http://tronche.com/gui/x/icccm/
 * http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html */
static void pager_property_notify_event(PagerPlugin * pg, XEvent * ev)
{
    /* State may be PropertyNewValue, PropertyDeleted. */
    if (((XPropertyEvent*) ev)->state == PropertyNewValue)
    {
        Atom at = ev->xproperty.atom;
        Window win = ev->xproperty.window;
        if (win != GDK_ROOT_WINDOW())
        {
            /* Look up task structure by X window handle. */
            PagerTask * tk = task_lookup(pg, win);
            if (tk != NULL)
            {
                /* Install an error handler that ignores BadWindow.
                 * We frequently get a PropertyNotify event on deleted windows. */
                XErrorHandler previous_error_handler = XSetErrorHandler(panel_handle_x_error_swallow_BadWindow_BadDrawable);

                /* Dispatch on atom. */
                if (at == a_WM_STATE)   
                {
                    /* Window changed state. */
                    tk->ws = get_wm_state(tk->win);
                    desk_set_dirty_by_win(pg, tk);
                }
                else if (at == a_NET_WM_STATE)
                {
                    /* Window changed EWMH state. */
                    get_net_wm_state(tk->win, &tk->nws);
                    desk_set_dirty_by_win(pg, tk);
                }
                else if (at == a_NET_WM_DESKTOP)
                {
                    /* Window changed desktop.
                     * Mark both old and new desktops for redraw. */
                    desk_set_dirty_by_win(pg, tk);
                    tk->desktop = get_net_wm_desktop(tk->win);
                    desk_set_dirty_by_win(pg, tk);

                XSetErrorHandler(previous_error_handler);
                }
            }
        }
    }
}
Пример #5
0
static void
do_net_client_list_stacking(FbEv *ev, pager *p)
{
    int i;
    task *t;

    ENTER;
    if (p->wins)
        XFree(p->wins);
    p->wins = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_CLIENT_LIST_STACKING,
          XA_WINDOW, &p->winnum);
    if (!p->wins || !p->winnum)
        RET();

    /* refresh existing tasks and add new */
    for (i = 0; i < p->winnum; i++) {
        if ((t = g_hash_table_lookup(p->htable, &p->wins[i]))) {
            t->refcount++;
            if (t->stacking != i) {
                t->stacking = i;
                desk_set_dirty_by_win(p, t);
            }
        } else {
            t = g_new0(task, 1);
            t->refcount++;
            t->win = p->wins[i];
            t->ws = get_wm_state (t->win);
            t->desktop = get_net_wm_desktop(t->win);
            get_net_wm_state(t->win, &t->nws);
            get_net_wm_window_type(t->win, &t->nwwt);
            task_get_sizepos(t);
            if (!FBPANEL_WIN(t->win))
                XSelectInput (GDK_DISPLAY(), t->win, PropertyChangeMask | StructureNotifyMask);
            g_hash_table_insert(p->htable, &t->win, t);
            DBG("add %x\n", t->win);
            desk_set_dirty_by_win(p, t);
        }
    }
    /* pass throu hash table and delete stale windows */
    g_hash_table_foreach_remove(p->htable, (GHRFunc) task_remove_stale, (gpointer)p);
    RET();
}
Пример #6
0
/*
 * List all hidden windows.
 *
 */
int findhidden(void) {
    xcb_query_tree_reply_t *reply;
    int i;
    int len;
    xcb_window_t *children;
    xcb_get_window_attributes_reply_t *attr;
    uint32_t state;
    xcb_get_property_cookie_t cookie;
    xcb_icccm_get_text_property_reply_t prop;
    xcb_generic_error_t *error;

    /* Get all children. */
    reply = xcb_query_tree_reply(conn,
                                 xcb_query_tree(conn, screen->root), 0);
    if (NULL == reply) {
        return -1;
    }

    len = xcb_query_tree_children_length(reply);
    children = xcb_query_tree_children(reply);

    /* List all hidden windows on this root. */
    for (i = 0; i < len; i ++) {
        attr = xcb_get_window_attributes_reply(
                   conn, xcb_get_window_attributes(conn, children[i]), NULL);

        if (!attr) {
            fprintf(stderr, "Couldn't get attributes for window %d.",
                    children[i]);
            continue;
        }

        /*
         * Don't bother windows in override redirect mode.
         *
         * This mode means they wouldn't have been reported to us
         * with a MapRequest if we had been running, so in the
         * normal case we wouldn't have seen them.
         */
        if (!attr->override_redirect) {
            state = get_wm_state(children[i]);
            if (state == XCB_ICCCM_WM_STATE_ICONIC) {
                /*
                 * Example names:
                 *
                 * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78,
                 * 0x76, 0x74 WM_ICON_NAME(STRING) = "urxvt"
                 * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76,
                 * 0x74 WM_NAME(STRING) = "urxvt"
                 */
                cookie = xcb_icccm_get_wm_icon_name(conn, children[i]);
                xcb_icccm_get_wm_icon_name_reply(conn, cookie, &prop, &error);

                prop.name[prop.name_len] = '\0';
                if (printcommand) {
                    /* FIXME: Need to escape : in prop.name. */
                    printf("'%s':'xdotool windowmap 0x%x windowraise 0x%x'\n",
                           prop.name, children[i], children[i]);
                } else {
                    puts(prop.name);
                }
            }
        } /* if not override redirect */

        free(attr);
    } /* for */

    free(reply);

    return 0;
}