Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS runtime warnings regarding access of NSView/NSWindow properties from a non-main thread #7393

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
49 changes: 46 additions & 3 deletions backends/imgui_impl_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@
NSTextInputContext* InputContext;
id Monitor;

ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
struct {
NSLock *lock;
CGFloat backingScaleFactor;
CGRect bounds;
} exclusive;

ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); @autoreleasepool {this->exclusive.lock = [[NSLock alloc] init]; } }
};

static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); }
Expand Down Expand Up @@ -389,8 +395,33 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) {
#endif



NSLock *ImGui_IO_lock;


@interface ScopedLock : NSObject
@property (strong) NSLock *lockptr;
@end

@implementation ScopedLock

- (id)init:(NSLock *)incoming
{
_lockptr = incoming;
[_lockptr lock];
return self;
}

- (void)dealloc {
[_lockptr unlock];
}
@end


bool ImGui_ImplOSX_Init(NSView* view)
{
ImGui_IO_lock = [[NSLock alloc] init];

ImGuiIO& io = ImGui::GetIO();
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData();
io.BackendPlatformUserData = (void*)bd;
Expand Down Expand Up @@ -605,8 +636,18 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
// Setup display size
if (view)
{
const float dpi = (float)[view.window backingScaleFactor];
io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height);
dispatch_async(dispatch_get_main_queue(), ^{
[bd->exclusive.lock lock];
bd->exclusive.backingScaleFactor = view.window.backingScaleFactor;
bd->exclusive.bounds = view.bounds;
[bd->exclusive.lock unlock];
});

[bd->exclusive.lock lock];
const float dpi = (float) bd->exclusive.backingScaleFactor;
io.DisplaySize = ImVec2((float) bd->exclusive.bounds.size.width, bd->exclusive.bounds.size.height);
[bd->exclusive.lock unlock];

io.DisplayFramebufferScale = ImVec2(dpi, dpi);
}

Expand Down Expand Up @@ -647,6 +688,8 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
{
ImGuiIO& io = ImGui::GetIO();

ScopedLock *sclock = [[ScopedLock alloc] init:ImGui_IO_lock];

if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
{
int button = (int)[event buttonNumber];
Expand Down