|
@@ -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 @@ struct ImGui_ImplOSX_Data
|
|
|
ImGuiObserver* Observer;
|
|
|
KeyEventResponder* KeyEventResponder;
|
|
|
NSTextInputContext* InputContext;
|
|
|
+ id Monitor;
|
|
|
|
|
|
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
|
|
};
|
|
@@ -76,6 +78,10 @@ static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui
|
|
|
|
|
|
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 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|
|
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 @@ void ImGui_ImplOSX_Shutdown()
|
|
|
{
|
|
|
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 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
|
|
|
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 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
|
|
|
|
|
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;
|
|
|
+ }];
|
|
|
+}
|