mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 22:45:58 +01:00
keybinds: allow repeating multiple binds (#8290)
This commit is contained in:
parent
cc923ad031
commit
6113f4da7f
2 changed files with 34 additions and 42 deletions
|
@ -144,11 +144,30 @@ CKeybindManager::CKeybindManager() {
|
||||||
},
|
},
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
|
m_pRepeatKeyTimer = makeShared<CEventLoopTimer>(
|
||||||
|
std::nullopt,
|
||||||
|
[this](SP<CEventLoopTimer> self, void* data) {
|
||||||
|
if (m_vActiveKeybinds.size() == 0 || g_pSeatManager->keyboard.expired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (SKeybind* k : m_vActiveKeybinds) {
|
||||||
|
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(k->handler);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
|
||||||
|
DISPATCHER->second(k->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
|
||||||
|
self->updateTimeout(std::chrono::milliseconds(1000 / PACTIVEKEEB->repeatRate));
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
|
|
||||||
g_pEventLoopManager->addTimer(m_pLongPressTimer);
|
g_pEventLoopManager->addTimer(m_pLongPressTimer);
|
||||||
|
g_pEventLoopManager->addTimer(m_pRepeatKeyTimer);
|
||||||
|
|
||||||
static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) {
|
static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) {
|
||||||
// clear cuz realloc'd
|
// clear cuz realloc'd
|
||||||
m_pActiveKeybind = nullptr;
|
m_vActiveKeybinds.clear();
|
||||||
m_pLastLongPressKeybind = nullptr;
|
m_pLastLongPressKeybind = nullptr;
|
||||||
m_vPressedSpecialBinds.clear();
|
m_vPressedSpecialBinds.clear();
|
||||||
});
|
});
|
||||||
|
@ -161,12 +180,16 @@ CKeybindManager::~CKeybindManager() {
|
||||||
g_pEventLoopManager->removeTimer(m_pLongPressTimer);
|
g_pEventLoopManager->removeTimer(m_pLongPressTimer);
|
||||||
m_pLongPressTimer.reset();
|
m_pLongPressTimer.reset();
|
||||||
}
|
}
|
||||||
|
if (m_pRepeatKeyTimer && g_pEventLoopManager) {
|
||||||
|
g_pEventLoopManager->removeTimer(m_pRepeatKeyTimer);
|
||||||
|
m_pRepeatKeyTimer.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||||
m_lKeybinds.push_back(kb);
|
m_lKeybinds.push_back(kb);
|
||||||
|
|
||||||
m_pActiveKeybind = nullptr;
|
m_vActiveKeybinds.clear();
|
||||||
m_pLastLongPressKeybind = nullptr;
|
m_pLastLongPressKeybind = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +203,7 @@ void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pActiveKeybind = nullptr;
|
m_vActiveKeybinds.clear();
|
||||||
m_pLastLongPressKeybind = nullptr;
|
m_pLastLongPressKeybind = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,11 +449,7 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
|
||||||
.submapAtPress = m_szCurrentSelectedSubmap,
|
.submapAtPress = m_szCurrentSelectedSubmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_pActiveKeybindEventSource) {
|
m_vActiveKeybinds.clear();
|
||||||
wl_event_source_remove(m_pActiveKeybindEventSource);
|
|
||||||
m_pActiveKeybindEventSource = nullptr;
|
|
||||||
m_pActiveKeybind = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pLastLongPressKeybind = nullptr;
|
m_pLastLongPressKeybind = nullptr;
|
||||||
|
|
||||||
|
@ -482,11 +501,7 @@ bool CKeybindManager::onAxisEvent(const IPointer::SAxisEvent& e) {
|
||||||
|
|
||||||
m_tScrollTimer.reset();
|
m_tScrollTimer.reset();
|
||||||
|
|
||||||
if (m_pActiveKeybindEventSource) {
|
m_vActiveKeybinds.clear();
|
||||||
wl_event_source_remove(m_pActiveKeybindEventSource);
|
|
||||||
m_pActiveKeybindEventSource = nullptr;
|
|
||||||
m_pActiveKeybind = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (e.source == WL_POINTER_AXIS_SOURCE_WHEEL && e.axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
|
if (e.source == WL_POINTER_AXIS_SOURCE_WHEEL && e.axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
|
||||||
|
@ -525,11 +540,7 @@ bool CKeybindManager::onMouseEvent(const IPointer::SButtonEvent& e) {
|
||||||
.modmaskAtPressTime = MODS,
|
.modmaskAtPressTime = MODS,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_pActiveKeybindEventSource) {
|
m_vActiveKeybinds.clear();
|
||||||
wl_event_source_remove(m_pActiveKeybindEventSource);
|
|
||||||
m_pActiveKeybindEventSource = nullptr;
|
|
||||||
m_pActiveKeybind = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
if (e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||||
m_dPressedKeys.push_back(KEY);
|
m_dPressedKeys.push_back(KEY);
|
||||||
|
@ -580,22 +591,6 @@ void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
|
||||||
handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:off:" + switchName}, true);
|
handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:off:" + switchName}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int repeatKeyHandler(void* data) {
|
|
||||||
SKeybind** ppActiveKeybind = (SKeybind**)data;
|
|
||||||
|
|
||||||
if (!*ppActiveKeybind || g_pSeatManager->keyboard.expired())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler);
|
|
||||||
|
|
||||||
Debug::log(LOG, "Keybind repeat triggered, calling dispatcher.");
|
|
||||||
DISPATCHER->second((*ppActiveKeybind)->arg);
|
|
||||||
|
|
||||||
wl_event_source_timer_update(g_pKeybindManager->m_pActiveKeybindEventSource, 1000 / g_pSeatManager->keyboard->repeatRate);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
eMultiKeyCase CKeybindManager::mkKeysymSetMatches(const std::set<xkb_keysym_t> keybindKeysyms, const std::set<xkb_keysym_t> pressedKeysyms) {
|
eMultiKeyCase CKeybindManager::mkKeysymSetMatches(const std::set<xkb_keysym_t> keybindKeysyms, const std::set<xkb_keysym_t> pressedKeysyms) {
|
||||||
// Returns whether two sets of keysyms are equal, partially equal, or not
|
// Returns whether two sets of keysyms are equal, partially equal, or not
|
||||||
// matching. (Partially matching means that pressed is a subset of bound)
|
// matching. (Partially matching means that pressed is a subset of bound)
|
||||||
|
@ -770,12 +765,10 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k.repeat) {
|
if (k.repeat) {
|
||||||
m_pActiveKeybind = &k;
|
|
||||||
m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, repeatKeyHandler, &m_pActiveKeybind);
|
|
||||||
|
|
||||||
const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
|
const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();
|
||||||
|
|
||||||
wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
|
m_vActiveKeybinds.push_back(&k);
|
||||||
|
m_pRepeatKeyTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!k.nonConsuming)
|
if (!k.nonConsuming)
|
||||||
|
|
|
@ -102,8 +102,6 @@ class CKeybindManager {
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<SDispatchResult(std::string)>> m_mDispatchers;
|
std::unordered_map<std::string, std::function<SDispatchResult(std::string)>> m_mDispatchers;
|
||||||
|
|
||||||
wl_event_source* m_pActiveKeybindEventSource = nullptr;
|
|
||||||
|
|
||||||
bool m_bGroupsLocked = false;
|
bool m_bGroupsLocked = false;
|
||||||
|
|
||||||
std::list<SKeybind> m_lKeybinds;
|
std::list<SKeybind> m_lKeybinds;
|
||||||
|
@ -121,8 +119,9 @@ class CKeybindManager {
|
||||||
|
|
||||||
inline static std::string m_szCurrentSelectedSubmap = "";
|
inline static std::string m_szCurrentSelectedSubmap = "";
|
||||||
|
|
||||||
SKeybind * m_pActiveKeybind = nullptr, *m_pLastLongPressKeybind = nullptr;
|
std::vector<SKeybind*> m_vActiveKeybinds;
|
||||||
SP<CEventLoopTimer> m_pLongPressTimer;
|
SKeybind* m_pLastLongPressKeybind = nullptr;
|
||||||
|
SP<CEventLoopTimer> m_pLongPressTimer, m_pRepeatKeyTimer;
|
||||||
|
|
||||||
uint32_t m_uTimeLastMs = 0;
|
uint32_t m_uTimeLastMs = 0;
|
||||||
uint32_t m_uLastCode = 0;
|
uint32_t m_uLastCode = 0;
|
||||||
|
|
Loading…
Reference in a new issue