/** Record that the given drawable contains the pointer. */ void event_drawable_under_mouse(lua_State *L, int ud) { void *d; lua_pushvalue(L, ud); d = luaA_object_ref(L, -1); if (d == globalconf.drawable_under_mouse) { /* Nothing to do */ luaA_object_unref(L, d); return; } if (globalconf.drawable_under_mouse != NULL) { /* Emit leave on previous drawable */ luaA_object_push(L, globalconf.drawable_under_mouse); luaA_object_emit_signal(L, -1, "mouse::leave", 0); lua_pop(L, 1); /* Unref the previous drawable */ luaA_object_unref(L, globalconf.drawable_under_mouse); globalconf.drawable_under_mouse = NULL; } if (d != NULL) { /* Reference the drawable for leave event later */ globalconf.drawable_under_mouse = d; /* Emit enter */ luaA_object_emit_signal(L, ud, "mouse::enter", 0); } }
static void screen_deduplicate(lua_State *L, screen_array_t *screens) { /* Remove duplicate screens */ for(int first = 0; first < screens->len; first++) { screen_t *first_screen = screens->tab[first]; for(int second = 0; second < screens->len; second++) { screen_t *second_screen = screens->tab[second]; if (first == second) continue; if (first_screen->geometry.width < second_screen->geometry.width && first_screen->geometry.height < second_screen->geometry.height) /* Don't drop a smaller screen */ continue; if (first_screen->geometry.x == second_screen->geometry.x && first_screen->geometry.y == second_screen->geometry.y) { /* Found a duplicate */ first_screen->geometry.width = MAX(first_screen->geometry.width, second_screen->geometry.width); first_screen->geometry.height = MAX(first_screen->geometry.height, second_screen->geometry.height); screen_array_take(screens, second); luaA_object_unref(L, second_screen); /* Restart the search */ screen_deduplicate(L, screens); return; } } } }
/** Get or set global mouse bindings. * This binding will be available when you'll click on root window. * \param L The Lua VM state. * \return The number of element pushed on stack. * \luastack * \lparam An array of mouse button bindings objects, or nothing. * \lreturn The array of mouse button bindings objects. */ static int luaA_root_buttons(lua_State *L) { if(lua_gettop(L) == 1) { luaA_checktable(L, 1); foreach(button, globalconf.buttons) luaA_object_unref(globalconf.L, *button); button_array_wipe(&globalconf.buttons); button_array_init(&globalconf.buttons); lua_pushnil(L); while(lua_next(L, 1)) button_array_append(&globalconf.buttons, luaA_object_ref(L, -1)); return 1; } lua_createtable(L, globalconf.buttons.len, 0); for(int i = 0; i < globalconf.buttons.len; i++) { luaA_object_push(L, globalconf.buttons.tab[i]); lua_rawseti(L, -2, i + 1); } return 1; }
/** Get or set global key bindings. * This binding will be available when you'll press keys on root window. * \param L The Lua VM state. * \return The number of element pushed on stack. * \luastack * \lparam An array of key bindings objects, or nothing. * \lreturn The array of key bindings objects of this client. */ static int luaA_root_keys(lua_State *L) { if(lua_gettop(L) == 1) { luaA_checktable(L, 1); foreach(key, globalconf.keys) luaA_object_unref(globalconf.L, *key); key_array_wipe(&globalconf.keys); key_array_init(&globalconf.keys); lua_pushnil(L); while(lua_next(L, 1)) key_array_append(&globalconf.keys, luaA_object_ref_class(L, -1, &key_class)); xcb_screen_t *s = globalconf.screen; xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, s->root, XCB_BUTTON_MASK_ANY); xwindow_grabkeys(s->root, &globalconf.keys); return 1; } lua_createtable(L, globalconf.keys.len, 0); for(int i = 0; i < globalconf.keys.len; i++) { luaA_object_push(L, globalconf.keys.tab[i]); lua_rawseti(L, -2, i + 1); } return 1; }
/** Tag a client with the tag on top of the stack. * \param c the client to tag */ void tag_client(client_t *c) { tag_t *t = luaA_object_ref_class(globalconf.L, -1, &tag_class); /* don't tag twice */ if(is_client_tagged(c, t)) { luaA_object_unref(globalconf.L, t); return; } client_array_append(&t->clients, c); ewmh_client_update_desktop(c); banning_need_update((c)->screen); /* call hook */ if(globalconf.hooks.tagged != LUA_REFNIL) { luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, t); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tagged, 2, 0); } tag_client_emit_signal(globalconf.L, t, c, "tagged"); }
/** Remove a global signal. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lparam A string with the event name. * \lparam The function to call. */ static int luaA_awesome_remove_signal(lua_State *L) { const char *name = luaL_checkstring(L, 1); luaA_checkfunction(L, 2); const void *func = lua_topointer(L, 2); signal_remove(&global_signals, name, func); luaA_object_unref(L, (void *) func); return 0; }
static int luaA_timer_stop(lua_State *L) { atimer_t *timer = luaA_checkudata(L, 1, &timer_class); if(timer->started) { g_source_remove(timer->source_id); luaA_object_unref(L, timer); timer->started = false; } else luaA_warn(L, "timer not started"); return 0; }
/** Untag a client with specified tag. * \param c the client to tag * \param t the tag to tag the client with */ void untag_client(client_t *c, tag_t *t) { for(int i = 0; i < t->clients.len; i++) if(t->clients.tab[i] == c) { lua_State *L = globalconf_get_lua_State(); client_array_take(&t->clients, i); banning_need_update(); ewmh_client_update_desktop(c); tag_client_emit_signal(t, c, "untagged"); luaA_object_unref(L, t); return; } }
/** Tag a client with the tag on top of the stack. * \param L The Lua VM state. * \param c the client to tag */ void tag_client(lua_State *L, client_t *c) { tag_t *t = luaA_object_ref_class(L, -1, &tag_class); /* don't tag twice */ if(is_client_tagged(c, t)) { luaA_object_unref(L, t); return; } client_array_append(&t->clients, c); ewmh_client_update_desktop(c); banning_need_update(); tag_client_emit_signal(t, c, "tagged"); }
/** Remove a tag from screen. Tag must be on a screen and have no clients. * \param tag The tag to remove. */ void tag_remove_from_screen(tag_t *tag) { if(!tag->screen) return; int screen_index = screen_array_indexof(&globalconf.screens, tag->screen); int phys_screen = screen_virttophys(screen_index); tag_array_t *tags = &tag->screen->tags; for(int i = 0; i < tags->len; i++) if(tags->tab[i] == tag) { tag_array_take(tags, i); break; } /* tag was selected? If so, reban */ if(tag->selected) banning_need_update(tag->screen); ewmh_update_net_numbers_of_desktop(phys_screen); ewmh_update_net_desktop_names(phys_screen); /* call hook */ if(globalconf.hooks.tags != LUA_REFNIL) { lua_pushnumber(globalconf.L, screen_index + 1); luaA_object_push(globalconf.L, tag); lua_pushliteral(globalconf.L, "remove"); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tags, 3, 0); } screen_t *s = tag->screen; tag->screen = NULL; luaA_object_push(globalconf.L, tag); luaA_object_emit_signal(globalconf.L, -1, "property::screen", 0); screen_emit_signal(globalconf.L, s, "tag::detach", 1); luaA_object_unref(globalconf.L, tag); }
/** Untag a client with specified tag. * \param c the client to tag * \param t the tag to tag the client with */ void untag_client(client_t *c, tag_t *t) { for(int i = 0; i < t->clients.len; i++) if(t->clients.tab[i] == c) { client_array_take(&t->clients, i); banning_need_update((c)->screen); ewmh_client_update_desktop(c); /* call hook */ if(globalconf.hooks.tagged != LUA_REFNIL) { luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, t); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tagged, 2, 0); } tag_client_emit_signal(globalconf.L, t, c, "untagged"); luaA_object_unref(globalconf.L, t); return; } }
void drawin_unref_simplified(drawin_t **item) { luaA_object_unref(globalconf.L, *item); }
/** Delete a widget node structure. * \param node The node to destroy. */ void widget_node_delete(widget_node_t *node) { luaA_object_unref(globalconf.L, node->widget); }
void tag_unref_simplified(tag_t **tag) { lua_State *L = globalconf_get_lua_State(); luaA_object_unref(L, *tag); }
void tag_unref_simplified(tag_t **tag) { luaA_object_unref(globalconf.L, *tag); }