mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
On WIN32, process pending PL_Events and paints after mouse and keyboard events to eliminate starvation of reflow and paints bug 163528 r=rods@netscape.com sr=kin@netscape.com
This commit is contained in:
parent
e28f216899
commit
b515157170
@ -40,6 +40,9 @@
|
||||
#include "prmon.h"
|
||||
#include "prtime.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#ifdef MOZ_AIMM
|
||||
#include <initguid.h>
|
||||
#include "aimm.h"
|
||||
@ -63,6 +66,11 @@ NS_RegisterClass nsToolkit::mRegisterClass = &RegisterClassW;
|
||||
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
// Cached reference to event queue service
|
||||
static nsCOMPtr<nsIEventQueueService> gEventQueueService;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsToolkit, nsIToolkit)
|
||||
|
||||
//
|
||||
@ -438,6 +446,9 @@ nsToolkit::~nsToolkit()
|
||||
// Remove the TLS reference to the toolkit...
|
||||
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
|
||||
|
||||
// Remove reference to cached event queue
|
||||
gEventQueueService = nsnull;
|
||||
|
||||
#ifdef MOZ_STATIC_COMPONENT_LIBS
|
||||
nsToolkit::Shutdown();
|
||||
#endif
|
||||
@ -536,6 +547,23 @@ nsToolkit::Shutdown()
|
||||
::UnregisterClass("nsToolkitClass", nsToolkit::mDllInstance);
|
||||
}
|
||||
|
||||
nsIEventQueue*
|
||||
nsToolkit::GetEventQueue()
|
||||
{
|
||||
if (! gEventQueueService) {
|
||||
gEventQueueService = do_GetService(kEventQueueServiceCID);
|
||||
}
|
||||
|
||||
if (gEventQueueService) {
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
gEventQueueService->GetSpecialEventQueue(
|
||||
nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
|
||||
getter_AddRefs(eventQueue));
|
||||
return eventQueue;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -50,6 +50,8 @@ struct IActiveIMMApp;
|
||||
#endif
|
||||
|
||||
struct MethodInfo;
|
||||
class nsIEventQueue;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper around the thread running the message pump.
|
||||
@ -72,6 +74,7 @@ class nsToolkit : public nsIToolkit
|
||||
PRThread* GetGuiThread(void) { return mGuiThread; }
|
||||
HWND GetDispatchWindow(void) { return mDispatchWnd; }
|
||||
void CreateInternalWindow(PRThread *aThread);
|
||||
nsIEventQueue* GetEventQueue(void);
|
||||
|
||||
private:
|
||||
~nsToolkit();
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include <windows.h>
|
||||
|
||||
//#include <winuser.h>
|
||||
@ -3581,14 +3582,28 @@ BOOL CALLBACK nsWindow::DispatchStarvedPaints(HWND aWnd, LPARAM aMsg)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check for starved paints and dispatch any pending paint
|
||||
// Check for pending paints and dispatch any pending paint
|
||||
// messages for any nsIWidget which is a descendant of the
|
||||
// top-level window that *this* window is embedded within.
|
||||
// Note: We do not dispatch pending messages for non nsIWidget
|
||||
// managed windows.
|
||||
// Also dispatch pending PL_Events to avoid PL_EventQueue starvation.
|
||||
// Note: We do not dispatch pending paint messages for non
|
||||
// nsIWidget managed windows.
|
||||
|
||||
void nsWindow::CheckForStarvedPaints()
|
||||
void nsWindow::DispatchPendingEvents()
|
||||
{
|
||||
// Need to flush all pending PL_Events before
|
||||
// painting to prevent reflow events from being starved.
|
||||
// Note: Unfortunately, The flushing of PL_Events can not done by
|
||||
// dispatching the native WM_TIMER event that is used for PL_Event
|
||||
// notification because the timer message will not appear in the
|
||||
// native msg queue until 10ms after the event is posted. Which is too late.
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
nsToolkit *toolkit = NS_STATIC_CAST(nsToolkit *, mToolkit);
|
||||
eventQueue = toolkit->GetEventQueue();
|
||||
if (eventQueue) {
|
||||
eventQueue->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
// Quickly check to see if there are any
|
||||
// paint events pending.
|
||||
if (::GetQueueStatus(QS_PAINT)) {
|
||||
@ -3790,7 +3805,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
printf("%s\t\twp=%x\tlp=%x\n",
|
||||
(WM_KEYUP==msg)?"WM_KEYUP":"WM_SYSKEYUP" , wParam, lParam);
|
||||
#endif
|
||||
CheckForStarvedPaints();
|
||||
mIsShiftDown = IS_VK_DOWN(NS_VK_SHIFT);
|
||||
if(WM_SYSKEYUP==msg)
|
||||
{
|
||||
@ -3817,6 +3831,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
// ignore [shift+]alt+space so the OS can handle it
|
||||
if (mIsAltDown && !mIsControlDown && IS_VK_DOWN(NS_VK_SPACE)) {
|
||||
result = PR_FALSE;
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3824,6 +3839,8 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
result = OnKeyUp(wParam, (HIWORD(lParam)), lParam);
|
||||
else
|
||||
result = PR_FALSE;
|
||||
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
|
||||
// Let ths fall through if it isn't a key pad
|
||||
@ -3833,7 +3850,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
printf("%s\t\twp=%4x\tlp=%8x\n",
|
||||
(WM_KEYDOWN==msg)?"WM_KEYDOWN":"WM_SYSKEYDOWN" , wParam, lParam);
|
||||
#endif
|
||||
CheckForStarvedPaints();
|
||||
|
||||
mIsShiftDown = IS_VK_DOWN(NS_VK_SHIFT);
|
||||
if(WM_SYSKEYDOWN==msg)
|
||||
@ -3860,6 +3876,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
// ignore [shift+]alt+space so the OS can handle it
|
||||
if (mIsAltDown && !mIsControlDown && IS_VK_DOWN(NS_VK_SPACE)) {
|
||||
result = PR_FALSE;
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3884,6 +3901,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
result = PR_TRUE;
|
||||
*aRetValue = 0;
|
||||
}
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
|
||||
// say we've dealt with erase background if widget does
|
||||
@ -3903,20 +3921,24 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
case WM_MOUSEMOVE:
|
||||
//RelayMouseEvent(msg,wParam, lParam);
|
||||
|
||||
// Suppress synchronous painting of starved paint
|
||||
// events when mouse moves are generated by widget
|
||||
// Suppress dispatch of pending events
|
||||
// when mouse moves are generated by widget
|
||||
// creation instead of user input.
|
||||
{
|
||||
POINT mp;
|
||||
DWORD pos = ::GetMessagePos();
|
||||
mp.x = (short)LOWORD(pos);
|
||||
mp.y = (short)HIWORD(pos);
|
||||
PRBool userMovedMouse = PR_FALSE;
|
||||
if ((gLastMouseMovePoint.x != mp.x) ||
|
||||
(gLastMouseMovePoint.y != mp.y)) {
|
||||
CheckForStarvedPaints();
|
||||
userMovedMouse = PR_TRUE;
|
||||
}
|
||||
|
||||
result = DispatchMouseEvent(NS_MOUSE_MOVE, wParam);
|
||||
if (userMovedMouse) {
|
||||
DispatchPendingEvents();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3935,14 +3957,14 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN, wParam);
|
||||
DispatchPendingEvents();
|
||||
} break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
//RelayMouseEvent(msg,wParam, lParam);
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_UP, wParam);
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
|
||||
case WM_CONTEXTMENU:
|
||||
@ -3971,13 +3993,13 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN, wParam);
|
||||
DispatchPendingEvents();
|
||||
} break;
|
||||
|
||||
case WM_MBUTTONUP:
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_UP, wParam);
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
|
||||
case WM_MBUTTONDBLCLK:
|
||||
@ -3997,13 +4019,13 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN, wParam);
|
||||
DispatchPendingEvents();
|
||||
} break;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
CheckForStarvedPaints();
|
||||
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_UP, wParam);
|
||||
DispatchPendingEvents();
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDBLCLK:
|
||||
|
@ -401,7 +401,7 @@ protected:
|
||||
static nsWindow * GetNSWindowPtr(HWND aWnd);
|
||||
static BOOL SetNSWindowPtr(HWND aWnd, nsWindow * ptr);
|
||||
|
||||
void CheckForStarvedPaints();
|
||||
void DispatchPendingEvents();
|
||||
virtual PRBool ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *aRetValue);
|
||||
virtual PRBool DispatchWindowEvent(nsGUIEvent* event);
|
||||
virtual PRBool DispatchWindowEvent(nsGUIEvent*event, nsEventStatus &aStatus);
|
||||
|
Loading…
Reference in New Issue
Block a user