diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index 9f4082d..0f54587 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -215,9 +215,7 @@ func main() { usercfg.Load() // Hide the mouse cursor over the window, we draw our own sprite image for it. - if !native.HasTouchscreen(engine) { - engine.ShowCursor(false) - } + engine.ShowCursor(false) // Set the app window icon. if engine, ok := game.Engine.(*sdl.Renderer); ok { diff --git a/pkg/cursor/cursor.go b/pkg/cursor/cursor.go index 0698b8f..629812b 100644 --- a/pkg/cursor/cursor.go +++ b/pkg/cursor/cursor.go @@ -25,7 +25,7 @@ var NoCursor = &Cursor{} // Draw the cursor on screen. NOTE: Does not draw on touchscreen devices. func Draw(e render.Engine) { - if native.HasTouchscreen(e) { + if native.IsTouchScreenMode { return } diff --git a/pkg/doodle.go b/pkg/doodle.go index 0a619c9..80c28e0 100644 --- a/pkg/doodle.go +++ b/pkg/doodle.go @@ -141,6 +141,20 @@ func (d *Doodle) Run() error { } d.event = ev + // If they have touched a touch screen, set the touchscreen mode boolean. This + // will hide the mouse cursor until they let up off the screen. + if !native.IsTouchScreenMode { + if ev.IsFingerDown { + log.Debug("TouchScreenMode ON!") + native.IsTouchScreenMode = true + } + } else { + if !ev.IsFingerDown { + log.Debug("TouchScreenMode OFF") + native.IsTouchScreenMode = false + } + } + // Always have an accurate idea of the window size. if ev.WindowResized { d.width, d.height = d.Engine.WindowSize() diff --git a/pkg/native/engine_sdl.go b/pkg/native/engine_sdl.go index c7998d8..57b6cb0 100644 --- a/pkg/native/engine_sdl.go +++ b/pkg/native/engine_sdl.go @@ -20,6 +20,9 @@ import ( // not for JavaScript/WASM yet. // HasTouchscreen checks if the device has at least one SDL_GetNumTouchDevices. +// +// Note: SDL2 GetNumTouchDevices will sometimes return 0 until a touch device is actually touched. On Macbooks, +// the trackpad counts as a touch device and on first touch, HasTouchscreen may begin returning true. func HasTouchscreen(e render.Engine) bool { if _, ok := e.(*sdl.Renderer); ok { return sdl2.GetNumTouchDevices() > 0 diff --git a/pkg/native/touch_screen.go b/pkg/native/touch_screen.go new file mode 100644 index 0000000..ce5c136 --- /dev/null +++ b/pkg/native/touch_screen.go @@ -0,0 +1,12 @@ +package native + +// Common code to handle basic touch screen detection. + +/* +IsTouchScreenMode is set to true when the user has touched the screen, and false when the mouse is moved. + +This informs the game's control scheme: if the user has a touch screen and they've touched it, +the custom mouse cursor is hidden (as it becomes distracting) and if they then move a real mouse +over the window, the custom cursor appears again and we assume non-touchscreen mode once more. +*/ +var IsTouchScreenMode bool diff --git a/pkg/uix/canvas_scrolling.go b/pkg/uix/canvas_scrolling.go index bd076ca..18f9d32 100644 --- a/pkg/uix/canvas_scrolling.go +++ b/pkg/uix/canvas_scrolling.go @@ -56,7 +56,7 @@ func (w *Canvas) loopEditorScroll(ev *event.State) error { } // Multitouch events to pan the level, like middle click on desktop. - if ev.Touching { + if ev.Touching && ev.TouchNumFingers > 1 { // Intention: user drags with 2 fingers to scroll the canvas. // SDL2 will register one finger also as a Button1 mouse click. // We need to record the "mouse cursor" as start point but then