| 208 | |
| 209 | #ifdef INCLUDE_KEYBD_HOOK |
| 210 | void 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 | } |
no test coverage detected