Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bind: new long press option #8302

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
bool transparent = false;
bool ignoreMods = false;
bool multiKey = false;
bool longPress = false;
bool hasDescription = false;
bool dontInhibit = false;
const auto BINDARGS = command.substr(4);
Expand All @@ -2184,6 +2185,8 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
ignoreMods = true;
} else if (arg == 's') {
multiKey = true;
} else if (arg == 'o') {
longPress = true;
littleblack111 marked this conversation as resolved.
Show resolved Hide resolved
} else if (arg == 'd') {
hasDescription = true;
} else if (arg == 'p') {
Expand Down Expand Up @@ -2258,7 +2261,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command

g_pKeybindManager->addKeybind(SKeybind{
parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER, COMMAND, locked, m_szCurrentSubmap, DESCRIPTION, release,
repeat, mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit});
repeat, mouse, nonConsuming, transparent, ignoreMods, multiKey, longPress, hasDescription, dontInhibit});
}

return {};
Expand Down
24 changes: 24 additions & 0 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,20 @@ int repeatKeyHandler(void* data) {
return 0;
}

int longPressHandler(void* data) {
SKeybind** ppActiveKeybind = (SKeybind**)data;

if (!*ppActiveKeybind || g_pSeatManager->keyboard.expired())
vaxerski marked this conversation as resolved.
Show resolved Hide resolved
return 0;

const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler);

Debug::log(LOG, "Keybind long press triggered, calling dispatcher.");
DISPATCHER->second((*ppActiveKeybind)->arg);

return 0;
}

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
// matching. (Partially matching means that pressed is a subset of bound)
Expand Down Expand Up @@ -701,6 +715,16 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
}
}

if (k.longPress) {
m_pActiveKeybind = &k;
m_pActiveKeybindEventSource = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, longPressHandler, &m_pActiveKeybind);

const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();

wl_event_source_timer_update(m_pActiveKeybindEventSource, PACTIVEKEEB->repeatDelay);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't use event sources. See managers/eventLoop/EventLoopTimer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you want me to include "eventLoop/EventLoopTimer.hpp"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ye

Copy link
Contributor Author

@littleblack111 littleblack111 Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried:

            m_pActiveKeybind            = &k;

            const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();

			m_pLongPressTimer = makeShared<CEventLoopTimer>(
				std::chrono::milliseconds(PACTIVEKEEB->repeatDelay),
				longPressHandler,
				&m_pActiveKeybind
			);

			g_pEventLoopManager->addTimer(m_pLongPressTimer);
                        continue;

not sure why now it doesn't work anymore.
(m_pLongPressTimer is in the .hpp file)

Copy link
Member

@vaxerski vaxerski Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the timer should be created and added in the constructor, then here you'd call setTimeout instead (or whatever the name was)

Copy link
Contributor Author

@littleblack111 littleblack111 Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what is m_pLastKeybind

you used it yourself, a member of CKeybindManager. m_pLastLongPressKeybind is a new one I added for the sake of this functionality

wait, you meant m_pActiveKeybind?

Wait so in a lambda function with [this] u can directly reference its members?

I'll try this when I get back so I can test it

No wonder why When I was doing that but passing in "this" or m_pActiceKeybind it'd crash

Copy link
Contributor Author

@littleblack111 littleblack111 Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, after trying to directly reference the class members in a [this] lambda func.
this is what happens,

			if (!m_pActiveKeybind)
				return 0;

result in

(EE) failed to read Wayland events: Broken pipe
[1]    1217210 illegal hardware instruction (core dumped)  ./build/Hyprland

stuff using it:

			SKeybind** ppActiveKeybind = (SKeybind**)m_pActiveKeybind;
        if (!*ppActiveKeybind)
return 0

raises SEGEV

i was thinking m_pActiveKeybind might be null? so i gave it &k before calling the update, but doesnt help

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to see the entire code

Copy link
Contributor Author

@littleblack111 littleblack111 Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here:

	m_pLongPressTimer = makeShared<CEventLoopTimer>(
		std::nullopt,
		[this](SP<CEventLoopTimer> self, void* data) {
			SKeybind** ppActiveKeybind = (SKeybind**)m_pActiveKeybind;

			if (!m_pActiveKeybind) // wayland broken pipe then crash
				return 0;

			if (!*ppActiveKeybind || g_pSeatManager->keyboard.expired()) // SEGEV
				return 0;

			// const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find((*ppActiveKeybind)->handler);

			// Debug::log(LOG, "Keybind long press triggered, calling dispatcher.");
			// DISPATCHER->second((*ppActiveKeybind)->arg);
		},
		nullptr
	);

this code is in the constructor

and this in the k.longPress:

            m_pActiveKeybind            = &k;
			
			const auto PACTIVEKEEB = g_pSeatManager->keyboard.lock();

			m_pLongPressTimer->updateTimeout(std::chrono::milliseconds(PACTIVEKEEB->repeatDelay));
			// m_pLastLongPressKeybind = &k;

			// continue;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you didn't add it in the ctor g_pEventLoopManager->addTimer

continue;
}

const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);

if (SPECIALTRIGGERED && !pressed)
Expand Down
Loading