forked from Mirror/Ryujinx
Improve heuristic for showing the keyboard (#2066)
This commit is contained in:
parent
f556c80d02
commit
8b4e4fc076
1 changed files with 15 additions and 8 deletions
|
@ -50,6 +50,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
private bool _okPressed = false;
|
private bool _okPressed = false;
|
||||||
private Encoding _encoding = Encoding.Unicode;
|
private Encoding _encoding = Encoding.Unicode;
|
||||||
private long _lastTextSetMillis = 0;
|
private long _lastTextSetMillis = 0;
|
||||||
|
private bool _lastWasHidden = false;
|
||||||
|
|
||||||
public event EventHandler AppletStateChanged;
|
public event EventHandler AppletStateChanged;
|
||||||
|
|
||||||
|
@ -350,12 +351,12 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
// The Calc request tells the Applet to enter the main input handling loop, which will end
|
// The Calc request tells the Applet to enter the main input handling loop, which will end
|
||||||
// with either a text being submitted or a cancel request from the user.
|
// with either a text being submitted or a cancel request from the user.
|
||||||
|
|
||||||
// NOTE: Some Calc requests happen early in the process and are not meant to be shown. This possibly
|
// NOTE: Some Calc requests happen early in the application and are not meant to be shown. This possibly
|
||||||
// happens because the game has complete control over when the inline keyboard is drawn, but here it
|
// happens because the game has complete control over when the inline keyboard is drawn, but here it
|
||||||
// would cause a dialog to pop in the emulator, which is inconvenient. An algorithm is applied to
|
// would cause a dialog to pop in the emulator, which is inconvenient. An algorithm is applied to
|
||||||
// decide whether it is a dummy Calc or not, but regardless of the result, the dummy Calc appears to
|
// decide whether it is a dummy Calc or not, but regardless of the result, the dummy Calc appears to
|
||||||
// never happen twice, so the keyboard will always show if it has already been shown before.
|
// never happen twice, so the keyboard will always show if it has already been shown before.
|
||||||
bool forceShowKeyboard = _alreadyShown;
|
bool shouldShowKeyboard = _alreadyShown;
|
||||||
_alreadyShown = true;
|
_alreadyShown = true;
|
||||||
|
|
||||||
// Read the Calc data.
|
// Read the Calc data.
|
||||||
|
@ -379,7 +380,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
// input dialog may show, but it is better than a soft lock.
|
// input dialog may show, but it is better than a soft lock.
|
||||||
if (_keyboardBackgroundCalc.Appear.ShouldBeHidden == 0)
|
if (_keyboardBackgroundCalc.Appear.ShouldBeHidden == 0)
|
||||||
{
|
{
|
||||||
forceShowKeyboard = true;
|
shouldShowKeyboard = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send an initialization finished signal.
|
// Send an initialization finished signal.
|
||||||
|
@ -387,10 +388,10 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
SetInlineState(state);
|
SetInlineState(state);
|
||||||
_interactiveSession.Push(InlineResponses.FinishedInitialize(state));
|
_interactiveSession.Push(InlineResponses.FinishedInitialize(state));
|
||||||
// Start a task with the GUI handler to get user's input.
|
// Start a task with the GUI handler to get user's input.
|
||||||
new Task(() => { GetInputTextAndSend(forceShowKeyboard, state); }).Start();
|
new Task(() => { GetInputTextAndSend(shouldShowKeyboard, state); }).Start();
|
||||||
break;
|
break;
|
||||||
case InlineKeyboardRequest.Finalize:
|
case InlineKeyboardRequest.Finalize:
|
||||||
// The calling process wants to close the keyboard applet and will wait for a state change.
|
// The calling application wants to close the keyboard applet and will wait for a state change.
|
||||||
_backgroundState = InlineKeyboardState.Uninitialized;
|
_backgroundState = InlineKeyboardState.Uninitialized;
|
||||||
AppletStateChanged?.Invoke(this, null);
|
AppletStateChanged?.Invoke(this, null);
|
||||||
break;
|
break;
|
||||||
|
@ -403,7 +404,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetInputTextAndSend(bool forceShowKeyboard, InlineKeyboardState oldState)
|
private void GetInputTextAndSend(bool shouldShowKeyboard, InlineKeyboardState oldState)
|
||||||
{
|
{
|
||||||
bool submit = true;
|
bool submit = true;
|
||||||
|
|
||||||
|
@ -422,27 +423,32 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
SetInlineState(newState);
|
SetInlineState(newState);
|
||||||
ChangedString("", newState);
|
ChangedString("", newState);
|
||||||
|
|
||||||
if (inputElapsedMillis < DebounceTimeMillis)
|
if (!_lastWasHidden && (inputElapsedMillis < DebounceTimeMillis))
|
||||||
{
|
{
|
||||||
// A repeated Calc request has been received without player interaction, after the input has been
|
// A repeated Calc request has been received without player interaction, after the input has been
|
||||||
// sent. This behavior happens in some games, so instead of showing another dialog, just apply a
|
// sent. This behavior happens in some games, so instead of showing another dialog, just apply a
|
||||||
// time-based debouncing algorithm and repeat the last submission, either a value or a cancel.
|
// time-based debouncing algorithm and repeat the last submission, either a value or a cancel.
|
||||||
|
// It is also possible that the first Calc request was hidden by accident, in this case use the
|
||||||
|
// debouncing as an oportunity to properly ask for input.
|
||||||
inputText = _textValue;
|
inputText = _textValue;
|
||||||
submit = _textValue != null;
|
submit = _textValue != null;
|
||||||
|
_lastWasHidden = false;
|
||||||
|
|
||||||
Logger.Warning?.Print(LogClass.Application, "Debouncing repeated keyboard request");
|
Logger.Warning?.Print(LogClass.Application, "Debouncing repeated keyboard request");
|
||||||
}
|
}
|
||||||
else if (!forceShowKeyboard)
|
else if (!shouldShowKeyboard)
|
||||||
{
|
{
|
||||||
// Submit the default text to avoid soft locking if the keyboard was ignored by
|
// Submit the default text to avoid soft locking if the keyboard was ignored by
|
||||||
// accident. It's better to change the name than being locked out of the game.
|
// accident. It's better to change the name than being locked out of the game.
|
||||||
inputText = DefaultText;
|
inputText = DefaultText;
|
||||||
|
_lastWasHidden = true;
|
||||||
|
|
||||||
Logger.Debug?.Print(LogClass.Application, "Received a dummy Calc, keyboard will not be shown");
|
Logger.Debug?.Print(LogClass.Application, "Received a dummy Calc, keyboard will not be shown");
|
||||||
}
|
}
|
||||||
else if (_device.UiHandler == null)
|
else if (_device.UiHandler == null)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, "GUI Handler is not set. Falling back to default");
|
Logger.Warning?.Print(LogClass.Application, "GUI Handler is not set. Falling back to default");
|
||||||
|
_lastWasHidden = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -461,6 +467,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||||
|
|
||||||
submit = _device.UiHandler.DisplayInputDialog(args, out inputText);
|
submit = _device.UiHandler.DisplayInputDialog(args, out inputText);
|
||||||
inputText = submit ? inputText : null;
|
inputText = submit ? inputText : null;
|
||||||
|
_lastWasHidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The 'Complete' state indicates the Calc request has been fulfilled by the applet.
|
// The 'Complete' state indicates the Calc request has been fulfilled by the applet.
|
||||||
|
|
Loading…
Reference in a new issue