mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
AppleEvent: Improve key repeat fine tuning
This commit is contained in:
parent
dbc9a3de63
commit
e646a47885
@ -6357,18 +6357,56 @@ functioning. Feature highlights:
|
||||
\emph{Note}: Currently \texttt{V1}, \texttt{V2}, and \texttt{AMI} unlike \texttt{Auto} only do filtering of
|
||||
the particular specified protocol. This may change in the future versions.
|
||||
|
||||
\item
|
||||
\texttt{KeySkipFirstDelay}\\
|
||||
\textbf{Type}: \texttt{plist\ boolean}\\
|
||||
\textbf{Failsafe}: \texttt{false}\\
|
||||
\textbf{Description}: Suppress initial delay before key repeat in
|
||||
OpenCore implementation of Apple Event protocol.
|
||||
\item
|
||||
\texttt{KeyInitialDelay}\\
|
||||
\textbf{Type}: \texttt{plist\ integer}\\
|
||||
\textbf{Failsafe}: \texttt{0} (acts as \texttt{50}, or 500ms)\\
|
||||
\textbf{Description}: Configure initial keyboard repeat delay in OpenCore implementation
|
||||
of Apple Event protocol, in units of 10ms.
|
||||
|
||||
When combining OpenCore \texttt{KeySupport} with the Apple Event protocol, key repeat behaviour
|
||||
may show one additional slow key repeat before normal key repeat starts. Enabling this option
|
||||
works around this problem by suppressing the initial repeat delay in the OpenCore Apple Event
|
||||
implementation. This option is recommended to be set when using \texttt{KeySupport} mode, in most
|
||||
cases, and is not recommended to be set on any systems which are not using \texttt{KeySupport} mode.
|
||||
In order to fine tune keyboard behaviour three values are relavent:
|
||||
\texttt{KeyForgetThreshold}, \texttt{KeyInitialDelay} and \texttt{KeySubsequentDelay}.
|
||||
|
||||
The tuning procedure is as follows:
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item On systems which are not using \texttt{KeySupport}, no tuning
|
||||
is needed.
|
||||
\item On systems which are using \texttt{KeySupport}, it is important to tune
|
||||
\texttt{KeyForgetThreshold} as documented above, in order to get reliable key-held
|
||||
behaviour - including reliable responses to boot hotkeys - within OC.
|
||||
\item After this, no further tuning is \emph{required} for reliable operation.
|
||||
However for fine tuning, proceed as follows:
|
||||
\end{itemize}
|
||||
|
||||
Apple Event protocol is used widely for key input in OpenCore, since we have to
|
||||
provide it for Apple's own pre-boot systems to use anyway. However, a minor issue
|
||||
is that when combining OpenCore \texttt{KeySupport} with Apple Event key handling,
|
||||
key repeat behaviour may show one additional slow key repeat before normal key repeat starts.
|
||||
This is perfectly usable in practice, but in order to fine tune your key response and avoid
|
||||
this minor issue, configure the value of \texttt{KeyInitialDelay} to be the same as the value of
|
||||
\texttt{KeySubsequentDelay}, i.e. by default configure a value of \texttt{5} for
|
||||
\texttt{KeyInitialDelay}. On many systems this will be sufficient. However on some
|
||||
pathological - especially PS/2 - systems, you may find that using \texttt{5} and \texttt{5}
|
||||
for \texttt{KeyInitialDelay} and \texttt{KeySubsequentDelay} causes two key responses for
|
||||
every key press. In this case, you will need to tune the shared value upwards until you avoid
|
||||
this new symptom. E.g. values as high as \texttt{9} and \texttt{9} have been observed required
|
||||
on some systems.
|
||||
|
||||
\emph{Note}: When tuning keyboard behaviour, double key responses can make it impossible to
|
||||
access some boot entries - avoid making your system unbootable. If you do not have easy access to
|
||||
another boot method, you are recommended to set \texttt{Misc/Boot/Timeout} to \texttt{5} before
|
||||
trying this procedure, so that your normal OS will boot after a short time anyway.
|
||||
|
||||
\item
|
||||
\texttt{KeySubsequentDelay}\\
|
||||
\textbf{Type}: \texttt{plist\ integer}\\
|
||||
\textbf{Failsafe}: \texttt{0} (acts as \texttt{5}, or 50ms)\\
|
||||
\textbf{Description}: Configure subsequent keyboard repeat delay in OpenCore implementation
|
||||
of Apple Event protocol, in units of 10ms.
|
||||
|
||||
See documentation of \texttt{KeyInitialDelay}.
|
||||
|
||||
\item
|
||||
\texttt{KeySwap}\\
|
||||
|
||||
@ -1154,8 +1154,10 @@
|
||||
<false/>
|
||||
<key>KeyForgetThreshold</key>
|
||||
<integer>5</integer>
|
||||
<key>KeySkipFirstDelay</key>
|
||||
<true/>
|
||||
<key>KeyInitialDelay</key>
|
||||
<integer>0</integer>
|
||||
<key>KeySubsequentDelay</key>
|
||||
<integer>0</integer>
|
||||
<key>KeySupport</key>
|
||||
<true/>
|
||||
<key>KeySupportMode</key>
|
||||
|
||||
@ -1351,8 +1351,10 @@
|
||||
<false/>
|
||||
<key>KeyForgetThreshold</key>
|
||||
<integer>5</integer>
|
||||
<key>KeySkipFirstDelay</key>
|
||||
<true/>
|
||||
<key>KeyInitialDelay</key>
|
||||
<integer>0</integer>
|
||||
<key>KeySubsequentDelay</key>
|
||||
<integer>0</integer>
|
||||
<key>KeySupport</key>
|
||||
<true/>
|
||||
<key>KeySupportMode</key>
|
||||
|
||||
@ -22,14 +22,18 @@
|
||||
Install and initialise Apple Event protocol.
|
||||
|
||||
@param[in] Reinstall Overwrite installed protocol.
|
||||
@param[in] KeySkipFirstDelay Modify keyboard handling to suppress initial delay.
|
||||
@param[in] KeyInitialDelay Key repeat initial delay in 10ms units.
|
||||
If less than or equal to 0 then use 50.
|
||||
@param[in] KeySubsequentDelay Key repeat subsequent delay in 10ms units.
|
||||
If less than or equal to 0 then use 5.
|
||||
|
||||
@retval installed or located protocol or NULL.
|
||||
**/
|
||||
APPLE_EVENT_PROTOCOL *
|
||||
OcAppleEventInstallProtocol (
|
||||
IN BOOLEAN Reinstall,
|
||||
IN BOOLEAN KeySkipFirstDelay
|
||||
IN UINT16 KeyInitialDelay OPTIONAL,
|
||||
IN UINT16 KeySubsequentDelay OPTIONAL
|
||||
);
|
||||
|
||||
#endif // OC_APPLE_EVENT_LIB_H
|
||||
|
||||
@ -604,9 +604,10 @@ typedef enum {
|
||||
_(OC_STRING , KeySupportMode , , OC_STRING_CONSTR ("Auto", _, __) , OC_DESTR (OC_STRING)) \
|
||||
_(OC_STRING , PointerSupportMode , , OC_STRING_CONSTR ("", _, __) , OC_DESTR (OC_STRING)) \
|
||||
_(UINT32 , TimerResolution , , 0 , ()) \
|
||||
_(UINT16 , KeyInitialDelay , , 0 , ()) \
|
||||
_(UINT16 , KeySubsequentDelay , , 0 , ()) \
|
||||
_(UINT8 , KeyForgetThreshold , , 0 , ()) \
|
||||
_(BOOLEAN , KeySupport , , FALSE , ()) \
|
||||
_(BOOLEAN , KeySkipFirstDelay , , FALSE , ()) \
|
||||
_(BOOLEAN , KeyFiltering , , FALSE , ()) \
|
||||
_(BOOLEAN , KeySwap , , FALSE , ()) \
|
||||
_(BOOLEAN , PointerSupport , , FALSE , ())
|
||||
|
||||
@ -154,10 +154,11 @@ EventInputKeyFromAppleKeyCode (
|
||||
IN BOOLEAN Shifted
|
||||
);
|
||||
|
||||
// InternalSkipFirstKeyDelay
|
||||
// InternalSetKeyDelays
|
||||
VOID
|
||||
InternalSkipFirstKeyDelay (
|
||||
IN BOOLEAN SkipFirstDelay
|
||||
InternalSetKeyDelays (
|
||||
IN UINT16 KeyInitialDelay,
|
||||
IN UINT16 KeySubsequentDelay
|
||||
);
|
||||
|
||||
#endif // APPLE_EVENT_INTERNAL_H_
|
||||
|
||||
@ -66,19 +66,29 @@ STATIC KEY_STROKE_INFORMATION mKeyStrokeInfo[10];
|
||||
// mCLockChanged
|
||||
STATIC BOOLEAN mCLockChanged = FALSE;
|
||||
|
||||
// mSkipFirstDelay
|
||||
STATIC BOOLEAN mSkipFirstDelay = FALSE;
|
||||
// mKeyInitialDelay, mKeySubsequentDelay
|
||||
STATIC UINTN mKeyInitialDelay = 50;
|
||||
STATIC UINTN mKeySubsequentDelay = 5;
|
||||
|
||||
// mAppleKeyMapAggregator
|
||||
STATIC APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *mKeyMapAggregator = NULL;
|
||||
|
||||
// InternalSkipFirstKeyDelay
|
||||
// InternalSetKeyDelays
|
||||
VOID
|
||||
InternalSkipFirstKeyDelay (
|
||||
IN BOOLEAN SkipFirstDelay
|
||||
InternalSetKeyDelays (
|
||||
IN UINT16 KeyInitialDelay,
|
||||
IN UINT16 KeySubsequentDelay
|
||||
)
|
||||
{
|
||||
mSkipFirstDelay = SkipFirstDelay;
|
||||
if (KeyInitialDelay != 0) {
|
||||
mKeyInitialDelay = KeyInitialDelay;
|
||||
}
|
||||
|
||||
if (KeySubsequentDelay != 0) {
|
||||
mKeySubsequentDelay = KeySubsequentDelay;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "OCAE: Using %d (%d0ms) and %d (%d0ms)\n", mKeyInitialDelay, mKeyInitialDelay, mKeySubsequentDelay, mKeySubsequentDelay));
|
||||
}
|
||||
|
||||
// InternalGetAppleKeyStrokes
|
||||
@ -504,9 +514,9 @@ InternalGetCurrentKeyStroke (
|
||||
|
||||
if (KeyInfo != NULL) {
|
||||
AcceptStroke = (BOOLEAN)(
|
||||
(!mSkipFirstDelay && KeyInfo->NumberOfStrokes < (KEY_STROKE_DELAY * 10))
|
||||
(KeyInfo->NumberOfStrokes < mKeyInitialDelay)
|
||||
? (KeyInfo->NumberOfStrokes == 0)
|
||||
: ((KeyInfo->NumberOfStrokes % KEY_STROKE_DELAY) == 0)
|
||||
: (((KeyInfo->NumberOfStrokes - mKeyInitialDelay) % mKeySubsequentDelay) == 0)
|
||||
);
|
||||
|
||||
if (AcceptStroke) {
|
||||
|
||||
@ -548,15 +548,19 @@ AppleEventUnload (
|
||||
/**
|
||||
Install and initialise Apple Event protocol.
|
||||
|
||||
@param[in] Reinstall Overwrite installed protocol.
|
||||
@param[in] KeySkipFirstDelay Modify keyboard handling to suppress initial delay.
|
||||
@param[in] Reinstall Overwrite installed protocol.
|
||||
@param[in] KeyInitialDelay Key repeat initial delay in 10ms units.
|
||||
If less than or equal to 0 then use 50.
|
||||
@param[in] KeySubsequentDelay Key repeat subsequent delay in 10ms units.
|
||||
If less than or equal to 0 then use 5.
|
||||
|
||||
@retval installed or located protocol or NULL.
|
||||
**/
|
||||
APPLE_EVENT_PROTOCOL *
|
||||
OcAppleEventInstallProtocol (
|
||||
IN BOOLEAN Reinstall,
|
||||
IN BOOLEAN KeySkipFirstDelay
|
||||
IN UINT16 KeyInitialDelay OPTIONAL,
|
||||
IN UINT16 KeySubsequentDelay OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -584,7 +588,7 @@ OcAppleEventInstallProtocol (
|
||||
}
|
||||
}
|
||||
|
||||
InternalSkipFirstKeyDelay (KeySkipFirstDelay);
|
||||
InternalSetKeyDelays (KeyInitialDelay, KeySubsequentDelay);
|
||||
|
||||
//
|
||||
// Apple code supports unloading, ours does not.
|
||||
|
||||
@ -728,7 +728,8 @@ OC_SCHEMA
|
||||
mUefiInputSchema[] = {
|
||||
OC_SCHEMA_BOOLEAN_IN ("KeyFiltering", OC_GLOBAL_CONFIG, Uefi.Input.KeyFiltering),
|
||||
OC_SCHEMA_INTEGER_IN ("KeyForgetThreshold", OC_GLOBAL_CONFIG, Uefi.Input.KeyForgetThreshold),
|
||||
OC_SCHEMA_BOOLEAN_IN ("KeySkipFirstDelay", OC_GLOBAL_CONFIG, Uefi.Input.KeySkipFirstDelay),
|
||||
OC_SCHEMA_INTEGER_IN ("KeyInitialDelay", OC_GLOBAL_CONFIG, Uefi.Input.KeyInitialDelay),
|
||||
OC_SCHEMA_INTEGER_IN ("KeySubsequentDelay", OC_GLOBAL_CONFIG, Uefi.Input.KeySubsequentDelay),
|
||||
OC_SCHEMA_BOOLEAN_IN ("KeySupport", OC_GLOBAL_CONFIG, Uefi.Input.KeySupport),
|
||||
OC_SCHEMA_STRING_IN ("KeySupportMode", OC_GLOBAL_CONFIG, Uefi.Input.KeySupportMode),
|
||||
OC_SCHEMA_BOOLEAN_IN ("KeySwap", OC_GLOBAL_CONFIG, Uefi.Input.KeySwap),
|
||||
|
||||
@ -36,7 +36,7 @@ AIKProtocolArriveHandler (
|
||||
Keycode = (AIK_SELF *) Context;
|
||||
|
||||
if (Keycode == NULL || Keycode->OurJobIsDone) {
|
||||
DEBUG ((DEBUG_INFO, "AIKProtocolArriveHandler got null handler or called when done\n"));
|
||||
DEBUG ((DEBUG_INFO, "AIK: ProtocolArriveHandler got null handler or called when done\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ AIKProtocolArriveHandler (
|
||||
//
|
||||
AIKProtocolArriveUninstall (Keycode);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "AIKProtocolArriveHandler AIKInstall failed - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "AIK: ProtocolArriveHandler AIKInstall failed - %r\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ AIKPollKeyboardHandler (
|
||||
|
||||
Keycode = (AIK_SELF *) Context;
|
||||
if (Keycode == NULL || Keycode->OurJobIsDone) {
|
||||
DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler got null handler or called when done\n"));
|
||||
DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler got null handler or called when done\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -205,12 +205,12 @@ AIKInstall (
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = gBS->SetTimer (Keycode->PollKeyboardEvent, TimerPeriodic, AIK_KEY_POLL_INTERVAL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler timer setting failed - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler timer setting failed - %r\n", Status));
|
||||
gBS->CloseEvent (Keycode->PollKeyboardEvent);
|
||||
Keycode->PollKeyboardEvent = NULL;
|
||||
}
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler event creation failed - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "AIK: PollKeyboardHandler event creation failed - %r\n", Status));
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -259,7 +259,6 @@ OcAppleGenericInputKeycodeInit (
|
||||
//
|
||||
// Allow to see whether this is installed, even on success
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "AIKInstall - %r\n", Status));
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// No AppleKeyMapAggregator present, install on its availability.
|
||||
@ -269,10 +268,14 @@ OcAppleGenericInputKeycodeInit (
|
||||
//
|
||||
// TODO: Should there be DEBUG_ERROR here (critical error?)
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "AIK is NOT waiting for protocols - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "AIK: NOT waiting for protocols - %r\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "AIK: Using %d (%d0ms)\n", KeyForgotThreshold, KeyForgotThreshold));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@ -341,7 +341,11 @@ OcReinstallProtocols (
|
||||
DEBUG ((DEBUG_ERROR, "OC: Failed to install key map protocols\n"));
|
||||
}
|
||||
|
||||
if (OcAppleEventInstallProtocol (Config->Uefi.ProtocolOverrides.AppleEvent, Config->Uefi.Input.KeySkipFirstDelay) == NULL) {
|
||||
if (OcAppleEventInstallProtocol (
|
||||
Config->Uefi.ProtocolOverrides.AppleEvent,
|
||||
Config->Uefi.Input.KeyInitialDelay,
|
||||
Config->Uefi.Input.KeySubsequentDelay
|
||||
) == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "OC: Failed to install key event protocol\n"));
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user