static dlist * skippy_run(MainWin *mw, dlist *clients, int force, Window focus, Window leader, Bool all_xin) { unsigned int width, height, tree_count, u; float factor; int xoff, yoff; XEvent ev; int die = 0; dlist *iter, *tmp; Window dummy_w, *tree_windows; CARD32 desktop = wm_get_current_desktop(mw->dpy); Bool refocus = False; /* Update the main window's geometry (and Xinerama info if applicable) */ mainwin_update(mw); #ifdef XINERAMA if(all_xin) mw->xin_active = 0; #else /* ! XINERAMA */ if(all_xin); #endif /* XINERAMA */ /* Update the client table, pick the ones we want and sort them */ clients = update_clients(mw, clients); tmp = dlist_first(dlist_find_all(clients, (dlist_match_func)clientwin_validate_func, &desktop)); if(leader != None) { mw->cod = dlist_first(dlist_find_all(tmp, clientwin_check_group_leader_func, (void*)&leader)); dlist_free(tmp); } else mw->cod = tmp; if(! mw->cod) return clients; dlist_sort(mw->cod, clientwin_sort_func, 0); /* Move the mini windows around */ layout_run(mw, mw->cod, &width, &height); factor = (float)(mw->width - 100) / width; if(factor * height > mw->height - 100) factor = (float)(mw->height - 100) / height; xoff = (mw->width - (float)width * factor) / 2; yoff = (mw->height - (float)height * factor) / 2; for(iter = mw->cod; iter; iter = iter->next) clientwin_move((ClientWin*)iter->data, factor, xoff, yoff); /* Get the currently focused window and select which mini-window to focus */ iter = dlist_find(mw->cod, clientwin_cmp_func, (void *)focus); if(! iter) iter = mw->cod; mw->focus = (ClientWin*)iter->data; mw->focus->focused = 1; /* Save the stacking tree */ XQueryTree(mw->dpy, mw->root, &dummy_w, &dummy_w, &tree_windows, &tree_count); mw->stack_touched = False; /* Map the client windows */ for(iter = mw->cod; iter; iter = iter->next) clientwin_map((ClientWin*)iter->data, force); XWarpPointer(mw->dpy, None, mw->focus->mini.window, 0, 0, 0, 0, mw->focus->mini.width / 2, mw->focus->mini.height / 2); /* Restore the stacking order (using XRestackWindows seems like a bad idea) */ if(mw->stack_touched) for(u = 0; u < tree_count; ++u) XRaiseWindow(mw->dpy, tree_windows[u]); XFree(tree_windows); /* Map the main window and run our event loop */ mainwin_map(mw); while(! die) { XNextEvent(mw->dpy, &ev); if(ev.type == KeyRelease && ev.xkey.keycode == mw->key_q) { DIE_NOW = 1; break; } else if(ev.type == DestroyNotify || ev.type == UnmapNotify) { dlist *iter = dlist_find(clients, clientwin_cmp_func, (void *)ev.xany.window); if(iter) { ClientWin *cw = (ClientWin *)iter->data; clients = dlist_first(dlist_remove(iter)); iter = dlist_find(mw->cod, clientwin_cmp_func, (void *)ev.xany.window); if(iter) mw->cod = dlist_first(dlist_remove(iter)); clientwin_destroy(cw); if(! mw->cod) { die = 1; break; } } } else if(ev.xany.window == mw->window) die = mainwin_handle(mw, &ev); else if(ev.type == PropertyNotify && (ev.xproperty.atom == ESETROOT_PMAP_ID || ev.xproperty.atom == _XROOTPMAP_ID)) mainwin_update_background(mw); else if(mw->tooltip && ev.xany.window == mw->tooltip->window) tooltip_handle(mw->tooltip, &ev); else if(ev.type == KeyRelease && ev.xkey.keycode == mw->key_escape) { refocus = True; break; } else { dlist *iter; for(iter = mw->cod; iter; iter = iter->next) { ClientWin *cw = (ClientWin *)iter->data; if(cw->mini.window == ev.xany.window) { die = clientwin_handle(cw, &ev); break; } } } } /* Unmap the main window and clean up */ mainwin_unmap(mw); XFlush(mw->dpy); REDUCE(clientwin_unmap((ClientWin*)iter->data), mw->cod); dlist_free(mw->cod); mw->cod = 0; if(die == 2) DIE_NOW = 1; if(refocus) XSetInputFocus(mw->dpy, focus, RevertToPointerRoot, CurrentTime); return clients; }
static dlist * skippy_run(MainWin *mw, dlist *clients, Window focus, Window leader, Bool all_xin) { XEvent ev; int die = 0; Bool refocus = False; int last_rendered; /* Update the main window's geometry (and Xinerama info if applicable) */ mainwin_update(mw); #ifdef XINERAMA if(all_xin) mw->xin_active = 0; #else /* ! XINERAMA */ if(all_xin); #endif /* XINERAMA */ /* Map the main window and run our event loop */ if(mw->lazy_trans) { mainwin_map(mw); XFlush(mw->dpy); } clients = do_layout(mw, clients, focus, leader); if(! mw->cod) return clients; /* Map the main window and run our event loop */ if(! mw->lazy_trans) mainwin_map(mw); last_rendered = time_in_millis(); while(! die) { int i, j, now, timeout; int move_x = -1, move_y = -1; struct pollfd r_fd; XFlush(mw->dpy); r_fd.fd = ConnectionNumber(mw->dpy); r_fd.events = POLLIN; if(mw->poll_time > 0) timeout = MAX(0, mw->poll_time + last_rendered - time_in_millis()); else timeout = -1; i = poll(&r_fd, 1, timeout); now = time_in_millis(); if(now >= last_rendered + mw->poll_time) { REDUCE(if( ((ClientWin*)iter->data)->damaged ) clientwin_repair(iter->data), mw->cod); last_rendered = now; } i = XPending(mw->dpy); for(j = 0; j < i; ++j) { XNextEvent(mw->dpy, &ev); if (ev.type == MotionNotify) { move_x = ev.xmotion.x_root; move_y = ev.xmotion.y_root; } else if(ev.type == DestroyNotify || ev.type == UnmapNotify) { dlist *iter = dlist_find(clients, clientwin_cmp_func, (void *)ev.xany.window); if(iter) { ClientWin *cw = (ClientWin *)iter->data; clients = dlist_first(dlist_remove(iter)); iter = dlist_find(mw->cod, clientwin_cmp_func, (void *)ev.xany.window); if(iter) mw->cod = dlist_first(dlist_remove(iter)); clientwin_destroy(cw, True); if(! mw->cod) { die = 1; break; } } } else if (mw->poll_time >= 0 && ev.type == mw->damage_event_base + XDamageNotify) { XDamageNotifyEvent *d_ev = (XDamageNotifyEvent *)&ev; dlist *iter = dlist_find(mw->cod, clientwin_cmp_func, (void *)d_ev->drawable); if(iter) { if(mw->poll_time == 0) clientwin_repair((ClientWin *)iter->data); else ((ClientWin *)iter->data)->damaged = True; } } else if(ev.type == KeyRelease && ev.xkey.keycode == mw->key_q) { DIE_NOW = 1; die = 1; break; } else if(ev.type == KeyRelease && ev.xkey.keycode == mw->key_escape) { refocus = True; die = 1; break; } else if(ev.xany.window == mw->window) die = mainwin_handle(mw, &ev); else if(ev.type == PropertyNotify) { if(ev.xproperty.atom == ESETROOT_PMAP_ID || ev.xproperty.atom == _XROOTPMAP_ID) { mainwin_update_background(mw); REDUCE(clientwin_render((ClientWin *)iter->data), mw->cod); } } else if(mw->tooltip && ev.xany.window == mw->tooltip->window) tooltip_handle(mw->tooltip, &ev); else { dlist *iter; for(iter = mw->cod; iter; iter = iter->next) { ClientWin *cw = (ClientWin *)iter->data; if(cw->mini.window == ev.xany.window) { die = clientwin_handle(cw, &ev); if(die) break; } } if(die) break; } } if(mw->tooltip && move_x != -1) tooltip_move(mw->tooltip, move_x + 20, move_y + 20); }