static void plot_delete(plot_t *g) { p_delete(&g->title); p_delete(&g->lines); p_delete(&g->values); }
static void a_xcb_check_cb(EV_P_ ev_check *w, int revents) { xcb_generic_event_t *mouse = NULL, *event; while((event = xcb_poll_for_event(globalconf.connection))) { /* We will treat mouse events later. * We cannot afford to treat all mouse motion events, * because that would be too much CPU intensive, so we just * take the last we get after a bunch of events. */ if(XCB_EVENT_RESPONSE_TYPE(event) == XCB_MOTION_NOTIFY) { p_delete(&mouse); mouse = event; } else { event_handle(event); p_delete(&event); } } if(mouse) { event_handle(mouse); p_delete(&mouse); } }
/** Remove systray information in X. * \param phys_screen Physical screen. */ void systray_cleanup(int phys_screen) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = false; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); }
/** Check whether a composite manager is running. * \return True if such a manager is running. */ static bool composite_manager_running(void) { xcb_intern_atom_reply_t *atom_r; xcb_get_selection_owner_reply_t *selection_r; char *atom_name; bool result; if(!(atom_name = xcb_atom_name_by_screen("_NET_WM_CM", globalconf.default_screen))) { warn("error getting composite manager atom"); return false; } atom_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL); p_delete(&atom_name); if(!atom_r) return false; selection_r = xcb_get_selection_owner_reply(globalconf.connection, xcb_get_selection_owner_unchecked(globalconf.connection, atom_r->atom), NULL); p_delete(&atom_r); result = selection_r != NULL && selection_r->owner != XCB_NONE; p_delete(&selection_r); return result; }
/** Get the pointer position. * \param window The window to get position on. * \param x will be set to the Pointer-x-coordinate relative to window * \param y will be set to the Pointer-y-coordinate relative to window * \param child Will be set to the window under the pointer. * \param mask will be set to the current buttons state * \return true on success, false if an error occurred **/ bool mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask) { xcb_query_pointer_cookie_t query_ptr_c; xcb_query_pointer_reply_t *query_ptr_r; query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, window); query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL); if(!query_ptr_r || !query_ptr_r->same_screen) { p_delete(&query_ptr_r); return false; } *x = query_ptr_r->win_x; *y = query_ptr_r->win_y; if(mask) *mask = query_ptr_r->mask; if(child) *child = query_ptr_r->child; p_delete(&query_ptr_r); return true; }
/** Remove systray information in X. */ void systray_cleanup(void) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); xcb_unmap_window(globalconf.connection, globalconf.systray.window); }
/** Initialize systray information in X. */ void systray_init(void) { xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; xcb_screen_t *xscreen = globalconf.screen; globalconf.systray.window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, xscreen->root_depth, globalconf.systray.window, xscreen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen); if(!atom_name) fatal("error getting systray atom name"); atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL); if(!atom_systray_r) fatal("error getting systray atom"); globalconf.systray.atom = atom_systray_r->atom; p_delete(&atom_systray_r); }
/** Initialize systray information in X. * \param phys_screen Physical screen. */ void systray_init(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); globalconf.screens[phys_screen].systray.window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, xscreen->root_depth, globalconf.screens[phys_screen].systray.window, xscreen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** Destroy definitively a graph widget. * \param widget Who slay. */ static void graph_destructor(widget_t *widget) { graph_data_t *d = widget->data; plot_array_wipe(&d->plots); p_delete(&d->draw_from); p_delete(&d->draw_to); p_delete(&d); }
/** Register systray in X. * \param phys_screen Physical screen. */ void systray_register(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Set registered even if it fails to don't try again unless forced */ if(globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = true; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens.tab[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens.tab[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** The map request event handler. * \param ev The event. */ static void event_handle_maprequest(xcb_map_request_event_t *ev) { client_t *c; xcb_get_window_attributes_cookie_t wa_c; xcb_get_window_attributes_reply_t *wa_r; xcb_get_geometry_cookie_t geom_c; xcb_get_geometry_reply_t *geom_r; wa_c = xcb_get_window_attributes_unchecked(globalconf.connection, ev->window); if(!(wa_r = xcb_get_window_attributes_reply(globalconf.connection, wa_c, NULL))) return; if(wa_r->override_redirect) goto bailout; if(xembed_getbywin(&globalconf.embedded, ev->window)) { xcb_map_window(globalconf.connection, ev->window); xembed_window_activate(globalconf.connection, ev->window); } else if((c = client_getbywin(ev->window))) { /* Check that it may be visible, but not asked to be hidden */ if(client_on_selected_tags(c) && !c->hidden) { lua_State *L = globalconf_get_lua_State(); luaA_object_push(L, c); client_set_minimized(L, -1, false); lua_pop(L, 1); /* it will be raised, so just update ourself */ client_raise(c); } } else { geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window); if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL))) { goto bailout; } client_manage(ev->window, geom_r, wa_r); p_delete(&geom_r); } bailout: p_delete(&wa_r); }
/** Get a window state (WM_STATE). * \param cookie The cookie. * \return The current state of the window, or 0 on error. */ uint32_t window_state_get_reply(xcb_get_property_cookie_t cookie, int* pStateFound) { /* This is a bug fixed in updated versions of awesome already */ /* setting the result to 0 maps to XCB_WM_STATE_WITHDRAWN which */ /* causes a problem in scan. The default value should be XCB_WM_STATE_NORMAL */ /* returning 0 inside pStateFound to indicate to the caller that */ /* it was not found */ uint32_t result = XCB_WM_STATE_NORMAL; if (pStateFound){ *pStateFound = 0; } xcb_get_property_reply_t *prop_r; if((prop_r = xcb_get_property_reply(globalconf.connection, cookie, NULL))) { if(xcb_get_property_value_length(prop_r)){ result = *(uint32_t *) xcb_get_property_value(prop_r); if (pStateFound){ *pStateFound = 1; } } p_delete(&prop_r); } return result; }
/** Update the list of supported protocols for a client. * \param c The client. * \param reply The xcb property reply. */ void property_update_wm_protocols(client_t *c, xcb_get_property_reply_t *reply) { xcb_icccm_get_wm_protocols_reply_t protocols; xcb_get_property_reply_t *reply_copy; if(reply) { reply_copy = p_dup(reply, 1); if(!xcb_icccm_get_wm_protocols_from_reply(reply_copy, &protocols)) { p_delete(&reply_copy); return; } } else { /* If this fails for any reason, we still got the old value */ if(!xcb_icccm_get_wm_protocols_reply(globalconf.connection, xcb_icccm_get_wm_protocols_unchecked(globalconf.connection, c->window, WM_PROTOCOLS), &protocols, NULL)) return; } xcb_icccm_get_wm_protocols_reply_wipe(&c->protocols); memcpy(&c->protocols, &protocols, sizeof(protocols)); }
void property_update_net_wm_pid(client_t *c, xcb_get_property_reply_t *reply) { bool no_reply = !reply; if(no_reply) { xcb_get_property_cookie_t prop_c = xcb_get_property_unchecked(globalconf.connection, false, c->window, _NET_WM_PID, XCB_ATOM_CARDINAL, 0L, 1L); reply = xcb_get_property_reply(globalconf.connection, prop_c, NULL); } if(reply && reply->value_len) { uint32_t *rdata = xcb_get_property_value(reply); if(rdata) { luaA_object_push(globalconf.L, c); client_set_pid(globalconf.L, -1, *rdata); lua_pop(globalconf.L, 1); } } if(no_reply) p_delete(&reply); }
/** Grab the mouse. * \param cursor The cursor to use while grabbing. * \return True if mouse was grabbed. */ static bool mousegrabber_grab(xcb_cursor_t cursor) { xcb_window_t root = globalconf.screen->root; for(int i = 1000; i; i--) { xcb_grab_pointer_reply_t *grab_ptr_r; xcb_grab_pointer_cookie_t grab_ptr_c = xcb_grab_pointer_unchecked(globalconf.connection, false, root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, cursor, XCB_CURRENT_TIME); if((grab_ptr_r = xcb_grab_pointer_reply(globalconf.connection, grab_ptr_c, NULL))) { p_delete(&grab_ptr_r); return true; } usleep(1000); } return false; }
/** Delete a textbox widget. * \param w The widget to destroy. */ static void textbox_destructor(widget_t *w) { textbox_data_t *d = w->data; draw_text_context_wipe(&d->data); p_delete(&d); }
/** Handle systray message. * \param ev The event. * \return 0 on no error. */ int systray_process_client_message(xcb_client_message_event_t *ev) { int screen_nbr = 0, ret = 0; xcb_get_geometry_cookie_t geom_c; xcb_get_geometry_reply_t *geom_r; xcb_screen_iterator_t iter; switch(ev->data.data32[1]) { case SYSTEM_TRAY_REQUEST_DOCK: geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window); if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL))) return -1; for(iter = xcb_setup_roots_iterator(xcb_get_setup(globalconf.connection)), screen_nbr = 0; iter.rem && iter.data->root != geom_r->root; xcb_screen_next (&iter), ++screen_nbr); p_delete(&geom_r); ret = systray_request_handle(ev->data.data32[2], screen_nbr, NULL); break; } return ret; }
static void drawin_wipe(drawin_t *w) { /* The drawin must already be unmapped, else it * couldn't be garbage collected -> no unmap needed */ p_delete(&w->cursor); if(w->surface) { /* Make sure that cairo knows that this surface can't be unused anymore. * This is needed since lua could still have a reference to it. */ cairo_surface_finish(w->surface); cairo_surface_destroy(w->surface); w->surface = NULL; } if(w->window) { /* Activate BMA */ client_ignore_enterleave_events(); /* Make sure we don't accidentally kill the systray window */ drawin_systray_kickout(w); xcb_destroy_window(globalconf.connection, w->window); /* Deactivate BMA */ client_restore_enterleave_events(); w->window = XCB_NONE; } if(w->pixmap) { xcb_free_pixmap(globalconf.connection, w->pixmap); w->pixmap = XCB_NONE; } }
void atoms_init(xcb_connection_t *conn) { unsigned int i; xcb_intern_atom_cookie_t cs[countof(ATOM_LIST)]; xcb_intern_atom_reply_t *r; /* Create the atom and get the reply in a XCB way (e.g. send all * the requests at the same time and then get the replies) */ for(i = 0; i < countof(ATOM_LIST); i++) cs[i] = xcb_intern_atom_unchecked(conn, false, a_strlen(ATOM_LIST[i].name), ATOM_LIST[i].name); for(i = 0; i < countof(ATOM_LIST); i++) { if(!(r = xcb_intern_atom_reply(conn, cs[i], NULL))) /* An error occured, get reply for next atom */ continue; *ATOM_LIST[i].atom = r->atom; p_delete(&r); } }
/** Get the opacity of a window. * \param cookie A cookie for a reply to a get property request for _NET_WM_WINDOW_OPACITY. * \return The opacity, between 0 and 1. */ double xwindow_get_opacity_from_cookie(xcb_get_property_cookie_t cookie) { xcb_get_property_reply_t *prop_r = xcb_get_property_reply(globalconf.connection, cookie, NULL); if(prop_r && prop_r->value_len && prop_r->format == 32) { uint32_t value = *(uint32_t *) xcb_get_property_value(prop_r); p_delete(&prop_r); return (double) value / (double) 0xffffffff; } p_delete(&prop_r); return -1; }
/** Garbage collect a tag. * \param L The Lua VM state. * \return 0. */ static int luaA_tag_gc(lua_State *L) { tag_t *tag = luaA_checkudata(L, 1, &tag_class); client_array_wipe(&tag->clients); p_delete(&tag->name); return luaA_object_gc(L); }
/** Garbage collect a tag. * \param L The Lua VM state. * \return 0. */ static int luaA_tag_gc(lua_State *L) { tag_t *tag = luaL_checkudata(L, 1, "tag"); client_array_wipe(&tag->clients); p_delete(&tag->name); return 0; }
/** XRandR event handler for RRNotify subtype XRROutputChangeNotifyEvent */ static void event_handle_randr_output_change_notify(xcb_randr_notify_event_t *ev) { if(ev->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { xcb_randr_output_t output = ev->u.oc.output; uint8_t connection = ev->u.oc.connection; char *output_name = NULL; const char *connection_str = NULL; xcb_randr_get_output_info_reply_t *info = NULL; lua_State *L = globalconf_get_lua_State(); info = xcb_randr_get_output_info_reply(globalconf.connection, xcb_randr_get_output_info_unchecked(globalconf.connection, output, XCB_CURRENT_TIME), NULL); if(!info) return; output_name = p_dup((char *)xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info)); switch(connection) { case XCB_RANDR_CONNECTION_CONNECTED: connection_str = "Connected"; break; case XCB_RANDR_CONNECTION_DISCONNECTED: connection_str = "Disconnected"; break; default: connection_str = "Unknown"; break; } lua_pushstring(L, output_name); lua_pushstring(L, connection_str); signal_object_emit(L, &global_signals, "screen::change", 2); p_delete(&output_name); p_delete(&info); /* The docs for RRSetOutputPrimary say we get this signal */ screen_update_primary(); } }
/** Delete a font. * \param font Font to delete. */ void draw_font_delete(font_t **font) { if(*font) { pango_font_description_free((*font)->desc); p_delete(font); } }
static int luaA_key_get_keysym(lua_State *L, keyb_t *k) { char *name = get_keysym_name(k->keysym); if(!name) return 0; lua_pushstring(L, name); p_delete(&name); return 1; }
static void screen_scan_randr_monitors(lua_State *L, screen_array_t *screens) { xcb_randr_get_monitors_cookie_t monitors_c = xcb_randr_get_monitors(globalconf.connection, globalconf.screen->root, 1); xcb_randr_get_monitors_reply_t *monitors_r = xcb_randr_get_monitors_reply(globalconf.connection, monitors_c, NULL); xcb_randr_monitor_info_iterator_t monitor_iter; if (monitors_r == NULL) { warn("RANDR GetMonitors failed; this should not be possible"); return; } for(monitor_iter = xcb_randr_get_monitors_monitors_iterator(monitors_r); monitor_iter.rem; xcb_randr_monitor_info_next(&monitor_iter)) { screen_t *new_screen; screen_output_t output; xcb_randr_output_t *randr_outputs; xcb_get_atom_name_cookie_t name_c; xcb_get_atom_name_reply_t *name_r; if(!xcb_randr_monitor_info_outputs_length(monitor_iter.data)) continue; new_screen = screen_add(L, screens); new_screen->geometry.x = monitor_iter.data->x; new_screen->geometry.y = monitor_iter.data->y; new_screen->geometry.width = monitor_iter.data->width; new_screen->geometry.height = monitor_iter.data->height; new_screen->xid = monitor_iter.data->name; output.mm_width = monitor_iter.data->width_in_millimeters; output.mm_height = monitor_iter.data->height_in_millimeters; name_c = xcb_get_atom_name_unchecked(globalconf.connection, monitor_iter.data->name); name_r = xcb_get_atom_name_reply(globalconf.connection, name_c, NULL); if (name_r) { const char *name = xcb_get_atom_name_name(name_r); size_t len = xcb_get_atom_name_name_length(name_r); output.name = memcpy(p_new(char *, len + 1), name, len); output.name[len] = '\0'; p_delete(&name_r); } else { output.name = a_strdup("unknown"); } randr_output_array_init(&output.outputs); randr_outputs = xcb_randr_monitor_info_outputs(monitor_iter.data); for(int i = 0; i < xcb_randr_monitor_info_outputs_length(monitor_iter.data); i++) { randr_output_array_append(&output.outputs, randr_outputs[i]); } screen_output_array_append(&new_screen->outputs, output); }
/** Remove a client from stack history. * \param c The client. */ void stack_client_delete(client_t *c) { client_node_t *node = client_node_client_getby(globalconf.stack, c); if(node) { client_node_list_detach(&globalconf.stack, node); p_delete(&node); ewmh_update_net_client_list_stacking(c->phys_screen); } }
/** Update leader hint of a client. * \param c The client. * \param cookie Cookie returned by property_get_wm_client_leader. */ void property_update_wm_client_leader(client_t *c, xcb_get_property_cookie_t cookie) { xcb_get_property_reply_t *reply; void *data; reply = xcb_get_property_reply(globalconf.connection, cookie, NULL); if(reply && reply->value_len && (data = xcb_get_property_value(reply))) c->leader_window = *(xcb_window_t *) data; p_delete(&reply); }
/** Register a new xproperty. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lparam The name of the X11 property * \lparam One of "string", "number" or "boolean" */ int luaA_register_xproperty(lua_State *L) { const char *name; struct xproperty property; struct xproperty *found; const char *const args[] = { "string", "number", "boolean" }; xcb_intern_atom_reply_t *atom_r; int type; name = luaL_checkstring(L, 1); type = luaL_checkoption(L, 2, NULL, args); if (type == 0) property.type = PROP_STRING; else if (type == 1) property.type = PROP_NUMBER; else property.type = PROP_BOOLEAN; atom_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(name), name), NULL); if(!atom_r) return 0; property.atom = atom_r->atom; p_delete(&atom_r); found = xproperty_array_lookup(&globalconf.xproperties, &property); if(found) { /* Property already registered */ if(found->type != property.type) return luaL_error(L, "xproperty '%s' already registered with different type", name); } else { buffer_t buf; buffer_inita(&buf, a_strlen(name) + a_strlen("xproperty::") + 1); buffer_addf(&buf, "xproperty::%s", name); property.name = a_strdup(name); xproperty_array_insert(&globalconf.xproperties, property); signal_add(&window_class.signals, buf.s); signal_add(&global_signals, buf.s); buffer_wipe(&buf); } return 0; }
/** Tag newindex. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_tag_newindex(lua_State *L) { size_t len; tag_t *tag = luaL_checkudata(L, 1, "tag"); const char *attr = luaL_checklstring(L, 2, &len); switch(a_tokenize(attr, len)) { int screen; case A_TK_NAME: { const char *buf = luaL_checklstring(L, 3, &len); p_delete(&tag->name); a_iso2utf8(buf, len, &tag->name, NULL); } break; case A_TK_SCREEN: if(!lua_isnil(L, 3)) { screen = luaL_checknumber(L, 3) - 1; luaA_checkscreen(screen); } else screen = SCREEN_UNDEF; if(tag->screen != SCREEN_UNDEF) tag_remove_from_screen(tag); if(screen != SCREEN_UNDEF) { /* push tag on top of the stack */ lua_pushvalue(L, 1); tag_append_to_screen(&globalconf.screens[screen]); } break; case A_TK_SELECTED: if(tag->screen != SCREEN_UNDEF) tag_view(tag, luaA_checkboolean(L, 3)); return 0; default: return 0; } if(tag->screen != SCREEN_UNDEF && tag->selected) globalconf.screens[tag->screen].need_arrange = true; return 0; }