Exemple #1
0
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;
}
Exemple #2
0
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);
	    
	}