Skip to content

Commit

Permalink
Backends: OSX: Fix keys remaining stuck in pressed state when CMD-tab…
Browse files Browse the repository at this point in the history
…bing to a different application. (ocornut#3832)
  • Loading branch information
rokups committed Apr 19, 2021
1 parent 936f532 commit 733c4f5
Showing 1 changed file with 51 additions and 20 deletions.
71 changes: 51 additions & 20 deletions backends/imgui_impl_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-04-19: Inputs: Added a fix for keys remaining stuck in pressed state when CMD-tabbing into different application.
// 2021-01-27: Inputs: Added a fix for mouse position not being reported when mouse buttons other than left one are down.
// 2020-10-28: Inputs: Added a fix for handling keypad-enter key.
// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap".
Expand All @@ -30,12 +31,15 @@
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-07-07: Initial version.

@class ImFocusObserver;

// Data
static CFAbsoluteTime g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_MouseCursorHidden = false;
static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
static ImFocusObserver* g_FocusObserver = NULL;

// Undocumented methods for creating cursors.
@interface NSCursor()
Expand All @@ -45,6 +49,46 @@ + (id)_windowResizeNorthSouthCursor;
+ (id)_windowResizeEastWestCursor;
@end

// Utility functions
static int mapCharacterToKey(int c)
{
if (c >= 'a' && c <= 'z')
return c - 'a' + 'A';
if (c == 25) // SHIFT+TAB -> TAB
return 9;
if (c >= 0 && c < 256)
return c;
if (c >= 0xF700 && c < 0xF700 + 256)
return c - 0xF700 + 256;
return -1;
}

static void resetKeys()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.KeysDown, 0, sizeof(io.KeysDown));
io.KeyCtrl = io.KeyShift = io.KeyAlt = io.KeySuper = false;
}


@interface ImFocusObserver : NSObject

- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;

@end

@implementation ImFocusObserver

- (void)onApplicationBecomeInactive:(NSNotification*)aNotification
{
// 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
bool ImGui_ImplOSX_Init()
{
Expand Down Expand Up @@ -122,12 +166,19 @@ bool ImGui_ImplOSX_Init()
strcpy(s_clipboard.Data, string_c);
return s_clipboard.Data;
};

g_FocusObserver = [[ImFocusObserver alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver
selector:@selector(onApplicationBecomeInactive:)
name:NSApplicationDidResignActiveNotification
object:nil];

return true;
}

void ImGui_ImplOSX_Shutdown()
{
g_FocusObserver = NULL;
}

static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
Expand Down Expand Up @@ -187,26 +238,6 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
ImGui_ImplOSX_UpdateMouseCursorAndButtons();
}

static int mapCharacterToKey(int c)
{
if (c >= 'a' && c <= 'z')
return c - 'a' + 'A';
if (c == 25) // SHIFT+TAB -> TAB
return 9;
if (c >= 0 && c < 256)
return c;
if (c >= 0xF700 && c < 0xF700 + 256)
return c - 0xF700 + 256;
return -1;
}

static void resetKeys()
{
ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < IM_ARRAYSIZE(io.KeysDown); n++)
io.KeysDown[n] = false;
}

bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
{
ImGuiIO& io = ImGui::GetIO();
Expand Down

0 comments on commit 733c4f5

Please sign in to comment.