keybinds: set a fallback releasePending flag for special lua binds (#14600)

fixes #14445
This commit is contained in:
Vaxry
2026-06-07 12:24:08 +02:00
committed by Vaxry
parent c11104377e
commit acdad4ed38
3 changed files with 31 additions and 2 deletions
@@ -176,6 +176,10 @@ static int dsp_pass(lua_State* L) {
const auto PWINDOW = g_pCompositor->getWindowByRegex(lua_tostring(L, lua_upvalueindex(1)));
if (!PWINDOW)
return Internal::dispatcherError(L, "hl.pass: window not found", WARN, C_NOTFOUND);
if (g_pKeybindManager->m_currentKeybind)
g_pKeybindManager->m_currentKeybind->releasePending = true;
return Internal::checkResult(L, CA::pass(PWINDOW));
}
@@ -201,6 +205,9 @@ static int dsp_event(lua_State* L) {
}
static int dsp_global(lua_State* L) {
if (g_pKeybindManager->m_currentKeybind)
g_pKeybindManager->m_currentKeybind->releasePending = true;
return Internal::checkResult(L, CA::global(lua_tostring(L, lua_upvalueindex(1))));
}
@@ -359,6 +366,9 @@ static int dsp_sendShortcut(lua_State* L) {
return Internal::dispatcherError(L, "send_shortcut: window not found", WARN, C_NOTFOUND);
}
if (g_pKeybindManager->m_currentKeybind)
g_pKeybindManager->m_currentKeybind->releasePending = true;
return Internal::checkResult(L, CA::pass(modMask, *keycodeResult, window));
}
@@ -618,10 +628,16 @@ static int dsp_denyFromGroup(lua_State* L) {
}
static int dsp_mouseDrag(lua_State* L) {
if (g_pKeybindManager->m_currentKeybind)
g_pKeybindManager->m_currentKeybind->releasePending = true;
return Internal::checkResult(L, CA::mouse("movewindow"));
}
static int dsp_mouseResize(lua_State* L) {
if (g_pKeybindManager->m_currentKeybind)
g_pKeybindManager->m_currentKeybind->releasePending = true;
return Internal::checkResult(L, CA::mouse("resizewindow"));
}
+13 -1
View File
@@ -20,6 +20,7 @@
#include <cstring>
#include <hyprutils/string/String.hpp>
#include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::String;
#include <sys/ioctl.h>
@@ -401,6 +402,12 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
shadowKeybinds();
}
if (m_pressedKeys.empty()) {
for (const auto& k : m_keybinds) {
k->releasePending = false; // reset this flag once we don't press any keys to avoid stale
}
}
return !suppressEvent && !mouseBindWasActive;
}
@@ -587,7 +594,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
}
for (auto& k : m_keybinds) {
const bool SPECIALDISPATCHER = k->handler == "global" || k->handler == "pass" || k->handler == "sendshortcut" || k->handler == "mouse";
const bool SPECIALDISPATCHER = k->handler == "global" || k->handler == "pass" || k->handler == "sendshortcut" || k->handler == "mouse" || k->releasePending;
const bool SPECIALTRIGGERED = std::ranges::find_if(m_pressedSpecialBinds, [&](const auto& other) { return other == k; }) != m_pressedSpecialBinds.end();
const bool IGNORECONDITIONS =
SPECIALDISPATCHER && !pressed && SPECIALTRIGGERED; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
@@ -724,6 +731,11 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
const auto DISPATCHER = m_dispatchers.find(k->mouse ? "mouse" : k->handler);
k->releasePending = false; // reset this flag if it's set
m_currentKeybind = k;
Hyprutils::Utils::CScopeGuard x([this] { m_currentKeybind.reset(); });
if (SPECIALTRIGGERED && !pressed)
std::erase_if(m_pressedSpecialBinds, [&](const auto& other) { return other == k; });
else if (SPECIALDISPATCHER && pressed)
+2 -1
View File
@@ -60,7 +60,8 @@ struct SKeybind {
std::string displayKey = "";
// DO NOT INITIALIZE
bool shadowed = false;
bool shadowed = false;
bool releasePending = false;
};
enum eFocusWindowMode : uint8_t {