Backends: OSX: Removed ImGui_ImplOSX_HandleEvent() from backend API. Move event tracking (desktop only) to OSX backend. (#4821)
Fix using NSKeyUp (#5268).
diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h
index 8590619..d483dcf 100644
--- a/backends/imgui_impl_osx.h
+++ b/backends/imgui_impl_osx.h
@@ -22,4 +22,3 @@
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
-IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view);
diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm
index 59c34a1..fa4807f 100644
--- a/backends/imgui_impl_osx.mm
+++ b/backends/imgui_impl_osx.mm
@@ -23,6 +23,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2022-05-03: Inputs: Removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture.
// 2022-04-27: Misc: Store backend data in a per-context struct, allowing to use this backend with multiple contexts.
// 2022-03-22: Inputs: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key
// 2022-02-07: Inputs: Forward keyDown/keyUp events to OS when unused by dear imgui.
@@ -66,6 +67,7 @@
ImGuiObserver* Observer;
KeyEventResponder* KeyEventResponder;
NSTextInputContext* InputContext;
+ id Monitor;
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
};
@@ -76,6 +78,10 @@
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return static_cast<CFTimeInterval>(static_cast<double>(clock_gettime_nsec_np(CLOCK_UPTIME_RAW)) / 1e9); }
+// Forward Declarations
+static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
+static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
+
// Undocumented methods for creating cursors.
@interface NSCursor()
+ (id)_windowResizeNorthWestSouthEastCursor;
@@ -429,15 +435,7 @@
bd->KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
bd->InputContext = [[NSTextInputContext alloc] initWithClient:bd->KeyEventResponder];
[view addSubview:bd->KeyEventResponder];
-
- // Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down).
- // This monitor taps into global event stream and captures these events.
- NSEventMask eventMask = NSEventMaskFromType(NSKeyUp) | NSEventMaskFlagsChanged;
- [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
- {
- ImGui_ImplOSX_HandleEvent(event, bd->KeyEventResponder);
- return event;
- }];
+ ImGui_ImplOSX_AddTrackingArea(view);
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
{
@@ -462,6 +460,11 @@
{
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
bd->Observer = NULL;
+ if (bd->Monitor != NULL)
+ {
+ [NSEvent removeMonitor:bd->Monitor];
+ bd->Monitor = NULL;
+ }
ImGui_ImplOSX_DestroyBackendData();
}
@@ -591,7 +594,7 @@
ImGui_ImplOSX_UpdateImePosWithView(view);
}
-bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
+static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
{
ImGuiIO& io = ImGui::GetIO();
@@ -716,3 +719,27 @@
return false;
}
+
+static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
+{
+ // If we want to receive key events, we either need to be in the responder chain of the key view,
+ // or else we can install a local monitor. The consequence of this heavy-handed approach is that
+ // we receive events for all controls, not just Dear ImGui widgets. If we had native controls in our
+ // window, we'd want to be much more careful than just ingesting the complete event stream.
+ // To match the behavior of other backends, we pass every event down to the OS.
+ ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
+ if (bd->Monitor)
+ return;
+ NSEventMask eventMask = 0;
+ eventMask |= NSEventMaskMouseMoved | NSEventMaskScrollWheel;
+ eventMask |= NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged;
+ eventMask |= NSEventMaskRightMouseDown | NSEventMaskRightMouseUp | NSEventMaskRightMouseDragged;
+ eventMask |= NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp | NSEventMaskOtherMouseDragged;
+ eventMask |= NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
+ bd->Monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask
+ handler:^NSEvent* _Nullable(NSEvent* event)
+ {
+ ImGui_ImplOSX_HandleEvent(event, view);
+ return event;
+ }];
+}
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index f23fe48..1a81813 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -39,6 +39,10 @@
- Renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete).
(This was never used in public API functions but technically present in imgui.h and ImGuiIO).
+- Backends: OSX: Removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend
+ automatically handling event capture. Examples that are using the OSX backend have removed
+ all the now-unnecessary calls to ImGui_ImplOSX_HandleEvent(), applications can do as well.
+ [@stuartcarnie] (#4821)
Other Changes:
@@ -105,6 +109,7 @@
- Backends: OSX, Metal: Store backend data in a per-context struct, allowing to use these backends with
multiple contexts. (#5203, #5221, #4141) [@noisewuwei]
- Examples: Emscripten+WebGPU: Fix building for latest WebGPU specs. (#3632)
+- Examples: OSX+Metal, OSX+OpenGL: Removed now-unnecessary calls to ImGui_ImplOSX_HandleEvent(). (#4821)
-----------------------------------------------------------------------
diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm
index db1ef3a..d29f8d9 100644
--- a/examples/example_apple_metal/main.mm
+++ b/examples/example_apple_metal/main.mm
@@ -17,7 +17,7 @@
#include "imgui_impl_metal.h"
#if TARGET_OS_OSX
#include "imgui_impl_osx.h"
-@interface AppViewController : NSViewController
+@interface AppViewController : NSViewController<NSWindowDelegate>
@end
#else
@interface AppViewController : UIViewController
@@ -100,15 +100,8 @@
self.mtkView.delegate = self;
#if TARGET_OS_OSX
- // Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view
- NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
- options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
- owner:self
- userInfo:nil];
- [self.view addTrackingArea:trackingArea];
-
ImGui_ImplOSX_Init(self.view);
-
+ [NSApp activateIgnoringOtherApps:YES];
#endif
}
@@ -209,20 +202,18 @@
#if TARGET_OS_OSX
-// Forward Mouse events to Dear ImGui OSX backend.
--(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
--(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
+- (void)viewWillAppear
+{
+ [super viewWillAppear];
+ self.view.window.delegate = self;
+}
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+ ImGui_ImplMetal_Shutdown();
+ ImGui_ImplOSX_Shutdown();
+ ImGui::DestroyContext();
+}
#else
@@ -286,9 +277,8 @@
backing:NSBackingStoreBuffered
defer:NO];
self.window.contentViewController = rootViewController;
- [self.window orderFront:self];
[self.window center];
- [self.window becomeKeyWindow];
+ [self.window makeKeyAndOrderFront:self];
}
return self;
}
diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm
index 482a94f..92754b8 100644
--- a/examples/example_apple_opengl2/main.mm
+++ b/examples/example_apple_opengl2/main.mm
@@ -142,26 +142,6 @@
-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
-(void)dealloc { animationTimer = nil; }
-//-----------------------------------------------------------------------------------
-// Input processing
-//-----------------------------------------------------------------------------------
-
-// Forward Mouse/Keyboard events to Dear ImGui OSX backend.
-// Other events are registered via addLocalMonitorForEventsMatchingMask()
--(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
--(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-
@end
//-----------------------------------------------------------------------------------
diff --git a/imgui.cpp b/imgui.cpp
index 8bcd9ab..bc801bb 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -386,6 +386,7 @@
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
+ - 2022/05/03 (1.88) - backends: osx: removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture. All ImGui_ImplOSX_HandleEvent() calls should be removed as they are now unnecessary.
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
- 2022/01/20 (1.87) - inputs: reworded gamepad IO.
- Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values.