widget/windows/nsToolkit.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/widget/windows/nsToolkit.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,235 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsToolkit.h"
    1.10 +#include "nsAppShell.h"
    1.11 +#include "nsWindow.h"
    1.12 +#include "nsWidgetsCID.h"
    1.13 +#include "prmon.h"
    1.14 +#include "prtime.h"
    1.15 +#include "nsIServiceManager.h"
    1.16 +#include "nsComponentManagerUtils.h"
    1.17 +#include <objbase.h>
    1.18 +#include "WinUtils.h"
    1.19 +
    1.20 +#include "nsUXThemeData.h"
    1.21 +
    1.22 +// unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
    1.23 +#include <unknwn.h>
    1.24 +
    1.25 +using namespace mozilla::widget;
    1.26 +
    1.27 +nsToolkit* nsToolkit::gToolkit = nullptr;
    1.28 +HINSTANCE nsToolkit::mDllInstance = 0;
    1.29 +static const unsigned long kD3DUsageDelay = 5000;
    1.30 +
    1.31 +static void
    1.32 +StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
    1.33 +{
    1.34 +  if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
    1.35 +    nsWindow::StartAllowingD3D9(true);
    1.36 +  }
    1.37 +}
    1.38 +
    1.39 +MouseTrailer*       nsToolkit::gMouseTrailer;
    1.40 +
    1.41 +//-------------------------------------------------------------------------
    1.42 +//
    1.43 +// constructor
    1.44 +//
    1.45 +//-------------------------------------------------------------------------
    1.46 +nsToolkit::nsToolkit()  
    1.47 +{
    1.48 +    MOZ_COUNT_CTOR(nsToolkit);
    1.49 +
    1.50 +#if defined(MOZ_STATIC_COMPONENT_LIBS)
    1.51 +    nsToolkit::Startup(GetModuleHandle(nullptr));
    1.52 +#endif
    1.53 +
    1.54 +    gMouseTrailer = &mMouseTrailer;
    1.55 +
    1.56 +    if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
    1.57 +      mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1");
    1.58 +      mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9,
    1.59 +                                       nullptr,
    1.60 +                                       kD3DUsageDelay,
    1.61 +                                       nsITimer::TYPE_ONE_SHOT);
    1.62 +    }
    1.63 +}
    1.64 +
    1.65 +
    1.66 +//-------------------------------------------------------------------------
    1.67 +//
    1.68 +// destructor
    1.69 +//
    1.70 +//-------------------------------------------------------------------------
    1.71 +nsToolkit::~nsToolkit()
    1.72 +{
    1.73 +    MOZ_COUNT_DTOR(nsToolkit);
    1.74 +    gMouseTrailer = nullptr;
    1.75 +}
    1.76 +
    1.77 +void
    1.78 +nsToolkit::Startup(HMODULE hModule)
    1.79 +{
    1.80 +    nsToolkit::mDllInstance = hModule;
    1.81 +    WinUtils::Initialize();
    1.82 +    nsUXThemeData::Initialize();
    1.83 +}
    1.84 +
    1.85 +void
    1.86 +nsToolkit::Shutdown()
    1.87 +{
    1.88 +    delete gToolkit;
    1.89 +    gToolkit = nullptr;
    1.90 +}
    1.91 +
    1.92 +void
    1.93 +nsToolkit::StartAllowingD3D9()
    1.94 +{
    1.95 +  if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
    1.96 +    nsToolkit::GetToolkit()->mD3D9Timer->Cancel();
    1.97 +    nsWindow::StartAllowingD3D9(false);
    1.98 +  }
    1.99 +}
   1.100 +
   1.101 +//-------------------------------------------------------------------------
   1.102 +//
   1.103 +// Return the nsToolkit for the current thread.  If a toolkit does not
   1.104 +// yet exist, then one will be created...
   1.105 +//
   1.106 +//-------------------------------------------------------------------------
   1.107 +// static
   1.108 +nsToolkit* nsToolkit::GetToolkit()
   1.109 +{
   1.110 +  if (!gToolkit) {
   1.111 +    gToolkit = new nsToolkit();
   1.112 +  }
   1.113 +
   1.114 +  return gToolkit;
   1.115 +}
   1.116 +
   1.117 +
   1.118 +//-------------------------------------------------------------------------
   1.119 +//
   1.120 +//
   1.121 +//-------------------------------------------------------------------------
   1.122 +MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nullptr), mCaptureWindow(nullptr),
   1.123 +  mIsInCaptureMode(false), mEnabled(true)
   1.124 +{
   1.125 +}
   1.126 +//-------------------------------------------------------------------------
   1.127 +//
   1.128 +//
   1.129 +//-------------------------------------------------------------------------
   1.130 +MouseTrailer::~MouseTrailer()
   1.131 +{
   1.132 +  DestroyTimer();
   1.133 +}
   1.134 +//-------------------------------------------------------------------------
   1.135 +//
   1.136 +//
   1.137 +//-------------------------------------------------------------------------
   1.138 +void MouseTrailer::SetMouseTrailerWindow(HWND aWnd) 
   1.139 +{
   1.140 +  if (mMouseTrailerWindow != aWnd && mTimer) {
   1.141 +    // Make sure TimerProc is fired at least once for the old window
   1.142 +    TimerProc(nullptr, nullptr);
   1.143 +  }
   1.144 +  mMouseTrailerWindow = aWnd;
   1.145 +  CreateTimer();
   1.146 +}
   1.147 +
   1.148 +//-------------------------------------------------------------------------
   1.149 +//
   1.150 +//
   1.151 +//-------------------------------------------------------------------------
   1.152 +void MouseTrailer::SetCaptureWindow(HWND aWnd) 
   1.153 +{ 
   1.154 +  mCaptureWindow = aWnd;
   1.155 +  if (mCaptureWindow) {
   1.156 +    mIsInCaptureMode = true;
   1.157 +  }
   1.158 +}
   1.159 +
   1.160 +//-------------------------------------------------------------------------
   1.161 +//
   1.162 +//
   1.163 +//-------------------------------------------------------------------------
   1.164 +nsresult MouseTrailer::CreateTimer()
   1.165 +{
   1.166 +  if (mTimer || !mEnabled) {
   1.167 +    return NS_OK;
   1.168 +  } 
   1.169 +
   1.170 +  nsresult rv;
   1.171 +  mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
   1.172 +  NS_ENSURE_SUCCESS(rv, rv);
   1.173 +
   1.174 +  return mTimer->InitWithFuncCallback(TimerProc, nullptr, 200,
   1.175 +                                      nsITimer::TYPE_REPEATING_SLACK);
   1.176 +}
   1.177 +
   1.178 +//-------------------------------------------------------------------------
   1.179 +//
   1.180 +//
   1.181 +//-------------------------------------------------------------------------
   1.182 +void MouseTrailer::DestroyTimer()
   1.183 +{
   1.184 +  if (mTimer) {
   1.185 +    mTimer->Cancel();
   1.186 +    mTimer = nullptr;
   1.187 +  }
   1.188 +}
   1.189 +
   1.190 +//-------------------------------------------------------------------------
   1.191 +//
   1.192 +//
   1.193 +//-------------------------------------------------------------------------
   1.194 +void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
   1.195 +{
   1.196 +  MouseTrailer *mtrailer = nsToolkit::gMouseTrailer;
   1.197 +  NS_ASSERTION(mtrailer, "MouseTrailer still firing after deletion!");
   1.198 +
   1.199 +  // Check to see if we are in mouse capture mode,
   1.200 +  // Once capture ends we could still get back one more timer event.
   1.201 +  // Capture could end outside our window.
   1.202 +  // Also, for some reason when the mouse is on the frame it thinks that
   1.203 +  // it is inside the window that is being captured.
   1.204 +  if (mtrailer->mCaptureWindow) {
   1.205 +    if (mtrailer->mCaptureWindow != mtrailer->mMouseTrailerWindow) {
   1.206 +      return;
   1.207 +    }
   1.208 +  } else {
   1.209 +    if (mtrailer->mIsInCaptureMode) {
   1.210 +      // mMouseTrailerWindow could be bad from rolling over the frame, so clear 
   1.211 +      // it if we were capturing and now this is the first timer callback 
   1.212 +      // since we canceled the capture
   1.213 +      mtrailer->mMouseTrailerWindow = nullptr;
   1.214 +      mtrailer->mIsInCaptureMode = false;
   1.215 +      return;
   1.216 +    }
   1.217 +  }
   1.218 +
   1.219 +  if (mtrailer->mMouseTrailerWindow && ::IsWindow(mtrailer->mMouseTrailerWindow)) {
   1.220 +    POINT mp;
   1.221 +    DWORD pos = ::GetMessagePos();
   1.222 +    mp.x = GET_X_LPARAM(pos);
   1.223 +    mp.y = GET_Y_LPARAM(pos);
   1.224 +    HWND mouseWnd = ::WindowFromPoint(mp);
   1.225 +    if (mtrailer->mMouseTrailerWindow != mouseWnd) {
   1.226 +      // Notify someone that a mouse exit happened.
   1.227 +      PostMessage(mtrailer->mMouseTrailerWindow, WM_MOUSELEAVE, 0, 0);
   1.228 +
   1.229 +      // we are out of this window, destroy timer
   1.230 +      mtrailer->DestroyTimer();
   1.231 +      mtrailer->mMouseTrailerWindow = nullptr;
   1.232 +    }
   1.233 +  } else {
   1.234 +    mtrailer->DestroyTimer();
   1.235 +    mtrailer->mMouseTrailerWindow = nullptr;
   1.236 +  }
   1.237 +}
   1.238 +

mercurial