Flags& Flags::remove(ModifierFlag flag) { // We consider the following case. // (ModifierFlag::SHIFT_L | ModifierFlag::SHIFT_R).remove(ModifierFlag::SHIFT_L). // // The value of SHIFT_L and SHIFT_R is below. // // ModifierFlag::SHIFT_L : 0x20002 // ModifierFlag::SHIFT_R : 0x20004 // // So, the correct value of above case is 0x20004 (SHIFT_R). // // If we remove bits simple way (value_ &= ~flags), // the result value becomes 0x00004. It's not right. // // Therefore, we save the old value, and restore the necessary bits from it. // Flags old = *this; // keep ModifierFlag::NUMPAD. value_ &= ~(flag.getRawBits()); auto& pairs = KeyCodeModifierFlagPairs::getPairs(); for (size_t i = 0; i < pairs.size(); ++i) { ModifierFlag f = pairs[i].getModifierFlag(); if (f == flag) continue; if (!old.isOn(f)) continue; value_ |= f.getRawBits(); } return *this; }
Flags operator|(ModifierFlag lhs, ModifierFlag rhs) { return Flags(lhs.getRawBits() | rhs.getRawBits()); }
void EventOutputQueue::FireModifiers::fire(AutogenId autogenId, PhysicalEventType physicalEventType, Flags toFlags, KeyboardType keyboardType) { if (lastFlags_ == toFlags) return; if (physicalEventType == PhysicalEventType::DOWN) { isIgnorePhysicalUpEvent_ = false; } else if (physicalEventType == PhysicalEventType::UP) { if (isIgnorePhysicalUpEvent_) { return; } } // ------------------------------------------------------------ // At first we handle KeyUp events and handle KeyDown events next. // We need to end KeyDown at Command+Space to Option_L+Shift_L. // // When Option_L+Shift_L has a meaning (switch input language at Windows), // it does not works well when the last is KeyUp of Command. // ModifierFlag::NUMPAD handling. // (We need to remove ModifierFlag::NUMPAD at first in order to strip NUMPAD flag from normal modifier key events.) if (!toFlags.isOn(ModifierFlag::NUMPAD)) { lastFlags_.remove(ModifierFlag::NUMPAD); } // ------------------------------------------------------------ // KeyUp for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) { ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i); // Skipping invalid flags if (flag.getKeyCode() == KeyCode::VK_NONE) continue; // Skipping virtual modifiers. if (flag.getRawBits() == 0) continue; // ---------------------------------------- if (!lastFlags_.isOn(flag)) continue; if (toFlags.isOn(flag)) continue; lastFlags_.remove(flag); Params_KeyboardEventCallBack params(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false); EventOutputQueue::push(params, autogenId); } // KeyDown for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) { ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i); // Skipping invalid flags if (flag.getKeyCode() == KeyCode::VK_NONE) continue; // Skipping virtual modifiers. if (flag.getRawBits() == 0) continue; // ---------------------------------------- if (!toFlags.isOn(flag)) continue; if (lastFlags_.isOn(flag)) continue; lastFlags_.add(flag); Params_KeyboardEventCallBack params(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false); EventOutputQueue::push(params, autogenId); } // ModifierFlag::NUMPAD handling. // (We need to add ModifierFlag::NUMPAD at last in order to strip NUMPAD flag from normal modifier key events.) if (toFlags.isOn(ModifierFlag::NUMPAD)) { lastFlags_.add(ModifierFlag::NUMPAD); } }