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

Swipe gestures support PoC #2355

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Swipe gestures support PoC #2355

wants to merge 15 commits into from

Conversation

lwouis
Copy link
Owner

@lwouis lwouis commented Feb 21, 2023

//TODO: App Expose activates if swipe down with 3-fingers right after AltTab activation. There is no issue if wait for some time.
//TODO: enable/disable trackpad usage in settings
class TrackpadEvents {
//TODO: Should we add a sensetivity setting instead of these magic numbers?
Copy link
Owner Author

Choose a reason for hiding this comment

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

We can either hardcode such numbers if they are stable in macOS over time, or we may be able to read the system settings, like we read the key repeat rate today, or other System Settings settings.

@@ -0,0 +1,113 @@
import M5MultitouchSupport

//TODO: patch M5MultitouchSupport pod to make it not to crash after sleep. See https://github.com/mhuusko5/M5MultitouchSupport/issues/1
Copy link
Owner Author

Choose a reason for hiding this comment

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

I'm a bit worried to rely on a third-party library that hasn't been updated in 8 years, and that has a crash on wake that has only been found this year.

Is there no way to roll our own code for multi-fingers gesture? Is it too rough when using the AppKit APIs?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Update: i just searched online for this, and there is no information out there. I understand better why you went with this library. Classic Apple move to not properly support such a classic interaction decades after it's been added to macOS.

I've updated the issue on the M5MultitouchSupport repo. Maybe we could add something like this to fix the issue.

Copy link

Choose a reason for hiding this comment

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

I don't want to add a 3-rd party library either but it's just a PoC.
We could patch M5MultitouchSupport as I did it for Touch-Tab https://github.com/ris58h/Touch-Tab/blob/master/patches/M5MultitouchSupport%2B1.1.0.diff (it works fine) or use any other library.
Seems like https://github.com/Kyome22/OpenMultitouchSupport is a good candidate.

P.S.:
Code in both libraries is nearly identical (M5MultitouchSupport vs OpenMultitouchSupport) but OpenMultitouchSupport checks if MTDeviceIsRunning before releasing the device.

Copy link

Choose a reason for hiding this comment

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

It turned out that OpenMultitouchSupport has the same issue Kyome22/OpenMultitouchSupport#2 It seems like we have to patch anyway.

Should I commit changes in Pods dir after a new pod is installed?

} else {
if isHorizontal {
DispatchQueue.main.async { App.app.showUi() }
activated = true
Copy link
Owner Author

Choose a reason for hiding this comment

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

Do we need to track this bool actually? Maybe App.app.appIsBeingUsed is enough?

Shouldn't the user be able to open AltTab with alt+tab, but then 3-fingers swipe left or right?

Copy link

Choose a reason for hiding this comment

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

We need to track that the UI was triggered by swiping because end of the swipe (number of fingers not equal to 3 in our case) hides the UI. If a user opens the UI from menu or by shortcut, every mouse move except 3-finger swipe will close the UI.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Maybe the following logic could work?

We track that we reached 3 fingers either:

  • Before AltTab was opened with the trackpad gesture
  • After it was opened with the keyboard shortcut

From that point on, any < 3 fingers gesture means we should focus the window and close UI.

Copy link

@ris58h ris58h Feb 22, 2023

Choose a reason for hiding this comment

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

We could track what caused the UI to be shown by adding a parameter to showUI method and storing it for future checks.

@lwouis
Copy link
Owner Author

lwouis commented Feb 21, 2023

Here are comments on your message in the original ticket.

User has to disable 3-finger swipe between full-screen apps or make it 4-finger in System Settings > Trackpad > More Gestures > Swipe between full-screen apps.

Today when the user sets their keyboard shortcut to command+tab, we use a private API to disable the native shortcut, so that we can replace it. There may be a way to disable the native 3-finger swipe, if the user sets AltTab to use 3-finger swipes in the preferences, in the same fashion. Maybe.

No settings. It's not clear to me where they should be added.

I suggested how to implement the preference here.

App crashes after sleep. See mhuusko5/M5MultitouchSupport#1

I added a comment there. Maybe we could dig into that workaround?

Only 3-finger swipes are supported.

Maybe it's ok with 3 fingers for now. Maybe no-one needs 4 fingers. And 2 fingers is definitely not a good idea for a global trigger.

App Expose activates if swipe down with 3-fingers right after AltTab activation. There is no issue if wait for some time.

Again, we could maybe disable that with private API calls. Alternatively, we could maybe absorb some of the gesture events like we absorb keyboard events (so that the apps under AltTab don't get a keyUp event when we release option to close AltTab).

Furthermore, I want to add that in this PR, you have implemented left/right swipes to move around the thumbnails. I think ideally we would want to implement 360 movement to move around the grid of thumbnails if the user has many.

@ris58h
Copy link

ris58h commented Feb 22, 2023

Today when the user sets their keyboard shortcut to command+tab, we use a private API to disable the native shortcut, so that we can replace it. There may be a way to disable the native 3-finger swipe, if the user sets AltTab to use 3-finger swipes in the preferences, in the same fashion. Maybe.

I couldn't find the way to do it using private API used in M5 library because it's just a callback. Maybe we could use CGEventTap as it's done here https://github.com/Kolsha/Force-Command-Click/blob/master/main.m

I suggested how to implement the preference here

Just to make it clear: do you want to add Gesture tab to Shortcut tabs?

I added a comment there. Maybe we could dig into that workaround?

I've answered there.

Maybe it's ok with 3 fingers for now. Maybe no-one needs 4 fingers. And 2 fingers is definitely not a good idea for a global trigger.

Yeah, 2-fingers is not an option here.

Again, we could maybe disable that with private API calls. Alternatively, we could maybe absorb some of the gesture events like we absorb keyboard events (so that the apps under AltTab don't get a keyUp event when we release option to close AltTab).

It's strange to me that App Expose doesn't activate if I wait for a couple of seconds. I've answered in the code comments about disabling native behavior.

Furthermore, I want to add that in this PR, you have implemented left/right swipes to move around the thumbnails. I think ideally we would want to implement 360 movement to move around the grid of thumbnails if the user has many.

What is 360 movement? I've already implemented thumbnails navigation in all directions (left/right/up/down).

@lwouis
Copy link
Owner Author

lwouis commented Feb 22, 2023

Just to make it clear: do you want to add Gesture tab to Shortcut tabs?

Yes. That way people can decide which windows they will see in that mode. Originally I was thinking people could bind different swipes (e.g. 3 fingers vs 4 fingers) to different windows to show. A bit like how option+tab shows all windows, and option+` shows only the active app windows, with keyboard shortcuts.

What is 360 movement? I've already implemented thumbnails navigation in all directions (left/right/up/down).

The way I would describe it is: imagine that moving your 3-fingers gesture on the trackpad moves a hidden mouse cursor. When you move in 2D space, in 360 degrees of freedom, you're now moving around precisely. Now we make that hidden mouse cursor select thumbnails.

It's very different from only being able to go in 1 direction at a time. You can move in diagonal.

To imagine the difference, imagine that you are inside a folder, and in grid view. Now imagine wanting to go to up-and-left to a particular file. Either you swipe directly towards the file (i.e. 360 movement), and the selection roughly follows your motion, or you would have to swipe horizontally, then vertically, a distance that potentially quite long, and see your selection move in a L pattern.

If you use a Windows machine, and check out the built-in alt+tab UX with a trackpad, you can experience how great the 360 experience is.

On that note, currently we can scroll up and down with the mouse wheel or 2-fingers trackpad, when the grid has a lot to display. That code should probably be updated to accomodate the new 3-fingers interactions.

@ris58h
Copy link

ris58h commented Feb 22, 2023

It's very different from only being able to go in 1 direction at a time. You can move in diagonal.

Oh, I got it.

On that note, currently we can scroll up and down with the mouse wheel or 2-fingers trackpad, when the grid has a lot to display. That code should probably be updated to accomodate the new 3-fingers interactions.

I've tried to allow both scrolling and moving with trackpad with 2 and 3 finger swipes accordingly but it was clunky. Unfortunately I don't have a Windows laptop right now to check. I believe we should mimic Windows behavior if it's possible.

@lwouis
Copy link
Owner Author

lwouis commented Feb 22, 2023

I've tried to allow both scrolling and moving with trackpad with 2 and 3 finger swipes accordingly but it was clunky. Unfortunately I don't have a Windows laptop right now to check. I believe we should mimic Windows behavior if it's possible.

Windows behavior is actually pretty bad in that regard. I generally find their UX very good, but for some reason their scrolling is horrible. It's row-by-row instead of pixel-by-pixel, so it can be confusing to the user. They also don't do any form of "look ahead" like they would do in a platformer video game where we want to see a bit of what's ahead, not be at the bleeding edge.

Finally, if you own Parallels, or maybe even with the free VirtualBox or BootCamp, you can install a free Windows 10 VM these days, from Microsoft website. It's an easy way to play around with Windows on a mac, for free.

@ris58h
Copy link

ris58h commented Feb 25, 2023

@lwouis it almost works now. Things to do:

  • ❌ Settings layout is broken in Gesture tab. It's just a cosmetic issue.
  • ✅ Fix an issue with trackpad event's hiding UI when UI is activated not with trackpad.
  • Patch M5MultitouchSupport lib. BackgroundWork for TrackpadEvents.
  • ❌ 360 movement.
  • On release do nothing for the swipe.

I believe we should go with MVP. 360 movement and On release do nothing aren't that important. What do you think?

}

//TODO: controls in Gesture tab aren't centered like in Shortcut tab
//TODO: 'On release do nothing' doesn't work. See ShortcutStylePreference.focusOnRelease usage and ATShortcut.shouldTrigger usage
Copy link

Choose a reason for hiding this comment

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

For keyboard shortcut 'On release do nothing' is implemented via skipping shortcut action. I haven't found workaround to the swipe yet. We could just not support such option for swiping.

@lwouis
Copy link
Owner Author

lwouis commented Feb 25, 2023

I believe we should go with MVP. 360 movement and On release do nothing aren't that important. What do you think?

This app has no deadline pressure. We can take time to polish things before shipping 👍

@lwouis lwouis mentioned this pull request Mar 27, 2023
@Shahriarnz14
Copy link

Hi just wondering, if there is an update on this feature yet? :)
Find it as the only missing piece of an already amazing work!

@ris58h
Copy link

ris58h commented Apr 15, 2023

@Shahriarnz14 I haven't touched it for a while - I use Touch-Tab instead. The current state of the PR is described in this comment. I'm new to macOS development so there are some issues:

  • AltTab uses some hacks to make layout looks good but Settings layout is broken for the new Gesture tab because it has different layout than Shortcut tabs.
  • AltTab uses background threads to process system events but I couldn't make a separate thread that accepts touch events.

@lwouis
Copy link
Owner Author

lwouis commented Apr 15, 2023

@ris58h I just checked out the branch, and played with it. You've done some really good work. The feature works well. I'm really impressed you were able to implement the event tracking without the third-party library. I remember trying in the past and hitting a wall, so I'm really impressed. Thank you for all the work here! 🙇‍♂️

It's very promising, but there needs to be a few more things before we can ship it. In addition to the checklist you shared above, I would add one: clarifying conflicts/issues with the native gestures to the user. For instance, should we have AltTab use gestures by default? Would it work on a default macOS install? Would it conflict with other gestures? We probably should add some form of tooltip/warning when the user could get a broken experience. We could (probably) read the state of some of the System Settings, and depending on the situation, warn the user to toggle some things off to not conflict with AltTab. Some of the TODOS you've written in the PR seem to show non-obvious conflicts, for instance:

//TODO: underlying content scrolls if both Mission Control and App Expose use 4-finger swipes or are off in Trackpad settings. It doesn't scroll if any of them use 3-finger swipe though.

@billjcnickolas
Copy link

I'm also interested in this PR. Any chance there's an update on this?
Migrating from Windows to Mac would be hell of a lot easier if this is added.

@ris58h
Copy link

ris58h commented Jun 1, 2023

@billjcnickolas it was just a PoC. I'm stuck on some issues but I'm not going to spent my time on them anymore.

@billjcnickolas
Copy link

@ris58h Thank you for your response. It is indeed a really good PoC and I feel like it's really close to completion. I'm not familiar with swift development at all otherwise would've wanted to help.
I feel like it's only lacking one small push to get completed.
I wonder if @lwouis can take a look at this some time and see if it can make it to the end product!
I realized there are many others looking for this feature (from various youtube channels recommending alt-tab-macos to gh issues and even in this pr) that I think there's enough demand for it. 🤞

Comment on lines +7 to +10
fileprivate let accVelXThreshold: Float = 0.05
fileprivate let accVelYThreshold: Float = 0.075
fileprivate var accVelX: Float = 0
fileprivate var accVelY: Float = 0

Choose a reason for hiding this comment

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

Suggested change
fileprivate let accVelXThreshold: Float = 0.05
fileprivate let accVelYThreshold: Float = 0.075
fileprivate var accVelX: Float = 0
fileprivate var accVelY: Float = 0
fileprivate let accVelXThreshold: Float = 0.03
fileprivate let accVelYThreshold: Float = 0.06
fileprivate var accVelX: Float = 0.35
fileprivate var accVelY: Float = 0.125

Thanks @lwouis for your work! I also tried your touch-pad and found the same problem with this PR. The sensitivity is not matched with Windows (in my experience). I tried different numbers and found that 0.03, 0.06, 0.35, and 0.125 are more sensitive and like how Windows works.

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.

5 participants