diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex index 5fff2768..2b08de70 100755 --- a/Docs/Configuration.tex +++ b/Docs/Configuration.tex @@ -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}\\ diff --git a/Docs/Sample.plist b/Docs/Sample.plist index 13193fee..4ed8a28f 100644 --- a/Docs/Sample.plist +++ b/Docs/Sample.plist @@ -1154,8 +1154,10 @@ KeyForgetThreshold 5 - KeySkipFirstDelay - + KeyInitialDelay + 0 + KeySubsequentDelay + 0 KeySupport KeySupportMode diff --git a/Docs/SampleCustom.plist b/Docs/SampleCustom.plist index 38b7bc49..206ad961 100644 --- a/Docs/SampleCustom.plist +++ b/Docs/SampleCustom.plist @@ -1351,8 +1351,10 @@ KeyForgetThreshold 5 - KeySkipFirstDelay - + KeyInitialDelay + 0 + KeySubsequentDelay + 0 KeySupport KeySupportMode diff --git a/Include/Acidanthera/Library/OcAppleEventLib.h b/Include/Acidanthera/Library/OcAppleEventLib.h index 3c2c910b..7dca3221 100644 --- a/Include/Acidanthera/Library/OcAppleEventLib.h +++ b/Include/Acidanthera/Library/OcAppleEventLib.h @@ -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 diff --git a/Include/Acidanthera/Library/OcConfigurationLib.h b/Include/Acidanthera/Library/OcConfigurationLib.h index f3a9353b..f4c949f3 100644 --- a/Include/Acidanthera/Library/OcConfigurationLib.h +++ b/Include/Acidanthera/Library/OcConfigurationLib.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 , ()) diff --git a/Library/OcAppleEventLib/AppleEventInternal.h b/Library/OcAppleEventLib/AppleEventInternal.h index 2acd4390..7d013e23 100644 --- a/Library/OcAppleEventLib/AppleEventInternal.h +++ b/Library/OcAppleEventLib/AppleEventInternal.h @@ -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_ diff --git a/Library/OcAppleEventLib/KeyHandler.c b/Library/OcAppleEventLib/KeyHandler.c index b57ad11f..ea171f1b 100644 --- a/Library/OcAppleEventLib/KeyHandler.c +++ b/Library/OcAppleEventLib/KeyHandler.c @@ -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) { diff --git a/Library/OcAppleEventLib/OcAppleEventLib.c b/Library/OcAppleEventLib/OcAppleEventLib.c index 4c3595e7..397c3998 100644 --- a/Library/OcAppleEventLib/OcAppleEventLib.c +++ b/Library/OcAppleEventLib/OcAppleEventLib.c @@ -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. diff --git a/Library/OcConfigurationLib/OcConfigurationLib.c b/Library/OcConfigurationLib/OcConfigurationLib.c index 9ea502c3..eb7f5a98 100644 --- a/Library/OcConfigurationLib/OcConfigurationLib.c +++ b/Library/OcConfigurationLib/OcConfigurationLib.c @@ -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), diff --git a/Library/OcInputLib/Keycode/AIK.c b/Library/OcInputLib/Keycode/AIK.c index e91d5762..ce6a2c9d 100644 --- a/Library/OcInputLib/Keycode/AIK.c +++ b/Library/OcInputLib/Keycode/AIK.c @@ -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; } diff --git a/Library/OcMainLib/OpenCoreUefi.c b/Library/OcMainLib/OpenCoreUefi.c index d29c83dd..a82471d0 100644 --- a/Library/OcMainLib/OpenCoreUefi.c +++ b/Library/OcMainLib/OpenCoreUefi.c @@ -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")); }