Toy* Toys::AddToy(Toy::EnumToyType type)
{
	Toy *toy = Toy::Create(type, m_pClient, /*parent*/0, GetWindowFlags());
	if( toy )
	{
		connect(toy, SIGNAL(recvWidgetsChanged()), this, SLOT(onRecvWidgetsChanged()));
		connect(toy, SIGNAL(closing(Toy*)), this, SLOT(onToyClosing(Toy*)));
		connect(toy, SIGNAL(changed()), this, SLOT(onToyChanged()));
		connect(toy, SIGNAL(toggleMainWindow()), this, SLOT(onToyToggledMainWindow()));
		if(m_Opacity != 100)
			toy->setWindowOpacity(m_Opacity * 0.01);
		m_List.push_back(toy);

		if( !m_Loading )
		{
			toy->showNormal();
			BuildRecvWidgetsTable();
			toy->raise();
		}

		emit changed();
	}

	return toy;
}
void Toys::UpdateWindowFlags()
{
	for(TOY_LIST::const_iterator i=m_List.begin(); i!=m_List.end(); i++)
	{
		Toy *toy = *i;
		QPoint pos( toy->frameGeometry().topLeft() );
		Qt::WindowStates ws = toy->windowState();
		bool wasVisible = toy->isVisible();

		toy->hide();

		toy->setWindowFlags( GetWindowFlags() );

		if( ws.testFlag(Qt::WindowMinimized) )
		{
			toy->showMinimized();
		}
		else if( ws.testFlag(Qt::WindowMaximized) )
		{
			toy->showMaximized();
			if( !wasVisible )
				toy->close();
		}
		else
		{
			toy->move( pos );
			toy->showNormal();
			Toy::ClipToScreen( *toy );
			if( !wasVisible )
				toy->close();
		}
	}
}
void emX11WindowPort::SetPosSize(
	double x, double y, PosSizeArgSpec posSpec,
	double w, double h, PosSizeArgSpec sizeSpec
)
{
	if ((GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0) {
		posSpec=PSAS_IGNORE;
		sizeSpec=PSAS_IGNORE;
	}
	if (posSpec==PSAS_IGNORE) {
		x=GetViewX();
		y=GetViewY();
	}
	else {
		if (posSpec==PSAS_WINDOW) {
			x+=BorderL;
			y+=BorderT;
		}
		x=floor(x+0.5);
		y=floor(y+0.5);
		PosForced=true;
		PosPending=true;
	}
	if (sizeSpec==PSAS_IGNORE) {
		w=GetViewWidth();
		h=GetViewHeight();
	}
	else {
		if (sizeSpec==PSAS_WINDOW) {
			w-=BorderL+BorderR;
			h-=BorderT+BorderB;
		}
		w=floor(w+0.5);
		h=floor(h+0.5);
		if (w<MinPaneW) w=MinPaneW;
		if (h<MinPaneH) h=MinPaneH;
		SizeForced=true;
		SizePending=true;
	}
	SetViewGeometry(x,y,w,h,Screen.PixelTallness);
	WakeUp();
}
bool emX11WindowPort::Cycle()
{
	XWindowAttributes attr;
	XSizeHints xsh;
	emString str;
	emCursor cur;
	::Window win;
	::Cursor xcur;
	emX11WindowPort * wp;
	double vrx,vry,vrw,vrh,fx,fy,fw,fh;
	int i,x,y,w,h;
	Status xs;

	if (
		FullscreenUpdateTimer &&
		IsSignaled(FullscreenUpdateTimer->GetSignal())
	) {
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		if (
			fabs(PaneX-vrx)>0.51 || fabs(PaneY-vry)>0.51 ||
			fabs(PaneW-vrw)>0.51 || fabs(PaneH-vrh)>0.51
		) {
			PosForced=true;
			PosPending=true;
			SizeForced=true;
			SizePending=true;
			SetViewGeometry(vrx,vry,vrw,vrh,Screen.PixelTallness);
		}

		// Workaround for lots of focus problems with several window managers:
		if (Screen.GrabbingWinPort==this) {
			XMutex.Lock();
			XGetInputFocus(Disp,&win,&i);
			XMutex.Unlock();
			wp=NULL;
			for (i=Screen.WinPorts.GetCount()-1; i>=0; i--) {
				if (Screen.WinPorts[i]->Win==win) {
					wp=Screen.WinPorts[i];
					break;
				}
			}
			if (wp==this) {
				if (!Focused) {
					Focused=true;
					SetViewFocused(true);
					emWarning("emX11WindowPort: Focus workaround 1 applied.");
				}
			}
			else {
				while (wp) {
					if (wp==this) break;
					wp=wp->Owner;
				}
				if (!wp) {
					XMutex.Lock();
					xs=XGetWindowAttributes(Disp,Win,&attr);
					XMutex.Unlock();
					if (xs && attr.map_state==IsViewable) {
						XMutex.Lock();
						XSetInputFocus(Disp,Win,RevertToNone,CurrentTime);
						XMutex.Unlock();
						emWarning("emX11WindowPort: Focus workaround 2 applied.");
					}
				}
			}
		}
	}

	if (
		!PostConstructed && !PosForced && Owner &&
		(GetWindowFlags()&emWindow::WF_FULLSCREEN)==0
	) {
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		fx=Owner->GetViewX()-Owner->BorderL;
		fy=Owner->GetViewY()-Owner->BorderT;
		fw=Owner->GetViewWidth()+Owner->BorderL+Owner->BorderR;
		fh=Owner->GetViewHeight()+Owner->BorderT+Owner->BorderB;
		fx+=fw*0.5;
		fy+=fh*0.5;
		fw=GetViewWidth()+BorderL+BorderR;
		fh=GetViewHeight()+BorderT+BorderB;
		fx-=fw*0.5+emGetDblRandom(-0.03,0.03)*vrw;
		fy-=fh*0.5+emGetDblRandom(-0.03,0.03)*vrh;
		if (fx>vrx+vrw-fw) fx=vrx+vrw-fw;
		if (fy>vry+vrh-fh) fy=vry+vrh-fh;
		if (fx<vrx) fx=vrx;
		if (fy<vry) fy=vry;
		SetViewGeometry(
			fx+BorderL,fy+BorderT,
			GetViewWidth(),GetViewHeight(),
			Screen.PixelTallness
		);
		PosPending=true;
		PosForced=true;
	}

	if (PosPending || SizePending) {
		x=((int)GetViewX())-BorderL;
		y=((int)GetViewY())-BorderT;
		w=(int)GetViewWidth();
		h=(int)GetViewHeight();
		memset(&xsh,0,sizeof(xsh));
		xsh.flags     =PMinSize;
		xsh.min_width =MinPaneW;
		xsh.min_height=MinPaneH;
		if (PosForced) {
			xsh.flags|=PPosition|USPosition;
			xsh.x=x;
			xsh.y=y;
		}
		if (SizeForced) {
			xsh.flags|=PSize|USSize;
			xsh.width=w;
			xsh.height=h;
		}
		XMutex.Lock();
		XSetWMNormalHints(Disp,Win,&xsh);
		if (PosPending && SizePending) {
			XMoveResizeWindow(Disp,Win,x,y,w,h);
		}
		else if (PosPending) {
			XMoveWindow(Disp,Win,x,y);
		}
		else {
			XResizeWindow(Disp,Win,w,h);
		}
		XMutex.Unlock();
		PosPending=false;
		SizePending=false;
	}

	if (TitlePending) {
		str=GetWindowTitle();
		if (Title!=str) {
			Title=str;
			XMutex.Lock();
			XmbSetWMProperties(Disp,Win,Title.Get(),NULL,NULL,0,NULL,NULL,NULL);
			XMutex.Unlock();
		}
		TitlePending=false;
	}

	if (IconPending) {
		SetIconProperty(GetWindowIcon());
		IconPending=false;
	}

	if (CursorPending) {
		cur=GetViewCursor();
		if (Cursor!=cur) {
			Cursor=cur;
			xcur=Screen.GetXCursor(cur);
			XMutex.Lock();
			XDefineCursor(Disp,Win,xcur);
			XMutex.Unlock();
		}
		CursorPending=false;
	}

	if (!PostConstructed) {
		PostConstruct();
		PostConstructed=true;
	}

	if (!InvalidRects.IsEmpty() && Mapped) {
		UpdatePainting();
		if (!LaunchFeedbackSent) {
			LaunchFeedbackSent=true;
			SendLaunchFeedback();
		}
	}

	return false;
}
void emX11WindowPort::HandleEvent(XEvent & event)
{
	emInputEvent inputEvent;
	emX11WindowPort * wp;
	char tmp[256];
	char keymap[32];
	KeySym ks;
	emInputKey key;
	Status status;
	int i,x,y,w,h,mask,repeat,variant,len;
	double mx,my;
	bool inside;

	// Remember:
	// - Calling InputToView may delete this window port.
	// - The grab stuff is very very tricky.

	switch (event.type) {
	case MotionNotify:
		mx=PaneX+event.xmotion.x+Screen.MouseWarpX;
		my=PaneY+event.xmotion.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		for (i=0; i<3; i++) {
			if      (i==0) { key=EM_KEY_LEFT_BUTTON  ; mask=Button1Mask; }
			else if (i==1) { key=EM_KEY_MIDDLE_BUTTON; mask=Button2Mask; }
			else           { key=EM_KEY_RIGHT_BUTTON ; mask=Button3Mask; }
			if (Screen.InputState.Get(key) && (event.xmotion.state&mask)==0) {
				Screen.InputState.Set(key,false);
				Screen.InputStateClock++;
			}
		}
		return;
	case ButtonPress:
		mx=PaneX+event.xbutton.x+Screen.MouseWarpX;
		my=PaneY+event.xbutton.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		wp=SearchOwnedPopupAt(mx,my);
		if (wp) {
			if (wp->Mapped) {
				event.xbutton.x+=PaneX-wp->PaneX;
				event.xbutton.y+=PaneY-wp->PaneY;
				wp->HandleEvent(event);
			}
			return;
		}
		if (ModalDescendants>0) {
			FocusModalDescendant(true);
			return;
		}
		inside=(
			mx>=PaneX && mx<PaneX+PaneW &&
			my>=PaneY && my<PaneY+PaneH
		);
		if (
			!inside &&
			Screen.GrabbingWinPort==this &&
			(GetWindowFlags()&emWindow::WF_POPUP)!=0
		) {
			XMutex.Lock();
			XAllowEvents(Disp,ReplayPointer,CurrentTime);
			XMutex.Unlock();
			Screen.GrabbingWinPort=NULL;
			LastButtonPress=EM_KEY_NONE;
			SignalWindowClosing();
		}
		for (i=Screen.WinPorts.GetCount()-1; i>=0; i--) {
			wp=Screen.WinPorts[i];
			if (
				(wp->GetWindowFlags()&emWindow::WF_POPUP)!=0 &&
				wp!=this && !wp->IsAncestorOf(this)
			) {
				wp->SignalWindowClosing();
			}
		}
		if (!inside) return;
		if (!Focused && event.xbutton.button>=1 && event.xbutton.button<=5) {
			RequestFocus();
			Screen.UpdateKeymapAndInputState();
		}
		if (event.xbutton.button>=1 && event.xbutton.button<=3) {
			if      (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON;
			else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON;
			else                              key=EM_KEY_RIGHT_BUTTON;
			if (!Screen.InputState.Get(key)) {
				Screen.InputState.Set(key,true);
				Screen.InputStateClock++;
				if (
					key==LastButtonPress &&
					event.xbutton.time>LastButtonPressTime &&
					event.xbutton.time-LastButtonPressTime<=330 &&
					event.xbutton.x>=LastButtonPressX-10 &&
					event.xbutton.x<=LastButtonPressX+10 &&
					event.xbutton.y>=LastButtonPressY-10 &&
					event.xbutton.y<=LastButtonPressY+10
				) {
					repeat=LastButtonPressRepeat+1;
				}
				else {
					repeat=0;
				}
				LastButtonPress=key;
				LastButtonPressTime=event.xbutton.time;
				LastButtonPressX=event.xbutton.x;
				LastButtonPressY=event.xbutton.y;
				LastButtonPressRepeat=repeat;
				inputEvent.Setup(key,"",repeat,0);
				InputStateClock=Screen.InputStateClock;
				InputToView(inputEvent,Screen.InputState);
				return;
			}
		}
		else if (event.xbutton.button==4) {
			inputEvent.Setup(EM_KEY_WHEEL_UP,"",0,0);
			InputStateClock=Screen.InputStateClock;
			InputToView(inputEvent,Screen.InputState);
			return;
		}
		else if (event.xbutton.button==5) {
			inputEvent.Setup(EM_KEY_WHEEL_DOWN,"",0,0);
			InputStateClock=Screen.InputStateClock;
			InputToView(inputEvent,Screen.InputState);
			return;
		}
		return;
	case ButtonRelease:
		mx=PaneX+event.xbutton.x+Screen.MouseWarpX;
		my=PaneY+event.xbutton.y+Screen.MouseWarpY;
		if (
			Screen.InputState.GetMouseX()!=mx ||
			Screen.InputState.GetMouseY()!=my
		) {
			Screen.InputState.SetMouse(mx,my);
			Screen.InputStateClock++;
		}
		if (event.xbutton.button>=1 && event.xbutton.button<=3) {
			if      (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON;
			else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON;
			else                              key=EM_KEY_RIGHT_BUTTON;
			if (Screen.InputState.Get(key)) {
				Screen.InputState.Set(key,false);
				Screen.InputStateClock++;
				inputEvent.Eat();
				InputStateClock=Screen.InputStateClock;
				InputToView(inputEvent,Screen.InputState);
				return;
			}
		}
		return;
	case KeyPress:
		i=event.xkey.keycode/8;
		mask=1<<(event.xkey.keycode&7);
		if (i<32 && (Screen.Keymap[i]&mask)==0) {
			Screen.Keymap[i]|=mask;
			Screen.UpdateInputStateFromKeymap();
		}
		if (InputContext) {
			XMutex.Lock();
			len=XmbLookupString(
				InputContext,
				&event.xkey,
				tmp,
				sizeof(tmp)-1,
				&ks,
				&status
			);
			XMutex.Unlock();
			if (status!=XLookupChars && status!=XLookupBoth) len=0;
			if (status!=XLookupKeySym && status!=XLookupBoth) ks=0;
		}
		else {
			XMutex.Lock();
			len=XLookupString(
				&event.xkey,
				tmp,
				sizeof(tmp)-1,
				&ks,
				&ComposeStatus
			);
			XMutex.Unlock();
		}
		tmp[len]=0;
		key=emX11Screen::ConvertKey(ks,&variant);
		if (key==EM_KEY_NONE && !tmp[0]) return;
		repeat=0;
		if (
			key!=EM_KEY_NONE &&
			Screen.InputState.Get(key) &&
			RepeatKey==key
		) {
			repeat=KeyRepeat+1;
		}
		if (ModalDescendants>0) return;
		RepeatKey=key;
		KeyRepeat=repeat;
		inputEvent.Setup(key,tmp,repeat,variant);
		InputStateClock=Screen.InputStateClock;
		InputToView(inputEvent,Screen.InputState);
		return;
	case KeyRelease:
		memset(keymap,0,sizeof(keymap));
		XMutex.Lock();
		XQueryKeymap(Disp,keymap);
		XMutex.Unlock();
		i=event.xkey.keycode/8;
		mask=1<<(event.xkey.keycode&7);
		if (i<32 && (keymap[i]&mask)==0) {
			RepeatKey=EM_KEY_NONE;
			if ((Screen.Keymap[i]&mask)!=0) {
				Screen.Keymap[i]&=~mask;
				Screen.UpdateInputStateFromKeymap();
			}
		}
		return;
	case Expose:
		x=event.xexpose.x;
		y=event.xexpose.y;
		w=event.xexpose.width;
		h=event.xexpose.height;
		InvalidatePainting(PaneX+x,PaneY+y,w,h);
		return;
	case FocusIn:
		if (
			event.xfocus.mode==NotifyNormal ||
			event.xfocus.mode==NotifyWhileGrabbed
		) {
			if (InputContext) {
				XMutex.Lock();
				XSetICFocus(InputContext);
				XMutex.Unlock();
			}
			Screen.UpdateKeymapAndInputState();
			RepeatKey=EM_KEY_NONE;
			if (!Focused) {
				Focused=true;
				SetViewFocused(true);
			}
			if (ModalDescendants>0) FocusModalDescendant();
		}
		return;
	case FocusOut:
		if (
			event.xfocus.mode==NotifyNormal ||
			event.xfocus.mode==NotifyWhileGrabbed
		) {
			if (InputContext) {
				XMutex.Lock();
				XUnsetICFocus(InputContext);
				XMutex.Unlock();
			}
			if (Focused) {
				Focused=false;
				SetViewFocused(false);
			}
			LastButtonPress=EM_KEY_NONE;
			RepeatKey=EM_KEY_NONE;
		}
		return;
	case ConfigureNotify:
		// The meaning of the coordinates from event.xconfigure depends on
		// the window manager. Therefore:
		GetAbsWinGeometry(Disp,Win,&x,&y,&w,&h);
		if (PaneX!=x || PaneY!=y || PaneW!=w || PaneH!=h) {
			PaneX=x;
			PaneY=y;
			PaneW=w;
			PaneH=h;
			ClipX1=PaneX;
			ClipY1=PaneY;
			ClipX2=PaneX+PaneW;
			ClipY2=PaneY+PaneH;
			InvalidRects.Set(PaneX,PaneY,PaneX+PaneW,PaneY+PaneH);
			WakeUp();
			if (!PosPending && !SizePending) {
				SetViewGeometry(
					PaneX,PaneY,
					PaneW,PaneH,
					Screen.PixelTallness
				);
			}
			else if (!PosPending) {
				SetViewGeometry(
					PaneX,PaneY,
					GetViewWidth(),GetViewHeight(),
					Screen.PixelTallness
				);
			}
			else if (!SizePending) {
				SetViewGeometry(
					GetViewX(),GetViewY(),
					PaneW,PaneH,
					Screen.PixelTallness
				);
			}
			Screen.InputStateClock++;
		}
		return;
	case MapNotify:
		if (event.xmap.window==Win && !Mapped) {
			Mapped=true;
			WakeUp();
		}
		return;
	case UnmapNotify:
		if (event.xmap.window==Win && Mapped) {
			Mapped=false;
		}
		return;
	case ClientMessage:
		if (event.xclient.data.l[0]==(long)Screen.WM_DELETE_WINDOW) {
			if (ModalDescendants<=0) SignalWindowClosing();
			else FocusModalDescendant(true);
		}
		return;
	}
}
void emX11WindowPort::PostConstruct()
{
	int i,r;

	if ((GetWindowFlags()&(
		emWindow::WF_POPUP|emWindow::WF_UNDECORATED|emWindow::WF_FULLSCREEN
	))!=0) {
		XMutex.Lock();
		XMapRaised(Disp,Win);
		XMutex.Unlock();
	}
	else {
		XMutex.Lock();
		XMapWindow(Disp,Win);
		XMutex.Unlock();
	}

	if (Focused) {
		if (MakeViewable()) {
			if ((GetWindowFlags()&emWindow::WF_MODAL)!=0 && Owner) {
				XMutex.Lock();
				XSetInputFocus(Disp,Win,RevertToParent,CurrentTime);
				XMutex.Unlock();
			}
			else {
				XMutex.Lock();
				XSetInputFocus(Disp,Win,RevertToNone,CurrentTime);
				XMutex.Unlock();
			}
		}
		else {
			Focused=false;
			SetViewFocused(false);
		}
	}

	if (
		(GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0 ||
		(
			(GetWindowFlags()&emWindow::WF_POPUP)!=0 &&
			(
				!Screen.GrabbingWinPort ||
				(Screen.GrabbingWinPort->GetWindowFlags()&emWindow::WF_FULLSCREEN)==0
			)
		)
	) {
		if (MakeViewable()) {
			for (i=0; ; i++) {
				XMutex.Lock();
				r=XGrabKeyboard(
					Disp,
					Win,
					True,
					GrabModeSync,
					GrabModeAsync,
					CurrentTime
				);
				XMutex.Unlock();
				if (r==GrabSuccess) break;
				if (i>10) emFatalError("XGrabKeyboard failed.");
				emWarning("XGrabKeyboard failed - trying again...");
				emSleepMS(50);
			}
			for (i=0; ; i++) {
				XMutex.Lock();
				r=XGrabPointer(
					Disp,
					Win,
					True,
					ButtonPressMask|ButtonReleaseMask|PointerMotionMask|
					ButtonMotionMask|EnterWindowMask|LeaveWindowMask,
					GrabModeSync,
					GrabModeAsync,
					(GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0 ? Win : None,
					None,
					CurrentTime
				);
				XMutex.Unlock();
				if (r==GrabSuccess) break;
				if (i>10) emFatalError("XGrabPointer failed.");
				emWarning("XGrabPointer failed - trying again...");
				emSleepMS(50);
			}
			XMutex.Lock();
			XAllowEvents(Disp,SyncPointer,CurrentTime);
			XMutex.Unlock();
			Screen.GrabbingWinPort=this;
		}
	}

	if ((GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0) {
		FullscreenUpdateTimer=new emTimer(GetScheduler());
		AddWakeUpSignal(FullscreenUpdateTimer->GetSignal());
		FullscreenUpdateTimer->Start(500,true);
	}

	if ((GetWindowFlags()&emWindow::WF_MODAL)!=0) {
		SetModalState(true);
	}
}
void emX11WindowPort::PreConstruct()
{
	XSetWindowAttributes xswa;
	XWMHints xwmh;
	XClassHint xch;
	XSizeHints xsh;
	XGCValues xgcv;
	long eventMask,extraEventMask;
	double vrx,vry,vrw,vrh,d;
	int border;
	bool haveBorder;

	if ((GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0) {
		Screen.LeaveFullscreenModes(&GetWindow());
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		MinPaneW=1;
		MinPaneH=1;
		PaneX=(int)(vrx+0.5);
		PaneY=(int)(vry+0.5);
		PaneW=(int)(vrw+0.5);
		PaneH=(int)(vrh+0.5);
		BorderL=0;
		BorderT=0;
		BorderR=0;
		BorderB=0;
		haveBorder=false;
		Focused=true;
	}
	else if ((GetWindowFlags()&(emWindow::WF_POPUP|emWindow::WF_UNDECORATED))!=0) {
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		MinPaneW=1;
		MinPaneH=1;
		PaneX=(int)(vrx+vrw*emGetDblRandom(0.22,0.28)+0.5);
		PaneY=(int)(vry+vrh*emGetDblRandom(0.22,0.28)+0.5);
		PaneW=(int)(vrw*0.5+0.5);
		PaneH=(int)(vrh*0.5+0.5);
		BorderL=0;
		BorderT=0;
		BorderR=0;
		BorderB=0;
		haveBorder=false;
		Focused=true;
	}
	else {
		Screen.LeaveFullscreenModes(&GetWindow());
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		MinPaneW=32;
		MinPaneH=32;
		if (!Owner && (GetWindowFlags()&emWindow::WF_MODAL)==0) {
			d=emMin(vrw,vrh)*0.08;
			PaneX=(int)(vrx+d*emGetDblRandom(0.5,1.5)+0.5);
			PaneY=(int)(vry+d*emGetDblRandom(0.8,1.2)+0.5);
			PaneW=(int)(vrw-d*2.0+0.5);
			PaneH=(int)(vrh-d*2.0+0.5);
		}
		else {
			PaneX=(int)(vrx+vrw*emGetDblRandom(0.22,0.28)+0.5);
			PaneY=(int)(vry+vrh*emGetDblRandom(0.22,0.28)+0.5);
			PaneW=(int)(vrw*0.5+0.5);
			PaneH=(int)(vrh*0.5+0.5);
		}
		// Some window managers seem to expect that we would expect this:
		BorderL=3;
		BorderT=18;
		BorderR=3;
		BorderB=3;
		haveBorder=true;
		if ((GetWindowFlags()&emWindow::WF_MODAL)!=0) Focused=true;
		else Focused=false;
	}
	ClipX1=PaneX;
	ClipY1=PaneY;
	ClipX2=PaneX+PaneW;
	ClipY2=PaneY+PaneH;
	PosForced=false;
	PosPending=false;
	SizeForced=false;
	SizePending=false;
	InvalidRects.Set(PaneX,PaneY,PaneX+PaneW,PaneY+PaneH);
	Title.Empty();
	TitlePending=true;
	IconPending=true;
	Cursor=-1;
	CursorPending=true;
	PostConstructed=false;
	Mapped=false;
	InputStateClock=0;
	LastButtonPress=EM_KEY_NONE;
	RepeatKey=EM_KEY_NONE;
	memset(&ComposeStatus,0,sizeof(ComposeStatus));

	memset(&xsh,0,sizeof(xsh));
	xsh.flags     =PMinSize;
	xsh.min_width =MinPaneW;
	xsh.min_height=MinPaneH;

	eventMask=
		ExposureMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|
		KeyPressMask|KeyReleaseMask|StructureNotifyMask|SubstructureNotifyMask|
		VisibilityChangeMask|FocusChangeMask
	;

	memset(&xswa,0,sizeof(xswa));
	xswa.bit_gravity=ForgetGravity;
	xswa.colormap=Screen.Colmap;
	xswa.event_mask=eventMask;

	if (haveBorder) {
		xswa.override_redirect=False;
		border=1;
	}
	else {
		xswa.override_redirect=True;
		border=0;
	}

	XMutex.Lock();
	Win=XCreateWindow(
		Disp,
		Screen.RootWin,
		PaneX-BorderL,
		PaneY-BorderT,
		PaneW,
		PaneH,
		border,
		Screen.VisuDepth,
		InputOutput,
		Screen.Visu,
		CWBitGravity|CWColormap|CWEventMask|CWOverrideRedirect,
		&xswa
	);
	XMutex.Unlock();

	Screen.WCThread->AddWindow(Win);

	if (Owner) {
		XMutex.Lock();
		XSetTransientForHint(Disp,Win,Owner->Win);
		XMutex.Unlock();
	}

	if (Screen.InputMethod) {
		XMutex.Lock();
		InputContext=XCreateIC(
			Screen.InputMethod,
			XNInputStyle,XIMPreeditNothing|XIMStatusNothing,
			XNClientWindow,Win,
			(char*)NULL
		);
		XMutex.Unlock();
		if (InputContext==NULL) {
			emFatalError("Failed to create X input context.");
		}
	}
	else {
		InputContext=NULL;
	}

	if (InputContext) {
		XMutex.Lock();
		XGetICValues(InputContext,XNFilterEvents,&extraEventMask,(char*)NULL);
		XMutex.Unlock();
		eventMask|=extraEventMask;
	}
	XMutex.Lock();
	XSelectInput(Disp,Win,eventMask);
	XMutex.Unlock();

	memset(&xwmh,0,sizeof(xwmh));
	xwmh.flags=(InputHint|StateHint);
	xwmh.input=True;
	xwmh.initial_state=NormalState;

	memset(&xch,0,sizeof(xch));
	xch.res_name =(char*)GetWMResName().Get();
	xch.res_class=(char*)"EagleMode";

	XMutex.Lock();
	XmbSetWMProperties(Disp,Win,Title.Get(),NULL,NULL,0,&xsh,&xwmh,&xch);
	XMutex.Unlock();

	XMutex.Lock();
	XChangeProperty(
		Disp,
		Win,
		Screen.WM_PROTOCOLS,
		XA_ATOM,
		32,
		PropModeReplace,
		(const unsigned char*)&Screen.WM_DELETE_WINDOW,
		1
	);
	XMutex.Unlock();

	memset(&xgcv,0,sizeof(xgcv));
	XMutex.Lock();
	Gc=XCreateGC(Disp,Win,0,&xgcv);
	XMutex.Unlock();

	SetViewFocused(Focused);
	SetViewGeometry(PaneX,PaneY,PaneW,PaneH,Screen.PixelTallness);

	WakeUp();
}