Пример #1
0
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();
}
Пример #2
0
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();
}
Пример #3
0
/** 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);
}
Пример #4
0
/** 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);
}
Пример #5
0
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
}
Пример #6
0
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;
}