Exemple #1
0
JBoolean
JXApplication::HandleOneEventForWindow
	(
	JXWindow*		window,
	const JBoolean	origAllowSleep
	)
{
	const JBoolean origHadBlockingWindowFlag = itsHadBlockingWindowFlag;

	itsHasBlockingWindowFlag = kJTrue;
	itsHadBlockingWindowFlag = kJFalse;		// req'd by JXWindow

	if (itsIdleTaskStack->IsEmpty())
		{
		PushIdleTaskStack();
		}

	UpdateCurrentTime();
	const JBoolean allowSleep =
		JI2B(origAllowSleep && HandleCustomEventWhileBlocking());

	UpdateCurrentTime();
	JBoolean windowHasEvents = kJFalse;

	const JXDisplay* uiDisplay = window->GetDisplay();

	Window eventWindow [ kEventWindowCount ];
	eventWindow[0] = window->GetXWindow();

	JPtrArrayIterator<JXDisplay> iter(itsDisplayList);
	JXDisplay* display;
	JIndex displayIndex = 0;
	while (iter.Next(&display))
		{
		JXMenuManager* menuMgr = display->GetMenuManager();
		if (!origHadBlockingWindowFlag)
			{
			menuMgr->CloseCurrentMenus();
			}

		JXWindow* mouseContainer;

		displayIndex++;
		itsCurrDisplayIndex = displayIndex;		// itsCurrDisplayIndex might change during event
		if (XPending(*display) != 0)
			{
			// get mouse and keyboard grabbers -- for menus inside blocking window

			eventWindow[1] = eventWindow[2] = None;

			JXWindow* grabber;
			if (display == uiDisplay && display->GetMouseGrabber(&grabber) &&
				menuMgr->IsMenuForWindow(grabber, window))
				{
				eventWindow[1] = grabber->GetXWindow();
				}
			if (display == uiDisplay && display->GetKeyboardGrabber(&grabber) &&
				menuMgr->IsMenuForWindow(grabber, window))
				{
				eventWindow[2] = grabber->GetXWindow();
				}

			// process one event

			XEvent xEvent;
			if (display == uiDisplay &&
				XCheckIfEvent(*display, &xEvent, GetNextWindowEvent,
							  reinterpret_cast<char*>(eventWindow)))
				{
				windowHasEvents = kJTrue;
				if (xEvent.type != MotionNotify)
					{
					itsLastIdleTime = itsCurrentTime;
					}
				display->HandleEvent(xEvent, itsCurrentTime);
				}
			else if (XCheckIfEvent(*display, &xEvent, GetNextBkgdEvent, NULL))
				{
				display->HandleEvent(xEvent, itsCurrentTime);
				}
			else if (display == uiDisplay &&
					 display->GetMouseContainer(&mouseContainer) &&
					 mouseContainer == window)
				{
				display->Idle(itsCurrentTime);
				}
			else
				{
				display->Update();
				}

			// discard mouse and keyboard events

			DiscardEventInfo discardInfo(display, NULL);
			if (display == uiDisplay)
				{
				discardInfo.eventWindow = eventWindow;
				}
			while (XCheckIfEvent(*display, &xEvent, DiscardNextEvent,
								 reinterpret_cast<char*>(&discardInfo)))
				{ };
			}
		else if (display == uiDisplay &&
				 display->GetMouseContainer(&mouseContainer) &&
				 mouseContainer == window)
			{
			display->Idle(itsCurrentTime);
			}
		else
			{
			display->Update();
			}
		}

	PerformTasks(windowHasEvents, allowSleep);

	itsHasBlockingWindowFlag = kJFalse;
	itsHadBlockingWindowFlag = kJTrue;

	return windowHasEvents;
}
JBoolean
JXApplication::HandleOneEventForWindow
	(
	JXWindow*		window,
	const JBoolean	origAllowSleep,
	const JBoolean do_tasks
	)
{
	const JBoolean origHadBlockingWindowFlag = itsHadBlockingWindowFlag;

	itsHasBlockingWindowFlag = kJTrue;
	itsHadBlockingWindowFlag = kJFalse;		// req'd by JXWindow

	if (itsIdleTaskStack->IsEmpty())
		{
		PushIdleTaskStack();
		}

	UpdateCurrentTime();
	const JBoolean allowSleep =
		JI2B(origAllowSleep && HandleCustomEventWhileBlocking());

	UpdateCurrentTime();
	JBoolean windowHasEvents = kJFalse;

	const JXDisplay* uiDisplay = window->GetDisplay();

	Window eventWindow [ kEventWindowCount ];
	eventWindow[0] = window->GetXWindow();

	JPtrArrayIterator<JXDisplay> iter(itsDisplayList);
	JXDisplay* display;
	JIndex displayIndex = 0;
	while (iter.Next(&display))
		{
		JXMenuManager* menuMgr = display->GetMenuManager();
		if (!origHadBlockingWindowFlag)
			{
			menuMgr->CloseCurrentMenus();
			}

		JXWindow* mouseContainer;

		displayIndex++;
		itsCurrDisplayIndex = displayIndex;		// itsCurrDisplayIndex might change during event
		if (XPending(*display) != 0)
			{
			// get mouse and keyboard grabbers -- for menus inside blocking window

			eventWindow[1] = eventWindow[2] = None;

			JXWindow* grabber;
			if (display == uiDisplay && display->GetMouseGrabber(&grabber) &&
				menuMgr->IsMenuForWindow(grabber, window))
				{
				eventWindow[1] = grabber->GetXWindow();
				}
			if (display == uiDisplay && display->GetKeyboardGrabber(&grabber) &&
				menuMgr->IsMenuForWindow(grabber, window))
				{
				eventWindow[2] = grabber->GetXWindow();
				}

			// process one event

			XEvent xEvent;
			if (display == uiDisplay &&
				XCheckIfEvent(*display, &xEvent, GetNextWindowEvent,
							  reinterpret_cast<char*>(eventWindow)))
				{
				windowHasEvents = kJTrue;
				if (xEvent.type != MotionNotify)
					{
					itsLastIdleTime = itsCurrentTime;
					}
				display->HandleEvent(xEvent, itsCurrentTime);
				}
#if 0
			// cd: background event check is now done as part of window event check
			// to give better update responsiveness when dragging a window
			else if (XCheckIfEvent(*display, &xEvent, GetNextBkgdEvent, NULL))
				{
				display->HandleEvent(xEvent, itsCurrentTime);
				}
#endif
			else if (display == uiDisplay &&
					 display->GetMouseContainer(&mouseContainer) &&
					 mouseContainer == window)
				{
				display->Idle(itsCurrentTime);
				}
			else
				{
				display->Update();
				}

			// discard mouse and keyboard events

			DiscardEventInfo discardInfo(display, NULL);
			if (display == uiDisplay)
				{
				discardInfo.eventWindow = eventWindow;
				}
			while (XCheckIfEvent(*display, &xEvent, DiscardNextEvent,
								 reinterpret_cast<char*>(&discardInfo)))
				{ };
			}
		else if (display == uiDisplay &&
				 display->GetMouseContainer(&mouseContainer) &&
				 mouseContainer == window)
			{
			display->Idle(itsCurrentTime);
			}
		else
			{
			display->Update();
			}
		}

	// Perform idle tasks when we don't receive any events and
	// during long intervals of "mouse moved".
	if (do_tasks)
	{
		if (!windowHasEvents)
			{
				PerformPermanentTasks();
			PerformIdleTasks();
			itsLastIdleTime = itsCurrentTime;
			PerformUrgentTasks();
			if (allowSleep)
				{
				JWait(itsMaxSleepTime / 1000.0);
				}
			}
		else if (windowHasEvents &&
				 itsCurrentTime - itsLastIdleTime > itsMaxSleepTime)
			{
				PerformPermanentTasks();
			PerformIdleTasks();
			itsLastIdleTime = itsCurrentTime;
			PerformUrgentTasks();
			}
		else
			{
				PerformPermanentTasks();
			PerformUrgentTasks();
			}
	}

	itsHasBlockingWindowFlag = kJFalse;
	itsHadBlockingWindowFlag = kJTrue;

	return windowHasEvents;
}