Complete OSK function support

This commit is contained in:
Bashar Astifan 2023-08-23 21:01:00 +04:00
parent 04d72ebe54
commit c6e7760283
10 changed files with 216 additions and 34 deletions

View file

@ -475,6 +475,10 @@ void SliderPopupScreen::OnCompleted(DialogResult result) {
e.a = *value_;
OnChange.Trigger(e);
}
#if PPSSPP_PLATFORM(UWP)
// Inform UI to hide OSK and to disable keyboard mode
System_NotifyUIState("hide_keyboard");
#endif
}
void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
@ -488,6 +492,10 @@ void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
} else {
*value_ = originalValue_;
}
#if PPSSPP_PLATFORM(UWP)
// Inform UI to hide OSK and to disable keyboard mode
System_NotifyUIState("hide_keyboard");
#endif
}
PopupTextInputChoice::PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams)
@ -551,6 +559,10 @@ void TextEditPopupScreen::OnCompleted(DialogResult result) {
e.v = edit_;
OnChange.Trigger(e);
}
#if PPSSPP_PLATFORM(UWP)
// Inform UI to hide OSK and to disable keyboard mode
System_NotifyUIState("hide_keyboard");
#endif
}
void AbstractChoiceWithValueDisplay::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {

View file

@ -272,6 +272,13 @@ static bool MatchesKeyDef(const std::vector<InputMapping> &defs, const KeyInput
// TODO: O/X confirm preference for xperia play?
bool IsDPadKey(const KeyInput &key) {
#if PPSSPP_PLATFORM(UWP)
if (key.flags & KEY_CHAR) {
// Better not to check if flags has `KEY_CHAR`
// many of Windows chars has similar codes to `NKCODE` actions buttons
return false;
}
#endif#
if (dpadKeys.empty()) {
return key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT;
} else {
@ -280,6 +287,13 @@ bool IsDPadKey(const KeyInput &key) {
}
bool IsAcceptKey(const KeyInput &key) {
#if PPSSPP_PLATFORM(UWP)
if (key.flags & KEY_CHAR) {
// Better not to check if flags has `KEY_CHAR`
// many of Windows chars has similar codes to `NKCODE` actions buttons
return false;
}
#endif#
if (confirmKeys.empty()) {
// This path is pretty much not used, confirmKeys should be set.
// TODO: Get rid of this stuff?
@ -294,6 +308,12 @@ bool IsAcceptKey(const KeyInput &key) {
}
bool IsEscapeKey(const KeyInput &key) {
#if PPSSPP_PLATFORM(UWP)
if (key.flags & KEY_CHAR) {
// `a` char has equal value to `NKCODE_BUTTON_CIRCLE_PS3` = 97
return false;
}
#endif#
if (cancelKeys.empty()) {
// This path is pretty much not used, cancelKeys should be set.
// TODO: Get rid of this stuff?
@ -308,6 +328,12 @@ bool IsEscapeKey(const KeyInput &key) {
}
bool IsTabLeftKey(const KeyInput &key) {
#if PPSSPP_PLATFORM(UWP)
if (key.flags & KEY_CHAR) {
// `f` char has equal value to `NKCODE_BUTTON_L1` = 102
return false;
}
#endif
if (tabLeftKeys.empty()) {
// This path is pretty much not used, tabLeftKeys should be set.
// TODO: Get rid of this stuff?
@ -318,6 +344,13 @@ bool IsTabLeftKey(const KeyInput &key) {
}
bool IsTabRightKey(const KeyInput &key) {
#if PPSSPP_PLATFORM(UWP)
if (key.flags & KEY_CHAR) {
// Better not to check if flags has `KEY_CHAR`
// many of Windows chars has similar codes to `NKCODE` actions buttons
return false;
}
#endif#
if (tabRightKeys.empty()) {
// This path is pretty much not used, tabRightKeys should be set.
// TODO: Get rid of this stuff?
@ -1079,6 +1112,17 @@ TextEdit::TextEdit(const std::string &text, const std::string &title, const std:
caret_ = (int)text_.size();
}
void TextEdit::FocusChanged(int focusFlags) {
#if PPSSPP_PLATFORM(UWP)
if (focusFlags == FF_GOTFOCUS) {
System_NotifyUIState("show_keyboard");
}
else {
System_NotifyUIState("hide_keyboard");
}
#endif
}
void TextEdit::Draw(UIContext &dc) {
dc.PushScissor(bounds_);
dc.SetFontStyle(dc.theme->uiFont);
@ -1155,7 +1199,14 @@ bool TextEdit::Key(const KeyInput &input) {
return false;
bool textChanged = false;
// Process hardcoded navigation keys. These aren't chars.
#if PPSSPP_PLATFORM(UWP)
// In Windows (UWP) [chars event], some chars like `z` has equal value to `NKCODE_MOVE_HOME` = 122
// we already excluded non-char keys from being sent as `KEY_CHAR` (in keyboard/OSK mode)
// so if flags has `KEY_CHAR` then it's char 100%
if (input.flags & KEY_DOWN && !(input.flags & KEY_CHAR)) {
#else
if (input.flags & KEY_DOWN) {
#endif
switch (input.keyCode) {
case NKCODE_CTRL_LEFT:
case NKCODE_CTRL_RIGHT:

View file

@ -971,6 +971,7 @@ public:
void SetMaxLen(size_t maxLen) { maxLen_ = maxLen; }
void SetTextAlign(int align) { align_ = align; } // Only really useful for setting FLAG_DYNAMIC_ASCII
void FocusChanged(int focusFlags) override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
void Draw(UIContext &dc) override;
std::string DescribeText() const override;

View file

@ -2113,6 +2113,11 @@ bool HostnameSelectScreen::CanComplete(DialogResult result) {
void HostnameSelectScreen::OnCompleted(DialogResult result) {
if (result == DR_OK)
*value_ = StripSpaces(addrView_->GetText());
#if PPSSPP_PLATFORM(UWP)
// Inform UI to hide OSK and to disable keyboard mode
System_NotifyUIState("hide_keyboard");
#endif
}
void GestureMappingScreen::CreateViews() {

View file

@ -129,6 +129,7 @@
#endif
#if PPSSPP_PLATFORM(UWP)
#include <dwrite_3.h>
#include "UWP/UWPHelpers/InputHelpers.h"
#endif
#if PPSSPP_PLATFORM(ANDROID)
#include "android/jni/app-android.h"
@ -1269,6 +1270,14 @@ bool NativeKey(const KeyInput &key) {
return false;
}
#if PPSSPP_PLATFORM(UWP)
// Ignore if key sent from OnKeyDown/OnKeyUp/XInput while keyboard mode active
// it's already handled by `OnCharacterReceived`
if (IgnoreInput(key.keyCode) && !(key.flags & KEY_CHAR)) {
return false;
}
#endif
// INFO_LOG(SYSTEM, "Key code: %i flags: %i", key.keyCode, key.flags);
#if !defined(MOBILE_DEVICE)
if (g_Config.bPauseExitsEmulator) {

View file

@ -53,7 +53,7 @@ void App::InitialPPSSPP() {
// Initial net
net::Init();
//Prepare for initialization
// Prepare for initialization
std::wstring internalDataFolderW = ApplicationData::Current->LocalFolder->Path->Data();
g_Config.internalDataDirectory = Path(internalDataFolderW);
g_Config.memStickDirectory = g_Config.internalDataDirectory;
@ -78,7 +78,7 @@ void App::InitialPPSSPP() {
// it's better to call it here
const char* argv[2] = { "fake", nullptr };
std::string cacheFolder = ConvertWStringToUTF8(ApplicationData::Current->TemporaryFolder->Path->Data());
// Ee will not be able to use `argv`
// We will not be able to use `argv`
// since launch parameters usually handled by `OnActivated`
// and `OnActivated` will be invoked later, even after `PPSSPP_UWPMain(..)`
// so we are handling launch cases using `LaunchItem`

View file

@ -256,22 +256,41 @@ bool DX::DeviceResources::CreateAdaptersList(ComPtr<ID3D11Device> device) {
Microsoft::WRL::ComPtr<IDXGIFactory4> deviceFactory;
deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory));
// Current adapter (Get current adapter name)
DXGI_ADAPTER_DESC currentDefaultAdapterDesc;
deviceAdapter->GetDesc(&currentDefaultAdapterDesc);
std::string currentDefaultAdapterName = ConvertWStringToUTF8(currentDefaultAdapterDesc.Description);
UINT i = 0;
IDXGIAdapter* pAdapter;
IDXGIAdapter* customAdapter = nullptr;
auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo;
bool isXbox = deviceInfo->DeviceFamily == "Windows.Xbox";
while (deviceFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND)
{
++i;
DXGI_ADAPTER_DESC vAdapterDesc;
pAdapter->GetDesc(&vAdapterDesc);
auto adapterDescription = ConvertWStringToUTF8(vAdapterDesc.Description);
m_vAdapters.push_back(adapterDescription);
if (g_Config.sD3D11Device == adapterDescription) {
customAdapter = pAdapter;
if (isXbox && adapterDescription == "Microsoft Basic Render Driver") {
// Skip, very slow and not usefull for Xbox
continue;
}
m_vAdapters.push_back(adapterDescription);
if (!g_Config.sD3D11Device.empty() && g_Config.sD3D11Device == adapterDescription) {
// Double check if it's the same default adapter
if (adapterDescription != currentDefaultAdapterName) {
customAdapter = pAdapter;
}
}
++i;
}
deviceFactory->Release();
if (m_vAdapters.size() == 1) {
// Only one (default) adapter, clear the list to hide device option from settings
m_vAdapters.clear();
}
bool reCreateDevice = false;
if (customAdapter) {
reCreateDevice = true;

View file

@ -42,7 +42,7 @@
#include "UWPHelpers/StorageManager.h"
#include "UWPHelpers/StorageAsync.h"
#include "UWPHelpers/LaunchItem.h"
#include <UWPHelpers/InputHelpers.h>
#include "UWPHelpers/InputHelpers.h"
using namespace UWP;
using namespace Windows::Foundation;
@ -198,6 +198,7 @@ void PPSSPP_UWPMain::OnDeviceRestored() {
}
void PPSSPP_UWPMain::OnKeyDown(int scanCode, Windows::System::VirtualKey virtualKey, int repeatCount) {
// TODO: Look like (Ctrl, Alt, Shift) don't trigger this event
auto iter = virtualKeyCodeToNKCode.find(virtualKey);
if (iter != virtualKeyCodeToNKCode.end()) {
KeyInput key{};
@ -220,12 +221,12 @@ void PPSSPP_UWPMain::OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKe
}
void PPSSPP_UWPMain::OnCharacterReceived(int scanCode, unsigned int keyCode) {
// TODO: Once on-screen keyboard show/hide solved, add `InputPaneVisible()` as extra condition
if (!PSP_IsInited() && !IsCtrlOnHold()) {
// This event triggered only in chars case, (Arrows, Delete..etc don't call it)
if (isKeyboardActive() && !IsCtrlOnHold()) {
KeyInput key{};
key.deviceId = DEVICE_ID_KEYBOARD;
key.keyCode = (InputKeyCode)keyCode;
key.flags = KEY_DOWN | KEY_CHAR;
key.flags = KEY_DOWN | KEY_UP | KEY_CHAR;
NativeKey(key);
}
}
@ -359,10 +360,9 @@ int System_GetPropertyInt(SystemProperty prop) {
case SYSPROP_DEVICE_TYPE:
{
auto ver = Windows::System::Profile::AnalyticsInfo::VersionInfo;
if (ver->DeviceFamily == "Windows.Mobile") {
if (IsMobile()) {
return DEVICE_TYPE_MOBILE;
} else if (ver->DeviceFamily == "Windows.Xbox") {
} else if (IsXBox()) {
return DEVICE_TYPE_TV;
} else {
return DEVICE_TYPE_DESKTOP;
@ -407,8 +407,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
switch (prop) {
case SYSPROP_HAS_OPEN_DIRECTORY:
{
auto ver = Windows::System::Profile::AnalyticsInfo::VersionInfo;
return ver->DeviceFamily != "Windows.Xbox";
return !IsXBox();
}
case SYSPROP_HAS_FILE_BROWSER:
return true;
@ -550,7 +549,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([]()
{
ShowInputPane();
ActivateKeyboardInput();
}));
}
else if (!strcmp(param1.c_str(), "hide_keyboard")) {
@ -559,7 +558,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([]()
{
HideInputPane();
DeactivateKeyboardInput();
}));
}
return true;

View file

@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <list>
#include "InputHelpers.h"
#include "UWPUtil.h"
@ -29,6 +30,13 @@ using namespace Windows::ApplicationModel::Core;
using namespace Windows::Data::Xml::Dom;
using namespace Windows::UI::Notifications;
#pragma region Extenstions
template<typename T>
bool findInList(std::list<T>& inputList, T& str) {
return (std::find(inputList.begin(), inputList.end(), str) != inputList.end());
};
#pragma endregion
#pragma region Input Keyboard
bool isKeybaordAvailable() {
@ -43,24 +51,89 @@ bool isTouchAvailable() {
return hasTouch;
}
bool keyboardVisible = false;
bool InputPaneVisible() {
return keyboardVisible;
bool keyboardActive = false;
bool inputPaneVisible = false;
bool isInputPaneVisible() {
// On Xbox we can check this using input pan
if (IsXBox()) {
return InputPane::GetForCurrentView()->Visible;
}
else {
return inputPaneVisible;
}
}
void ShowInputPane() {
VERBOSE_LOG(COMMON, "ShowInputKeyboard");
InputPane::GetForCurrentView()->TryShow();
keyboardVisible = true;
bool isKeyboardActive() {
return keyboardActive;
}
void HideInputPane() {
VERBOSE_LOG(COMMON, "HideInputKeyboard");
InputPane::GetForCurrentView()->TryHide();
keyboardVisible = false;
void ActivateKeyboardInput() {
DEBUG_LOG(COMMON, "Activate input keyboard");
// When no
inputPaneVisible = InputPane::GetForCurrentView()->TryShow();
keyboardActive = true;
if (inputPaneVisible) {
DEBUG_LOG(COMMON, "Input pane: TryShow accepted");
}
else {
DEBUG_LOG(COMMON, "Input pane: (TryShow is not accepted or pane is not supported)");
}
}
void DeactivateKeyboardInput() {
DEBUG_LOG(COMMON, "Deactivate input keyboard");
if (InputPane::GetForCurrentView()->TryHide()) {
inputPaneVisible = false;
DEBUG_LOG(COMMON, "Input pane: TryHide accepted");
}
else {
DEBUG_LOG(COMMON, "Input pane: TryHide is not accepted, or pane is not visible");
}
keyboardActive = false;
}
bool IgnoreInput(int keyCode) {
// When keyboard mode active and char is passed this function return 'true'
// it will help to prevent KeyDown from sending the same code again
bool ignoreInput = false;
if (isKeyboardActive() && !IsCtrlOnHold()) {
// To avoid bothering KeyDown to check this case always
// we don't get here unless keyboard mode is active
std::list<int> nonCharList = {
NKCODE_CTRL_LEFT,
NKCODE_CTRL_RIGHT,
NKCODE_MOVE_HOME,
NKCODE_PAGE_UP,
NKCODE_MOVE_END,
NKCODE_PAGE_DOWN,
NKCODE_FORWARD_DEL,
NKCODE_DEL,
NKCODE_ENTER,
NKCODE_NUMPAD_ENTER,
NKCODE_EXT_MOUSEBUTTON_1,
NKCODE_EXT_MOUSEBUTTON_2,
NKCODE_EXT_MOUSEBUTTON_3,
NKCODE_EXT_MOUSEBUTTON_4,
NKCODE_EXT_MOUSEBUTTON_5,
NKCODE_ESCAPE
};
if (!isInputPaneVisible()) {
// Keyboard active but no on-screen keyboard
// allow arrow keys for navigation
nonCharList.push_back(NKCODE_DPAD_UP);
nonCharList.push_back(NKCODE_DPAD_DOWN);
nonCharList.push_back(NKCODE_DPAD_LEFT);
nonCharList.push_back(NKCODE_DPAD_RIGHT);
nonCharList.push_back(NKCODE_BACK);
}
ignoreInput = !findInList(nonCharList, keyCode);
}
return ignoreInput;
}
#pragma endregion
#pragma region Keys Status
@ -92,4 +165,14 @@ std::string GetLangRegion() {
}
return langRegion;
}
bool IsXBox() {
auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo;
return deviceInfo->DeviceFamily == "Windows.Xbox";
}
bool IsMobile() {
auto deviceInfo = Windows::System::Profile::AnalyticsInfo::VersionInfo;
return deviceInfo->DeviceFamily == "Windows.Mobile";
}
#pragma endregion

View file

@ -22,11 +22,12 @@
bool isKeybaordAvailable();
bool isTouchAvailable();
// Input Pane
bool InputPaneVisible();
void ShowInputPane();
void HideInputPane();
// Input Keyboard/Pane
bool isInputPaneVisible();
bool isKeyboardActive();
void ActivateKeyboardInput();
void DeactivateKeyboardInput();
bool IgnoreInput(int keyCode);
// Keys Status
bool IsCapsLockOn();
@ -35,3 +36,5 @@ bool IsCtrlOnHold();
// Misc
std::string GetLangRegion();
bool IsXBox();
bool IsMobile();