MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey-v1.0 / UpdateModifierState

Function UpdateModifierState

Source/hook_include.cpp:210–647  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

208
209#ifdef INCLUDE_KEYBD_HOOK
210void UpdateModifierState(KBDLLHOOKSTRUCT &event, vk_type vk, sc_type sc, bool key_up, bool aIsSuppressed)
211// Always use the parameter vk rather than event.vkCode because the caller or caller's caller
212// might have adjusted vk, namely to make it a left/right specific modifier key rather than a
213// neutral one.
214{
215 // This part is done even if the key is being ignored because we always want their status
216 // to be correct *regardless* of whether the key is ignored. This is especially important
217 // in cases such as Shift-Alt-Tab and Alt-Tab both have substitutes. NOTE: We don't want
218 // the CapsLock/Numlock/Scrolllock section up here with it because for those cases, we
219 // genuinely want to ignore them entirely when the hook itself sends a keybd_event for one
220 // of them.
221 // Since low-level (but not high level) keyboard hook supports left/right VKs, use
222 // them in pref. to scan code because it's much more likely to be compatible with
223 // non-English or non-std keyboards.
224
225 // Below excludes KEY_IGNORE_ALL_EXCEPT_MODIFIER since that type of event should not
226 // be ignored by this function. UPDATE: KEY_PHYS_IGNORE is now considered to be something
227 // that should not be ignored because if more than one instance has the hook installed,
228 // it is possible for g_modifiersLR_logical_non_ignored to say that a key is down in one
229 // instance when that instance's g_modifiersLR_logical doesn't say it's down, which is
230 // definitely wrong. So is now omitted from the below:
231 bool is_not_ignored = event.dwExtraInfo != KEY_IGNORE;
232
233 switch (vk)
234 {
235 // Normally (for physical key presses) the vk will be left/right specific. However,
236 // if another app calls keybd_event() or a similar function to inject input,
237 // the generic key will be received if that's what was sent.
238 // Try to keep the most often-pressed keys at the top for potentially better
239 // performance (depends on how the compiler implements the switch stmt: jump table
240 // vs. if-then-else tree):
241 case VK_LSHIFT:
242 if (key_up)
243 {
244 if (!aIsSuppressed)
245 {
246 g_modifiersLR_logical &= ~MOD_LSHIFT;
247 // Even if is_not_ignored == true, this is updated unconditionally on key-up events
248 // to ensure that g_modifiersLR_logical_non_ignored never says a key is down when
249 // g_modifiersLR_logical says its up, which might otherwise happen in cases such
250 // as alt-tab. See this comment further below, where the operative word is "relied":
251 // "key pushed ALT down, or relied upon it already being down, so go up". UPDATE:
252 // The above is no longer a concern because KeyEvent() now defaults to the mode
253 // which causes our var "is_not_ignored" to be true here. Only the Send command
254 // overrides this default, and it takes responsibility for ensuring that the older
255 // comment above never happens by forcing any down-modifiers to be up if they're
256 // not logically down as reflected in g_modifiersLR_logical. There's more
257 // explanation for g_modifiersLR_logical_non_ignored in keyboard.h:
258 if (is_not_ignored)
259 g_modifiersLR_logical_non_ignored &= ~MOD_LSHIFT;
260 }
261 if (EventIsPhysical(event, vk, sc, key_up)) // Note that ignored events can be physical via KEYEVENT_PHYS()
262 {
263 g_modifiersLR_physical &= ~MOD_LSHIFT;
264 g_PhysicalKeyState[VK_LSHIFT] = 0;
265 g_PhysicalKeyState[VK_SHIFT] = g_PhysicalKeyState[VK_RSHIFT]; // Neutral is down if right is down.
266 }
267 }

Callers 1

UpdateKeyStateFunction · 0.85

Calls 1

EventIsPhysicalFunction · 0.85

Tested by

no test coverage detected