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; }
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; }
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; }