Ejemplo n.º 1
0
static int
property_handle_net_wm_opacity(uint8_t state,
                               xcb_window_t window)
{
    drawin_t *drawin = drawin_getbywin(window);

    if(drawin)
    {
        luaA_object_push(globalconf.L, drawin);
        window_set_opacity(globalconf.L, -1, xwindow_get_opacity(drawin->window));
        lua_pop(globalconf.L, -1);
    }
    else
    {
        client_t *c = client_getbywin(window);
        if(c)
        {
            luaA_object_push(globalconf.L, c);
            window_set_opacity(globalconf.L, -1, xwindow_get_opacity(c->window));
            lua_pop(globalconf.L, 1);
        }
    }

    return 0;
}
Ejemplo n.º 2
0
/** The expose event handler.
 * \param ev The event.
 */
static void
event_handle_expose(xcb_expose_event_t *ev)
{
    drawin_t *drawin;
    client_t *client;

    if((drawin = drawin_getbywin(ev->window)))
        drawin_refresh_pixmap_partial(drawin,
                                      ev->x, ev->y,
                                      ev->width, ev->height);
    if ((client = client_getbyframewin(ev->window)))
        client_refresh_partial(client, ev->x, ev->y, ev->width, ev->height);
}
Ejemplo n.º 3
0
/** The enter notify event handler.
 * \param ev The event.
 */
static void
event_handle_enternotify(xcb_enter_notify_event_t *ev)
{
    lua_State *L = globalconf_get_lua_State();
    client_t *c;
    drawin_t *drawin;

    globalconf.timestamp = ev->time;

    if(ev->mode != XCB_NOTIFY_MODE_NORMAL)
        return;

    if((drawin = drawin_getbywin(ev->event)))
    {
        luaA_object_push(L, drawin);
        luaA_object_push_item(L, -1, drawin->drawable);
        event_drawable_under_mouse(L, -1);
        lua_pop(L, 2);
    }

    if((c = client_getbyframewin(ev->event)))
    {
        luaA_object_push(L, c);
        /* Ignore enter with detail inferior: The pointer was previously inside
         * of a child window, so technically this isn't a 'real' enter.
         */
        if (ev->detail != XCB_NOTIFY_DETAIL_INFERIOR)
            luaA_object_emit_signal(L, -1, "mouse::enter", 0);

        drawable_t *d = client_get_drawable(c, ev->event_x, ev->event_y);
        if (d)
        {
            luaA_object_push_item(L, -1, d);
            event_drawable_under_mouse(L, -1);
            lua_pop(L, 1);
        }
        lua_pop(L, 1);
    }
    else if (ev->event == globalconf.screen->root) {
        /* When there are multiple X screens with awesome running separate
         * instances, reset focus.
         */
        globalconf.focus.need_update = true;
    }
}
Ejemplo n.º 4
0
/** The motion notify event handler.
 * \param ev The event.
 */
static void
event_handle_motionnotify(xcb_motion_notify_event_t *ev)
{
    lua_State *L = globalconf_get_lua_State();
    drawin_t *w;
    client_t *c;

    globalconf.timestamp = ev->time;

    if(event_handle_mousegrabber(ev->root_x, ev->root_y, ev->state))
        return;

    if((c = client_getbyframewin(ev->event)))
    {
        luaA_object_push(L, c);
        lua_pushinteger(L, ev->event_x);
        lua_pushinteger(L, ev->event_y);
        luaA_object_emit_signal(L, -3, "mouse::move", 2);

        /* now check if a titlebar was "hit" */
        int x = ev->event_x, y = ev->event_y;
        drawable_t *d = client_get_drawable_offset(c, &x, &y);
        if (d)
        {
            luaA_object_push_item(L, -1, d);
            event_drawable_under_mouse(L, -1);
            lua_pushinteger(L, x);
            lua_pushinteger(L, y);
            luaA_object_emit_signal(L, -3, "mouse::move", 2);
            lua_pop(L, 1);
        }
        lua_pop(L, 1);
    }

    if((w = drawin_getbywin(ev->event)))
    {
        luaA_object_push(L, w);
        luaA_object_push_item(L, -1, w->drawable);
        event_drawable_under_mouse(L, -1);
        lua_pushinteger(L, ev->event_x);
        lua_pushinteger(L, ev->event_y);
        luaA_object_emit_signal(L, -3, "mouse::move", 2);
        lua_pop(L, 2);
    }
}
Ejemplo n.º 5
0
/** Get the client which is under the pointer.
 * \param L The Lua VM state.
 * \return The number of elements pushed on stack.
 * \luastack
 * \lreturn A client or nil.
 */
static int
luaA_mouse_object_under_pointer(lua_State *L)
{
    int16_t mouse_x, mouse_y;
    xcb_window_t child;

    if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL))
        return 0;

    drawin_t *drawin;
    client_t *client;

    if((drawin = drawin_getbywin(child)))
        return luaA_object_push(L, drawin);

    if((client = client_getbyframewin(child)))
        return luaA_object_push(globalconf.L, client);

    return 0;
}
Ejemplo n.º 6
0
/** The property notify event handler handling xproperties.
 * \param ev The event.
 */
static void
property_handle_propertynotify_xproperty(xcb_property_notify_event_t *ev)
{
    xproperty_t *prop;
    xproperty_t lookup = { .atom = ev->atom };
    buffer_t buf;
    void *obj;

    prop = xproperty_array_lookup(&globalconf.xproperties, &lookup);
    if(!prop)
        /* Property is not registered */
        return;

    if (ev->window != globalconf.screen->root)
    {
        obj = client_getbywin(ev->window);
        if(!obj)
            obj = drawin_getbywin(ev->window);
        if(!obj)
            return;
    } else
        obj = NULL;

    /* Get us the name of the property */
    buffer_inita(&buf, a_strlen(prop->name) + a_strlen("xproperty::") + 1);
    buffer_addf(&buf, "xproperty::%s", prop->name);

    /* And emit the right signal */
    if (obj)
    {
        luaA_object_push(globalconf.L, obj);
        luaA_object_emit_signal(globalconf.L, -1, buf.s, 0);
        lua_pop(globalconf.L, 1);
    } else
        signal_object_emit(globalconf.L, &global_signals, buf.s, 0);
    buffer_wipe(&buf);
}

/** The property notify event handler.
 * \param ev The event.
 */
void
property_handle_propertynotify(xcb_property_notify_event_t *ev)
{
    int (*handler)(uint8_t state,
                   xcb_window_t window) = NULL;

    globalconf.timestamp = ev->time;

    property_handle_propertynotify_xproperty(ev);

    /* Find the correct event handler */
#define HANDLE(atom_, cb) \
    if (ev->atom == atom_) \
    { \
        handler = cb; \
    } else
#define END return

    /* Xembed stuff */
    HANDLE(_XEMBED_INFO, property_handle_xembed_info)

    /* ICCCM stuff */
    HANDLE(XCB_ATOM_WM_TRANSIENT_FOR, property_handle_wm_transient_for)
    HANDLE(WM_CLIENT_LEADER, property_handle_wm_client_leader)
    HANDLE(XCB_ATOM_WM_NORMAL_HINTS, property_handle_wm_normal_hints)
    HANDLE(XCB_ATOM_WM_HINTS, property_handle_wm_hints)
    HANDLE(XCB_ATOM_WM_NAME, property_handle_wm_name)
    HANDLE(XCB_ATOM_WM_ICON_NAME, property_handle_wm_icon_name)
    HANDLE(XCB_ATOM_WM_CLASS, property_handle_wm_class)
    HANDLE(WM_PROTOCOLS, property_handle_wm_protocols)
    HANDLE(XCB_ATOM_WM_CLIENT_MACHINE, property_handle_wm_client_machine)
    HANDLE(WM_WINDOW_ROLE, property_handle_wm_window_role)

    /* EWMH stuff */
    HANDLE(_NET_WM_NAME, property_handle_net_wm_name)
    HANDLE(_NET_WM_ICON_NAME, property_handle_net_wm_icon_name)
    HANDLE(_NET_WM_STRUT_PARTIAL, property_handle_net_wm_strut_partial)
    HANDLE(_NET_WM_ICON, property_handle_net_wm_icon)
    HANDLE(_NET_WM_PID, property_handle_net_wm_pid)
    HANDLE(_NET_WM_WINDOW_OPACITY, property_handle_net_wm_opacity)

    /* background change */
    HANDLE(_XROOTPMAP_ID, property_handle_xrootpmap_id)

    /* If nothing was found, return */
    END;

#undef HANDLE
#undef END

    (*handler)(ev->state, ev->window);
}
Ejemplo n.º 7
0
/** The button press event handler.
 * \param ev The event.
 */
static void
event_handle_button(xcb_button_press_event_t *ev)
{
    lua_State *L = globalconf_get_lua_State();
    client_t *c;
    drawin_t *drawin;

    globalconf.timestamp = ev->time;

    {
        /* ev->state contains the state before the event. Compute the state
         * after the event for the mousegrabber.
         */
        uint16_t state = ev->state, change = 1 << (ev->detail - 1 + 8);
        if (XCB_EVENT_RESPONSE_TYPE(ev) == XCB_BUTTON_PRESS)
            state |= change;
        else
            state &= ~change;
        if(event_handle_mousegrabber(ev->root_x, ev->root_y, state))
            return;
    }

    /* ev->state is
     * button status (8 bits) + modifiers status (8 bits)
     * we don't care for button status that we get, especially on release, so
     * drop them */
    ev->state &= 0x00ff;

    if((drawin = drawin_getbywin(ev->event))
       || (drawin = drawin_getbywin(ev->child)))
    {
        /* If the drawin is child, then x,y are
         * relative to root window */
        if(drawin->window == ev->child)
        {
            ev->event_x -= drawin->geometry.x + drawin->border_width;
            ev->event_y -= drawin->geometry.y + drawin->border_width;
        }

        /* Push the drawable */
        luaA_object_push(L, drawin);
        luaA_object_push_item(L, -1, drawin->drawable);
        /* and handle the button raw button event */
        event_emit_button(L, ev);
        lua_pop(L, 1);
        /* check if any button object matches */
        event_button_callback(ev, &drawin->buttons, L, -1, 1, NULL);
        /* Either we are receiving this due to ButtonPress/Release on the root
         * window or because we grabbed the button on the window. In the later
         * case we have to call AllowEvents.
         * Use AsyncPointer instead of ReplayPointer so that the event is
         * "eaten" instead of being handled again on the root window.
         */
        if(ev->child == XCB_NONE)
            xcb_allow_events(globalconf.connection,
                             XCB_ALLOW_ASYNC_POINTER,
                             ev->time);
    }
    else if((c = client_getbyframewin(ev->event)) || (c = client_getbywin(ev->event)))
    {
        /* For clicks inside of c->window, we get two events. Once because of a
         * passive grab on c->window and then again for c->frame_window.
         * Ignore the second event (identifiable by ev->child != XCB_NONE).
         */
        if (ev->event != c->frame_window || ev->child == XCB_NONE)
        {
            luaA_object_push(L, c);
            if (c->window == ev->event)
            {
                /* Button event into the client itself (not titlebar), translate
                 * into the frame window.
                 */
                ev->event_x += c->titlebar[CLIENT_TITLEBAR_LEFT].size;
                ev->event_y += c->titlebar[CLIENT_TITLEBAR_TOP].size;
            }
            /* And handle the button raw button event */
            event_emit_button(L, ev);
            /* then check if a titlebar was "hit" */
            if (c->frame_window == ev->event)
            {
                int x = ev->event_x, y = ev->event_y;
                drawable_t *d = client_get_drawable_offset(c, &x, &y);
                if (d)
                {
                    /* Copy the event so that we can fake x/y */
                    xcb_button_press_event_t event = *ev;
                    event.event_x = x;
                    event.event_y = y;
                    luaA_object_push_item(L, -1, d);
                    event_emit_button(L, &event);
                    lua_pop(L, 1);
                }
            }
            /* then check if any button objects match */
            event_button_callback(ev, &c->buttons, L, -1, 1, NULL);
        }
        xcb_allow_events(globalconf.connection,
                         XCB_ALLOW_REPLAY_POINTER,
                         ev->time);
    }
    else if(ev->child == XCB_NONE)
        if(globalconf.screen->root == ev->event)
        {
            event_button_callback(ev, &globalconf.buttons, L, 0, 0, NULL);
            return;
        }
}