Пример #1
0
static dlist *
update_clients(MainWin *mw, dlist *clients, Bool *touched)
{
	dlist *stack, *iter;
	
	stack = dlist_first(wm_get_stack(mw->dpy));
	iter = clients = dlist_first(clients);
	
	if(touched)
		*touched = False;
	
	/* Terminate clients that are no longer managed */
	while(iter)
	{
		ClientWin *cw = (ClientWin *)iter->data;
		if(! dlist_find_data(stack, (void *)cw->client.window))
		{
			dlist *tmp = iter->next;
			clientwin_destroy((ClientWin *)iter->data, True);
			clients = dlist_remove(iter);
			iter = tmp;
			if(touched)
				*touched = True;
			continue;
		}
		clientwin_update(cw);
		iter = iter->next;
	}
	
	/* Add new clients */
	for(iter = dlist_first(stack); iter; iter = iter->next)
	{
		ClientWin *cw = (ClientWin*)dlist_find(clients, clientwin_cmp_func, iter->data);
		if(! cw && (Window)iter->data != mw->window)
		{
			cw = clientwin_create(mw, (Window)iter->data);
			if(! cw)
				continue;
			clients = dlist_add(clients, cw);
			clientwin_update(cw);
			if(touched)
				*touched = True;
		}
	}
	
	dlist_free(stack);
	
	return clients;
}
Пример #2
0
static dlist *
update_clients(MainWin *mw, dlist *clients)
{
	dlist *stack, *iter;
	
	stack = dlist_first(wm_get_stack(mw->dpy));
	iter = clients = dlist_first(clients);

	while(iter)
	{
		ClientWin *cw = (ClientWin *)iter->data;
		if(! dlist_find_data(stack, (void *)cw->client.window))
		{
			dlist *tmp = iter->next;
			clientwin_destroy((ClientWin *)iter->data);
			clients = dlist_remove(iter);
			iter = tmp;
			continue;
		}
		clientwin_update(cw);
		iter = iter->next;
	}
	
	for(iter = dlist_first(stack); iter; iter = iter->next)
	{
		ClientWin *cw = (ClientWin*)dlist_find(clients, clientwin_cmp_func, iter->data);
		if(! cw)
		{
			cw = clientwin_create(mw, (Window)iter->data);
			if(! cw)
				continue;
			clients = dlist_add(clients, cw);
			clientwin_update(cw);
		}
	}
	
	dlist_free(stack);
	
	return clients;
}
Пример #3
0
ClientWin *
clientwin_create(MainWin *mw, Window client) {
	session_t *ps = mw->ps;
	ClientWin *cw = allocchk(malloc(sizeof(ClientWin)));
	{
		static const ClientWin CLIENTWT_DEF = CLIENTWT_INIT;
		memcpy(cw, &CLIENTWT_DEF, sizeof(ClientWin));
	}

	XWindowAttributes attr;
	
	cw->mainwin = mw;
	cw->wid_client = client;
	if (ps->o.includeFrame)
		cw->src.window = wm_find_frame(ps, client);
	if (!cw->src.window)
		cw->src.window = client;
	cw->mini.format = mw->format;
	{
		XSetWindowAttributes sattr = {
			.border_pixel = 0,
			.background_pixel = 0,
			.colormap = mw->colormap,
			.event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask
				| KeyReleaseMask | EnterWindowMask | LeaveWindowMask
				| PointerMotionMask | ExposureMask | FocusChangeMask,
			.override_redirect = ps->o.lazyTrans,
		};
		cw->mini.window = XCreateWindow(ps->dpy,
				(ps->o.lazyTrans ? ps->root : mw->window), 0, 0, 1, 1, 0,
				mw->depth, InputOutput, mw->visual,
				CWColormap | CWBackPixel | CWBorderPixel | CWEventMask | CWOverrideRedirect, &sattr);
	}
	if (!cw->mini.window)
		goto clientwin_create_err;
	
	{
		static const char *PREFIX = "mini window of ";
		const int len = strlen(PREFIX) + 20;
		char *str = allocchk(malloc(len));
		snprintf(str, len, "%s%#010lx", PREFIX, cw->src.window);
		wm_wid_set_info(cw->mainwin->ps, cw->mini.window, str, None);
		free(str);
	}

	// Listen to events on the window. We don't want to miss any changes so
	// this is to be done as early as possible
	XSelectInput(cw->mainwin->ps->dpy, cw->src.window, SubstructureNotifyMask | StructureNotifyMask);

	XGetWindowAttributes(ps->dpy, client, &attr);
	if (IsViewable != attr.map_state)
		goto clientwin_create_err;
	clientwin_update(cw);
	
	// Get window pixmap
	if (ps->o.useNameWindowPixmap) {
		XCompositeRedirectWindow(ps->dpy, cw->src.window, CompositeRedirectAutomatic);
		cw->redirected = true;
		cw->cpixmap = XCompositeNameWindowPixmap(ps->dpy, cw->src.window);
	}
	// Create window picture
	{
		Drawable draw = cw->cpixmap;
		if (!draw) draw = cw->src.window;
		XRenderPictureAttributes pa = { .subwindow_mode = IncludeInferiors };
		cw->origin = XRenderCreatePicture(cw->mainwin->ps->dpy,
				draw, cw->src.format, CPSubwindowMode, &pa);
	}
	if (!cw->origin)
		goto clientwin_create_err;

	XRenderSetPictureFilter(cw->mainwin->ps->dpy, cw->origin, FilterBest, 0, 0);


	return cw;

clientwin_create_err:
	if (cw)
		clientwin_destroy(cw, False);

	return NULL;
}

void
clientwin_update(ClientWin *cw) {
	Window tmpwin;
	XWindowAttributes wattr;

	XGetWindowAttributes(cw->mainwin->ps->dpy, cw->src.window, &wattr);
	XTranslateCoordinates(cw->mainwin->ps->dpy, cw->src.window, wattr.root,
			-wattr.border_width, -wattr.border_width,
			&cw->src.x, &cw->src.y, &tmpwin);
	cw->src.width = wattr.width;
	cw->src.height = wattr.height;
	cw->src.format = XRenderFindVisualFormat(cw->mainwin->ps->dpy, wattr.visual);

	cw->mini.x = cw->mini.y = 0;
	cw->mini.width = cw->mini.height = 1;
}