fune/widget/windows/OSKInputPaneManager.cpp
Masayuki Nakano 7a8b3653f6 Bug 1639824 - Make OKInputPaneManager warn only when TryShow() and TryHide() fail, we're active and we get unexpected result r=m_kato
I see a lot of "IInputPane2::TryHide is failure" warnings while WPT for editing
API runs.

According to MSDN, they return true only when the application is foreground and
the input panel hasn't been the requested state yet.  Therefore, it should
check whether the foreground window is our process or not, and whether the
input pane state is expected or not before warning.

* https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.tryshow?view=winrt-18362
* https://docs.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.tryhide?view=winrt-18362

Differential Revision: https://phabricator.services.mozilla.com/D76295
2020-05-21 15:40:41 +00:00

101 lines
2.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sts=2 sw=2 et cin: */
/* 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/. */
#define NTDDI_VERSION NTDDI_WIN10_RS1
#include "OSKInputPaneManager.h"
#include "nsDebug.h"
#ifndef __MINGW32__
# include <inputpaneinterop.h>
# include <windows.ui.viewmanagement.h>
# include <wrl.h>
using namespace ABI::Windows::UI::ViewManagement;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
#endif
namespace mozilla {
namespace widget {
#ifndef __MINGW32__
static ComPtr<IInputPane2> GetInputPane(HWND aHwnd) {
ComPtr<IInputPaneInterop> inputPaneInterop;
HRESULT hr = RoGetActivationFactory(
HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
IID_PPV_ARGS(&inputPaneInterop));
if (NS_WARN_IF(FAILED(hr))) {
return nullptr;
}
ComPtr<IInputPane> inputPane;
hr = inputPaneInterop->GetForWindow(aHwnd, IID_PPV_ARGS(&inputPane));
if (NS_WARN_IF(FAILED(hr))) {
return nullptr;
}
ComPtr<IInputPane2> inputPane2;
inputPane.As(&inputPane2);
return inputPane2;
}
# ifdef DEBUG
static bool IsInputPaneVisible(ComPtr<IInputPane2>& aInputPane2) {
ComPtr<IInputPaneControl> inputPaneControl;
aInputPane2.As(&inputPaneControl);
if (NS_WARN_IF(!inputPaneControl)) {
return false;
}
boolean visible = false;
inputPaneControl->get_Visible(&visible);
return visible;
}
static bool IsForegroundApp() {
HWND foregroundWnd = ::GetForegroundWindow();
if (!foregroundWnd) {
return false;
}
DWORD pid;
::GetWindowThreadProcessId(foregroundWnd, &pid);
return pid == ::GetCurrentProcessId();
}
# endif
#endif
// static
void OSKInputPaneManager::ShowOnScreenKeyboard(HWND aWnd) {
#ifndef __MINGW32__
ComPtr<IInputPane2> inputPane2 = GetInputPane(aWnd);
if (!inputPane2) {
return;
}
boolean result;
inputPane2->TryShow(&result);
NS_WARNING_ASSERTION(
result || !IsForegroundApp() || IsInputPaneVisible(inputPane2),
"IInputPane2::TryShow is failure");
#endif
}
// static
void OSKInputPaneManager::DismissOnScreenKeyboard(HWND aWnd) {
#ifndef __MINGW32__
ComPtr<IInputPane2> inputPane2 = GetInputPane(aWnd);
if (!inputPane2) {
return;
}
boolean result;
inputPane2->TryHide(&result);
NS_WARNING_ASSERTION(
result || !IsForegroundApp() || !IsInputPaneVisible(inputPane2),
"IInputPane2::TryHide is failure");
#endif
}
} // namespace widget
} // namespace mozilla