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