Pārlūkot izejas kodu

Backends: OSX: Added support for io.AddMouseSourceEvent(). (#6314)

Also marked "mouse" input in example_apple_metal's UIKit micro-backend as being touch input.

# Conflicts:
#	docs/CHANGELOG.txt
David Maas 2 gadi atpakaļ
vecāks
revīzija
e92b29ad53

+ 1 - 0
backends/imgui_impl_osx.h

@@ -5,6 +5,7 @@
 
 // Implemented features:
 //  [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
+//  [X] Platform: Mouse support. Can discriminate Mouse/Pen.
 //  [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
 //  [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
 //  [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.

+ 29 - 0
backends/imgui_impl_osx.mm

@@ -5,6 +5,7 @@
 
 // Implemented features:
 //  [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
+//  [X] Platform: Mouse support. Can discriminate Mouse/Pen.
 //  [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
 //  [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
 //  [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
@@ -24,6 +25,7 @@
 
 // CHANGELOG
 // (minor and older changes stripped away, please see git history for details)
+//  2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
 //  2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
 //  2022-11-02: Fixed mouse coordinates before clicking the host window.
 //  2022-10-06: Fixed mouse inputs on flipped views.
@@ -609,6 +611,26 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
     ImGui_ImplOSX_UpdateImePosWithView(view);
 }
 
+// Must only be called for a mouse event, otherwise an exception occurs
+// (Note that NSEventTypeScrollWheel is considered "other input". Oddly enough an exception does not occur with it, but the value will sometimes be wrong!)
+static ImGuiMouseSource GetMouseSource(NSEvent* event)
+{
+    switch (event.subtype)
+    {
+        case NSEventSubtypeTabletPoint:
+            return ImGuiMouseSource_Pen;
+        // macOS considers input from relative touch devices (like the trackpad or Apple Magic Mouse) to be touch input.
+        // This doesn't really make sense for Dear ImGui, which expects absolute touch devices only.
+        // There does not seem to be a simple way to disambiguate things here so we consider NSEventSubtypeTouch events to always come from mice.
+        // See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/HandlingTouchEvents/HandlingTouchEvents.html#//apple_ref/doc/uid/10000060i-CH13-SW24
+        //case NSEventSubtypeTouch:
+        //    return ImGuiMouseSource_TouchScreen;
+        case NSEventSubtypeMouseEvent:
+        default:
+            return ImGuiMouseSource_Mouse;
+    }
+}
+
 static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
 {
     ImGuiIO& io = ImGui::GetIO();
@@ -617,7 +639,10 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
     {
         int button = (int)[event buttonNumber];
         if (button >= 0 && button < ImGuiMouseButton_COUNT)
+        {
+            io.AddMouseSourceEvent(GetMouseSource(event));
             io.AddMouseButtonEvent(button, true);
+        }
         return io.WantCaptureMouse;
     }
 
@@ -625,7 +650,10 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
     {
         int button = (int)[event buttonNumber];
         if (button >= 0 && button < ImGuiMouseButton_COUNT)
+        {
+            io.AddMouseSourceEvent(GetMouseSource(event));
             io.AddMouseButtonEvent(button, false);
+        }
         return io.WantCaptureMouse;
     }
 
@@ -639,6 +667,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
             mousePoint = NSMakePoint(mousePoint.x, mousePoint.y);
         else
             mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
+        io.AddMouseSourceEvent(GetMouseSource(event));
         io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
         return io.WantCaptureMouse;
     }

+ 4 - 1
docs/CHANGELOG.txt

@@ -86,7 +86,10 @@ Other changes:
 - Backends: GLFW: Added support on Win32 only for io.AddMouseSourceEvent() to discriminate
   Mouse/TouchScreen/Pen. (#2334, #2702)
 - Backends: GLFW: Fixed key modifiers handling on secondary viewports. (#6248, #6034) [@aiekick]
-- Backends: Android: Added support for io.AddMouseSourceEvent() to discriminate Mouse/TouchScreen/Pen. [@PathogenDavid]
+- Backends: Android: Added support for io.AddMouseSourceEvent() to discriminate Mouse/TouchScreen/Pen.
+  (#6315) [@PathogenDavid]
+- Backends: OSX: Added support for io.AddMouseSourceEvent() to discriminate Mouse/Pen.
+  (#6314) [@PathogenDavid]
 - Examples: Windows: Added 'misc/debuggers/imgui.natstepfilter' file to all Visual Studio projects,
   now that VS 2022 17.6 Preview 2 support adding Debug Step Filter spec files into projects.
 - Examples: SDL3: Updated for latest WIP SDL3 branch. (#6243)

+ 1 - 0
examples/example_apple_metal/main.mm

@@ -228,6 +228,7 @@
     UITouch *anyTouch = event.allTouches.anyObject;
     CGPoint touchLocation = [anyTouch locationInView:self.view];
     ImGuiIO &io = ImGui::GetIO();
+    io.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
     io.AddMousePosEvent(touchLocation.x, touchLocation.y);
 
     BOOL hasActiveTouch = NO;