Skip to content

Conversation

@tomsci
Copy link
Contributor

@tomsci tomsci commented Aug 16, 2021

Fixes #1047

Currently SolveSpace is nearly unusable on a mac if you only have a
buttonless trackpad and not a mouse, because there's no way to pan
(ie right-click-drag) or rotate (ie middle-click-drag). You can zoom,
but only by using two-finger-drag up and down, which ends up getting
interpreted as a scrollwheel event.

This change makes the app behave much more like any other mac app, by
adding 2-finger-drag pan gesture support and pinch-gesture zooming, and
3D rotate using shift-2-finger-drag.

I've also added support for the rotate two-finger trackpad gesture,
which rotates directly around the screen Z axis (rather than in all 3
dimensions) which is actually something I've found myself wanting to do
with the mouse but afaik there's no equivalent way of achieving that.

While I was there, I fixed a bugette in convertMouseEvent which was
incorrectly translating the NSEvent coordinates, and then fixing up the
fact that the sign of the y-coordinate was wrong as a result. Using the
convertPoint API correctly means that fixup is not required because
convertPoint handles it for you.

@ruevs
Copy link
Member

ruevs commented Aug 17, 2021

@tomsci I'm very glad to see you are familiar with Mac GUI programming.

I'm sure this is a huge improvement but I can't believe it was unusable before.

For rotating there is Shift+LeftDrag and Ctrl+LeftDrag don't they work on Mac with a trackpad? @vespakoen you are on Mac, is there no way to pan with the trackpad?!

We "recently" had a nice long "chat" about mice, trackpads (of differents sophistication) and touch screens here #825. It was in the context of smooth scrolling (zooming), which now works on Mac and Windows. One extra result is that now there is Shift+Scroll for 10x slower zooming.

Also be aware (if you are not already) of "turntable navigation" and CTRL+middle button drag #888 (comment)

@tomsci
Copy link
Contributor Author

tomsci commented Aug 17, 2021

For rotating there is Shift+LeftDrag and Ctrl+LeftDrag don't they work on Mac with a trackpad

They don't work for me on my mac :)

I should have added "depending on your trackpad and dexterity" - it is possible to rotate with shift-two-finger-click-drag (which is simulating shift-right-click-drag) but that is a very awkward gesture compared to shift-two-finger-drag (ie without the "click") which is what I've added. And to be honest I've only just discovered that shift-two-finger-click-drag works - it's not a standard finger contortion that I'm accustomed to performing. Mac trackpads are easiest to use with 2-finger gestures that don't require clicks, and those unfortunately require a chunk more code to support compared to the basic mouse case. I'm just relieved it wasn't necessary to drop down to the level of counting individual touches on the trackpad!

So yes it's true it's not "unusable", but I spent some few minutes clicking around and didn't figure it out when I first started using SolveSpace, and again when I started coding this PR, so it's not obvious :)

@ruevs
Copy link
Member

ruevs commented Aug 17, 2021

For rotating there is Shift+LeftDrag and Ctrl+LeftDrag don't they work on Mac with a trackpad

They don't work for me on my mac :)

Oh you are rigtht - sorry - it is Shift+RightDrag and Ctrl+RightDrag of course. My mistake. And a right drag on a trackpad is a "two finger click drag". I'm used to it since I've used "old school" trackpads quite a lot, but it is certainly not simple or intuitive unless someone is used to it.

@phkahler phkahler requested a review from vespakoen August 17, 2021 13:38
@phkahler
Copy link
Member

Looks well contained and not very big changes for what's covered by this PR.

@vespakoen
Copy link
Contributor

Cool! I just tested this and found the following things (might not all be caused by this PR though 😉)

  1. When "scrolling" to pan or rotating (by adding shift), it can show the labels for the menu icons:

Screenshot 2021-08-17 at 17 02 00

  1. It feels like the panning direction and rotate direction should be the opposite way?
    This might be because I turned off the "natural scrolling" feature perhaps?

Screenshot 2021-08-17 at 17 03 16

A bit off-topic, but dumping it here anyways as it might be interesting:

I once tried to expand the "turntable nav" to also allow locking on the X or Y axis (see my half-failed attempt here: vespakoen@97630bd)
I think it would be cool to have that and then to also be able to temporarily toggle those axis locks on by holding down a key (probably x y and z)

@phkahler
Copy link
Member

  1. When "scrolling" to pan or rotating (by adding shift), it can show the labels for the menu icons:

I've never seen that before.

It feels like the panning direction and rotate direction should be the opposite way?

Sliding fingers to the right should move the sketch to the right. Some people have complained that it feels backward and they seem to want the camera to move right, but moving the sketch is how solvespace works.

I once tried to expand the "turntable nav" to also allow locking on the X or Y axis (see my half-failed attempt here: vespakoen/solvespace@97630bd)

I think being able to select a point and rotate around it would be a huge benefit when looking at things up close / zoomed in. But that's not part of this.

@phkahler
Copy link
Member

I tried rerunning this one and it failed again, I assume it's because the fix was not present when the PR was created.

Since macOS tests can pass now, is there a way to rebase a PR and rerun tests?

@vespakoen
Copy link
Contributor

git fetch origin
git rebase origin/master

@tomsci
Copy link
Contributor Author

tomsci commented Aug 18, 2021

Since macOS tests can pass now, is there a way to rebase a PR and rerun tests?

Yep I will rebase and force push. Stand by, just writing another comment :)

@phkahler
Copy link
Member

phkahler commented Aug 18, 2021

git fetch origin
git rebase origin/master

Well yeah, but I meant through github since I'm not on my dev machine ;-) They have a "rebase and merge" button, but not just a plain rebase. They also allow you to rerun the tests.

@tomsci
Copy link
Contributor Author

tomsci commented Aug 18, 2021

When "scrolling" to pan or rotating (by adding shift), it can show the labels for the menu icons:

Darn, I really thought I'd got away with that! That's the downside of shoehorning this in via simulated onMouseEvents :-( Since there's no explicit "pan the camera by this much relative to the camera's current xyz coords" API we're pretending the mouse is moving when it isn't, and those simulated moves can potentially be telling GraphicsWindow that the pointer is over the toolbar area, which leads to the toolbar hover text being shown.

I debated refactoring GraphicsWindow::MouseMoved() into a separate CameraMove() API or something, which would allow us to move the camera position independently of the mouse cursor and thus avoid issues like this when the camera is being controlled by the trackpad, but that'd be a much bigger and wider-reaching PR.

I also tried using SixDofEvent but that API doesn't seem to be intended for this sort of input either since it has no way to express where in the window the event is happening, and rotates have to be specified in radians not screen pixels, so you can't easily do either the zoom or rotate gestures with it.

As an aside, why does middle-click rotate always rotate around the centre of the scene/window rather than around the location that was clicked on? This has always felt weird to me especially when zoomed far in, where a small rotate around the centre will quickly make the thing you were interested in vanish unless you made sure to centre it in the window on the thing of interest first. It seems to be how fusion does it too, but I don't really understand why - rotating around where you clicked definitely feels more natural to me. Anyway, I digress...

I'm not sure how best to fix the hover text thing without significant additional refactoring. Which I don't mind attempting, but the likelihood of messing something up for another platform/usecase will be higher. Suggestions welcome on what would be best to do here :)

It feels like the panning direction and rotate direction should be the opposite way?
This might be because I turned off the "natural scrolling" feature perhaps?

The pan behaviour should follow the standard mac behaviour - when "natural scrolling" is off, dragging down moves the content up, and dragging left moves the content to the right. When "Natural scrolling is on", dragging down moves the content down (but dragging left still moves content to the right, go figure...). That's what how standard apps like Preview.app behave and behaving the same as that seemed like the best option.

Currently SolveSpace is nearly unusable on a mac if you only have a
buttonless trackpad and not a mouse, because there's no way to pan
(ie right-click-drag) or rotate (ie middle-click-drag). You can zoom,
but only by using two-finger-drag up and down, which ends up getting
interpreted as a scrollwheel event.

This change makes the app behave much more like any other mac app, by
adding 2-finger-drag pan gesture support and pinch-gesture zooming, and
3D rotate using shift-2-finger-drag.

I've also added support for the rotate two-finger trackpad gesture,
which rotates directly around the screen Z axis (rather than in all 3
dimensions) which is actually something I've found myself wanting to do
with the mouse but afaik there's no equivalent way of achieving that.

While I was there, I fixed a bugette in convertMouseEvent which was
incorrectly translating the NSEvent coordinates, and then fixing up the
fact that the sign of the y-coordinate was wrong as a result. Using the
convertPoint API correctly means that fixup is not required because
convertPoint handles it for you.
@phkahler
Copy link
Member

As an aside, why does middle-click rotate always rotate around the centre of the scene/window rather than around the location that was clicked on? This has always felt weird to me especially when zoomed far in, where a small rotate around the centre will quickly make the thing you were interested in vanish unless you made sure to centre it in the window on the thing of interest first.

@tomsci Agreed. That's what I meant in one of my comments. It would be nice to select a point and have the rotation happen around that point. That could be done by rotating the way it is now and then panning so that point remains in the same place on the screen. Just a thought, not sure if that'd be the best way to do it.

Further off topic, I'd really like to see some of the VR input methods too ;-)

@tomsci
Copy link
Contributor Author

tomsci commented Aug 18, 2021

Yeah I realised after I wrote it that you could only rotate about the point you clicked on (assuming you clicked in empty space, not on an actual bit of geometry) if you have an active workplane, otherwise you don't know what the z-coord of the rotate origin should be. Or maybe you could do some sort of approximation based on the closest bit of geometry in the 3d space.

I'd really like to see some of the VR input methods too

I don't think any of my models are impressive enough to be worth looking at in VR but I admit I'm tempted :-) Maybe this will be enough impetus for me to look in to OpenXR...

@phkahler
Copy link
Member

Yeah I realised after I wrote it that you could only rotate about the point you clicked on (assuming you clicked in empty space, not on an actual bit of geometry) if you have an active workplane, otherwise you don't know what the z-coord of the rotate origin should be. Or maybe you could do some sort of approximation based on the closest bit of geometry in the 3d space.

I don't think we need the Z value, just pan the rotated model so the point is in the same screen position?

I'd really like to see some of the VR input methods too

I don't think any of my models are impressive enough to be worth looking at in VR but I admit I'm tempted :-) Maybe this will be enough impetus for me to look in to OpenXR...

The old emscripten port works in the web browser inside my Quest2. Not sure if the browser supports VR inputs? If so, I wonder if some gestures could be used in there with the model in the browser. Then a VR specific version could be made that pops the model out of the browser into the same VR space as the user? Someone would probably jump on developing that if we knew the pieces would all work together.

@tomsci
Copy link
Contributor Author

tomsci commented Aug 18, 2021

I don't think we need the Z value, just pan the rotated model so the point is in the same screen position?

Not sure, in my head it seems like you might need it but I'm pretty bad at visualising geometry so maybe not.

The old emscripten port works in the web browser inside my Quest2

Wow, C++ to javascript (to webgl?) to browser-projected-in-VR? Sounds like a terrifying technology stack but pretty cool that it worked I guess. I was thinking more like directly implementing an OpenXR renderer and hooking that up through WMR, but that's probably a huge amount of work and would never work on my mac anyway :-)

@ruevs
Copy link
Member

ruevs commented Aug 19, 2021

As an aside, why does middle-click rotate always rotate around the centre of the scene/window rather than around the location that was clicked on? This has always felt weird to me especially when zoomed far in, where a small rotate around the centre will quickly make the thing you were interested in vanish unless you made sure to centre it in the window on the thing of interest first.

@tomsci Agreed. That's what I meant in one of my comments. It would be nice to select a point and have the rotation happen around that point. That could be done by rotating the way it is now and then panning so that point remains in the same place on the screen. Just a thought, not sure if that'd be the best way to do it.

Now is the time to mention that this has been on line 6 of Jonathan's wishlist for eleven years ;-)
https://github.com/solvespace/solvespace/blob/master/wishlist.txt

Of course that file is a historical artefact so no one touches it.

It is also closely related to rotation with 6DOF controllers (3Dconnexion SpaceMouse etc.).

@ruevs
Copy link
Member

ruevs commented Aug 19, 2021

By the way the 3Dconnexion developers have thought about this a lot. Take a look at the "Center of Rotation" section here https://github.com/natevm/Foton/blob/master/external/spacemouse/Doc/DevInfo.htm

The rest of the Doc directory is pretty interesting as well.

@tomsci tomsci marked this pull request as draft August 20, 2021 18:14
@tomsci
Copy link
Contributor Author

tomsci commented Aug 20, 2021

Putting back to draft status as there are some broken interactions with the text window that I didn't notice. There's also some (preexisting) weirdnesses with the scrollbars on the text window that may be relevant. Also still open to suggestions on how best to fix the phantom hovertext issues. Maybe for that, we just need to fix when GraphicsWindow shows hovers since that also happens if you right-click-drag the mouse over the toolbar - it's just less unexpected of course since the cursor is right there. The case could be made though that it'd be better not showing hover text in the middle of a right-click-drag, and that'd solve it for the trackpad issue too.

@tomsci
Copy link
Contributor Author

tomsci commented Aug 20, 2021

Have pushed fixes for trackpad gestures in the text window, and the text window scrollbar issues that were annoying me (but are technically unrelated to the trackpad changes). The only remaining issue is the phantom hovertext, which I think would require some minor changes to the generic mouse.cpp to fix properly (to prevent toolbar hovers appearing when doing right-click-drag)

@phkahler
Copy link
Member

I also tried using SixDofEvent but that API doesn't seem to be intended for this sort of input either since it has no way to express where in the window the event is happening, and rotates have to be specified in radians not screen pixels, so you can't easily do either the zoom or rotate gestures with it.

@tomsci you can do a conversion, just use something like PI * dist_in_pixels / screen_width_in_pixels to produce a 180 degree rotation by dragging all the way across the screen. Ok, maybe 2*PI then to make it more sensitive.

This improves the behaviour of trackpad pan/rotate on mac which uses
simulated right-button events.
@tomsci
Copy link
Contributor Author

tomsci commented Aug 22, 2021

I've pushed commits to address the 3 specific issues that I put the PR back into draft for.

  1. The toolbar hover text appearing unexpectedly when doing a trackpad pan/rotate. I've 'fixed' this by not sending any right-button-drag or middle-button-drags to the toolbar, which works nicely and those gestures aren't actually used by anything on the toolbar. The one side-effect this has (on all platforms) is that right-click-dragging when the mouse starts over the toolbar will now immediately initiate a drag, rather than only starting the drag when the mouse moves off the toolbar into the main window. I don't think anyone will really care about this change in behaviour, since the toolbar itself doesn't ever respond to any non-left-click mouse button events, but I mention it for completeness.

  2. Trackpad gestures shouldn't have been applied in anything except the main window, which caused the text window to behave weirdly. Now fixed, text window now just does scrollwheel-style trackpad scrolling again.

  3. The mac scrollbars on the text window were nonfunctional for certain ratios of content to window height. The window could still be scrolled with the mouse but not by dragging the scrollbar. The code was neeearly right but off on some of the scaling calculations for translating between SolveSpace's scrollbar coordinate system and NSScroller's. This appears to have been an issue since at least the last major refactor of the scrolling code a couple of years ago. Now fixed. I also made the scroller hide when it wasn't needed, to match how the scrollbar behaves on other platforms and how scrollbars normally behave on mac. Well, I checked on win32, I didn't check what linux does but I assume it's probably the same.

I'm going to step back from the question of what the centre of rotation should be or whether some of these events could be input using SixDofEvent - it's an interesting discussion but it's getting a bit too deep into weeds for me :-) I think the trackpad is generally more mouselike than it is a 6-DOF controller so using the mouse API is probably ok. It's a shame there isn't a more nuanced API to say "I want a mouse-like rotate gesture with this much X and Y" rather than having to say "here's a shift-right-button x y motion" and having to know that that will result in a rotate, but that's more a philosophical objection than a real issue. And I can sympathise with the complexities of cross-platform input handling, been there before!

@tomsci tomsci marked this pull request as ready for review August 22, 2021 09:54
@vespakoen
Copy link
Contributor

I just checked this again and noticed that cmd+scrolling behaves strange.
I think the solution here is to not forward trackpad events when cmd in pressed.
cmd+right-mouse-down-scrolling works as expected.

@tomsci
Copy link
Contributor Author

tomsci commented Aug 26, 2021

You're right, I didn't realise that ctrl and cmd are swapped and didn't test that combination. In fact I didn't realise you could do an in-plane rotate with ctrl-right-click-drag full stop :-) I've made sure to clear controlDown from the trackpad simulated MouseEvents which makes cmd-two-finger-drag behave just like unmodified two-finger-drag which I think is probably the best option, since there's already an explicit gesture for doing an in-plane rotate with the trackpad (which doesn't require any modifiers).

@vespakoen
Copy link
Contributor

LGTM!

@vespakoen vespakoen merged commit e1b0784 into solvespace:master Aug 26, 2021
@nanoant
Copy link
Contributor

nanoant commented Sep 5, 2021

@tomsci Hi. I just tried to run latest master with your changes on my Mac using Magic Mouse, that has some sort of single finger touchpad that's emulating scroll wheel. And the problem is that now zoom with scroll is now gone and replaced with panning, which is kind of a bummer because there's no way to zoom anymore with Magic Mouse, and panning is duplicated as you could do panning with holding right mouse button before.
Can we please run your customizations only on real track pads, not on Magic Mouse scroll-wheel-kinda-trackpad?

@tomsci
Copy link
Contributor Author

tomsci commented Sep 5, 2021

@nanoant That wasn't intentional :-( I'm not sure the best way to distinguish a Magic Mouse from a trackpad, the documentation is frustratingly vague as to how the APIs line up with the actual hardware Apple produces. I don't have a Magic Mouse to test with but I can try some speculative changes if you'd be able to test them?

@nanoant
Copy link
Contributor

nanoant commented Sep 5, 2021

@tomsci I have Magic Mouse here. I've already managed to compile and run Solve Space here. Let me try if I can anything specific in NSEvent to disable the trackpad condition. I'll keep you informed.

@phkahler
Copy link
Member

phkahler commented Sep 5, 2021

I tried it on my Air, and I do miss the 2 finger zoom. Pinch zoom is great, as are the other changes so overall it seems better. But 2 finger zoom emulating a scroll wheel was nice.

@tomsci
Copy link
Contributor Author

tomsci commented Sep 5, 2021

Hopefully it's just a matter of becoming accustomed, I found myself hating that it zoomed when I expected it to pan because I was so accustomed to how other mac apps behave, and the fact that I kept zooming accidentally when I meant to pan was the primary motivation for making this PR :-)

@ruevs ruevs added the macOS label Jan 28, 2022
@ruevs
Copy link
Member

ruevs commented Aug 21, 2022

The old emscripten port works in the web browser inside my Quest2. Not sure if the browser supports VR inputs? If so, I wonder if some gestures could be used in there with the model in the browser.

@verylowfreq has added some gestures in the Web version here:
https://github.com/verylowfreq/solvespace/tree/emscripten-develop
https://github.com/verylowfreq/solvespace/commits/feature-em-fileio
Live version:
https://verylowfreq.github.io/experimental-solvespace-on-browser/

@ruevs ruevs added the UI label Nov 24, 2023
devin-ai-integration bot pushed a commit to erkinalp/solvespace that referenced this pull request Apr 3, 2025
)

* mac: Support for pan, zoom and rotate trackpad gestures

Currently SolveSpace is nearly unusable on a mac if you only have a
buttonless trackpad and not a mouse, because there's no way to pan
(ie right-click-drag) or rotate (ie middle-click-drag). You can zoom,
but only by using two-finger-drag up and down, which ends up getting
interpreted as a scrollwheel event.

This change makes the app behave much more like any other mac app, by
adding 2-finger-drag pan gesture support and pinch-gesture zooming, and
3D rotate using shift-2-finger-drag.

I've also added support for the rotate two-finger trackpad gesture,
which rotates directly around the screen Z axis (rather than in all 3
dimensions) which is actually something I've found myself wanting to do
with the mouse but afaik there's no equivalent way of achieving that.

While I was there, I fixed a bugette in convertMouseEvent which was
incorrectly translating the NSEvent coordinates, and then fixing up the
fact that the sign of the y-coordinate was wrong as a result. Using the
convertPoint API correctly means that fixup is not required because
convertPoint handles it for you.

* Don't do trackpad gestures on anything except the toplevel window

* mac: Fix non-functional scrollbar on text window

Which has not worked quite right since the last major refactor.

* Don't pass right-button drags to the toolbar

This improves the behaviour of trackpad pan/rotate on mac which uses
simulated right-button events.

* Don't pass cmd/ctrl modifier through on trackpad pan/rotate MouseEvents
dennisyangji pushed a commit to Orthogonalpub/ode_solvespace that referenced this pull request Nov 25, 2025
)

* mac: Support for pan, zoom and rotate trackpad gestures

Currently SolveSpace is nearly unusable on a mac if you only have a
buttonless trackpad and not a mouse, because there's no way to pan
(ie right-click-drag) or rotate (ie middle-click-drag). You can zoom,
but only by using two-finger-drag up and down, which ends up getting
interpreted as a scrollwheel event.

This change makes the app behave much more like any other mac app, by
adding 2-finger-drag pan gesture support and pinch-gesture zooming, and
3D rotate using shift-2-finger-drag.

I've also added support for the rotate two-finger trackpad gesture,
which rotates directly around the screen Z axis (rather than in all 3
dimensions) which is actually something I've found myself wanting to do
with the mouse but afaik there's no equivalent way of achieving that.

While I was there, I fixed a bugette in convertMouseEvent which was
incorrectly translating the NSEvent coordinates, and then fixing up the
fact that the sign of the y-coordinate was wrong as a result. Using the
convertPoint API correctly means that fixup is not required because
convertPoint handles it for you.

* Don't do trackpad gestures on anything except the toplevel window

* mac: Fix non-functional scrollbar on text window

Which has not worked quite right since the last major refactor.

* Don't pass right-button drags to the toolbar

This improves the behaviour of trackpad pan/rotate on mac which uses
simulated right-button events.

* Don't pass cmd/ctrl modifier through on trackpad pan/rotate MouseEvents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: use trackpad ilo mouse

5 participants