| 2273 | |
| 2274 | |
| 2275 | bool CollectInput(KBDLLHOOKSTRUCT &aEvent, const vk_type aVK, const sc_type aSC, bool aKeyUp, bool aIsIgnored |
| 2276 | , KeyHistoryItem *pKeyHistoryCurr, WPARAM &aHotstringWparamToPost, LPARAM &aHotstringLparamToPost) |
| 2277 | // Caller is responsible for having initialized aHotstringWparamToPost to HOTSTRING_INDEX_INVALID. |
| 2278 | // Returns true if the caller should treat the key as visible (non-suppressed). |
| 2279 | // Always use the parameter vk rather than event.vkCode because the caller or caller's caller |
| 2280 | // might have adjusted vk, namely to make it a left/right specific modifier key rather than a |
| 2281 | // neutral one. |
| 2282 | { |
| 2283 | // Transcription is done only once for all layers, so do this if any layer requests it: |
| 2284 | bool transcribe_modified_keys = false; |
| 2285 | |
| 2286 | for (auto *input = g_input; input; input = input->Prev) |
| 2287 | { |
| 2288 | if (input->InProgress() && input->IsInteresting(aEvent)) |
| 2289 | { |
| 2290 | if ( aKeyUp && input->ScriptObject && input->ScriptObject->onKeyUp |
| 2291 | && ( ((input->KeySC[aSC] | input->KeyVK[aVK]) & INPUT_KEY_NOTIFY) |
| 2292 | || input->NotifyNonText && !((input->KeyVK[aVK]) & INPUT_KEY_IS_TEXT) ) ) |
| 2293 | { |
| 2294 | PostMessage(g_hWnd, AHK_INPUT_KEYUP, (WPARAM)input, (aSC << 16) | aVK); |
| 2295 | } |
| 2296 | if (aKeyUp && (input->KeySC[aSC] & INPUT_KEY_DOWN_SUPPRESSED)) |
| 2297 | { |
| 2298 | input->KeySC[aSC] &= ~INPUT_KEY_DOWN_SUPPRESSED; |
| 2299 | return false; |
| 2300 | } |
| 2301 | if (aKeyUp && (input->KeyVK[aVK] & INPUT_KEY_DOWN_SUPPRESSED)) |
| 2302 | { |
| 2303 | input->KeyVK[aVK] &= ~INPUT_KEY_DOWN_SUPPRESSED; |
| 2304 | return false; |
| 2305 | } |
| 2306 | |
| 2307 | if (input->TranscribeModifiedKeys) |
| 2308 | transcribe_modified_keys = true; |
| 2309 | } |
| 2310 | } |
| 2311 | |
| 2312 | // The checks above suppress key-up if key-down was suppressed and the Input is still active. |
| 2313 | // Otherwise, avoid suppressing key-up since it may result in the key getting stuck down. |
| 2314 | // At the very least, this is needed for cases where a user presses a #z hotkey, for example, |
| 2315 | // to initiate an Input. When the user releases the LWIN/RWIN key during the input, that |
| 2316 | // up-event should not be suppressed otherwise the modifier key would get "stuck down". |
| 2317 | if (aKeyUp) |
| 2318 | return true; |
| 2319 | |
| 2320 | static vk_type sPendingDeadKeyVK = 0; |
| 2321 | static sc_type sPendingDeadKeySC = 0; // Need to track this separately because sometimes default VK-to-SC mapping isn't correct. |
| 2322 | static bool sPendingDeadKeyUsedShift = false; |
| 2323 | static bool sPendingDeadKeyUsedAltGr = false; |
| 2324 | |
| 2325 | bool transcribe_key = true; |
| 2326 | |
| 2327 | // Don't unconditionally transcribe modified keys such as Ctrl-C because calling ToAsciiEx() on |
| 2328 | // some such keys (e.g. Ctrl-LeftArrow or RightArrow if I recall correctly), disrupts the native |
| 2329 | // function of those keys. That is the reason for the existence of the |
| 2330 | // g_input.TranscribeModifiedKeys option. |
| 2331 | // Fix for v1.0.38: Below now uses g_modifiersLR_logical vs. g_modifiersLR_physical because |
| 2332 | // it's the logical state that determines what will actually be produced on the screen and |
no test coverage detected