Backends: OSX: Update to use io.AddEventKey() will full key map (#2625, #1873, #4858)
diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h
index 6cfe7eb..37851a3 100644
--- a/backends/imgui_impl_osx.h
+++ b/backends/imgui_impl_osx.h
@@ -4,9 +4,9 @@
 
 // Implemented features:
 //  [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
+//  [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'.
-//  [X] Platform: Keyboard arrays indexed using kVK_* codes, e.g. ImGui::IsKeyPressed(kVK_Space).
 
 // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
 // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm
index 9acd8ba..64a45ef 100644
--- a/backends/imgui_impl_osx.mm
+++ b/backends/imgui_impl_osx.mm
@@ -4,9 +4,9 @@
 
 // Implemented features:
 //  [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
+//  [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'.
-//  [X] Platform: Keyboard arrays indexed using kVK_* codes, e.g. ImGui::IsKeyPressed(kVK_Space).
 
 // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
 // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -22,6 +22,7 @@
 
 // CHANGELOG
 // (minor and older changes stripped away, please see git history for details)
+//  2022-01-10: Inputs: calling new io.AddKeyEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
 //  2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys.
 //  2021-12-13: Add game controller support.
 //  2021-09-21: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards.
@@ -50,6 +51,7 @@
 static bool                 g_MouseCursorHidden = false;
 static bool                 g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
 static bool                 g_MouseDown[ImGuiMouseButton_COUNT] = {};
+static ImGuiKeyModFlags     g_KeyModifiers = ImGuiKeyModFlags_None;
 static ImFocusObserver*     g_FocusObserver = nil;
 static KeyEventResponder*   g_KeyEventResponder = nil;
 
@@ -73,13 +75,6 @@
     return (double)mach_absolute_time() * g_HostClockPeriod;
 }
 
-static void resetKeys()
-{
-    ImGuiIO& io = ImGui::GetIO();
-    memset(io.KeysDown, 0, sizeof(io.KeysDown));
-    io.KeyCtrl = io.KeyShift = io.KeyAlt = io.KeySuper = false;
-}
-
 /**
  KeyEventResponder implements the NSTextInputClient protocol as is required by the macOS text input manager.
 
@@ -105,10 +100,17 @@
 
 - (void)keyDown:(NSEvent*)event
 {
+    ImGui_ImplOSX_HandleEvent(event, self);
+
     // Call to the macOS input manager system.
     [self interpretKeyEvents:@[event]];
 }
 
+- (void)keyUp:(NSEvent*)event
+{
+    ImGui_ImplOSX_HandleEvent(event, self);
+}
+
 - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 {
     ImGuiIO& io = ImGui::GetIO();
@@ -195,16 +197,134 @@
 {
     ImGuiIO& io = ImGui::GetIO();
     io.AddFocusEvent(false);
-
-    // Unfocused applications do not receive input events, therefore we must manually
-    // release any pressed keys when application loses focus, otherwise they would remain
-    // stuck in a pressed state. https://github.com/ocornut/imgui/issues/3832
-    resetKeys();
 }
 
 @end
 
 // Functions
+static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
+{
+    switch (key_code)
+    {
+        case kVK_ANSI_A: return ImGuiKey_A;
+        case kVK_ANSI_S: return ImGuiKey_S;
+        case kVK_ANSI_D: return ImGuiKey_D;
+        case kVK_ANSI_F: return ImGuiKey_F;
+        case kVK_ANSI_H: return ImGuiKey_H;
+        case kVK_ANSI_G: return ImGuiKey_G;
+        case kVK_ANSI_Z: return ImGuiKey_Z;
+        case kVK_ANSI_X: return ImGuiKey_X;
+        case kVK_ANSI_C: return ImGuiKey_C;
+        case kVK_ANSI_V: return ImGuiKey_V;
+        case kVK_ANSI_B: return ImGuiKey_B;
+        case kVK_ANSI_Q: return ImGuiKey_Q;
+        case kVK_ANSI_W: return ImGuiKey_W;
+        case kVK_ANSI_E: return ImGuiKey_E;
+        case kVK_ANSI_R: return ImGuiKey_R;
+        case kVK_ANSI_Y: return ImGuiKey_Y;
+        case kVK_ANSI_T: return ImGuiKey_T;
+        case kVK_ANSI_1: return ImGuiKey_1;
+        case kVK_ANSI_2: return ImGuiKey_2;
+        case kVK_ANSI_3: return ImGuiKey_3;
+        case kVK_ANSI_4: return ImGuiKey_4;
+        case kVK_ANSI_6: return ImGuiKey_6;
+        case kVK_ANSI_5: return ImGuiKey_5;
+        case kVK_ANSI_Equal: return ImGuiKey_Equal;
+        case kVK_ANSI_9: return ImGuiKey_9;
+        case kVK_ANSI_7: return ImGuiKey_7;
+        case kVK_ANSI_Minus: return ImGuiKey_Minus;
+        case kVK_ANSI_8: return ImGuiKey_8;
+        case kVK_ANSI_0: return ImGuiKey_0;
+        case kVK_ANSI_RightBracket: return ImGuiKey_RightBracket;
+        case kVK_ANSI_O: return ImGuiKey_O;
+        case kVK_ANSI_U: return ImGuiKey_U;
+        case kVK_ANSI_LeftBracket: return ImGuiKey_LeftBracket;
+        case kVK_ANSI_I: return ImGuiKey_I;
+        case kVK_ANSI_P: return ImGuiKey_P;
+        case kVK_ANSI_L: return ImGuiKey_L;
+        case kVK_ANSI_J: return ImGuiKey_J;
+        case kVK_ANSI_Quote: return ImGuiKey_Apostrophe;
+        case kVK_ANSI_K: return ImGuiKey_K;
+        case kVK_ANSI_Semicolon: return ImGuiKey_Semicolon;
+        case kVK_ANSI_Backslash: return ImGuiKey_Backslash;
+        case kVK_ANSI_Comma: return ImGuiKey_Comma;
+        case kVK_ANSI_Slash: return ImGuiKey_Slash;
+        case kVK_ANSI_N: return ImGuiKey_N;
+        case kVK_ANSI_M: return ImGuiKey_M;
+        case kVK_ANSI_Period: return ImGuiKey_Period;
+        case kVK_ANSI_Grave: return ImGuiKey_GraveAccent;
+        case kVK_ANSI_KeypadDecimal: return ImGuiKey_KeypadDecimal;
+        case kVK_ANSI_KeypadMultiply: return ImGuiKey_KeypadMultiply;
+        case kVK_ANSI_KeypadPlus: return ImGuiKey_KeypadAdd;
+        case kVK_ANSI_KeypadClear: return ImGuiKey_NumLock;
+        case kVK_ANSI_KeypadDivide: return ImGuiKey_KeypadDivide;
+        case kVK_ANSI_KeypadEnter: return ImGuiKey_KeypadEnter;
+        case kVK_ANSI_KeypadMinus: return ImGuiKey_KeypadSubtract;
+        case kVK_ANSI_KeypadEquals: return ImGuiKey_KeypadEqual;
+        case kVK_ANSI_Keypad0: return ImGuiKey_Keypad0;
+        case kVK_ANSI_Keypad1: return ImGuiKey_Keypad1;
+        case kVK_ANSI_Keypad2: return ImGuiKey_Keypad2;
+        case kVK_ANSI_Keypad3: return ImGuiKey_Keypad3;
+        case kVK_ANSI_Keypad4: return ImGuiKey_Keypad4;
+        case kVK_ANSI_Keypad5: return ImGuiKey_Keypad5;
+        case kVK_ANSI_Keypad6: return ImGuiKey_Keypad6;
+        case kVK_ANSI_Keypad7: return ImGuiKey_Keypad7;
+        case kVK_ANSI_Keypad8: return ImGuiKey_Keypad8;
+        case kVK_ANSI_Keypad9: return ImGuiKey_Keypad9;
+        case kVK_Return: return ImGuiKey_Enter;
+        case kVK_Tab: return ImGuiKey_Tab;
+        case kVK_Space: return ImGuiKey_Space;
+        case kVK_Delete: return ImGuiKey_Backspace;
+        case kVK_Escape: return ImGuiKey_Escape;
+        case kVK_Command: return ImGuiKey_LeftSuper;
+        case kVK_Shift: return ImGuiKey_LeftShift;
+        case kVK_CapsLock: return ImGuiKey_CapsLock;
+        case kVK_Option: return ImGuiKey_LeftAlt;
+        case kVK_Control: return ImGuiKey_LeftControl;
+        case kVK_RightCommand: return ImGuiKey_RightSuper;
+        case kVK_RightShift: return ImGuiKey_RightShift;
+        case kVK_RightOption: return ImGuiKey_RightAlt;
+        case kVK_RightControl: return ImGuiKey_RightControl;
+//      case kVK_Function: return ImGuiKey_;
+//      case kVK_F17: return ImGuiKey_;
+//      case kVK_VolumeUp: return ImGuiKey_;
+//      case kVK_VolumeDown: return ImGuiKey_;
+//      case kVK_Mute: return ImGuiKey_;
+//      case kVK_F18: return ImGuiKey_;
+//      case kVK_F19: return ImGuiKey_;
+//      case kVK_F20: return ImGuiKey_;
+        case kVK_F5: return ImGuiKey_F5;
+        case kVK_F6: return ImGuiKey_F6;
+        case kVK_F7: return ImGuiKey_F7;
+        case kVK_F3: return ImGuiKey_F3;
+        case kVK_F8: return ImGuiKey_F8;
+        case kVK_F9: return ImGuiKey_F9;
+        case kVK_F11: return ImGuiKey_F11;
+        case kVK_F13: return ImGuiKey_PrintScreen;
+//      case kVK_F16: return ImGuiKey_;
+//      case kVK_F14: return ImGuiKey_;
+        case kVK_F10: return ImGuiKey_F10;
+        case 0x6E: return ImGuiKey_Menu;
+        case kVK_F12: return ImGuiKey_F12;
+//      case kVK_F15: return ImGuiKey_;
+        case kVK_Help: return ImGuiKey_Insert;
+        case kVK_Home: return ImGuiKey_Home;
+        case kVK_PageUp: return ImGuiKey_PageUp;
+        case kVK_ForwardDelete: return ImGuiKey_Delete;
+        case kVK_F4: return ImGuiKey_F4;
+        case kVK_End: return ImGuiKey_End;
+        case kVK_F2: return ImGuiKey_F2;
+        case kVK_PageDown: return ImGuiKey_PageDown;
+        case kVK_F1: return ImGuiKey_F1;
+        case kVK_LeftArrow: return ImGuiKey_LeftArrow;
+        case kVK_RightArrow: return ImGuiKey_RightArrow;
+        case kVK_DownArrow: return ImGuiKey_DownArrow;
+        case kVK_UpArrow: return ImGuiKey_UpArrow;
+        default: return ImGuiKey_None;
+    }
+}
+
+
 bool ImGui_ImplOSX_Init(NSView* view)
 {
     ImGuiIO& io = ImGui::GetIO();
@@ -216,30 +336,6 @@
     //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy)
     io.BackendPlatformName = "imgui_impl_osx";
 
-    // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeyDown[] array.
-    io.KeyMap[ImGuiKey_Tab]             = kVK_Tab;
-    io.KeyMap[ImGuiKey_LeftArrow]       = kVK_LeftArrow;
-    io.KeyMap[ImGuiKey_RightArrow]      = kVK_RightArrow;
-    io.KeyMap[ImGuiKey_UpArrow]         = kVK_UpArrow;
-    io.KeyMap[ImGuiKey_DownArrow]       = kVK_DownArrow;
-    io.KeyMap[ImGuiKey_PageUp]          = kVK_PageUp;
-    io.KeyMap[ImGuiKey_PageDown]        = kVK_PageDown;
-    io.KeyMap[ImGuiKey_Home]            = kVK_Home;
-    io.KeyMap[ImGuiKey_End]             = kVK_End;
-    io.KeyMap[ImGuiKey_Insert]          = kVK_F13;
-    io.KeyMap[ImGuiKey_Delete]          = kVK_ForwardDelete;
-    io.KeyMap[ImGuiKey_Backspace]       = kVK_Delete;
-    io.KeyMap[ImGuiKey_Space]           = kVK_Space;
-    io.KeyMap[ImGuiKey_Enter]           = kVK_Return;
-    io.KeyMap[ImGuiKey_Escape]          = kVK_Escape;
-    io.KeyMap[ImGuiKey_KeypadEnter]     = kVK_ANSI_KeypadEnter;
-    io.KeyMap[ImGuiKey_A]               = kVK_ANSI_A;
-    io.KeyMap[ImGuiKey_C]               = kVK_ANSI_C;
-    io.KeyMap[ImGuiKey_V]               = kVK_ANSI_V;
-    io.KeyMap[ImGuiKey_X]               = kVK_ANSI_X;
-    io.KeyMap[ImGuiKey_Y]               = kVK_ANSI_Y;
-    io.KeyMap[ImGuiKey_Z]               = kVK_ANSI_Z;
-
     // Load cursors. Some of them are undocumented.
     g_MouseCursorHidden = false;
     g_MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
@@ -296,6 +392,15 @@
     g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
     [view addSubview:g_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 = NSEventMaskFlagsChanged;
+    [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
+    {
+        ImGui_ImplOSX_HandleEvent(event, g_KeyEventResponder);
+        return event;
+    }];
+
     return true;
 }
 
@@ -344,7 +449,7 @@
     }
 }
 
-void ImGui_ImplOSX_UpdateGamepads()
+static void ImGui_ImplOSX_UpdateGamepads()
 {
     ImGuiIO& io = ImGui::GetIO();
     memset(io.NavInputs, 0, sizeof(io.NavInputs));
@@ -388,6 +493,15 @@
     io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
 }
 
+static void ImGui_ImplOSX_UpdateKeyModifiers()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    io.KeyCtrl  = (g_KeyModifiers & ImGuiKeyModFlags_Ctrl)  != 0;
+    io.KeyShift = (g_KeyModifiers & ImGuiKeyModFlags_Shift) != 0;
+    io.KeyAlt   = (g_KeyModifiers & ImGuiKeyModFlags_Alt)   != 0;
+    io.KeySuper = (g_KeyModifiers & ImGuiKeyModFlags_Super) != 0;
+}
+
 void ImGui_ImplOSX_NewFrame(NSView* view)
 {
     // Setup display size
@@ -409,28 +523,11 @@
     io.DeltaTime = (float)(current_time - g_Time);
     g_Time = current_time;
 
+    ImGui_ImplOSX_UpdateKeyModifiers();
     ImGui_ImplOSX_UpdateMouseCursorAndButtons();
     ImGui_ImplOSX_UpdateGamepads();
 }
 
-NSString* NSStringFromPhase(NSEventPhase phase)
-{
-    static NSString* strings[] =
-    {
-        @"none",
-        @"began",
-        @"stationary",
-        @"changed",
-        @"ended",
-        @"cancelled",
-        @"mayBegin",
-    };
-
-    int pos = phase == NSEventPhaseNone ? 0 : __builtin_ctzl((NSUInteger)phase) + 1;
-
-    return strings[pos];
-}
-
 bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
 {
     ImGuiIO& io = ImGui::GetIO();
@@ -497,8 +594,6 @@
             wheel_dy = [event deltaY];
         }
 
-        //NSLog(@"dx=%0.3ff, dy=%0.3f, phase=%@", wheel_dx, wheel_dy, NSStringFromPhase(event.phase));
-
         if (fabs(wheel_dx) > 0.0)
             io.MouseWheelH += (float)wheel_dx * 0.1f;
         if (fabs(wheel_dy) > 0.0)
@@ -508,35 +603,65 @@
 
     if (event.type == NSEventTypeKeyDown || event.type == NSEventTypeKeyUp)
     {
-        unsigned short code = event.keyCode;
-        IM_ASSERT(code >= 0 && code < IM_ARRAYSIZE(io.KeysDown));
-        io.KeysDown[code] = event.type == NSEventTypeKeyDown;
-        NSEventModifierFlags flags = event.modifierFlags;
-        io.KeyCtrl  = (flags & NSEventModifierFlagControl) != 0;
-        io.KeyShift = (flags & NSEventModifierFlagShift) != 0;
-        io.KeyAlt   = (flags & NSEventModifierFlagOption) != 0;
-        io.KeySuper = (flags & NSEventModifierFlagCommand) != 0;
+        if ([event isARepeat])
+            return io.WantCaptureKeyboard;
+
+        ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
+        io.AddKeyEvent(key, event.type == NSEventTypeKeyDown);
+        io.SetKeyEventNativeData(key, (int)[event keyCode], -1); // To support legacy indexing (<1.87 user code)
+
         return io.WantCaptureKeyboard;
     }
 
     if (event.type == NSEventTypeFlagsChanged)
     {
-        NSEventModifierFlags flags = event.modifierFlags;
-        switch (event.keyCode)
+        unsigned short key_code = [event keyCode];
+        unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
+
+        ImGuiKeyModFlags imgui_flags = ImGuiKeyModFlags_None;
+        if (flags & NSEventModifierFlagShift)
+            imgui_flags |= ImGuiKeyModFlags_Shift;
+        if (flags & NSEventModifierFlagControl)
+            imgui_flags |= ImGuiKeyModFlags_Ctrl;
+        if (flags & NSEventModifierFlagOption)
+            imgui_flags |= ImGuiKeyModFlags_Alt;
+        if (flags & NSEventModifierFlagCommand)
+            imgui_flags |= ImGuiKeyModFlags_Super;
+
+        g_KeyModifiers = imgui_flags;
+
+        ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
+        if (key != ImGuiKey_None)
         {
-        case kVK_Control:
-            io.KeyCtrl = (flags & NSEventModifierFlagControl) != 0;
-            break;
-        case kVK_Shift:
-            io.KeyShift = (flags & NSEventModifierFlagShift) != 0;
-            break;
-        case kVK_Option:
-            io.KeyAlt = (flags & NSEventModifierFlagOption) != 0;
-            break;
-        case kVK_Command:
-            io.KeySuper = (flags & NSEventModifierFlagCommand) != 0;
-            break;
+            // macOS does not generate down/up event for modifiers. We're trying
+            // to use hardware dependent masks to extract that information.
+            // 'imgui_mask' is left as a fallback.
+            NSEventModifierFlags mask = 0;
+            ImGuiKeyModFlags imgui_mask = ImGuiKeyModFlags_None;
+            switch (key_code)
+            {
+                case kVK_Control:      mask = 0x0001; imgui_mask = ImGuiKeyModFlags_Ctrl; break;
+                case kVK_RightControl: mask = 0x2000; imgui_mask = ImGuiKeyModFlags_Ctrl; break;
+                case kVK_Shift:        mask = 0x0002; imgui_mask = ImGuiKeyModFlags_Shift; break;
+                case kVK_RightShift:   mask = 0x0004; imgui_mask = ImGuiKeyModFlags_Shift; break;
+                case kVK_Command:      mask = 0x0008; imgui_mask = ImGuiKeyModFlags_Super; break;
+                case kVK_RightCommand: mask = 0x0010; imgui_mask = ImGuiKeyModFlags_Super; break;
+                case kVK_Option:       mask = 0x0020; imgui_mask = ImGuiKeyModFlags_Alt; break;
+                case kVK_RightOption:  mask = 0x0040; imgui_mask = ImGuiKeyModFlags_Alt; break;
+            }
+
+            if (mask)
+            {
+                NSEventModifierFlags modifier_flags = [event modifierFlags];
+                io.AddKeyEvent(key, (modifier_flags & mask) != 0);
+            }
+            else if (imgui_mask)
+            {
+                io.AddKeyEvent(key, (imgui_flags & imgui_mask) != 0);
+            }
+            io.SetKeyEventNativeData(key, keycode, -1); // To support legacy indexing (<1.87 user code)
         }
+
         return io.WantCaptureKeyboard;
     }
 
diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm
index bbe51d3..5c05fee 100644
--- a/examples/example_apple_metal/main.mm
+++ b/examples/example_apple_metal/main.mm
@@ -107,18 +107,6 @@
                                                                userInfo:nil];
     [self.view addTrackingArea:trackingArea];
 
-    // 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.
-    NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
-    [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
-    {
-        ImGui_ImplOSX_HandleEvent(event, self.view);
-        return event;
-    }];
-
     ImGui_ImplOSX_Init(self.view);
 
 #endif
@@ -223,8 +211,7 @@
 
 #if TARGET_OS_OSX
 
-// Forward Mouse/Keyboard events to Dear ImGui OSX backend.
-// Other events are registered via addLocalMonitorForEventsMatchingMask()
+// 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); }
diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm
index f859162..482a94f 100644
--- a/examples/example_apple_opengl2/main.mm
+++ b/examples/example_apple_opengl2/main.mm
@@ -36,15 +36,6 @@
 
 -(void)initialize
 {
-    // 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 = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
-    [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
-    {
-        ImGui_ImplOSX_HandleEvent(event, self);
-        return event;
-    }];
-
     // Setup Dear ImGui context
     // FIXME: This example doesn't have proper cleanup...
     IMGUI_CHECKVERSION();