void ewmh_update_clist(void) { int i, n = 0; Window *data = _malloc(cn * sizeof(Window)); for(i = cn - 1; i >= 0; i--) if(!(clients[i]->flags & DONT_LIST)) data[n++] = clients[i]->window; XChangeProperty(dpy, root, ewmh_atoms[NET_CLIENT_LIST], XA_WINDOW, 32, PropModeReplace, (unsigned char *) data, n); free(data); ewmh_update_stacking(); ewmh_update_strut(); }
void cfg_reinitialize(void) { int i; #ifdef USE_XFT int xft = xftfont ? 1 : 0; #endif /* free things from old configuration */ XFreeGC(dpy, gc); XFreeGC(dpy, igc); XFreeGC(dpy, bgc); XFreeGC(dpy, ibgc); keys_free(); /* read config again */ cfg_read(0); /* update some things */ p_attr.background_pixel = fg.pixel; p_attr.border_pixel = ibfg.pixel; select_root_events(); /* update clients */ for(i = 0; i < cn; i++) { #ifdef USE_XFT if(xftfont && !xft) clients[i]->wlist_draw = XftDrawCreate(dpy, clients[i]->wlist_item, visual, colormap); if(!xftfont && xft) { XftDrawDestroy(clients[i]->title_draw); XftDrawDestroy(clients[i]->wlist_draw); } #endif XDestroyWindow(dpy, clients[i]->button_parent_left); XDestroyWindow(dpy, clients[i]->button_parent_right); free((void *) clients[i]->buttons); clients[i]->flags ^= clients[i]->flags & HAS_BUTTONS; buttons_create(clients[i]); /* buttons are now on top of the client window */ XRaiseWindow(dpy, clients[i]->window); /* hence this line */ client_update(clients[i]); client_update_name(clients[i]); (clients[i] == current) ? client_set_bg(clients[i], bg, fg) : client_set_bg(clients[i], ibg, ifg); if(clients[i]->flags & IS_TASKBAR) client_set_layer(clients[i], taskbar_ontop ? TOP : NORMAL); XUngrabButton(dpy, AnyButton, AnyModifier, clients[i]->parent); client_grab_buttons(clients[i]); if(clients[i]->flags & FULLSCREEN && clients[i]->layer <= NORMAL && fullscreen_stacking != FS_NORMAL) client_update_layer(clients[i], (fullscreen_stacking == FS_ALWAYS_ONTOP) ? NORMAL : TOP); if(clients[i]->flags & HAS_BORDER) XSetWindowBorderWidth(dpy, clients[i]->parent, border_width); ewmh_update_extents(clients[i]); } ewmh_update_number_of_desktops(); ewmh_update_geometry(); ewmh_update_strut(); }
/** Return window struts (reserved space at the edge of the screen). * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_window_struts(lua_State *L) { window_t *window = luaA_checkudata(L, 1, &window_class); if(lua_gettop(L) == 2) { luaA_tostrut(L, 2, &window->strut); ewmh_update_strut(window->window, &window->strut); luaA_object_emit_signal(L, 1, "property::struts", 0); /* We don't know the correct screen, update them all */ foreach(s, globalconf.screens) screen_update_workarea(*s); } return luaA_pushstrut(L, window->strut); }
/** Return window struts (reserved space at the edge of the screen). * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_window_struts(lua_State *L) { window_t *window = luaA_checkudata(L, 1, &window_class); if(lua_gettop(L) == 2) { luaA_tostrut(L, 2, &window->strut); ewmh_update_strut(window->window, &window->strut); luaA_object_emit_signal(L, 1, "property::struts", 0); /* FIXME: Only emit if the workarea actually changed * (= window is visible, only on the right screen)? */ foreach(s, globalconf.screens) screen_emit_signal(L, s, "property::workarea", 0); } return luaA_pushstrut(L, window->strut); }
void screens_get(void) { #if defined(USE_XINERAMA) || defined(DEBUG) int i; #endif #ifdef USE_XINERAMA int event, error; XineramaScreenInfo *screeninfo; if(XineramaQueryExtension(dpy, &event, &error)) { screeninfo = XineramaQueryScreens(dpy, &nscreens); if(nscreens) { screens = _realloc((void *) screens, nscreens * sizeof(screen_dimensions)); for(i = 0; i < nscreens; i++) { screens[i].x = screeninfo[i].x_org; screens[i].y = screeninfo[i].y_org; screens[i].width = screeninfo[i].width; screens[i].height = screeninfo[i].height; } XFree((void *) screeninfo); goto ok; } } #endif nscreens = 1; screens = _realloc(screens, sizeof(screen_dimensions)); screens[0].x = 0; screens[0].y = 0; screens[0].width = XDisplayWidth(dpy, screen); screens[0].height = XDisplayHeight(dpy, screen); ok: screens_update_current(); ewmh_update_geometry(); ewmh_update_strut(); if(wlist_screen > nscreens) wlist_screen = nscreens - 1; #ifdef DEBUG printf(NAME ": screens_get(): loaded screen info\n"); for(i = 0; i < nscreens; i++) printf("\tscreen %i: %ix%i+%i+%i\n", i, screens[i].width, screens[i].height, screens[i].x, screens[i].y); #endif }
bool ewmh_handle_event(XEvent *ev) { client *c; int i, j, xo, yo; long extents[4]; Atom rt; int rf; unsigned long nir, bar; switch(ev->type) { case ClientMessage: c = owner(ev->xclient.window); if(ev->xclient.message_type == ewmh_atoms[NET_WM_MOVERESIZE]) { if(c) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_MOVERESIZE\n"); #endif if(ev->xclient.data.l[2] == NET_WM_MOVERESIZE_MOVE || ev->xclient.data.l[2] == NET_WM_MOVERESIZE_MOVE_KEYBOARD) { client_focus(c, true); xo = client_width_total_intern(c) / 2; yo = client_height_total_intern(c) / 2; XWarpPointer(dpy, None, c->parent, 0, 0, 0, 0, xo, yo); drag_start(A_MOVE, AnyButton, client_x(c) + xo, client_y(c) + yo); } if(ev->xclient.data.l[2] == NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT || ev->xclient.data.l[2] == NET_WM_MOVERESIZE_SIZE_KEYBOARD) { client_focus(c, true); drag_start(A_RESIZE, AnyButton, ev->xclient.data.l[0], ev->xclient.data.l[1]); } } return true; } if(ev->xclient.message_type == ewmh_atoms[NET_CLOSE_WINDOW]) { if(c) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_CLOSE_WINDOW\n"); #endif delete_window(c); } return true; } if(ev->xclient.message_type == ewmh_atoms[NET_ACTIVE_WINDOW]) { if(c) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_ACTIVE_WINDOW\n"); #endif if(c->flags & ICONIC) client_restore(c); else { if(c->desktop != desktop && c->desktop != STICKY) desktop_goto(c->desktop); client_raise(c); } if(evh != wlist_handle_event) client_focus(c, true); } return true; } if(ev->xclient.message_type == ewmh_atoms[NET_RESTACK_WINDOW]) { if(c && ev->xclient.data.l[1] == None) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_RESTACK_WINDOW\n"); #endif client_raise(c); } /* schould also add code for handling this when a sibling window is passed */ /* but we schould find/create a way to test this first */ return true; } if(ev->xclient.message_type == ewmh_atoms[NET_WM_STATE]) { if(c) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_STATE\n"); #endif j = 0; for(i = 1; i < 3; i++) { if(((Atom) ev->xclient.data.l[i]) == ewmh_atoms[NET_WM_STATE_MAXIMIZED_HORZ]) j |= MAXIMIZED_L | MAXIMIZED_R; if(((Atom) ev->xclient.data.l[i]) == ewmh_atoms[NET_WM_STATE_MAXIMIZED_VERT]) j |= MAXIMIZED_T | MAXIMIZED_B; } if(j) client_toggle_state(c, j); if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_FULLSCREEN] && (ev->xclient.data.l[0] == NET_WM_STATE_TOGGLE || (ev->xclient.data.l[0] == NET_WM_STATE_ADD && !(c->flags & FULLSCREEN)) || (ev->xclient.data.l[0] == NET_WM_STATE_REMOVE && (c->flags & FULLSCREEN)))) client_fullscreen(c); if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_ABOVE]) { if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_ADD]) client_set_layer(c, TOP); if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_REMOVE] && c->layer == TOP) client_set_layer(c, NORMAL); if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_TOGGLE]) client_set_layer(c, (c->layer == TOP) ? NORMAL : TOP); } if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_BELOW]) { if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_ADD]) client_set_layer(c, BOTTOM); if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_REMOVE] && c->layer == BOTTOM) client_set_layer(c, NORMAL); if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_TOGGLE]) client_set_layer(c, (c->layer == BOTTOM) ? NORMAL : BOTTOM); } return true; } } if(ev->xclient.message_type == ewmh_atoms[NET_CURRENT_DESKTOP]) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_CURRENT_DESKTOP\n"); #endif desktop_goto(ev->xclient.data.l[0]); return true; } if(ev->xclient.message_type == ewmh_atoms[NET_WM_DESKTOP]) { if(c && ev->xclient.data.l[0] >= STICKY) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_DESKTOP\n"); #endif client_to_desktop(c, (ev->xclient.data.l[0] <= dc) ? ev->xclient.data.l[0] : dc - 1); } return true; } if(ev->xclient.message_type == ewmh_atoms[NET_REQUEST_FRAME_EXTENTS]) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_REQUEST_FRAME_EXTENTS\n"); #endif extents[0] = border_width; extents[1] = border_width; extents[2] = border_width + title_height; extents[3] = border_width; XChangeProperty(dpy, ev->xclient.window, ewmh_atoms[NET_FRAME_EXTENTS], XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &extents, 4); return true; } if(ev->xclient.message_type == ewmh_atoms[NET_SHOWING_DESKTOP]) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_SHOWING_DESKTOP\n"); #endif client_iconify_all(); return true; } break; case PropertyNotify: if(ev->xproperty.atom == ewmh_atoms[NET_WM_STRUT_PARTIAL] || ev->xproperty.atom == ewmh_atoms[NET_WM_STRUT]) { #ifdef DEBUG_EVENTS printf(NAME ": ewmh_handle_event(): handling PropertyNotify event (_NET_WM_STRUT or _NET_WM_STRUT_PARTIAL changed)\n"); #endif ewmh_update_strut(); return true; } c = owner(ev->xproperty.window); if(c && ev->xproperty.atom == ewmh_atoms[NET_WM_NAME]) { if(XGetWindowProperty(dpy, c->window, ewmh_atoms[NET_WM_NAME], 0, 1024, False, xa_utf8_string, &rt, &rf, &nir, &bar, (unsigned char **) &c->ewmh_name) != Success) c->ewmh_name = NULL; else client_update_name(c); return true; } break; } return false; }