Bug 506815 - Replace old MouseTrailer code with TrackMouseEvent api. r=jimm

This commit is contained in:
mycoolclub 2014-10-01 02:38:00 +02:00
parent 6e36377de2
commit 73c841fc10
3 changed files with 8 additions and 190 deletions

View File

@ -33,8 +33,6 @@ StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
}
}
MouseTrailer* nsToolkit::gMouseTrailer;
//-------------------------------------------------------------------------
//
// constructor
@ -48,8 +46,6 @@ nsToolkit::nsToolkit()
nsToolkit::Startup(GetModuleHandle(nullptr));
#endif
gMouseTrailer = &mMouseTrailer;
if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1");
mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9,
@ -68,7 +64,6 @@ nsToolkit::nsToolkit()
nsToolkit::~nsToolkit()
{
MOZ_COUNT_DTOR(nsToolkit);
gMouseTrailer = nullptr;
}
void
@ -110,126 +105,3 @@ nsToolkit* nsToolkit::GetToolkit()
return gToolkit;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nullptr), mCaptureWindow(nullptr),
mIsInCaptureMode(false), mEnabled(true)
{
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
MouseTrailer::~MouseTrailer()
{
DestroyTimer();
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(HWND aWnd)
{
if (mMouseTrailerWindow != aWnd && mTimer) {
// Make sure TimerProc is fired at least once for the old window
TimerProc(nullptr, nullptr);
}
mMouseTrailerWindow = aWnd;
CreateTimer();
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetCaptureWindow(HWND aWnd)
{
mCaptureWindow = aWnd;
if (mCaptureWindow) {
mIsInCaptureMode = true;
}
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
nsresult MouseTrailer::CreateTimer()
{
if (mTimer || !mEnabled) {
return NS_OK;
}
nsresult rv;
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return mTimer->InitWithFuncCallback(TimerProc, nullptr, 200,
nsITimer::TYPE_REPEATING_SLACK);
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::DestroyTimer()
{
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
{
MouseTrailer *mtrailer = nsToolkit::gMouseTrailer;
NS_ASSERTION(mtrailer, "MouseTrailer still firing after deletion!");
// Check to see if we are in mouse capture mode,
// Once capture ends we could still get back one more timer event.
// Capture could end outside our window.
// Also, for some reason when the mouse is on the frame it thinks that
// it is inside the window that is being captured.
if (mtrailer->mCaptureWindow) {
if (mtrailer->mCaptureWindow != mtrailer->mMouseTrailerWindow) {
return;
}
} else {
if (mtrailer->mIsInCaptureMode) {
// mMouseTrailerWindow could be bad from rolling over the frame, so clear
// it if we were capturing and now this is the first timer callback
// since we canceled the capture
mtrailer->mMouseTrailerWindow = nullptr;
mtrailer->mIsInCaptureMode = false;
return;
}
}
if (mtrailer->mMouseTrailerWindow && ::IsWindow(mtrailer->mMouseTrailerWindow)) {
POINT mp;
DWORD pos = ::GetMessagePos();
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
HWND mouseWnd = ::WindowFromPoint(mp);
if (mtrailer->mMouseTrailerWindow != mouseWnd) {
// Notify someone that a mouse exit happened.
PostMessage(mtrailer->mMouseTrailerWindow, WM_MOUSELEAVE, 0, 0);
// we are out of this window, destroy timer
mtrailer->DestroyTimer();
mtrailer->mMouseTrailerWindow = nullptr;
}
} else {
mtrailer->DestroyTimer();
mtrailer->mMouseTrailerWindow = nullptr;
}
}

View File

@ -20,41 +20,6 @@
#define GET_Y_LPARAM(pt) (short(HIWORD(pt)))
#endif
/**
* Makes sure exit/enter mouse messages are always dispatched.
* In the case where the mouse has exited the outer most window the
* only way to tell if it has exited is to set a timer and look at the
* mouse pointer to see if it is within the outer most window.
*/
class MouseTrailer
{
public:
HWND GetMouseTrailerWindow() { return mMouseTrailerWindow; }
HWND GetCaptureWindow() { return mCaptureWindow; }
void SetMouseTrailerWindow(HWND aWnd);
void SetCaptureWindow(HWND aWnd);
void Disable() { mEnabled = false; DestroyTimer(); }
void Enable() { mEnabled = true; CreateTimer(); }
void DestroyTimer();
MouseTrailer();
~MouseTrailer();
private:
nsresult CreateTimer();
static void TimerProc(nsITimer* aTimer, void* aClosure);
// Information for mouse enter/exit events
HWND mMouseTrailerWindow;
HWND mCaptureWindow;
bool mIsInCaptureMode;
bool mEnabled;
nsCOMPtr<nsITimer> mTimer;
};
/**
* Wrapper around the thread running the message pump.
* The toolkit abstraction is necessary because the message pump must
@ -73,7 +38,6 @@ public:
static nsToolkit* GetToolkit();
static HINSTANCE mDllInstance;
static MouseTrailer *gMouseTrailer;
static void Startup(HMODULE hModule);
static void Shutdown();
@ -83,7 +47,6 @@ protected:
static nsToolkit* gToolkit;
nsCOMPtr<nsITimer> mD3D9Timer;
MouseTrailer mMouseTrailer;
};
#endif // TOOLKIT_H

View File

@ -3126,19 +3126,20 @@ NS_METHOD nsWindow::EnableDragDrop(bool aEnable)
NS_METHOD nsWindow::CaptureMouse(bool aCapture)
{
if (!nsToolkit::gMouseTrailer) {
NS_ERROR("nsWindow::CaptureMouse called after nsToolkit destroyed");
return NS_OK;
}
TRACKMOUSEEVENT mTrack;
mTrack.cbSize = sizeof(TRACKMOUSEEVENT);
mTrack.dwFlags = TME_LEAVE;
mTrack.dwHoverTime = 0;
if (aCapture) {
nsToolkit::gMouseTrailer->SetCaptureWindow(mWnd);
mTrack.hwndTrack = mWnd;
::SetCapture(mWnd);
} else {
nsToolkit::gMouseTrailer->SetCaptureWindow(nullptr);
mTrack.hwndTrack = nullptr;
::ReleaseCapture();
}
sIsInMouseCapture = aCapture;
// Requests WM_MOUSELEAVE events for this window.
TrackMouseEvent(&mTrack);
return NS_OK;
}
@ -4004,12 +4005,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
// call the event callback
if (mWidgetListener) {
if (nsToolkit::gMouseTrailer)
nsToolkit::gMouseTrailer->Disable();
if (aEventType == NS_MOUSE_MOVE) {
if (nsToolkit::gMouseTrailer && !sIsInMouseCapture) {
nsToolkit::gMouseTrailer->SetMouseTrailerWindow(mWnd);
}
nsIntRect rect;
GetBounds(rect);
rect.x = 0;
@ -4040,9 +4036,6 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
result = DispatchWindowEvent(&event);
if (nsToolkit::gMouseTrailer)
nsToolkit::gMouseTrailer->Enable();
// Release the widget with NS_IF_RELEASE() just in case
// the context menu key code in EventListenerManager::HandleEvent()
// released it already.
@ -6608,16 +6601,6 @@ void nsWindow::OnDestroy()
IMEHandler::OnDestroyWindow(this);
// Turn off mouse trails if enabled.
MouseTrailer* mtrailer = nsToolkit::gMouseTrailer;
if (mtrailer) {
if (mtrailer->GetMouseTrailerWindow() == mWnd)
mtrailer->DestroyTimer();
if (mtrailer->GetCaptureWindow() == mWnd)
mtrailer->SetCaptureWindow(nullptr);
}
// Free GDI window class objects
if (mBrush) {
VERIFY(::DeleteObject(mBrush));