1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsAppShell.h"
9 #include "nsWidgetsCID.h"
12 #include "nsIServiceManager.h"
13 #include "nsComponentManagerUtils.h"
17 #include "nsUXThemeData.h"
19 // unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
22 using namespace mozilla::widget
;
24 nsToolkit
* nsToolkit::gToolkit
= nullptr;
25 HINSTANCE
nsToolkit::mDllInstance
= 0;
26 static const unsigned long kD3DUsageDelay
= 5000;
29 StartAllowingD3D9(nsITimer
*aTimer
, void *aClosure
)
31 if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop
) {
32 nsWindow::StartAllowingD3D9(true);
36 MouseTrailer
* nsToolkit::gMouseTrailer
;
38 //-------------------------------------------------------------------------
42 //-------------------------------------------------------------------------
43 nsToolkit::nsToolkit()
45 MOZ_COUNT_CTOR(nsToolkit
);
47 #if defined(MOZ_STATIC_COMPONENT_LIBS)
48 nsToolkit::Startup(GetModuleHandle(nullptr));
51 gMouseTrailer
= &mMouseTrailer
;
53 if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop
) {
54 mD3D9Timer
= do_CreateInstance("@mozilla.org/timer;1");
55 mD3D9Timer
->InitWithFuncCallback(::StartAllowingD3D9
,
58 nsITimer::TYPE_ONE_SHOT
);
63 //-------------------------------------------------------------------------
67 //-------------------------------------------------------------------------
68 nsToolkit::~nsToolkit()
70 MOZ_COUNT_DTOR(nsToolkit
);
71 gMouseTrailer
= nullptr;
75 nsToolkit::Startup(HMODULE hModule
)
77 nsToolkit::mDllInstance
= hModule
;
78 WinUtils::Initialize();
79 nsUXThemeData::Initialize();
90 nsToolkit::StartAllowingD3D9()
92 if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop
) {
93 nsToolkit::GetToolkit()->mD3D9Timer
->Cancel();
94 nsWindow::StartAllowingD3D9(false);
98 //-------------------------------------------------------------------------
100 // Return the nsToolkit for the current thread. If a toolkit does not
101 // yet exist, then one will be created...
103 //-------------------------------------------------------------------------
105 nsToolkit
* nsToolkit::GetToolkit()
108 gToolkit
= new nsToolkit();
115 //-------------------------------------------------------------------------
118 //-------------------------------------------------------------------------
119 MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nullptr), mCaptureWindow(nullptr),
120 mIsInCaptureMode(false), mEnabled(true)
123 //-------------------------------------------------------------------------
126 //-------------------------------------------------------------------------
127 MouseTrailer::~MouseTrailer()
131 //-------------------------------------------------------------------------
134 //-------------------------------------------------------------------------
135 void MouseTrailer::SetMouseTrailerWindow(HWND aWnd
)
137 if (mMouseTrailerWindow
!= aWnd
&& mTimer
) {
138 // Make sure TimerProc is fired at least once for the old window
139 TimerProc(nullptr, nullptr);
141 mMouseTrailerWindow
= aWnd
;
145 //-------------------------------------------------------------------------
148 //-------------------------------------------------------------------------
149 void MouseTrailer::SetCaptureWindow(HWND aWnd
)
151 mCaptureWindow
= aWnd
;
152 if (mCaptureWindow
) {
153 mIsInCaptureMode
= true;
157 //-------------------------------------------------------------------------
160 //-------------------------------------------------------------------------
161 nsresult
MouseTrailer::CreateTimer()
163 if (mTimer
|| !mEnabled
) {
168 mTimer
= do_CreateInstance("@mozilla.org/timer;1", &rv
);
169 NS_ENSURE_SUCCESS(rv
, rv
);
171 return mTimer
->InitWithFuncCallback(TimerProc
, nullptr, 200,
172 nsITimer::TYPE_REPEATING_SLACK
);
175 //-------------------------------------------------------------------------
178 //-------------------------------------------------------------------------
179 void MouseTrailer::DestroyTimer()
187 //-------------------------------------------------------------------------
190 //-------------------------------------------------------------------------
191 void MouseTrailer::TimerProc(nsITimer
* aTimer
, void* aClosure
)
193 MouseTrailer
*mtrailer
= nsToolkit::gMouseTrailer
;
194 NS_ASSERTION(mtrailer
, "MouseTrailer still firing after deletion!");
196 // Check to see if we are in mouse capture mode,
197 // Once capture ends we could still get back one more timer event.
198 // Capture could end outside our window.
199 // Also, for some reason when the mouse is on the frame it thinks that
200 // it is inside the window that is being captured.
201 if (mtrailer
->mCaptureWindow
) {
202 if (mtrailer
->mCaptureWindow
!= mtrailer
->mMouseTrailerWindow
) {
206 if (mtrailer
->mIsInCaptureMode
) {
207 // mMouseTrailerWindow could be bad from rolling over the frame, so clear
208 // it if we were capturing and now this is the first timer callback
209 // since we canceled the capture
210 mtrailer
->mMouseTrailerWindow
= nullptr;
211 mtrailer
->mIsInCaptureMode
= false;
216 if (mtrailer
->mMouseTrailerWindow
&& ::IsWindow(mtrailer
->mMouseTrailerWindow
)) {
218 DWORD pos
= ::GetMessagePos();
219 mp
.x
= GET_X_LPARAM(pos
);
220 mp
.y
= GET_Y_LPARAM(pos
);
221 HWND mouseWnd
= ::WindowFromPoint(mp
);
222 if (mtrailer
->mMouseTrailerWindow
!= mouseWnd
) {
223 // Notify someone that a mouse exit happened.
224 PostMessage(mtrailer
->mMouseTrailerWindow
, WM_MOUSELEAVE
, 0, 0);
226 // we are out of this window, destroy timer
227 mtrailer
->DestroyTimer();
228 mtrailer
->mMouseTrailerWindow
= nullptr;
231 mtrailer
->DestroyTimer();
232 mtrailer
->mMouseTrailerWindow
= nullptr;