bool FlagStatus::isOn(const Vector_ModifierFlag& modifierFlags) const { bool strict = false; for (size_t i = 0; i < modifierFlags.size(); ++i) { if (modifierFlags[i] == ModifierFlag::ZERO) continue; if (modifierFlags[i] == ModifierFlag::NONE) { strict = true; } else { if (! isOn(modifierFlags[i])) return false; } } // If modifierFlags contains ModifierFlag::NONE, // return false when unspecified modifierflag is pressed. if (strict) { for (size_t i = 0; i < item_.size(); ++i) { if (item_[i].sum(true) > 0 && ! modifierFlags.is_include(item_[i].flag_)) { return false; } } } return true; }
TEST(FlagStatus, subtract) { FlagStatus flagStatus1; FlagStatus flagStatus2; flagStatus1.increase(ModifierFlag::CONTROL_L); flagStatus1.increase(ModifierFlag::OPTION_L); flagStatus1.increase(ModifierFlag::SHIFT_L); flagStatus1.increase(ModifierFlag::SHIFT_L); flagStatus1.decrease(ModifierFlag::COMMAND_R); flagStatus2.increase(ModifierFlag::CONTROL_L); flagStatus2.increase(ModifierFlag::FN); Vector_ModifierFlag v; flagStatus1.subtract(flagStatus2, v); EXPECT_EQ(3, v.size()); EXPECT_EQ(ModifierFlag::OPTION_L, v[0]); EXPECT_EQ(ModifierFlag::SHIFT_L, v[1]); EXPECT_EQ(ModifierFlag::SHIFT_L, v[2]); flagStatus2.subtract(flagStatus1, v); EXPECT_EQ(2, v.size()); EXPECT_EQ(ModifierFlag::COMMAND_R, v[0]); EXPECT_EQ(ModifierFlag::FN, v[1]); }
TEST(FlagStatus, negative_lock_clear) { FlagStatus flagStatus; { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::FN); v.push_back(ModifierFlag::SHIFT_L); flagStatus.negative_lock_increase(v); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); flagStatus.increase(v); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); flagStatus.increase(v); EXPECT_EQ(ModifierFlag::COMMAND_L | ModifierFlag::FN | ModifierFlag::SHIFT_L, flagStatus.makeFlags()); flagStatus.reset(); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); flagStatus.increase(v); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); flagStatus.negative_lock_clear(); EXPECT_EQ(ModifierFlag::COMMAND_L | ModifierFlag::FN | ModifierFlag::SHIFT_L, flagStatus.makeFlags()); } }
TEST(FlagStatus, decrease) { FlagStatus flagStatus; { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::CONTROL_L); flagStatus.increase(v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L), flagStatus.makeFlags()); } flagStatus.decrease(ModifierFlag::CONTROL_L); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L), flagStatus.makeFlags()); }
void FlagStatus::subtract(const FlagStatus& other, Vector_ModifierFlag& modifierFlags) const { modifierFlags.clear(); if (item_.size() == other.item_.size()) { for (size_t i = 0; i < item_.size(); ++i) { int sum1 = item_[i].sum(true); int sum2 = other.item_[i].sum(true); if (sum1 > sum2) { for (int j = 0; j < sum1 - sum2; ++j) { modifierFlags.push_back(item_[i].flag_); } } } } }
TEST(FlagStatus, sticky_clear) { FlagStatus flagStatus; { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::FN); v.push_back(ModifierFlag::SHIFT_L); flagStatus.sticky_increase(v); EXPECT_EQ(ModifierFlag::COMMAND_L | ModifierFlag::FN | ModifierFlag::SHIFT_L, flagStatus.makeFlags()); } flagStatus.sticky_clear(); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); }
TEST(FlagStatus, sticky_increase) { FlagStatus flagStatus; // Do nothing with ModifierFlag::NONE. flagStatus.sticky_increase(ModifierFlag::NONE); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::FN); flagStatus.sticky_increase(v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::FN), flagStatus.makeFlags()); } flagStatus.sticky_decrease(ModifierFlag::COMMAND_L); EXPECT_EQ(Flags(ModifierFlag::FN), flagStatus.makeFlags()); }
TEST(FlagStatus, temporary_decrease) { FlagStatus flagStatus; { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::CONTROL_L); flagStatus.increase(v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L), flagStatus.makeFlags()); } flagStatus.temporary_decrease(ModifierFlag::CONTROL_L); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L), flagStatus.makeFlags()); // temporary_increase will reset by flagStatus.set flagStatus.set(KeyCode::COMMAND_L, Flags(ModifierFlag::COMMAND_L)); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L), flagStatus.makeFlags()); }
TEST(FlagStatus, lock_clear) { FlagStatus flagStatus; { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::FN); v.push_back(ModifierFlag::SHIFT_L); flagStatus.lock_increase(v); EXPECT_EQ(ModifierFlag::COMMAND_L | ModifierFlag::FN | ModifierFlag::SHIFT_L, flagStatus.makeFlags()); } { flagStatus.increase(ModifierFlag::CAPSLOCK); EXPECT_EQ(ModifierFlag::CAPSLOCK | ModifierFlag::COMMAND_L | ModifierFlag::FN | ModifierFlag::SHIFT_L, flagStatus.makeFlags()); } flagStatus.lock_clear(); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); }
bool FlagStatus::isStuck(const Vector_ModifierFlag& modifierFlags) const { for (size_t i = 0; i < item_.size(); ++i) { if (item_[i].flag_ == ModifierFlag::ZERO) continue; if (item_[i].flag_ == ModifierFlag::NONE) continue; if (modifierFlags.is_include(item_[i].flag_) && item_[i].sticky_count_ <= 0) { return false; } } return true; }
TEST(FlagStatus, increase) { { FlagStatus flagStatus; // Do nothing with ModifierFlag::NONE. flagStatus.increase(ModifierFlag::NONE); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); flagStatus.increase(ModifierFlag::SHIFT_L); EXPECT_EQ(Flags(ModifierFlag::SHIFT_L), flagStatus.makeFlags()); { Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::CONTROL_L); flagStatus.increase(v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L | ModifierFlag::SHIFT_L), flagStatus.makeFlags()); } flagStatus.increase(ModifierFlag::NONE); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L | ModifierFlag::SHIFT_L), flagStatus.makeFlags()); } { FlagStatus flagStatus; Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::CONTROL_L); flagStatus.increase(ModifierFlag::SHIFT_L, v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L | ModifierFlag::SHIFT_L), flagStatus.makeFlags()); } { FlagStatus flagStatus; Vector_ModifierFlag v; v.push_back(ModifierFlag::COMMAND_L); v.push_back(ModifierFlag::CONTROL_L); flagStatus.increase(ModifierFlag::COMMAND_L, v); EXPECT_EQ(Flags(ModifierFlag::COMMAND_L | ModifierFlag::CONTROL_L), flagStatus.makeFlags()); flagStatus.decrease(v); EXPECT_EQ(Flags(0), flagStatus.makeFlags()); } }
void DependingPressingPeriodKeyToKey::dokeyup(void) { switch (periodtype_) { case PeriodType::SHORT_PERIOD: { periodtype_ = PeriodType::NONE; keytokey_[KeyToKeyType::SHORT_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP); break; } case PeriodType::LONG_PERIOD: { periodtype_ = PeriodType::NONE; keytokey_[KeyToKeyType::LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP); // ---------------------------------------- // handle PRESSING_TARGET_KEY_ONLY if (periodMS_.enabled(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) { if (! eventWatcherTarget_.isAnyEventHappen() && ic_.getmillisec() < periodMS_.get(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) { // ---------------------------------------- // Restore FlagStatus at key down. Vector_ModifierFlag added; Vector_ModifierFlag removed; FlagStatus::globalFlagStatus().subtract(flagStatusWhenKeyPressed_, added); flagStatusWhenKeyPressed_.subtract(FlagStatus::globalFlagStatus(), removed); for (size_t i = 0; i < added.size(); ++i) { FlagStatus::globalFlagStatus().decrease(added[i]); } for (size_t i = 0; i < removed.size(); ++i) { FlagStatus::globalFlagStatus().increase(removed[i]); } // ---------------------------------------- keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::DOWN); keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::UP); // ---------------------------------------- // Restore current FlagStatus. for (size_t i = 0; i < added.size(); ++i) { FlagStatus::globalFlagStatus().increase(added[i]); } for (size_t i = 0; i < removed.size(); ++i) { FlagStatus::globalFlagStatus().decrease(removed[i]); } } } break; } case PeriodType::LONG_LONG_PERIOD: { periodtype_ = PeriodType::NONE; keytokey_[KeyToKeyType::LONG_LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP); break; } case PeriodType::NONE: // do nothing break; } eventWatcherTarget_.unobserve(); }
TEST(Generic, changePressingState) { { FromEvent fe(KeyCode::RETURN); EXPECT_EQ(false, fe.isPressing()); // ---------------------------------------- // Without Flags // (For example, "change return to tab".) { FlagStatus currentFlags; Vector_ModifierFlag fromFlags; EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.isPressing()); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); // Another event does not modify state EXPECT_EQ(false, fe.changePressingState(*down_shift, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); EXPECT_EQ(false, fe.changePressingState(*up_shift, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); } // ---------------------------------------- // Set currentFlags // (For example, "change return to tab".) { Flags f(ModifierFlag::SHIFT_L); FlagStatus currentFlags(f); Vector_ModifierFlag fromFlags; EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.isPressing()); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); } // ---------------------------------------- // Set fromFlags // (For example, "change shift-return to tab".) { FlagStatus currentFlags; Vector_ModifierFlag fromFlags; fromFlags.push_back(ModifierFlag::SHIFT_L); // Does not change state if currentFlags lacks flags. EXPECT_EQ(false, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); } { Flags f(ModifierFlag::SHIFT_L); FlagStatus currentFlags(f); Vector_ModifierFlag fromFlags; fromFlags.push_back(ModifierFlag::SHIFT_L); EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.isPressing()); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); } { Flags f(ModifierFlag::SHIFT_L); FlagStatus currentFlags(f); Vector_ModifierFlag fromFlags; fromFlags.push_back(ModifierFlag::SHIFT_L); EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.isPressing()); // Change state even if currentFlags lacks flags when key is pressing. // This behavior is necessary for this case. // - shift down // - return down (shift-return is pressed.) // - shift up // - return up (shift-return is released.) currentFlags.reset(); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); // return false if call changePressingState once again. EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags)); } } { FromEvent fe(KeyCode::SPACE); FlagStatus currentFlags; Vector_ModifierFlag fromFlags; EXPECT_EQ(false, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags)); } { FromEvent fe(KeyCode::SHIFT_L); Flags f(ModifierFlag::SHIFT_L); FlagStatus currentFlags(f); Vector_ModifierFlag fromFlags; EXPECT_EQ(true, fe.changePressingState(*down_shift, currentFlags, fromFlags)); EXPECT_EQ(true, fe.isPressing()); currentFlags.reset(); EXPECT_EQ(true, fe.changePressingState(*up_shift, currentFlags, fromFlags)); EXPECT_EQ(false, fe.isPressing()); } // multiple times { FromEvent fe(KeyCode::RETURN); FlagStatus currentFlags; Vector_ModifierFlag fromFlags; EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.changePressingState(*down_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(true, fe.changePressingState(*up_return, currentFlags, fromFlags)); EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags)); } }
TEST(FlagStatus, isOn) { { FlagStatus flagStatus; { Vector_ModifierFlag modifierFlags; EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag(ModifierFlag::ZERO)); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::NONE); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::NONE); modifierFlags.push_back(ModifierFlag::ZERO); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } } { FlagStatus flagStatus; flagStatus.increase(ModifierFlag::SHIFT_L); { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::NONE); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_R); EXPECT_FALSE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::ZERO); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } } { FlagStatus flagStatus; flagStatus.increase(ModifierFlag::SHIFT_L); flagStatus.increase(ModifierFlag::ZERO); { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::NONE); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_R); EXPECT_FALSE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::ZERO); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::ZERO); modifierFlags.push_back(ModifierFlag::NONE); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } } { FlagStatus flagStatus; flagStatus.increase(ModifierFlag::SHIFT_L); flagStatus.increase(ModifierFlag::CONTROL_R); flagStatus.increase(ModifierFlag::COMMAND_R); { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::NONE); EXPECT_FALSE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_R); EXPECT_FALSE(flagStatus.isOn(modifierFlags)); } { Vector_ModifierFlag modifierFlags; modifierFlags.push_back(ModifierFlag::SHIFT_L); modifierFlags.push_back(ModifierFlag::CONTROL_R); modifierFlags.push_back(ModifierFlag::COMMAND_R); modifierFlags.push_back(ModifierFlag::NONE); EXPECT_TRUE(flagStatus.isOn(modifierFlags)); } } }