1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/winrt/MetroWidget.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1669 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "ContentHelper.h" 1.11 +#include "LayerManagerD3D10.h" 1.12 +#include "MetroWidget.h" 1.13 +#include "MetroApp.h" 1.14 +#include "mozilla/Preferences.h" 1.15 +#include "nsToolkit.h" 1.16 +#include "KeyboardLayout.h" 1.17 +#include "MetroUtils.h" 1.18 +#include "WinUtils.h" 1.19 +#include "nsToolkitCompsCID.h" 1.20 +#include "nsIAppStartup.h" 1.21 +#include "../resource.h" 1.22 +#include "nsIWidgetListener.h" 1.23 +#include "nsIPresShell.h" 1.24 +#include "nsPrintfCString.h" 1.25 +#include "nsWindowDefs.h" 1.26 +#include "FrameworkView.h" 1.27 +#include "nsTextStore.h" 1.28 +#include "Layers.h" 1.29 +#include "ClientLayerManager.h" 1.30 +#include "BasicLayers.h" 1.31 +#include "FrameMetrics.h" 1.32 +#include <windows.devices.input.h> 1.33 +#include "Windows.Graphics.Display.h" 1.34 +#include "DisplayInfo_sdk81.h" 1.35 +#include "nsNativeDragTarget.h" 1.36 +#ifdef MOZ_CRASHREPORTER 1.37 +#include "nsExceptionHandler.h" 1.38 +#endif 1.39 +#include "UIABridgePrivate.h" 1.40 +#include "WinMouseScrollHandler.h" 1.41 +#include "InputData.h" 1.42 +#include "mozilla/TextEvents.h" 1.43 +#include "mozilla/TouchEvents.h" 1.44 +#include "mozilla/MiscEvents.h" 1.45 + 1.46 +using namespace Microsoft::WRL; 1.47 +using namespace Microsoft::WRL::Wrappers; 1.48 + 1.49 +using namespace mozilla; 1.50 +using namespace mozilla::widget; 1.51 +using namespace mozilla::layers; 1.52 +using namespace mozilla::widget::winrt; 1.53 + 1.54 +using namespace ABI::Windows::ApplicationModel; 1.55 +using namespace ABI::Windows::ApplicationModel::Core; 1.56 +using namespace ABI::Windows::ApplicationModel::Activation; 1.57 +using namespace ABI::Windows::UI::Input; 1.58 +using namespace ABI::Windows::Devices::Input; 1.59 +using namespace ABI::Windows::UI::Core; 1.60 +using namespace ABI::Windows::System; 1.61 +using namespace ABI::Windows::Foundation; 1.62 +using namespace ABI::Windows::Foundation::Collections; 1.63 +using namespace ABI::Windows::Graphics::Display; 1.64 + 1.65 +#ifdef PR_LOGGING 1.66 +extern PRLogModuleInfo* gWindowsLog; 1.67 +#endif 1.68 + 1.69 +#if !defined(SM_CONVERTIBLESLATEMODE) 1.70 +#define SM_CONVERTIBLESLATEMODE 0x2003 1.71 +#endif 1.72 + 1.73 +static uint32_t gInstanceCount = 0; 1.74 +const char16_t* kMetroSubclassThisProp = L"MetroSubclassThisProp"; 1.75 +HWND MetroWidget::sICoreHwnd = nullptr; 1.76 + 1.77 +namespace mozilla { 1.78 +namespace widget { 1.79 +UINT sDefaultBrowserMsgId = RegisterWindowMessageW(L"DefaultBrowserClosing"); 1.80 +} } 1.81 + 1.82 +// WM_GETOBJECT id pulled from uia headers 1.83 +#define UiaRootObjectId -25 1.84 + 1.85 +namespace mozilla { 1.86 +namespace widget { 1.87 +namespace winrt { 1.88 +extern ComPtr<MetroApp> sMetroApp; 1.89 +extern ComPtr<IUIABridge> gProviderRoot; 1.90 +} } } 1.91 + 1.92 +namespace { 1.93 + 1.94 + void SendInputs(uint32_t aModifiers, INPUT* aExtraInputs, uint32_t aExtraInputsLen) 1.95 + { 1.96 + // keySequence holds the virtual key values of each of the keys we intend 1.97 + // to press 1.98 + nsAutoTArray<KeyPair,32> keySequence; 1.99 + for (uint32_t i = 0; i < ArrayLength(sModifierKeyMap); ++i) { 1.100 + const uint32_t* map = sModifierKeyMap[i]; 1.101 + if (aModifiers & map[0]) { 1.102 + keySequence.AppendElement(KeyPair(map[1], map[2])); 1.103 + } 1.104 + } 1.105 + 1.106 + uint32_t const len = keySequence.Length() * 2 + aExtraInputsLen; 1.107 + 1.108 + // The `inputs` array is a sequence of input events that will happen 1.109 + // serially. We set the array up so that each modifier key is pressed 1.110 + // down, then the additional input events happen, 1.111 + // then each modifier key is released in reverse order of when 1.112 + // it was pressed down. We pass this array to `SendInput`. 1.113 + // 1.114 + // inputs[0]: modifier key (e.g. shift, ctrl, etc) down 1.115 + // ... ... 1.116 + // inputs[keySequence.Length()-1]: modifier key (e.g. shift, ctrl, etc) down 1.117 + // inputs[keySequence.Length()]: aExtraInputs[0] 1.118 + // inputs[keySequence.Length()+1]: aExtraInputs[1] 1.119 + // ... ... 1.120 + // inputs[keySequence.Length() + aExtraInputsLen - 1]: aExtraInputs[aExtraInputsLen - 1] 1.121 + // inputs[keySequence.Length() + aExtraInputsLen]: modifier key (e.g. shift, ctrl, etc) up 1.122 + // ... ... 1.123 + // inputs[len-1]: modifier key (e.g. shift, ctrl, etc) up 1.124 + INPUT* inputs = new INPUT[len]; 1.125 + memset(inputs, 0, len * sizeof(INPUT)); 1.126 + for (uint32_t i = 0; i < keySequence.Length(); ++i) { 1.127 + inputs[i].type = inputs[len-i-1].type = INPUT_KEYBOARD; 1.128 + inputs[i].ki.wVk = inputs[len-i-1].ki.wVk = keySequence[i].mSpecific 1.129 + ? keySequence[i].mSpecific 1.130 + : keySequence[i].mGeneral; 1.131 + inputs[len-i-1].ki.dwFlags |= KEYEVENTF_KEYUP; 1.132 + } 1.133 + for (uint32_t i = 0; i < aExtraInputsLen; i++) { 1.134 + inputs[keySequence.Length()+i] = aExtraInputs[i]; 1.135 + } 1.136 + WinUtils::Log(" Sending inputs"); 1.137 + for (uint32_t i = 0; i < len; i++) { 1.138 + if (inputs[i].type == INPUT_KEYBOARD) { 1.139 + WinUtils::Log(" Key press: 0x%x %s", 1.140 + inputs[i].ki.wVk, 1.141 + inputs[i].ki.dwFlags & KEYEVENTF_KEYUP 1.142 + ? "UP" 1.143 + : "DOWN"); 1.144 + } else if(inputs[i].type == INPUT_MOUSE) { 1.145 + WinUtils::Log(" Mouse input: 0x%x 0x%x", 1.146 + inputs[i].mi.dwFlags, 1.147 + inputs[i].mi.mouseData); 1.148 + } else { 1.149 + WinUtils::Log(" Unknown input type!"); 1.150 + } 1.151 + } 1.152 + ::SendInput(len, inputs, sizeof(INPUT)); 1.153 + delete[] inputs; 1.154 + 1.155 + // The inputs have been sent, and the WM_* messages they generate are 1.156 + // waiting to be processed by our event loop. Now we manually pump 1.157 + // those messages so that, upon our return, all the inputs have been 1.158 + // processed. 1.159 + WinUtils::Log(" Inputs sent. Waiting for input messages to clear"); 1.160 + MSG msg; 1.161 + while (WinUtils::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { 1.162 + if (nsTextStore::ProcessRawKeyMessage(msg)) { 1.163 + continue; // the message is consumed by TSF 1.164 + } 1.165 + ::TranslateMessage(&msg); 1.166 + ::DispatchMessage(&msg); 1.167 + WinUtils::Log(" Dispatched 0x%x 0x%x 0x%x", msg.message, msg.wParam, msg.lParam); 1.168 + } 1.169 + WinUtils::Log(" No more input messages"); 1.170 + } 1.171 +} 1.172 + 1.173 +NS_IMPL_ISUPPORTS_INHERITED0(MetroWidget, nsBaseWidget) 1.174 + 1.175 +MetroWidget::MetroWidget() : 1.176 + mTransparencyMode(eTransparencyOpaque), 1.177 + mWnd(nullptr), 1.178 + mMetroWndProc(nullptr), 1.179 + mTempBasicLayerInUse(false), 1.180 + mRootLayerTreeId(), 1.181 + nsWindowBase() 1.182 +{ 1.183 + // Global initialization 1.184 + if (!gInstanceCount) { 1.185 + UserActivity(); 1.186 + nsTextStore::Initialize(); 1.187 + MouseScrollHandler::Initialize(); 1.188 + KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0)); 1.189 + } // !gInstanceCount 1.190 + gInstanceCount++; 1.191 +} 1.192 + 1.193 +MetroWidget::~MetroWidget() 1.194 +{ 1.195 + LogThis(); 1.196 + 1.197 + gInstanceCount--; 1.198 + 1.199 + // Global shutdown 1.200 + if (!gInstanceCount) { 1.201 + APZController::sAPZC = nullptr; 1.202 + nsTextStore::Terminate(); 1.203 + } // !gInstanceCount 1.204 +} 1.205 + 1.206 +static bool gTopLevelAssigned = false; 1.207 +NS_IMETHODIMP 1.208 +MetroWidget::Create(nsIWidget *aParent, 1.209 + nsNativeWidget aNativeParent, 1.210 + const nsIntRect &aRect, 1.211 + nsDeviceContext *aContext, 1.212 + nsWidgetInitData *aInitData) 1.213 +{ 1.214 + LogFunction(); 1.215 + 1.216 + nsWidgetInitData defaultInitData; 1.217 + if (!aInitData) 1.218 + aInitData = &defaultInitData; 1.219 + 1.220 + mWindowType = aInitData->mWindowType; 1.221 + 1.222 + // Ensure that the toolkit is created. 1.223 + nsToolkit::GetToolkit(); 1.224 + 1.225 + BaseCreate(aParent, aRect, aContext, aInitData); 1.226 + 1.227 + if (mWindowType != eWindowType_toplevel) { 1.228 + switch(mWindowType) { 1.229 + case eWindowType_dialog: 1.230 + WinUtils::Log("eWindowType_dialog window requested, returning failure."); 1.231 + break; 1.232 + case eWindowType_child: 1.233 + WinUtils::Log("eWindowType_child window requested, returning failure."); 1.234 + break; 1.235 + case eWindowType_popup: 1.236 + WinUtils::Log("eWindowType_popup window requested, returning failure."); 1.237 + break; 1.238 + case eWindowType_plugin: 1.239 + WinUtils::Log("eWindowType_plugin window requested, returning failure."); 1.240 + break; 1.241 + // we should support toolkit's eWindowType_invisible at some point. 1.242 + case eWindowType_invisible: 1.243 + WinUtils::Log("eWindowType_invisible window requested, this doesn't actually exist!"); 1.244 + return NS_OK; 1.245 + } 1.246 + NS_WARNING("Invalid window type requested."); 1.247 + return NS_ERROR_FAILURE; 1.248 + } 1.249 + 1.250 + if (gTopLevelAssigned) { 1.251 + // Need to accept so that the mochitest-chrome test harness window 1.252 + // can be created. 1.253 + NS_WARNING("New eWindowType_toplevel window requested after FrameworkView widget created."); 1.254 + NS_WARNING("Widget created but the physical window does not exist! Fix me!"); 1.255 + return NS_OK; 1.256 + } 1.257 + 1.258 + // the main widget gets created first 1.259 + gTopLevelAssigned = true; 1.260 + sMetroApp->SetWidget(this); 1.261 + WinUtils::SetNSWindowBasePtr(mWnd, this); 1.262 + 1.263 + if (mWidgetListener) { 1.264 + mWidgetListener->WindowActivated(); 1.265 + } 1.266 + 1.267 + return NS_OK; 1.268 +} 1.269 + 1.270 +void 1.271 +MetroWidget::SetView(FrameworkView* aView) 1.272 +{ 1.273 + mView = aView; 1.274 + // If we've already set this up, it points to a useless 1.275 + // layer manager, so reset it. 1.276 + mLayerManager = nullptr; 1.277 +} 1.278 + 1.279 +NS_IMETHODIMP 1.280 +MetroWidget::Destroy() 1.281 +{ 1.282 + if (mOnDestroyCalled) 1.283 + return NS_OK; 1.284 + WinUtils::Log("[%X] %s mWnd=%X type=%d", this, __FUNCTION__, mWnd, mWindowType); 1.285 + mOnDestroyCalled = true; 1.286 + 1.287 + nsCOMPtr<nsIWidget> kungFuDeathGrip(this); 1.288 + 1.289 + if (ShouldUseAPZC()) { 1.290 + nsresult rv; 1.291 + nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv); 1.292 + if (NS_SUCCEEDED(rv)) { 1.293 + observerService->RemoveObserver(this, "apzc-scroll-offset-changed"); 1.294 + observerService->RemoveObserver(this, "apzc-zoom-to-rect"); 1.295 + observerService->RemoveObserver(this, "apzc-disable-zoom"); 1.296 + } 1.297 + } 1.298 + 1.299 + RemoveSubclass(); 1.300 + NotifyWindowDestroyed(); 1.301 + 1.302 + // Prevent the widget from sending additional events. 1.303 + mWidgetListener = nullptr; 1.304 + mAttachedWidgetListener = nullptr; 1.305 + 1.306 + // Release references to children, device context, toolkit, and app shell. 1.307 + nsBaseWidget::Destroy(); 1.308 + nsBaseWidget::OnDestroy(); 1.309 + WinUtils::SetNSWindowBasePtr(mWnd, nullptr); 1.310 + 1.311 + if (mLayerManager) { 1.312 + mLayerManager->Destroy(); 1.313 + } 1.314 + 1.315 + mLayerManager = nullptr; 1.316 + mView = nullptr; 1.317 + mIdleService = nullptr; 1.318 + mWnd = nullptr; 1.319 + 1.320 + return NS_OK; 1.321 +} 1.322 + 1.323 +NS_IMETHODIMP 1.324 +MetroWidget::SetParent(nsIWidget *aNewParent) 1.325 +{ 1.326 + return NS_OK; 1.327 +} 1.328 + 1.329 +NS_IMETHODIMP 1.330 +MetroWidget::Show(bool bState) 1.331 +{ 1.332 + return NS_OK; 1.333 +} 1.334 + 1.335 +uint32_t 1.336 +MetroWidget::GetMaxTouchPoints() const 1.337 +{ 1.338 + ComPtr<IPointerDeviceStatics> deviceStatics; 1.339 + 1.340 + HRESULT hr = GetActivationFactory( 1.341 + HStringReference(RuntimeClass_Windows_Devices_Input_PointerDevice).Get(), 1.342 + deviceStatics.GetAddressOf()); 1.343 + 1.344 + if (FAILED(hr)) { 1.345 + return 0; 1.346 + } 1.347 + 1.348 + ComPtr< IVectorView<PointerDevice*> > deviceList; 1.349 + hr = deviceStatics->GetPointerDevices(&deviceList); 1.350 + 1.351 + if (FAILED(hr)) { 1.352 + return 0; 1.353 + } 1.354 + 1.355 + uint32_t deviceNum = 0; 1.356 + deviceList->get_Size(&deviceNum); 1.357 + 1.358 + uint32_t maxTouchPoints = 0; 1.359 + for (uint32_t index = 0; index < deviceNum; ++index) { 1.360 + ComPtr<IPointerDevice> device; 1.361 + PointerDeviceType deviceType; 1.362 + 1.363 + if (FAILED(deviceList->GetAt(index, device.GetAddressOf()))) { 1.364 + continue; 1.365 + } 1.366 + 1.367 + if (FAILED(device->get_PointerDeviceType(&deviceType))) { 1.368 + continue; 1.369 + } 1.370 + 1.371 + if (deviceType == PointerDeviceType_Touch) { 1.372 + uint32_t deviceMaxTouchPoints = 0; 1.373 + device->get_MaxContacts(&deviceMaxTouchPoints); 1.374 + maxTouchPoints = std::max(maxTouchPoints, deviceMaxTouchPoints); 1.375 + } 1.376 + } 1.377 + 1.378 + return maxTouchPoints; 1.379 +} 1.380 + 1.381 +NS_IMETHODIMP 1.382 +MetroWidget::IsVisible(bool & aState) 1.383 +{ 1.384 + aState = mView->IsVisible(); 1.385 + return NS_OK; 1.386 +} 1.387 + 1.388 +bool 1.389 +MetroWidget::IsVisible() const 1.390 +{ 1.391 + if (!mView) 1.392 + return false; 1.393 + return mView->IsVisible(); 1.394 +} 1.395 + 1.396 +NS_IMETHODIMP 1.397 +MetroWidget::EnableDragDrop(bool aEnable) { 1.398 + if (aEnable) { 1.399 + if (nullptr == mNativeDragTarget) { 1.400 + mNativeDragTarget = new nsNativeDragTarget(this); 1.401 + if (!mNativeDragTarget) { 1.402 + return NS_ERROR_FAILURE; 1.403 + } 1.404 + } 1.405 + 1.406 + HRESULT hr = ::RegisterDragDrop(mWnd, static_cast<LPDROPTARGET>(mNativeDragTarget)); 1.407 + return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; 1.408 + } else { 1.409 + if (nullptr == mNativeDragTarget) { 1.410 + return NS_OK; 1.411 + } 1.412 + 1.413 + HRESULT hr = ::RevokeDragDrop(mWnd); 1.414 + return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; 1.415 + } 1.416 +} 1.417 + 1.418 +NS_IMETHODIMP 1.419 +MetroWidget::IsEnabled(bool *aState) 1.420 +{ 1.421 + *aState = mView->IsEnabled(); 1.422 + return NS_OK; 1.423 +} 1.424 + 1.425 +bool 1.426 +MetroWidget::IsEnabled() const 1.427 +{ 1.428 + if (!mView) 1.429 + return false; 1.430 + return mView->IsEnabled(); 1.431 +} 1.432 + 1.433 +NS_IMETHODIMP 1.434 +MetroWidget::Enable(bool bState) 1.435 +{ 1.436 + return NS_OK; 1.437 +} 1.438 + 1.439 +NS_IMETHODIMP 1.440 +MetroWidget::GetBounds(nsIntRect &aRect) 1.441 +{ 1.442 + if (mView) { 1.443 + mView->GetBounds(aRect); 1.444 + } else { 1.445 + nsIntRect rect(0,0,0,0); 1.446 + aRect = rect; 1.447 + } 1.448 + return NS_OK; 1.449 +} 1.450 + 1.451 +NS_IMETHODIMP 1.452 +MetroWidget::GetScreenBounds(nsIntRect &aRect) 1.453 +{ 1.454 + if (mView) { 1.455 + mView->GetBounds(aRect); 1.456 + } else { 1.457 + nsIntRect rect(0,0,0,0); 1.458 + aRect = rect; 1.459 + } 1.460 + return NS_OK; 1.461 +} 1.462 + 1.463 +NS_IMETHODIMP 1.464 +MetroWidget::GetClientBounds(nsIntRect &aRect) 1.465 +{ 1.466 + if (mView) { 1.467 + mView->GetBounds(aRect); 1.468 + } else { 1.469 + nsIntRect rect(0,0,0,0); 1.470 + aRect = rect; 1.471 + } 1.472 + return NS_OK; 1.473 +} 1.474 + 1.475 +NS_IMETHODIMP 1.476 +MetroWidget::SetCursor(nsCursor aCursor) 1.477 +{ 1.478 + if (!mView) 1.479 + return NS_ERROR_FAILURE; 1.480 + 1.481 + switch (aCursor) { 1.482 + case eCursor_select: 1.483 + mView->SetCursor(CoreCursorType::CoreCursorType_IBeam); 1.484 + break; 1.485 + case eCursor_wait: 1.486 + mView->SetCursor(CoreCursorType::CoreCursorType_Wait); 1.487 + break; 1.488 + case eCursor_hyperlink: 1.489 + mView->SetCursor(CoreCursorType::CoreCursorType_Hand); 1.490 + break; 1.491 + case eCursor_standard: 1.492 + mView->SetCursor(CoreCursorType::CoreCursorType_Arrow); 1.493 + break; 1.494 + case eCursor_n_resize: 1.495 + case eCursor_s_resize: 1.496 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthSouth); 1.497 + break; 1.498 + case eCursor_w_resize: 1.499 + case eCursor_e_resize: 1.500 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeWestEast); 1.501 + break; 1.502 + case eCursor_nw_resize: 1.503 + case eCursor_se_resize: 1.504 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthwestSoutheast); 1.505 + break; 1.506 + case eCursor_ne_resize: 1.507 + case eCursor_sw_resize: 1.508 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNortheastSouthwest); 1.509 + break; 1.510 + case eCursor_crosshair: 1.511 + mView->SetCursor(CoreCursorType::CoreCursorType_Cross); 1.512 + break; 1.513 + case eCursor_move: 1.514 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeAll); 1.515 + break; 1.516 + case eCursor_help: 1.517 + mView->SetCursor(CoreCursorType::CoreCursorType_Help); 1.518 + break; 1.519 + // CSS3 custom cursors 1.520 + case eCursor_copy: 1.521 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_COPY); 1.522 + break; 1.523 + case eCursor_alias: 1.524 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ALIAS); 1.525 + break; 1.526 + case eCursor_cell: 1.527 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_CELL); 1.528 + break; 1.529 + case eCursor_grab: 1.530 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_GRAB); 1.531 + break; 1.532 + case eCursor_grabbing: 1.533 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_GRABBING); 1.534 + break; 1.535 + case eCursor_spinning: 1.536 + mView->SetCursor(CoreCursorType::CoreCursorType_Wait); 1.537 + break; 1.538 + case eCursor_context_menu: 1.539 + mView->SetCursor(CoreCursorType::CoreCursorType_Arrow); 1.540 + break; 1.541 + case eCursor_zoom_in: 1.542 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ZOOMIN); 1.543 + break; 1.544 + case eCursor_zoom_out: 1.545 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ZOOMOUT); 1.546 + break; 1.547 + case eCursor_not_allowed: 1.548 + case eCursor_no_drop: 1.549 + mView->SetCursor(CoreCursorType::CoreCursorType_UniversalNo); 1.550 + break; 1.551 + case eCursor_col_resize: 1.552 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_COLRESIZE); 1.553 + break; 1.554 + case eCursor_row_resize: 1.555 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ROWRESIZE); 1.556 + break; 1.557 + case eCursor_vertical_text: 1.558 + mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_VERTICALTEXT); 1.559 + break; 1.560 + case eCursor_all_scroll: 1.561 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeAll); 1.562 + break; 1.563 + case eCursor_nesw_resize: 1.564 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNortheastSouthwest); 1.565 + break; 1.566 + case eCursor_nwse_resize: 1.567 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthwestSoutheast); 1.568 + break; 1.569 + case eCursor_ns_resize: 1.570 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthSouth); 1.571 + break; 1.572 + case eCursor_ew_resize: 1.573 + mView->SetCursor(CoreCursorType::CoreCursorType_SizeWestEast); 1.574 + break; 1.575 + case eCursor_none: 1.576 + mView->ClearCursor(); 1.577 + break; 1.578 + default: 1.579 + NS_WARNING("Invalid cursor type"); 1.580 + break; 1.581 + } 1.582 + return NS_OK; 1.583 +} 1.584 + 1.585 +nsresult 1.586 +MetroWidget::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, 1.587 + int32_t aNativeKeyCode, 1.588 + uint32_t aModifierFlags, 1.589 + const nsAString& aCharacters, 1.590 + const nsAString& aUnmodifiedCharacters) 1.591 +{ 1.592 + KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance(); 1.593 + return keyboardLayout->SynthesizeNativeKeyEvent( 1.594 + this, aNativeKeyboardLayout, aNativeKeyCode, aModifierFlags, 1.595 + aCharacters, aUnmodifiedCharacters); 1.596 +} 1.597 + 1.598 +nsresult 1.599 +MetroWidget::SynthesizeNativeMouseEvent(nsIntPoint aPoint, 1.600 + uint32_t aNativeMessage, 1.601 + uint32_t aModifierFlags) 1.602 +{ 1.603 + WinUtils::Log("ENTERED SynthesizeNativeMouseEvent"); 1.604 + 1.605 + INPUT inputs[2]; 1.606 + memset(inputs, 0, 2*sizeof(INPUT)); 1.607 + inputs[0].type = inputs[1].type = INPUT_MOUSE; 1.608 + inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; 1.609 + // Inexplicably, the x and y coordinates that we want to move the mouse to 1.610 + // are specified as values in the range (0, 65535). (0,0) represents the 1.611 + // top left of the primary monitor and (65535, 65535) represents the 1.612 + // bottom right of the primary monitor. 1.613 + inputs[0].mi.dx = (aPoint.x * 65535) / ::GetSystemMetrics(SM_CXSCREEN); 1.614 + inputs[0].mi.dy = (aPoint.y * 65535) / ::GetSystemMetrics(SM_CYSCREEN); 1.615 + inputs[1].mi.dwFlags = aNativeMessage; 1.616 + SendInputs(aModifierFlags, inputs, 2); 1.617 + 1.618 + WinUtils::Log("Exiting SynthesizeNativeMouseEvent"); 1.619 + return NS_OK; 1.620 +} 1.621 + 1.622 +nsresult 1.623 +MetroWidget::SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint, 1.624 + uint32_t aNativeMessage, 1.625 + double aDeltaX, 1.626 + double aDeltaY, 1.627 + double aDeltaZ, 1.628 + uint32_t aModifierFlags, 1.629 + uint32_t aAdditionalFlags) 1.630 +{ 1.631 + return MouseScrollHandler::SynthesizeNativeMouseScrollEvent( 1.632 + this, aPoint, aNativeMessage, 1.633 + (aNativeMessage == WM_MOUSEWHEEL || aNativeMessage == WM_VSCROLL) ? 1.634 + static_cast<int32_t>(aDeltaY) : static_cast<int32_t>(aDeltaX), 1.635 + aModifierFlags, aAdditionalFlags); 1.636 +} 1.637 + 1.638 +static void 1.639 +CloseGesture() 1.640 +{ 1.641 + LogFunction(); 1.642 + nsCOMPtr<nsIAppStartup> appStartup = 1.643 + do_GetService(NS_APPSTARTUP_CONTRACTID); 1.644 + if (appStartup) { 1.645 + appStartup->Quit(nsIAppStartup::eForceQuit); 1.646 + } 1.647 +} 1.648 + 1.649 +// Async event sending for mouse and keyboard input. 1.650 + 1.651 +// defined in nsWindowBase, called from shared module WinMouseScrollHandler. 1.652 +bool 1.653 +MetroWidget::DispatchScrollEvent(mozilla::WidgetGUIEvent* aEvent) 1.654 +{ 1.655 + WidgetGUIEvent* newEvent = nullptr; 1.656 + switch(aEvent->eventStructType) { 1.657 + case NS_WHEEL_EVENT: 1.658 + { 1.659 + WidgetWheelEvent* oldEvent = aEvent->AsWheelEvent(); 1.660 + WidgetWheelEvent* wheelEvent = 1.661 + new WidgetWheelEvent(oldEvent->mFlags.mIsTrusted, oldEvent->message, oldEvent->widget); 1.662 + wheelEvent->AssignWheelEventData(*oldEvent, true); 1.663 + newEvent = static_cast<WidgetGUIEvent*>(wheelEvent); 1.664 + } 1.665 + break; 1.666 + case NS_CONTENT_COMMAND_EVENT: 1.667 + { 1.668 + WidgetContentCommandEvent* oldEvent = aEvent->AsContentCommandEvent(); 1.669 + WidgetContentCommandEvent* cmdEvent = 1.670 + new WidgetContentCommandEvent(oldEvent->mFlags.mIsTrusted, oldEvent->message, oldEvent->widget); 1.671 + cmdEvent->AssignContentCommandEventData(*oldEvent, true); 1.672 + newEvent = static_cast<WidgetGUIEvent*>(cmdEvent); 1.673 + } 1.674 + break; 1.675 + default: 1.676 + MOZ_CRASH("unknown event in DispatchScrollEvent"); 1.677 + break; 1.678 + } 1.679 + mEventQueue.Push(newEvent); 1.680 + nsCOMPtr<nsIRunnable> runnable = 1.681 + NS_NewRunnableMethod(this, &MetroWidget::DeliverNextScrollEvent); 1.682 + NS_DispatchToCurrentThread(runnable); 1.683 + return false; 1.684 +} 1.685 + 1.686 +void 1.687 +MetroWidget::DeliverNextScrollEvent() 1.688 +{ 1.689 + WidgetGUIEvent* event = 1.690 + static_cast<WidgetInputEvent*>(mEventQueue.PopFront()); 1.691 + DispatchWindowEvent(event); 1.692 + delete event; 1.693 +} 1.694 + 1.695 +// defined in nsWindowBase, called from shared module KeyboardLayout. 1.696 +bool 1.697 +MetroWidget::DispatchKeyboardEvent(WidgetGUIEvent* aEvent) 1.698 +{ 1.699 + MOZ_ASSERT(aEvent); 1.700 + WidgetKeyboardEvent* oldKeyEvent = aEvent->AsKeyboardEvent(); 1.701 + WidgetKeyboardEvent* keyEvent = 1.702 + new WidgetKeyboardEvent(oldKeyEvent->mFlags.mIsTrusted, 1.703 + oldKeyEvent->message, oldKeyEvent->widget); 1.704 + // XXX note this leaves pluginEvent null, which is fine for now. 1.705 + keyEvent->AssignKeyEventData(*oldKeyEvent, true); 1.706 + mKeyEventQueue.Push(keyEvent); 1.707 + nsCOMPtr<nsIRunnable> runnable = 1.708 + NS_NewRunnableMethod(this, &MetroWidget::DeliverNextKeyboardEvent); 1.709 + NS_DispatchToCurrentThread(runnable); 1.710 + return false; 1.711 +} 1.712 + 1.713 +// Used in conjunction with mKeyEventQueue to find a keypress event 1.714 +// that should not be delivered due to the return result of the 1.715 +// preceeding keydown. 1.716 +class KeyQueryIdAndCancel : public nsDequeFunctor { 1.717 +public: 1.718 + KeyQueryIdAndCancel(uint32_t aIdToCancel) : 1.719 + mId(aIdToCancel) { 1.720 + } 1.721 + virtual void* operator() (void* aObject) { 1.722 + WidgetKeyboardEvent* event = static_cast<WidgetKeyboardEvent*>(aObject); 1.723 + if (event->mUniqueId == mId) { 1.724 + event->mFlags.mPropagationStopped = true; 1.725 + } 1.726 + return nullptr; 1.727 + } 1.728 +protected: 1.729 + uint32_t mId; 1.730 +}; 1.731 + 1.732 +void 1.733 +MetroWidget::DeliverNextKeyboardEvent() 1.734 +{ 1.735 + WidgetKeyboardEvent* event = 1.736 + static_cast<WidgetKeyboardEvent*>(mKeyEventQueue.PopFront()); 1.737 + if (event->mFlags.mPropagationStopped) { 1.738 + // This can happen if a keypress was previously cancelled. 1.739 + delete event; 1.740 + return; 1.741 + } 1.742 + 1.743 + if (DispatchWindowEvent(event) && event->message == NS_KEY_DOWN) { 1.744 + // keydown events may be followed by multiple keypress events which 1.745 + // shouldn't be sent if preventDefault is called on keydown. 1.746 + KeyQueryIdAndCancel query(event->mUniqueId); 1.747 + mKeyEventQueue.ForEach(query); 1.748 + } 1.749 + delete event; 1.750 +} 1.751 + 1.752 +// static 1.753 +LRESULT CALLBACK 1.754 +MetroWidget::StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) 1.755 +{ 1.756 + MetroWidget* self = reinterpret_cast<MetroWidget*>( 1.757 + GetProp(aWnd, kMetroSubclassThisProp)); 1.758 + if (!self) { 1.759 + NS_NOTREACHED("Missing 'this' prop on subclassed metro window, this is bad."); 1.760 + return 0; 1.761 + } 1.762 + return self->WindowProcedure(aWnd, aMsg, aWParam, aLParam); 1.763 +} 1.764 + 1.765 +LRESULT 1.766 +MetroWidget::WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) 1.767 +{ 1.768 + if(sDefaultBrowserMsgId == aMsg) { 1.769 + CloseGesture(); 1.770 + } else if (WM_SETTINGCHANGE == aMsg) { 1.771 + if (aLParam && !wcsicmp(L"ConvertibleSlateMode", (wchar_t*)aLParam)) { 1.772 + // If we're switching away from slate mode, switch to Desktop for 1.773 + // hardware that supports this feature if the pref is set. 1.774 + if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0 && 1.775 + Preferences::GetBool("browser.shell.metro-auto-switch-enabled", 1.776 + false)) { 1.777 + nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID)); 1.778 + if (appStartup) { 1.779 + appStartup->Quit(nsIAppStartup::eForceQuit | nsIAppStartup::eRestart); 1.780 + } 1.781 + } 1.782 + } 1.783 + } 1.784 + 1.785 + // Indicates if we should hand messages to the default windows 1.786 + // procedure for processing. 1.787 + bool processDefault = true; 1.788 + 1.789 + // The result returned if we do not do default processing. 1.790 + LRESULT processResult = 0; 1.791 + 1.792 + MSGResult msgResult(&processResult); 1.793 + MouseScrollHandler::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult); 1.794 + if (msgResult.mConsumed) { 1.795 + return processResult; 1.796 + } 1.797 + 1.798 + nsTextStore::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult); 1.799 + if (msgResult.mConsumed) { 1.800 + return processResult; 1.801 + } 1.802 + 1.803 + switch (aMsg) { 1.804 + case WM_POWERBROADCAST: 1.805 + { 1.806 + switch (aWParam) 1.807 + { 1.808 + case PBT_APMSUSPEND: 1.809 + MetroApp::PostSleepWakeNotification(true); 1.810 + break; 1.811 + case PBT_APMRESUMEAUTOMATIC: 1.812 + case PBT_APMRESUMECRITICAL: 1.813 + case PBT_APMRESUMESUSPEND: 1.814 + MetroApp::PostSleepWakeNotification(false); 1.815 + break; 1.816 + } 1.817 + break; 1.818 + } 1.819 + 1.820 + // Keyboard handling is passed to KeyboardLayout, which delivers gecko events 1.821 + // via DispatchKeyboardEvent. 1.822 + 1.823 + case WM_KEYDOWN: 1.824 + case WM_SYSKEYDOWN: 1.825 + { 1.826 + MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); 1.827 + // If this method doesn't call NativeKey::HandleKeyDownMessage(), this 1.828 + // method must clean up the redirected message information itself. For 1.829 + // more information, see above comment of 1.830 + // RedirectedKeyDownMessageManager::AutoFlusher class definition in 1.831 + // KeyboardLayout.h. 1.832 + RedirectedKeyDownMessageManager::AutoFlusher 1.833 + redirectedMsgFlusher(this, msg); 1.834 + 1.835 + if (nsTextStore::IsComposingOn(this)) { 1.836 + break; 1.837 + } 1.838 + 1.839 + ModifierKeyState modKeyState; 1.840 + NativeKey nativeKey(this, msg, modKeyState); 1.841 + processDefault = !nativeKey.HandleKeyDownMessage(); 1.842 + // HandleKeyDownMessage cleaned up the redirected message information 1.843 + // itself, so, we should do nothing. 1.844 + redirectedMsgFlusher.Cancel(); 1.845 + break; 1.846 + } 1.847 + 1.848 + case WM_KEYUP: 1.849 + case WM_SYSKEYUP: 1.850 + { 1.851 + if (nsTextStore::IsComposingOn(this)) { 1.852 + break; 1.853 + } 1.854 + 1.855 + MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); 1.856 + ModifierKeyState modKeyState; 1.857 + NativeKey nativeKey(this, msg, modKeyState); 1.858 + processDefault = !nativeKey.HandleKeyUpMessage(); 1.859 + break; 1.860 + } 1.861 + 1.862 + case WM_CHAR: 1.863 + case WM_SYSCHAR: 1.864 + { 1.865 + if (nsTextStore::IsComposingOn(this)) { 1.866 + nsTextStore::CommitComposition(false); 1.867 + } 1.868 + 1.869 + MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); 1.870 + ModifierKeyState modKeyState; 1.871 + NativeKey nativeKey(this, msg, modKeyState); 1.872 + processDefault = !nativeKey.HandleCharMessage(msg); 1.873 + break; 1.874 + } 1.875 + 1.876 + case WM_INPUTLANGCHANGE: 1.877 + { 1.878 + KeyboardLayout::GetInstance()-> 1.879 + OnLayoutChange(reinterpret_cast<HKL>(aLParam)); 1.880 + processResult = 1; 1.881 + break; 1.882 + } 1.883 + 1.884 + case WM_APPCOMMAND: 1.885 + processDefault = HandleAppCommandMsg(aWParam, aLParam, &processResult); 1.886 + break; 1.887 + 1.888 + case WM_GETOBJECT: 1.889 + { 1.890 + DWORD dwObjId = (LPARAM)(DWORD) aLParam; 1.891 + // Passing this to CallWindowProc can result in a failure due to a timing issue 1.892 + // in winrt core window server code, so we call it directly here. Also, it's not 1.893 + // clear Windows::UI::Core::WindowServer::OnAutomationProviderRequestedEvent is 1.894 + // compatible with metro enabled desktop browsers, it makes an initial call to 1.895 + // UiaReturnRawElementProvider passing the return result from FrameworkView 1.896 + // OnAutomationProviderRequested as the hwnd (me scratches head) which results in 1.897 + // GetLastError always being set to invalid handle (6) after CallWindowProc returns. 1.898 + if (dwObjId == UiaRootObjectId && gProviderRoot) { 1.899 + ComPtr<IRawElementProviderSimple> simple; 1.900 + gProviderRoot.As(&simple); 1.901 + if (simple) { 1.902 + LRESULT res = UiaReturnRawElementProvider(aWnd, aWParam, aLParam, simple.Get()); 1.903 + if (res) { 1.904 + return res; 1.905 + } 1.906 + NS_ASSERTION(res, "UiaReturnRawElementProvider failed!"); 1.907 + WinUtils::Log("UiaReturnRawElementProvider failed! GetLastError=%X", GetLastError()); 1.908 + } 1.909 + } 1.910 + break; 1.911 + } 1.912 + 1.913 + default: 1.914 + { 1.915 + break; 1.916 + } 1.917 + } 1.918 + 1.919 + if (processDefault) { 1.920 + return CallWindowProc(mMetroWndProc, aWnd, aMsg, aWParam, 1.921 + aLParam); 1.922 + } 1.923 + return processResult; 1.924 +} 1.925 + 1.926 +static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 1.927 +{ 1.928 + WCHAR className[56]; 1.929 + if (GetClassNameW(hwnd, className, sizeof(className)/sizeof(WCHAR)) && 1.930 + !wcscmp(L"Windows.UI.Core.CoreWindow", className)) { 1.931 + DWORD processID = 0; 1.932 + GetWindowThreadProcessId(hwnd, &processID); 1.933 + if (processID && processID == GetCurrentProcessId()) { 1.934 + *((HWND*)lParam) = hwnd; 1.935 + return FALSE; 1.936 + } 1.937 + } 1.938 + return TRUE; 1.939 +} 1.940 + 1.941 +void 1.942 +MetroWidget::FindMetroWindow() 1.943 +{ 1.944 + LogFunction(); 1.945 + if (mWnd) 1.946 + return; 1.947 + EnumWindows(EnumWindowsProc, (LPARAM)&mWnd); 1.948 + NS_ASSERTION(mWnd, "Couldn't find our metro CoreWindow, this is bad."); 1.949 + 1.950 + // subclass it 1.951 + SetSubclass(); 1.952 + sICoreHwnd = mWnd; 1.953 + return; 1.954 +} 1.955 + 1.956 +void 1.957 +MetroWidget::SetSubclass() 1.958 +{ 1.959 + if (!mWnd) { 1.960 + NS_NOTREACHED("SetSubclass called without a valid hwnd."); 1.961 + return; 1.962 + } 1.963 + 1.964 + WNDPROC wndProc = reinterpret_cast<WNDPROC>( 1.965 + GetWindowLongPtr(mWnd, GWLP_WNDPROC)); 1.966 + if (wndProc != StaticWindowProcedure) { 1.967 + if (!SetPropW(mWnd, kMetroSubclassThisProp, this)) { 1.968 + NS_NOTREACHED("SetProp failed, can't continue."); 1.969 + return; 1.970 + } 1.971 + mMetroWndProc = 1.972 + reinterpret_cast<WNDPROC>( 1.973 + SetWindowLongPtr(mWnd, GWLP_WNDPROC, 1.974 + reinterpret_cast<LONG_PTR>(StaticWindowProcedure))); 1.975 + NS_ASSERTION(mMetroWndProc != StaticWindowProcedure, "WTF?"); 1.976 + } 1.977 +} 1.978 + 1.979 +void 1.980 +MetroWidget::RemoveSubclass() 1.981 +{ 1.982 + if (!mWnd) 1.983 + return; 1.984 + WNDPROC wndProc = reinterpret_cast<WNDPROC>( 1.985 + GetWindowLongPtr(mWnd, GWLP_WNDPROC)); 1.986 + if (wndProc == StaticWindowProcedure) { 1.987 + NS_ASSERTION(mMetroWndProc, "Should have old proc here."); 1.988 + SetWindowLongPtr(mWnd, GWLP_WNDPROC, 1.989 + reinterpret_cast<LONG_PTR>(mMetroWndProc)); 1.990 + mMetroWndProc = nullptr; 1.991 + } 1.992 + RemovePropW(mWnd, kMetroSubclassThisProp); 1.993 +} 1.994 + 1.995 +bool 1.996 +MetroWidget::ShouldUseOffMainThreadCompositing() 1.997 +{ 1.998 + // Either we're not initialized yet, or this is the toolkit widget 1.999 + if (!mView) { 1.1000 + return false; 1.1001 + } 1.1002 + // toolkit or test widgets can't use omtc, they don't have ICoreWindow. 1.1003 + return (CompositorParent::CompositorLoop() && mWindowType == eWindowType_toplevel); 1.1004 +} 1.1005 + 1.1006 +bool 1.1007 +MetroWidget::ShouldUseMainThreadD3D10Manager() 1.1008 +{ 1.1009 + // Either we're not initialized yet, or this is the toolkit widget 1.1010 + if (!mView) { 1.1011 + return false; 1.1012 + } 1.1013 + return (!CompositorParent::CompositorLoop() && mWindowType == eWindowType_toplevel); 1.1014 +} 1.1015 + 1.1016 +bool 1.1017 +MetroWidget::ShouldUseBasicManager() 1.1018 +{ 1.1019 + // toolkit or test widgets fall back on empty shadow layers 1.1020 + return (mWindowType != eWindowType_toplevel); 1.1021 +} 1.1022 + 1.1023 +bool 1.1024 +MetroWidget::ShouldUseAPZC() 1.1025 +{ 1.1026 + const char* kPrefName = "layers.async-pan-zoom.enabled"; 1.1027 + return ShouldUseOffMainThreadCompositing() && 1.1028 + Preferences::GetBool(kPrefName, false); 1.1029 +} 1.1030 + 1.1031 +void 1.1032 +MetroWidget::SetWidgetListener(nsIWidgetListener* aWidgetListener) 1.1033 +{ 1.1034 + mWidgetListener = aWidgetListener; 1.1035 + if (mController) { 1.1036 + mController->SetWidgetListener(aWidgetListener); 1.1037 + } 1.1038 +} 1.1039 + 1.1040 +CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight) 1.1041 +{ 1.1042 + CompositorParent *compositor = nsBaseWidget::NewCompositorParent(aSurfaceWidth, aSurfaceHeight); 1.1043 + 1.1044 + if (ShouldUseAPZC()) { 1.1045 + mRootLayerTreeId = compositor->RootLayerTreeId(); 1.1046 + 1.1047 + mController = new APZController(); 1.1048 + mController->SetWidgetListener(mWidgetListener); 1.1049 + 1.1050 + CompositorParent::SetControllerForLayerTree(mRootLayerTreeId, mController); 1.1051 + 1.1052 + APZController::sAPZC = CompositorParent::GetAPZCTreeManager(compositor->RootLayerTreeId()); 1.1053 + APZController::sAPZC->SetDPI(GetDPI()); 1.1054 + 1.1055 + nsresult rv; 1.1056 + nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv); 1.1057 + if (NS_SUCCEEDED(rv)) { 1.1058 + observerService->AddObserver(this, "apzc-scroll-offset-changed", false); 1.1059 + observerService->AddObserver(this, "apzc-zoom-to-rect", false); 1.1060 + observerService->AddObserver(this, "apzc-disable-zoom", false); 1.1061 + } 1.1062 + } 1.1063 + 1.1064 + return compositor; 1.1065 +} 1.1066 + 1.1067 +MetroWidget::TouchBehaviorFlags 1.1068 +MetroWidget::ContentGetAllowedTouchBehavior(const nsIntPoint& aPoint) 1.1069 +{ 1.1070 + return ContentHelper::GetAllowedTouchBehavior(this, aPoint); 1.1071 +} 1.1072 + 1.1073 +void 1.1074 +MetroWidget::ApzcGetAllowedTouchBehavior(WidgetInputEvent* aTransformedEvent, 1.1075 + nsTArray<TouchBehaviorFlags>& aOutBehaviors) 1.1076 +{ 1.1077 + LogFunction(); 1.1078 + return APZController::sAPZC->GetAllowedTouchBehavior(aTransformedEvent, aOutBehaviors); 1.1079 +} 1.1080 + 1.1081 +void 1.1082 +MetroWidget::ApzcSetAllowedTouchBehavior(const ScrollableLayerGuid& aGuid, 1.1083 + nsTArray<TouchBehaviorFlags>& aBehaviors) 1.1084 +{ 1.1085 + LogFunction(); 1.1086 + if (!APZController::sAPZC) { 1.1087 + return; 1.1088 + } 1.1089 + APZController::sAPZC->SetAllowedTouchBehavior(aGuid, aBehaviors); 1.1090 +} 1.1091 + 1.1092 +void 1.1093 +MetroWidget::ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid) 1.1094 +{ 1.1095 + LogFunction(); 1.1096 + if (!mController) { 1.1097 + return; 1.1098 + } 1.1099 + mController->ContentReceivedTouch(aGuid, true); 1.1100 +} 1.1101 + 1.1102 +void 1.1103 +MetroWidget::ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid) 1.1104 +{ 1.1105 + LogFunction(); 1.1106 + if (!mController) { 1.1107 + return; 1.1108 + } 1.1109 + mController->ContentReceivedTouch(aGuid, false); 1.1110 +} 1.1111 + 1.1112 +bool 1.1113 +MetroWidget::ApzHitTest(ScreenIntPoint& pt) 1.1114 +{ 1.1115 + if (!mController) { 1.1116 + return false; 1.1117 + } 1.1118 + return mController->HitTestAPZC(pt); 1.1119 +} 1.1120 + 1.1121 +void 1.1122 +MetroWidget::ApzTransformGeckoCoordinate(const ScreenIntPoint& aPoint, 1.1123 + LayoutDeviceIntPoint* aRefPointOut) 1.1124 +{ 1.1125 + if (!mController) { 1.1126 + return; 1.1127 + } 1.1128 + mController->TransformCoordinateToGecko(aPoint, aRefPointOut); 1.1129 +} 1.1130 + 1.1131 +nsEventStatus 1.1132 +MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent, 1.1133 + ScrollableLayerGuid* aOutTargetGuid) 1.1134 +{ 1.1135 + MOZ_ASSERT(aEvent); 1.1136 + 1.1137 + if (!mController) { 1.1138 + return nsEventStatus_eIgnore; 1.1139 + } 1.1140 + return mController->ReceiveInputEvent(aEvent, aOutTargetGuid); 1.1141 +} 1.1142 + 1.1143 +LayerManager* 1.1144 +MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager, 1.1145 + LayersBackend aBackendHint, 1.1146 + LayerManagerPersistence aPersistence, 1.1147 + bool* aAllowRetaining) 1.1148 +{ 1.1149 + bool retaining = true; 1.1150 + 1.1151 + // If we initialized earlier than the view, recreate the layer manager now 1.1152 + if (mLayerManager && 1.1153 + mTempBasicLayerInUse && 1.1154 + ShouldUseOffMainThreadCompositing()) { 1.1155 + mLayerManager = nullptr; 1.1156 + mTempBasicLayerInUse = false; 1.1157 + retaining = false; 1.1158 + } 1.1159 + 1.1160 + // If the backend device has changed, create a new manager (pulled from nswindow) 1.1161 + if (mLayerManager) { 1.1162 + if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_D3D10) { 1.1163 + LayerManagerD3D10 *layerManagerD3D10 = 1.1164 + static_cast<LayerManagerD3D10*>(mLayerManager.get()); 1.1165 + if (layerManagerD3D10->device() != 1.1166 + gfxWindowsPlatform::GetPlatform()->GetD3D10Device()) { 1.1167 + MOZ_ASSERT(!mLayerManager->IsInTransaction()); 1.1168 + 1.1169 + mLayerManager->Destroy(); 1.1170 + mLayerManager = nullptr; 1.1171 + retaining = false; 1.1172 + } 1.1173 + } 1.1174 + } 1.1175 + 1.1176 + HRESULT hr = S_OK; 1.1177 + 1.1178 + // Create a layer manager: try to use an async compositor first, if enabled. 1.1179 + // Otherwise fall back on the main thread d3d manager. 1.1180 + if (!mLayerManager) { 1.1181 + if (ShouldUseOffMainThreadCompositing()) { 1.1182 + NS_ASSERTION(aShadowManager == nullptr, "Async Compositor not supported with e10s"); 1.1183 + CreateCompositor(); 1.1184 + } else if (ShouldUseMainThreadD3D10Manager()) { 1.1185 + nsRefPtr<mozilla::layers::LayerManagerD3D10> layerManager = 1.1186 + new mozilla::layers::LayerManagerD3D10(this); 1.1187 + if (layerManager->Initialize(true, &hr)) { 1.1188 + mLayerManager = layerManager; 1.1189 + } 1.1190 + } else if (ShouldUseBasicManager()) { 1.1191 + mLayerManager = CreateBasicLayerManager(); 1.1192 + } 1.1193 + // Either we're not ready to initialize yet due to a missing view pointer, 1.1194 + // or something has gone wrong. 1.1195 + if (!mLayerManager) { 1.1196 + if (!mView) { 1.1197 + NS_WARNING("Using temporary basic layer manager."); 1.1198 + mLayerManager = new BasicLayerManager(this); 1.1199 + mTempBasicLayerInUse = true; 1.1200 + } else { 1.1201 +#ifdef MOZ_CRASHREPORTER 1.1202 + if (FAILED(hr)) { 1.1203 + char errorBuf[10]; 1.1204 + errorBuf[0] = '\0'; 1.1205 + _snprintf_s(errorBuf, sizeof(errorBuf), _TRUNCATE, "%X", hr); 1.1206 + CrashReporter:: 1.1207 + AnnotateCrashReport(NS_LITERAL_CSTRING("HRESULT"), 1.1208 + nsDependentCString(errorBuf)); 1.1209 + } 1.1210 +#endif 1.1211 + NS_RUNTIMEABORT("Couldn't create layer manager"); 1.1212 + } 1.1213 + } 1.1214 + } 1.1215 + 1.1216 + if (aAllowRetaining) { 1.1217 + *aAllowRetaining = retaining; 1.1218 + } 1.1219 + 1.1220 + return mLayerManager; 1.1221 +} 1.1222 + 1.1223 +NS_IMETHODIMP 1.1224 +MetroWidget::Invalidate(bool aEraseBackground, 1.1225 + bool aUpdateNCArea, 1.1226 + bool aIncludeChildren) 1.1227 +{ 1.1228 + nsIntRect rect; 1.1229 + if (mView) { 1.1230 + mView->GetBounds(rect); 1.1231 + } 1.1232 + Invalidate(rect); 1.1233 + return NS_OK; 1.1234 +} 1.1235 + 1.1236 +NS_IMETHODIMP 1.1237 +MetroWidget::Invalidate(const nsIntRect & aRect) 1.1238 +{ 1.1239 + if (mWnd) { 1.1240 + RECT rect; 1.1241 + rect.left = aRect.x; 1.1242 + rect.top = aRect.y; 1.1243 + rect.right = aRect.x + aRect.width; 1.1244 + rect.bottom = aRect.y + aRect.height; 1.1245 + InvalidateRect(mWnd, &rect, FALSE); 1.1246 + } 1.1247 + 1.1248 + return NS_OK; 1.1249 +} 1.1250 + 1.1251 +nsTransparencyMode 1.1252 +MetroWidget::GetTransparencyMode() 1.1253 +{ 1.1254 + return mTransparencyMode; 1.1255 +} 1.1256 + 1.1257 +void 1.1258 +MetroWidget::SetTransparencyMode(nsTransparencyMode aMode) 1.1259 +{ 1.1260 + mTransparencyMode = aMode; 1.1261 +} 1.1262 + 1.1263 +nsIWidgetListener* 1.1264 +MetroWidget::GetPaintListener() 1.1265 +{ 1.1266 + if (mOnDestroyCalled) 1.1267 + return nullptr; 1.1268 + return mAttachedWidgetListener ? mAttachedWidgetListener : 1.1269 + mWidgetListener; 1.1270 +} 1.1271 + 1.1272 +void MetroWidget::Paint(const nsIntRegion& aInvalidRegion) 1.1273 +{ 1.1274 + gfxWindowsPlatform::GetPlatform()->UpdateRenderMode(); 1.1275 + 1.1276 + nsIWidgetListener* listener = GetPaintListener(); 1.1277 + if (!listener) 1.1278 + return; 1.1279 + 1.1280 + listener->WillPaintWindow(this); 1.1281 + 1.1282 + // Refresh since calls like WillPaintWindow can destroy the widget 1.1283 + listener = GetPaintListener(); 1.1284 + if (!listener) 1.1285 + return; 1.1286 + 1.1287 + listener->PaintWindow(this, aInvalidRegion); 1.1288 + 1.1289 + listener = GetPaintListener(); 1.1290 + if (!listener) 1.1291 + return; 1.1292 + 1.1293 + listener->DidPaintWindow(); 1.1294 +} 1.1295 + 1.1296 +void MetroWidget::UserActivity() 1.1297 +{ 1.1298 + // Check if we have the idle service, if not we try to get it. 1.1299 + if (!mIdleService) { 1.1300 + mIdleService = do_GetService("@mozilla.org/widget/idleservice;1"); 1.1301 + } 1.1302 + 1.1303 + // Check that we now have the idle service. 1.1304 + if (mIdleService) { 1.1305 + mIdleService->ResetIdleTimeOut(0); 1.1306 + } 1.1307 +} 1.1308 + 1.1309 +// InitEvent assumes physical coordinates and is used by shared win32 code. Do 1.1310 +// not hand winrt event coordinates to this routine. 1.1311 +void 1.1312 +MetroWidget::InitEvent(WidgetGUIEvent& event, nsIntPoint* aPoint) 1.1313 +{ 1.1314 + if (!aPoint) { 1.1315 + event.refPoint.x = event.refPoint.y = 0; 1.1316 + } else { 1.1317 + event.refPoint.x = aPoint->x; 1.1318 + event.refPoint.y = aPoint->y; 1.1319 + } 1.1320 + event.time = ::GetMessageTime(); 1.1321 +} 1.1322 + 1.1323 +bool 1.1324 +MetroWidget::DispatchWindowEvent(WidgetGUIEvent* aEvent) 1.1325 +{ 1.1326 + MOZ_ASSERT(aEvent); 1.1327 + nsEventStatus status = nsEventStatus_eIgnore; 1.1328 + DispatchEvent(aEvent, status); 1.1329 + return (status == nsEventStatus_eConsumeNoDefault); 1.1330 +} 1.1331 + 1.1332 +NS_IMETHODIMP 1.1333 +MetroWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus & aStatus) 1.1334 +{ 1.1335 + if (event->AsInputEvent()) { 1.1336 + UserActivity(); 1.1337 + } 1.1338 + 1.1339 + aStatus = nsEventStatus_eIgnore; 1.1340 + 1.1341 + // Top level windows can have a view attached which requires events be sent 1.1342 + // to the underlying base window and the view. Added when we combined the 1.1343 + // base chrome window with the main content child for nc client area (title 1.1344 + // bar) rendering. 1.1345 + if (mAttachedWidgetListener) { 1.1346 + aStatus = mAttachedWidgetListener->HandleEvent(event, mUseAttachedEvents); 1.1347 + } 1.1348 + else if (mWidgetListener) { 1.1349 + aStatus = mWidgetListener->HandleEvent(event, mUseAttachedEvents); 1.1350 + } 1.1351 + 1.1352 + // the window can be destroyed during processing of seemingly innocuous events like, say, 1.1353 + // mousedowns due to the magic of scripting. mousedowns will return nsEventStatus_eIgnore, 1.1354 + // which causes problems with the deleted window. therefore: 1.1355 + if (mOnDestroyCalled) 1.1356 + aStatus = nsEventStatus_eConsumeNoDefault; 1.1357 + return NS_OK; 1.1358 +} 1.1359 + 1.1360 +#ifdef ACCESSIBILITY 1.1361 +mozilla::a11y::Accessible* 1.1362 +MetroWidget::GetAccessible() 1.1363 +{ 1.1364 + // We want the ability to forcibly disable a11y on windows, because 1.1365 + // some non-a11y-related components attempt to bring it up. See bug 1.1366 + // 538530 for details; we have a pref here that allows it to be disabled 1.1367 + // for performance and testing resons. 1.1368 + // 1.1369 + // This pref is checked only once, and the browser needs a restart to 1.1370 + // pick up any changes. 1.1371 + static int accForceDisable = -1; 1.1372 + 1.1373 + if (accForceDisable == -1) { 1.1374 + const char* kPrefName = "accessibility.win32.force_disabled"; 1.1375 + if (Preferences::GetBool(kPrefName, false)) { 1.1376 + accForceDisable = 1; 1.1377 + } else { 1.1378 + accForceDisable = 0; 1.1379 + } 1.1380 + } 1.1381 + 1.1382 + // If the pref was true, return null here, disabling a11y. 1.1383 + if (accForceDisable) 1.1384 + return nullptr; 1.1385 + 1.1386 + return GetRootAccessible(); 1.1387 +} 1.1388 +#endif 1.1389 + 1.1390 +double 1.1391 +MetroWidget::GetDefaultScaleInternal() 1.1392 +{ 1.1393 + return MetroUtils::ScaleFactor(); 1.1394 +} 1.1395 + 1.1396 +LayoutDeviceIntPoint 1.1397 +MetroWidget::CSSIntPointToLayoutDeviceIntPoint(const CSSIntPoint &aCSSPoint) 1.1398 +{ 1.1399 + CSSToLayoutDeviceScale scale = GetDefaultScale(); 1.1400 + LayoutDeviceIntPoint devPx(int32_t(NS_round(scale.scale * aCSSPoint.x)), 1.1401 + int32_t(NS_round(scale.scale * aCSSPoint.y))); 1.1402 + return devPx; 1.1403 +} 1.1404 + 1.1405 +float 1.1406 +MetroWidget::GetDPI() 1.1407 +{ 1.1408 + if (!mView) { 1.1409 + return 96.0; 1.1410 + } 1.1411 + return mView->GetDPI(); 1.1412 +} 1.1413 + 1.1414 +void 1.1415 +MetroWidget::ChangedDPI() 1.1416 +{ 1.1417 + if (mWidgetListener) { 1.1418 + nsIPresShell* presShell = mWidgetListener->GetPresShell(); 1.1419 + if (presShell) { 1.1420 + presShell->BackingScaleFactorChanged(); 1.1421 + } 1.1422 + } 1.1423 +} 1.1424 + 1.1425 +already_AddRefed<nsIPresShell> 1.1426 +MetroWidget::GetPresShell() 1.1427 +{ 1.1428 + if (mWidgetListener) { 1.1429 + nsCOMPtr<nsIPresShell> ps = mWidgetListener->GetPresShell(); 1.1430 + return ps.forget(); 1.1431 + } 1.1432 + return nullptr; 1.1433 +} 1.1434 + 1.1435 +NS_IMETHODIMP 1.1436 +MetroWidget::ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY) 1.1437 +{ 1.1438 + return NS_OK; 1.1439 +} 1.1440 + 1.1441 +void 1.1442 +MetroWidget::SizeModeChanged() 1.1443 +{ 1.1444 + if (mWidgetListener) { 1.1445 + mWidgetListener->SizeModeChanged(nsSizeMode_Normal); 1.1446 + } 1.1447 +} 1.1448 + 1.1449 +void 1.1450 +MetroWidget::Activated(bool aActiveated) 1.1451 +{ 1.1452 + if (mWidgetListener) { 1.1453 + aActiveated ? 1.1454 + mWidgetListener->WindowActivated() : 1.1455 + mWidgetListener->WindowDeactivated(); 1.1456 + } 1.1457 +} 1.1458 + 1.1459 +NS_IMETHODIMP 1.1460 +MetroWidget::Move(double aX, double aY) 1.1461 +{ 1.1462 + NotifyWindowMoved(aX, aY); 1.1463 + return NS_OK; 1.1464 +} 1.1465 + 1.1466 +NS_IMETHODIMP 1.1467 +MetroWidget::Resize(double aWidth, double aHeight, bool aRepaint) 1.1468 +{ 1.1469 + return Resize(0, 0, aWidth, aHeight, aRepaint); 1.1470 +} 1.1471 + 1.1472 +NS_IMETHODIMP 1.1473 +MetroWidget::Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint) 1.1474 +{ 1.1475 + WinUtils::Log("Resize: %f %f %f %f", aX, aY, aWidth, aHeight); 1.1476 + if (mAttachedWidgetListener) { 1.1477 + mAttachedWidgetListener->WindowResized(this, aWidth, aHeight); 1.1478 + } 1.1479 + if (mWidgetListener) { 1.1480 + mWidgetListener->WindowResized(this, aWidth, aHeight); 1.1481 + } 1.1482 + Invalidate(); 1.1483 + return NS_OK; 1.1484 +} 1.1485 + 1.1486 +NS_IMETHODIMP 1.1487 +MetroWidget::SetFocus(bool aRaise) 1.1488 +{ 1.1489 + return NS_OK; 1.1490 +} 1.1491 + 1.1492 +nsresult 1.1493 +MetroWidget::ConfigureChildren(const nsTArray<Configuration>& aConfigurations) 1.1494 +{ 1.1495 + return NS_OK; 1.1496 +} 1.1497 + 1.1498 +void* 1.1499 +MetroWidget::GetNativeData(uint32_t aDataType) 1.1500 +{ 1.1501 + switch(aDataType) { 1.1502 + case NS_NATIVE_WINDOW: 1.1503 + return mWnd; 1.1504 + case NS_NATIVE_ICOREWINDOW: 1.1505 + if (mView) { 1.1506 + return reinterpret_cast<IUnknown*>(mView->GetCoreWindow()); 1.1507 + } 1.1508 + break; 1.1509 + case NS_NATIVE_TSF_THREAD_MGR: 1.1510 + case NS_NATIVE_TSF_CATEGORY_MGR: 1.1511 + case NS_NATIVE_TSF_DISPLAY_ATTR_MGR: 1.1512 + return nsTextStore::GetNativeData(aDataType); 1.1513 + } 1.1514 + return nullptr; 1.1515 +} 1.1516 + 1.1517 +void 1.1518 +MetroWidget::FreeNativeData(void * data, uint32_t aDataType) 1.1519 +{ 1.1520 +} 1.1521 + 1.1522 +NS_IMETHODIMP 1.1523 +MetroWidget::SetTitle(const nsAString& aTitle) 1.1524 +{ 1.1525 + return NS_OK; 1.1526 +} 1.1527 + 1.1528 +nsIntPoint 1.1529 +MetroWidget::WidgetToScreenOffset() 1.1530 +{ 1.1531 + return nsIntPoint(0,0); 1.1532 +} 1.1533 + 1.1534 +NS_IMETHODIMP 1.1535 +MetroWidget::CaptureRollupEvents(nsIRollupListener * aListener, 1.1536 + bool aDoCapture) 1.1537 +{ 1.1538 + return NS_OK; 1.1539 +} 1.1540 + 1.1541 +NS_IMETHODIMP_(void) 1.1542 +MetroWidget::SetInputContext(const InputContext& aContext, 1.1543 + const InputContextAction& aAction) 1.1544 +{ 1.1545 + mInputContext = aContext; 1.1546 + nsTextStore::SetInputContext(this, mInputContext, aAction); 1.1547 + bool enable = (mInputContext.mIMEState.mEnabled == IMEState::ENABLED || 1.1548 + mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); 1.1549 + if (enable && 1.1550 + mInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE) { 1.1551 + bool open = (mInputContext.mIMEState.mOpen == IMEState::OPEN); 1.1552 + nsTextStore::SetIMEOpenState(open); 1.1553 + } 1.1554 +} 1.1555 + 1.1556 +NS_IMETHODIMP_(nsIWidget::InputContext) 1.1557 +MetroWidget::GetInputContext() 1.1558 +{ 1.1559 + return mInputContext; 1.1560 +} 1.1561 + 1.1562 +NS_IMETHODIMP 1.1563 +MetroWidget::NotifyIME(const IMENotification& aIMENotification) 1.1564 +{ 1.1565 + switch (aIMENotification.mMessage) { 1.1566 + case REQUEST_TO_COMMIT_COMPOSITION: 1.1567 + nsTextStore::CommitComposition(false); 1.1568 + return NS_OK; 1.1569 + case REQUEST_TO_CANCEL_COMPOSITION: 1.1570 + nsTextStore::CommitComposition(true); 1.1571 + return NS_OK; 1.1572 + case NOTIFY_IME_OF_FOCUS: 1.1573 + return nsTextStore::OnFocusChange(true, this, 1.1574 + mInputContext.mIMEState.mEnabled); 1.1575 + case NOTIFY_IME_OF_BLUR: 1.1576 + return nsTextStore::OnFocusChange(false, this, 1.1577 + mInputContext.mIMEState.mEnabled); 1.1578 + case NOTIFY_IME_OF_SELECTION_CHANGE: 1.1579 + return nsTextStore::OnSelectionChange(); 1.1580 + case NOTIFY_IME_OF_TEXT_CHANGE: 1.1581 + return nsTextStore::OnTextChange(aIMENotification); 1.1582 + case NOTIFY_IME_OF_POSITION_CHANGE: 1.1583 + return nsTextStore::OnLayoutChange(); 1.1584 + default: 1.1585 + return NS_ERROR_NOT_IMPLEMENTED; 1.1586 + } 1.1587 +} 1.1588 + 1.1589 +NS_IMETHODIMP 1.1590 +MetroWidget::GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) 1.1591 +{ 1.1592 + NS_ENSURE_ARG_POINTER(aLEDState); 1.1593 + *aLEDState = (::GetKeyState(aKeyCode) & 1) != 0; 1.1594 + return NS_OK; 1.1595 +} 1.1596 + 1.1597 +nsIMEUpdatePreference 1.1598 +MetroWidget::GetIMEUpdatePreference() 1.1599 +{ 1.1600 + return nsTextStore::GetIMEUpdatePreference(); 1.1601 +} 1.1602 + 1.1603 +NS_IMETHODIMP 1.1604 +MetroWidget::ReparentNativeWidget(nsIWidget* aNewParent) 1.1605 +{ 1.1606 + return NS_OK; 1.1607 +} 1.1608 + 1.1609 +void 1.1610 +MetroWidget::SuppressBlurEvents(bool aSuppress) 1.1611 +{ 1.1612 +} 1.1613 + 1.1614 +bool 1.1615 +MetroWidget::BlurEventsSuppressed() 1.1616 +{ 1.1617 + return false; 1.1618 +} 1.1619 + 1.1620 +void 1.1621 +MetroWidget::PickerOpen() 1.1622 +{ 1.1623 +} 1.1624 + 1.1625 +void 1.1626 +MetroWidget::PickerClosed() 1.1627 +{ 1.1628 +} 1.1629 + 1.1630 +bool 1.1631 +MetroWidget::HasPendingInputEvent() 1.1632 +{ 1.1633 + if (HIWORD(GetQueueStatus(QS_INPUT))) 1.1634 + return true; 1.1635 + return false; 1.1636 +} 1.1637 + 1.1638 +NS_IMETHODIMP 1.1639 +MetroWidget::Observe(nsISupports *subject, const char *topic, const char16_t *data) 1.1640 +{ 1.1641 + NS_ENSURE_ARG_POINTER(topic); 1.1642 + if (!strcmp(topic, "apzc-zoom-to-rect")) { 1.1643 + CSSRect rect = CSSRect(); 1.1644 + uint64_t viewId = 0; 1.1645 + int32_t presShellId = 0; 1.1646 + 1.1647 + int reScan = swscanf(data, L"%f,%f,%f,%f,%d,%llu", 1.1648 + &rect.x, &rect.y, &rect.width, &rect.height, 1.1649 + &presShellId, &viewId); 1.1650 + if(reScan != 6) { 1.1651 + NS_WARNING("Malformed apzc-zoom-to-rect message"); 1.1652 + } 1.1653 + 1.1654 + ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId); 1.1655 + APZController::sAPZC->ZoomToRect(guid, rect); 1.1656 + } 1.1657 + else if (!strcmp(topic, "apzc-disable-zoom")) { 1.1658 + uint64_t viewId = 0; 1.1659 + int32_t presShellId = 0; 1.1660 + 1.1661 + int reScan = swscanf(data, L"%d,%llu", 1.1662 + &presShellId, &viewId); 1.1663 + if (reScan != 2) { 1.1664 + NS_WARNING("Malformed apzc-disable-zoom message"); 1.1665 + } 1.1666 + 1.1667 + ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId); 1.1668 + APZController::sAPZC->UpdateZoomConstraints(guid, 1.1669 + ZoomConstraints(false, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f))); 1.1670 + } 1.1671 + return NS_OK; 1.1672 +}