static int property_handle_net_wm_opacity(uint8_t state, xcb_window_t window, xcb_atom_t name, xcb_get_property_reply_t *reply) { wibox_t *wibox = wibox_getbywin(window); if(wibox) { luaA_object_push(globalconf.L, wibox); wibox_set_opacity(globalconf.L, -1, window_opacity_get_from_reply(reply)); lua_pop(globalconf.L, -1); } else { client_t *c = client_getbywin(window); if(c) { luaA_object_push(globalconf.L, c); client_set_opacity(globalconf.L, -1, window_opacity_get_from_reply(reply)); lua_pop(globalconf.L, 1); } } return 0; }
/** The button press event handler. * \param data The type of mouse event. * \param connection The connection to the X server. * \param ev The event. */ static int event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_event_t *ev) { int screen; const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); client_t *c; wibox_t *wibox; if(event_handle_mousegrabber(ev->root_x, ev->root_y, 1 << (ev->detail - 1 + 8))) return 0; /* 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((wibox = wibox_getbywin(ev->event)) || (wibox = wibox_getbywin(ev->child))) { /* If the wibox is child, then x,y are * relative to root window */ if(wibox->window == ev->child) { ev->event_x -= wibox->geometry.x; ev->event_y -= wibox->geometry.y; } /* Push the wibox */ luaA_object_push(globalconf.L, wibox); /* Duplicate the wibox */ lua_pushvalue(globalconf.L, -1); /* Handle the button event on it */ event_button_callback(ev, &wibox->buttons, -1, 1, NULL); /* then try to match a widget binding */ widget_t *w = widget_getbycoords(wibox->orientation, &wibox->widgets, wibox->geometry.width, wibox->geometry.height, &ev->event_x, &ev->event_y); if(w) { /* Push widget (the wibox is already on stack) */ luaA_object_push_item(globalconf.L, -1, w); /* Move widget before wibox */ lua_insert(globalconf.L, -2); event_button_callback(ev, &w->buttons, -2, 2, NULL); } else /* Remove the wibox, we did not use it */ lua_pop(globalconf.L, 1); } else if((c = client_getbywin(ev->event))) { luaA_object_push(globalconf.L, c); event_button_callback(ev, &c->buttons, -1, 1, NULL); xcb_allow_events(globalconf.connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME); } else if(ev->child == XCB_NONE) for(screen = 0; screen < nb_screen; screen++) if(xutil_screen_get(connection, screen)->root == ev->event) { event_button_callback(ev, &globalconf.buttons, 0, 0, NULL); return 0; } return 0; }
/** The button press event handler. * \param data The type of mouse event. * \param connection The connection to the X server. * \param ev The event. */ static int event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_event_t *ev) { int screen; const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); client_t *c; wibox_t *wibox; /* 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; event_handle_mousegrabber(ev->root_x, ev->root_y, ev->state); if((wibox = wibox_getbywin(ev->event)) || (wibox = wibox_getbywin(ev->child))) { /* If the wibox is child, then x,y are * relative to root window */ if(wibox->sw.window == ev->child) { ev->event_x -= wibox->sw.geometry.x; ev->event_y -= wibox->sw.geometry.y; } /* check if we match a binding on the wibox */ button_array_t *b = &wibox->buttons; for(int i = 0; i < b->len; i++) if(ev->detail == b->tab[i]->button && ev->state == b->tab[i]->mod) switch(ev->response_type) { case XCB_BUTTON_PRESS: if(b->tab[i]->press != LUA_REFNIL) { wibox_push(globalconf.L, wibox); luaA_dofunction(globalconf.L, b->tab[i]->press, 1, 0); } break; case XCB_BUTTON_RELEASE: if(b->tab[i]->release != LUA_REFNIL) { wibox_push(globalconf.L, wibox); luaA_dofunction(globalconf.L, b->tab[i]->release, 1, 0); } break; } /* then try to match a widget binding */ widget_t *w = widget_getbycoords(wibox->position, &wibox->widgets, wibox->sw.geometry.width, wibox->sw.geometry.height, &ev->event_x, &ev->event_y); if(w) { b = &w->buttons; for(int i = 0; i < b->len; i++) if(ev->detail == b->tab[i]->button && ev->state == b->tab[i]->mod) switch(ev->response_type) { case XCB_BUTTON_PRESS: if(b->tab[i]->press != LUA_REFNIL) { wibox_push(globalconf.L, wibox); luaA_dofunction(globalconf.L, b->tab[i]->press, 1, 0); } break; case XCB_BUTTON_RELEASE: if(b->tab[i]->release != LUA_REFNIL) { wibox_push(globalconf.L, wibox); luaA_dofunction(globalconf.L, b->tab[i]->release, 1, 0); } break; } } /* return even if no widget match */ return 0; } else if((c = client_getbywin(ev->event))) { event_handle_mouse_button(c, ev->response_type, ev->detail, ev->state, &c->buttons); xcb_allow_events(globalconf.connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME); } else if(ev->child == XCB_NONE) { for(screen = 0; screen < nb_screen; screen++) if(xutil_screen_get(connection, screen)->root == ev->event) { event_handle_mouse_button(NULL, ev->response_type, ev->detail, ev->state, &globalconf.buttons); return 0; } } return 0; }