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

Gesture Hooks API #174

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Gesture Hooks API #174

wants to merge 1 commit into from

Conversation

matt1432
Copy link
Contributor

@matt1432 matt1432 commented Nov 11, 2024

I am trying to make it possible for another plugin to hook onto the opposite gesture of the workspace gesture.

I had the idea of copying hyprexpo's touchpad gesture on a touchscreen by having hyprgrass emit a hook when dragging the opposite way and then have hyprexpo hook onto it.

I have the hook and listen thing figured out, but the gesture part is very unclear to me.

I can't really tell how to listen to a gesture or even if one is recognized at all. Would love to get some info on that.

Thanks!

Edits:

Check List:

  • figure out why info.cancelled is the opposite in hyprexpo
  • figure out what the API will expose

@horriblename
Copy link
Owner

horriblename commented Nov 11, 2024

that's genius! I had the idea of using dispatchers to do somewhat the same thing but it was too clunky to use and so I dropped it.


I think rather than hooking on to the "opposite of workspace gesture" it's easier to provide hooks for a generic "swipe" event (and same for "edge" and others).

for that you can emit the events in handleDragGesture() and handleDragGestureEnd(). A drag basically means the gesture has a clear "start" and "end" point - when a "swipe" is first recognized, handleDragGesture() is called. when the gesture ends, e.g. lifted a finger, handleDragGestureEnd() is called.

not so important to the problem at hand, if handleDragGesture did not do anything (returns false), handleCompletedGesture() will be called in place of the usual "end" event.


I'd like to see some way for hook users to tell us if they did anything: if they handled the gesture, we need to block touch events from going to the app window (among other things). for this, EMIT_CANCELLABLE_EVENT might be useful

@matt1432
Copy link
Contributor Author

So I try having handleDragGesture(), handleDragGestureEnd() and dragGestureUpdate() emit the event but it seems like the workspace swipe takes ownership of any 3 finger swipes if that makes sense.

I try to swipe vertically instead to not trigger the workspace swipe but that does not emit anything during that gesture.

@horriblename
Copy link
Owner

can you push what you have now?

@matt1432
Copy link
Contributor Author

It's not much but here you go

src/main.cpp Outdated Show resolved Hide resolved
@matt1432
Copy link
Contributor Author

Crashes Hyprland as soon as I do a gesture :(

No crash report in ~/.cache/hyprland

@horriblename
Copy link
Owner

horriblename commented Nov 11, 2024

added some checks, so that workspace swipe doesn't crash

notification now works, but idk what the API should look like yet. i think at the very least we'll need 3 separate hook events for start/update/end and possibly more for each gesture type

edit: also the events should be namespaced under hypgrass: or something

@matt1432
Copy link
Contributor Author

i think at the very least we'll need 3 separate hook events for start/update/end and possibly more for each gesture type

Yes I was thinking that too.

the events should be namespaced under hypgrass: or something

Yes I agree

@matt1432
Copy link
Contributor Author

I tried your latest commit and it did work to emit changes for swipes, but the workspace swiping wasn't working, is that normal?

@matt1432 matt1432 changed the title Opposite Workspace Gesture Gesture Hooks API Nov 12, 2024
@horriblename
Copy link
Owner

yea right now the hook just "consumes" the drag event unconditionally

src/main.cpp Outdated Show resolved Hide resolved

IPointer::SSwipeUpdateEvent ev = {
.fingers = (uint32_t)gev.finger_count,
.delta = Vector2D(delta_percent.x * 5, delta_percent.y * 5),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To make it easier to hook onto, I convert the touch gesture event to a touchpad gesture event. However, I don't really know how to properly convert the delta.

Do you have any ideas @horriblename

Copy link
Owner

@horriblename horriblename Nov 14, 2024

Choose a reason for hiding this comment

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

I'm not really sure what unit touchpad swipes are in (and I have no clue where to even dig up this info). you can either:

  1. try whatever wizardry I did in updateWorkspaceSwipe()
  2. ask vaxry
  3. convert to touch events instead, in this case you can use GestureManager::pixelPositionToPercentagePosition() to get the position

try the 1 and 2 first

Copy link
Owner

Choose a reason for hiding this comment

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

I changed my mind, I think it's more helpful to give the exact position of gesture, instead of delta like in SSwipeUpdateEvent,

please use ITouch::SMotionEvent instead

Copy link
Owner

Choose a reason for hiding this comment

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

you can use GestureManager::pixelPositionToPercentagePosition() to get the position

Copy link
Contributor Author

@matt1432 matt1432 Nov 14, 2024

Choose a reason for hiding this comment

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

hmm, I was doing it this way to make it as easy as possible to implement in hyprexpo. Is ITouch::SMotionEvent a Hyprland thing? Edit: it is, I just found it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@horriblename ITouch::SMotionEvent doesn't have a fingers prop

@matt1432
Copy link
Contributor Author

@horriblename I finally figured out how to make the hooks compatible with hyprexpo's gesture, which was my original goal.

I had to stick with IPointer::SSwipeUpdateEvent instead of using ITouch::SMotionEvent like you said because it doesn't hold any info on the amount of fingers, and I feel like exposing a delta is better than the position when it comes to a gesture.

What do you think?

@matt1432
Copy link
Contributor Author

Also, should I be using EMIT_HOOK_EVENT_CANCELLABLE instead of EMIT_HOOK_EVENT?

src/GestureManager.cpp Outdated Show resolved Hide resolved
@horriblename
Copy link
Owner

Also, should I be using EMIT_HOOK_EVENT_CANCELLABLE instead of EMIT_HOOK_EVENT?

EMIT_HOOK_EVENT is fine. Only the start event needs to check that an event is handled

@horriblename
Copy link
Owner

I had to stick with IPointer::SSwipeUpdateEvent instead of using ITouch::SMotionEvent like you said because it doesn't hold any info on the amount of fingers

uuh I'll mull it over, but I think if we're exposing a hook API I'd like it to be extensible as possible

g_pHookSystem->emit(PEVENTVEC, info,
IPointer::SSwipeBeginEvent{.fingers = (uint32_t)gev.finger_count});

if (!info.cancelled) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@horriblename I figured out how to add it back, but to make it work with hyprexpo I had to check if info.cancelled was false instead of true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@horriblename Is this expected? I thought it would've been the opposite no?

@matt1432
Copy link
Contributor Author

matt1432 commented Dec 9, 2024

@horriblename Have you given this PR any more thoughts?

I added a small check list in my original message to clarify what I'm hung up on

@horriblename
Copy link
Owner

Sorry it took this long, I've decided to go ahead with #189 as a stopgap and leave the event hooks for another time.

#189 should cover your use cases (hyprexpo integration), I tested on Hyprspace but please help me test on hyprexpo as well.

I will be generalizing ideas from this PR for a more extensible event hook API.

@horriblename
Copy link
Owner

If you have no problems with #189 I will close this PR and merge that one

@matt1432
Copy link
Contributor Author

No worries!

#189 works perfectly for my use case. Just gave it a shot and I'm happy. Go for it

We can leave this PR open and leave it as a draft imo. It's up to you if you wanna continue it or open another one but it's still a good reference for what's possible and whatnot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants