mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Backed out changeset 60b8f96f35ec (bug 1645571) for causing bug 1907766
.
This commit is contained in:
parent
8f0f27d8a7
commit
5f14dd1f7c
@ -1,51 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "MockWinWidget.h"
|
||||
#include "mozilla/widget/OSKInputPaneManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
class WinInputPaneTest : public ::testing::Test {
|
||||
protected:
|
||||
HWND CreateNativeWindow(DWORD aStyle, DWORD aExStyle) {
|
||||
mMockWinWidget =
|
||||
MockWinWidget::Create(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | aStyle,
|
||||
aExStyle, LayoutDeviceIntRect(0, 0, 100, 100));
|
||||
EXPECT_NE(nullptr, mMockWinWidget.get());
|
||||
HWND hwnd = mMockWinWidget->GetWnd();
|
||||
|
||||
::ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
EXPECT_TRUE(UpdateWindow(hwnd));
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
void ExpectHasEventHandler(HWND aHwnd, bool aValue) {
|
||||
Maybe<bool> hasEventHandler =
|
||||
OSKInputPaneManager::HasInputPaneEventHandlerService(aHwnd);
|
||||
EXPECT_TRUE(hasEventHandler.isSome() && hasEventHandler.value() == aValue);
|
||||
}
|
||||
|
||||
RefPtr<MockWinWidget> mMockWinWidget;
|
||||
};
|
||||
|
||||
TEST_F(WinInputPaneTest, HasNoEventHandlerAtCreation) {
|
||||
HWND hwnd = CreateNativeWindow(/* aStyle = */ 0, /* aExStyle = */ 0);
|
||||
ExpectHasEventHandler(hwnd, false);
|
||||
}
|
||||
|
||||
TEST_F(WinInputPaneTest, HasEventHandlerAfterShowOnScreenKeyboard) {
|
||||
HWND hwnd = CreateNativeWindow(/* aStyle = */ 0, /* aExStyle = */ 0);
|
||||
ExpectHasEventHandler(hwnd, false);
|
||||
|
||||
OSKInputPaneManager::ShowOnScreenKeyboard(hwnd);
|
||||
ExpectHasEventHandler(hwnd, true);
|
||||
}
|
@ -13,7 +13,6 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
||||
UNIFIED_SOURCES += [
|
||||
"MockWinWidget.cpp",
|
||||
"TestWinHeaderOnlyUtils.cpp",
|
||||
"TestWinInputPane.cpp",
|
||||
"TestWinMessageLoggingUtils.cpp",
|
||||
"TestWinWindowOcclusionTracker.cpp",
|
||||
"TestWinWindowOcclusionTrackerInteractive.cpp",
|
||||
|
@ -7,17 +7,13 @@
|
||||
#define NTDDI_VERSION NTDDI_WIN10_RS1
|
||||
|
||||
#include "OSKInputPaneManager.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nscore.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#ifndef __MINGW32__
|
||||
# include <inputpaneinterop.h>
|
||||
# include <windows.ui.viewmanagement.h>
|
||||
# include <wrl.h>
|
||||
|
||||
using ABI::Windows::Foundation::ITypedEventHandler;
|
||||
using namespace ABI::Windows::UI::ViewManagement;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
@ -27,7 +23,7 @@ namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static ComPtr<IInputPane> GetInputPaneInternal(HWND aHwnd) {
|
||||
static ComPtr<IInputPane2> GetInputPane(HWND aHwnd) {
|
||||
ComPtr<IInputPaneInterop> inputPaneInterop;
|
||||
HRESULT hr = RoGetActivationFactory(
|
||||
HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
|
||||
@ -42,44 +38,6 @@ static ComPtr<IInputPane> GetInputPaneInternal(HWND aHwnd) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return inputPane;
|
||||
}
|
||||
|
||||
static ComPtr<IInputPane2> GetInputPane(HWND aHwnd) {
|
||||
ComPtr<IInputPane> inputPane = GetInputPaneInternal(aHwnd);
|
||||
if (!inputPane) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Bug 1645571: We need to ensure that we have a SID_InputPaneEventHandler
|
||||
// window service registered on aHwnd, or explorer.exe will mess with our
|
||||
// window through twinui!CKeyboardOcclusionMitigation::_MitigateWindow.
|
||||
|
||||
Maybe<bool> hasEventHandler =
|
||||
OSKInputPaneManager::HasInputPaneEventHandlerService(aHwnd);
|
||||
if (hasEventHandler.isSome() && !hasEventHandler.value()) {
|
||||
// Run IInputPane::add_Hiding once to register the window service.
|
||||
EventRegistrationToken token{};
|
||||
HRESULT registered = inputPane->add_Hiding(
|
||||
Callback<ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*>>(
|
||||
[](IInputPane* aInputPane, IInputPaneVisibilityEventArgs* aArgs) {
|
||||
return S_OK;
|
||||
})
|
||||
.Get(),
|
||||
&token);
|
||||
|
||||
// Validate our assumption that we now have the window service registered.
|
||||
hasEventHandler =
|
||||
OSKInputPaneManager::HasInputPaneEventHandlerService(aHwnd);
|
||||
if (SUCCEEDED(registered) &&
|
||||
!(hasEventHandler.isSome() && hasEventHandler.value())) {
|
||||
// If our assumption is wrong, we undo the operation. This prevents a
|
||||
// memory leak where we would be adding a new callback every time the
|
||||
// on-screen keyboard is shown.
|
||||
inputPane->remove_Hiding(token);
|
||||
}
|
||||
}
|
||||
|
||||
ComPtr<IInputPane2> inputPane2;
|
||||
inputPane.As(&inputPane2);
|
||||
return inputPane2;
|
||||
@ -139,42 +97,5 @@ void OSKInputPaneManager::DismissOnScreenKeyboard(HWND aWnd) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
Maybe<bool> OSKInputPaneManager::HasInputPaneEventHandlerService(HWND aHwnd) {
|
||||
using CoreIsWindowServiceSupportedFn =
|
||||
HRESULT(WINAPI*)(HWND aHwnd, LPCGUID aServiceSid);
|
||||
|
||||
static auto sCoreIsWindowServiceSupported =
|
||||
[]() -> CoreIsWindowServiceSupportedFn {
|
||||
HMODULE twinApiAppCore = LoadLibrarySystem32(L"twinapi.appcore.dll");
|
||||
if (!twinApiAppCore) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<CoreIsWindowServiceSupportedFn>(
|
||||
::GetProcAddress(twinApiAppCore, reinterpret_cast<LPCSTR>(8)));
|
||||
}();
|
||||
|
||||
if (!sCoreIsWindowServiceSupported) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
// {958e2b85-b035-4590-9bc5-ef01779b45dc}
|
||||
static const GUID sSID_InputPaneEventHandler{
|
||||
0x958e2b85,
|
||||
0xb035,
|
||||
0x4590,
|
||||
{0x9b, 0xc5, 0xef, 0x1, 0x77, 0x9b, 0x45, 0xdc}};
|
||||
|
||||
// Since we are calling a Windows internal function here, the function
|
||||
// signature is subject to arbitrary changes from Microsoft. This could
|
||||
// result in wrong results or even crashing. Ensure that if things are so bad
|
||||
// that we are about to crash, we just return Nothing instead.
|
||||
MOZ_SEH_TRY {
|
||||
return Some(SUCCEEDED(
|
||||
sCoreIsWindowServiceSupported(aHwnd, &sSID_InputPaneEventHandler)));
|
||||
}
|
||||
MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { return Nothing(); }
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
@ -7,8 +7,6 @@
|
||||
#ifndef mozilla_widget_OSKInputPaneManager_h
|
||||
#define mozilla_widget_OSKInputPaneManager_h
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace mozilla {
|
||||
@ -18,7 +16,6 @@ class OSKInputPaneManager final {
|
||||
public:
|
||||
static void ShowOnScreenKeyboard(HWND aHwnd);
|
||||
static void DismissOnScreenKeyboard(HWND aHwnd);
|
||||
static Maybe<bool> HasInputPaneEventHandlerService(HWND aHwnd);
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
@ -55,7 +55,6 @@ EXPORTS.mozilla.widget += [
|
||||
"InProcessWinCompositorWidget.h",
|
||||
"JumpListBuilder.h",
|
||||
"nsWindowLoggedMessages.h",
|
||||
"OSKInputPaneManager.h",
|
||||
"WinCompositorWidget.h",
|
||||
"WinCompositorWindowThread.h",
|
||||
"WindowsEMF.h",
|
||||
|
Loading…
Reference in New Issue
Block a user