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"));
}