OSX: Multiple window support. Manual merge from PR #1563.

This commit is contained in:
Branimir Karadžić 2018-11-28 15:19:13 -08:00
parent 57e2e3d7e1
commit 610d503d97

View File

@ -58,7 +58,6 @@ namespace entry
bgfx::setPlatformData(pd); bgfx::setPlatformData(pd);
} }
static WindowHandle s_defaultWindow = { 0 };
static uint8_t s_translateKey[256]; static uint8_t s_translateKey[256];
struct MainThreadEntry struct MainThreadEntry
@ -94,7 +93,8 @@ namespace entry
struct Context struct Context
{ {
Context() Context()
: m_scrollf(0.0f) : m_windowsCreated(0)
, m_scrollf(0.0f)
, m_mx(0) , m_mx(0)
, m_my(0) , m_my(0)
, m_scroll(0) , m_scroll(0)
@ -173,10 +173,10 @@ namespace entry
]; ];
} }
void getMousePos(int32_t* outX, int32_t* outY) void getMousePos(NSWindow *window, int* outX, int* outY)
{ {
WindowHandle handle = { 0 }; //WindowHandle handle = { 0 };
NSWindow* window = m_window[handle.idx]; //NSWindow* window = m_window[handle.idx];
NSRect originalFrame = [window frame]; NSRect originalFrame = [window frame];
NSPoint location = [window mouseLocationOutsideOfEventStream]; NSPoint location = [window mouseLocationOutsideOfEventStream];
@ -258,14 +258,18 @@ namespace entry
{ {
NSEventType eventType = [event type]; NSEventType eventType = [event type];
// TODO: Get correct window
NSWindow *window = [NSApp keyWindow];
WindowHandle handle = handleFromWindow(window);
switch (eventType) switch (eventType)
{ {
case NSEventTypeMouseMoved: case NSEventTypeMouseMoved:
case NSEventTypeLeftMouseDragged: case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDragged: case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDragged: case NSEventTypeOtherMouseDragged:
getMousePos(&m_mx, &m_my); getMousePos(window, &m_mx, &m_my);
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll);
break; break;
case NSEventTypeLeftMouseDown: case NSEventTypeLeftMouseDown:
@ -276,36 +280,36 @@ namespace entry
? MouseButton::Middle ? MouseButton::Middle
: MouseButton::Left : MouseButton::Left
; ;
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, mb, true); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, mb, true);
} }
break; break;
case NSEventTypeLeftMouseUp: case NSEventTypeLeftMouseUp:
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Left, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Left, false);
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Middle, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Middle, false);
break; break;
case NSEventTypeRightMouseDown: case NSEventTypeRightMouseDown:
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Right, true); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Right, true);
break; break;
case NSEventTypeRightMouseUp: case NSEventTypeRightMouseUp:
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Right, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Right, false);
break; break;
case NSEventTypeOtherMouseDown: case NSEventTypeOtherMouseDown:
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Middle, true); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Middle, true);
break; break;
case NSEventTypeOtherMouseUp: case NSEventTypeOtherMouseUp:
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Middle, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Middle, false);
break; break;
case NSEventTypeScrollWheel: case NSEventTypeScrollWheel:
m_scrollf += [event deltaY]; m_scrollf += [event deltaY];
m_scroll = (int32_t)m_scrollf; m_scroll = (int32_t)m_scrollf;
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll);
break; break;
case NSEventTypeKeyDown: case NSEventTypeKeyDown:
@ -324,8 +328,8 @@ namespace entry
else else
{ {
enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift }; enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift };
m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar); m_eventQueue.postCharEvent(handle, 1, pressedChar);
m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true); m_eventQueue.postKeyEvent(handle, key, modifiers, true);
return false; return false;
} }
} }
@ -342,7 +346,7 @@ namespace entry
if (key != Key::None) if (key != Key::None)
{ {
m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, false); m_eventQueue.postKeyEvent(handle, key, modifiers, false);
return false; return false;
} }
@ -362,10 +366,9 @@ namespace entry
return false; return false;
} }
void windowDidResize() void windowDidResize(NSWindow *window)
{ {
WindowHandle handle = { 0 }; WindowHandle handle = handleFromWindow(window);
NSWindow* window = m_window[handle.idx];
NSRect originalFrame = [window frame]; NSRect originalFrame = [window frame];
NSRect rect = [window contentRectForFrameRect: originalFrame]; NSRect rect = [window contentRectForFrameRect: originalFrame];
uint32_t width = uint32_t(rect.size.width); uint32_t width = uint32_t(rect.size.width);
@ -373,20 +376,22 @@ namespace entry
m_eventQueue.postSizeEvent(handle, width, height); m_eventQueue.postSizeEvent(handle, width, height);
// Make sure mouse button state is 'up' after resize. // Make sure mouse button state is 'up' after resize.
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Left, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Left, false);
m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, MouseButton::Right, false); m_eventQueue.postMouseEvent(handle, m_mx, m_my, m_scroll, MouseButton::Right, false);
} }
void windowDidBecomeKey() void windowDidBecomeKey(NSWindow *window)
{ {
m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume); WindowHandle handle = handleFromWindow(window);
m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume); m_eventQueue.postSuspendEvent(handle, Suspend::WillResume);
m_eventQueue.postSuspendEvent(handle, Suspend::DidResume);
} }
void windowDidResignKey() void windowDidResignKey(NSWindow *window)
{ {
m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend); WindowHandle handle = handleFromWindow(window);
m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend); m_eventQueue.postSuspendEvent(handle, Suspend::WillSuspend);
m_eventQueue.postSuspendEvent(handle, Suspend::DidSuspend);
} }
int32_t run(int _argc, const char* const* _argv) int32_t run(int _argc, const char* const* _argv)
@ -433,25 +438,12 @@ namespace entry
NSRect screenRect = [[NSScreen mainScreen] frame]; NSRect screenRect = [[NSScreen mainScreen] frame];
const float centerX = (screenRect.size.width - (float)ENTRY_DEFAULT_WIDTH )*0.5f; const float centerX = (screenRect.size.width - (float)ENTRY_DEFAULT_WIDTH )*0.5f;
const float centerY = (screenRect.size.height - (float)ENTRY_DEFAULT_HEIGHT)*0.5f; const float centerY = (screenRect.size.height - (float)ENTRY_DEFAULT_HEIGHT)*0.5f;
m_windowAlloc.alloc();
NSRect rect = NSMakeRect(centerX, centerY, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
NSWindow* window = [[NSWindow alloc]
initWithContentRect:rect
styleMask:m_style
backing:NSBackingStoreBuffered defer:NO
];
NSString* appName = [[NSProcessInfo processInfo] processName]; NSString* appName = [[NSProcessInfo processInfo] processName];
[window setTitle:appName]; createWindow(centerX, centerY, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, ENTRY_WINDOW_FLAG_NONE, [appName UTF8String]);
[window makeKeyAndOrderFront:window];
[window setAcceptsMouseMovedEvents:YES];
[window setBackgroundColor:[NSColor blackColor]];
[[Window sharedDelegate] windowCreated:window];
m_window[0] = window; m_windowFrame = [m_window[0] frame];
m_windowFrame = [window frame];
osxSetNSWindow(window); osxSetNSWindow(m_window[0]);
MainThreadEntry mte; MainThreadEntry mte;
mte.m_argc = _argc; mte.m_argc = _argc;
@ -461,7 +453,7 @@ namespace entry
thread.init(mte.threadFunc, &mte); thread.init(mte.threadFunc, &mte);
WindowHandle handle = { 0 }; WindowHandle handle = { 0 };
NSRect contentRect = [window contentRectForFrameRect: m_windowFrame]; NSRect contentRect = [m_window[0] contentRectForFrameRect: m_windowFrame];
uint32_t width = uint32_t(contentRect.size.width); uint32_t width = uint32_t(contentRect.size.width);
uint32_t height = uint32_t(contentRect.size.height); uint32_t height = uint32_t(contentRect.size.height);
m_eventQueue.postSizeEvent(handle, width, height); m_eventQueue.postSizeEvent(handle, width, height);
@ -491,10 +483,26 @@ namespace entry
return m_windowAlloc.isValid(_handle.idx); return m_windowAlloc.isValid(_handle.idx);
} }
WindowHandle handleFromWindow(NSWindow *window)
{
uint16_t windowIdx = 0;
for (uint16_t i = 0; i < m_windowsCreated; i++)
{
if (window == m_window[i])
{
windowIdx = i;
break;
}
}
WindowHandle handle = { windowIdx };
return handle;
}
EventQueue m_eventQueue; EventQueue m_eventQueue;
bx::HandleAllocT<ENTRY_CONFIG_MAX_WINDOWS> m_windowAlloc; bx::HandleAllocT<ENTRY_CONFIG_MAX_WINDOWS> m_windowAlloc;
NSWindow* m_window[ENTRY_CONFIG_MAX_WINDOWS]; NSWindow* m_window[ENTRY_CONFIG_MAX_WINDOWS];
SInt32 m_windowsCreated;
NSRect m_windowFrame; NSRect m_windowFrame;
float m_scrollf; float m_scrollf;
@ -525,8 +533,50 @@ namespace entry
WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title) WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
{ {
BX_UNUSED(_x, _y, _width, _height, _flags, _title); BX_UNUSED(_flags);
WindowHandle handle = { UINT16_MAX };
uint16_t handleIdx = IncrementAtomic(&s_ctx.m_windowsCreated);
if (handleIdx >= ENTRY_CONFIG_MAX_WINDOWS)
{
return { UINT16_MAX };
}
WindowHandle handle = { handleIdx };
void (^createWindowBlock)(void) = ^(void) {
s_ctx.m_windowAlloc.alloc();
NSRect rect = NSMakeRect(_x, _y, _width, _height);
NSWindow* window = [[NSWindow alloc]
initWithContentRect:rect
styleMask:s_ctx.m_style
backing:NSBackingStoreBuffered defer:NO
];
NSString* appName = [NSString stringWithUTF8String:_title];
[window setTitle:appName];
[window makeKeyAndOrderFront:window];
[window setAcceptsMouseMovedEvents:YES];
[window setBackgroundColor:[NSColor blackColor]];
[[Window sharedDelegate] windowCreated:window];
s_ctx.m_window[handleIdx] = window;
if(s_ctx.m_windowsCreated > 1)
{
s_ctx.m_eventQueue.postSizeEvent(handle, _width, _height);
s_ctx.m_eventQueue.postWindowEvent(handle, window);
}
};
if ([NSThread isMainThread])
{
createWindowBlock();
}
else
{
dispatch_async(dispatch_get_main_queue(), createWindowBlock);
}
return handle; return handle;
} }
@ -722,23 +772,23 @@ namespace entry
- (void)windowDidResize:(NSNotification*)notification - (void)windowDidResize:(NSNotification*)notification
{ {
BX_UNUSED(notification); NSWindow *window = [notification object];
using namespace entry; using namespace entry;
s_ctx.windowDidResize(); s_ctx.windowDidResize(window);
} }
- (void)windowDidBecomeKey:(NSNotification*)notification - (void)windowDidBecomeKey:(NSNotification*)notification
{ {
BX_UNUSED(notification); NSWindow *window = [notification object];
using namespace entry; using namespace entry;
s_ctx.windowDidBecomeKey(); s_ctx.windowDidBecomeKey(window);
} }
- (void)windowDidResignKey:(NSNotification*)notification - (void)windowDidResignKey:(NSNotification*)notification
{ {
BX_UNUSED(notification); NSWindow *window = [notification object];
using namespace entry; using namespace entry;
s_ctx.windowDidResignKey(); s_ctx.windowDidResignKey(window);
} }
@end @end