From 6f2ea0def2624a2521733c3b9dcc1f91e79d6914 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Sat, 7 Sep 2019 00:11:27 +0800 Subject: [PATCH 01/42] Implement Multi-Viewports on macOS --- examples/example_apple_opengl2/main.mm | 27 ++- examples/imgui_impl_osx.h | 3 +- examples/imgui_impl_osx.mm | 317 ++++++++++++++++++++++++- 3 files changed, 333 insertions(+), 14 deletions(-) diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index b5442ec48a54..6544f67f21a1 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -103,6 +103,14 @@ -(void)updateAndDrawDemoView // Present [[self openGLContext] flushBuffer]; + // Update and Render additional Platform Windows + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + if (!animationTimer) animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES]; } @@ -158,7 +166,7 @@ -(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self) // ImGuiExampleAppDelegate //----------------------------------------------------------------------------------- -@interface ImGuiExampleAppDelegate : NSObject +@interface ImGuiExampleAppDelegate : NSObject @property (nonatomic, readonly) NSWindow* window; @end @@ -181,10 +189,16 @@ -(NSWindow*)window [_window setTitle:@"Dear ImGui OSX+OpenGL2 Example"]; [_window setOpaque:YES]; [_window makeKeyAndOrderFront:NSApp]; + [_window setDelegate:self]; return (_window); } +-(void)windowWillClose:(NSNotification *)notification +{ + [NSApp terminate:self]; +} + -(void)setupMenu { NSMenu* mainMenuBar = [[NSMenu alloc] init]; @@ -242,14 +256,16 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings - ImGui_ImplOSX_Init(); + ImGui_ImplOSX_Init(self.window); ImGui_ImplOpenGL2_Init(); // Load Fonts @@ -268,6 +284,13 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification //IM_ASSERT(font != NULL); } +-(void)applicationWillTerminate:(NSNotification *)notification; +{ + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplOSX_Shutdown(); + ImGui::DestroyContext(); +} + @end int main(int argc, const char* argv[]) diff --git a/examples/imgui_impl_osx.h b/examples/imgui_impl_osx.h index 54e86157b728..eb202b7b885c 100644 --- a/examples/imgui_impl_osx.h +++ b/examples/imgui_impl_osx.h @@ -11,8 +11,9 @@ @class NSEvent; @class NSView; +@class NSWindow; -IMGUI_API bool ImGui_ImplOSX_Init(); +IMGUI_API bool ImGui_ImplOSX_Init(NSWindow *_Nonnull window); IMGUI_API void ImGui_ImplOSX_Shutdown(); IMGUI_API void ImGui_ImplOSX_NewFrame(NSView *_Nonnull view); IMGUI_API bool ImGui_ImplOSX_HandleEvent(NSEvent *_Nonnull event, NSView *_Nullable view); diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index ab667d98ed6b..e3f94b7d72f1 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -23,9 +23,16 @@ // 2018-07-07: Initial version. // Data -static CFAbsoluteTime g_Time = 0.0; -static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; -static bool g_MouseCursorHidden = false; +static NSWindow* g_Window = nil; +static CFAbsoluteTime g_Time = 0.0; +static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; +static bool g_MouseCursorHidden = false; +static bool g_WantUpdateMonitors = true; + +// Forward Declarations +static void ImGui_ImplOSX_InitPlatformInterface(); +static void ImGui_ImplOSX_ShutdownPlatformInterface(); +static void ImGui_ImplOSX_UpdateMonitors(); // Undocumented methods for creating cursors. @interface NSCursor() @@ -36,17 +43,24 @@ + (id)_windowResizeEastWestCursor; @end // Functions -bool ImGui_ImplOSX_Init() +bool ImGui_ImplOSX_Init(NSWindow* window) { ImGuiIO& io = ImGui::GetIO(); // Setup back-end capabilities flags io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - //io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy) io.BackendPlatformName = "imgui_impl_osx"; + // Our mouse update function expect PlatformHandle to be filled for the main viewport + g_Window = window; + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)g_Window; + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplOSX_InitPlatformInterface(); + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. const int offset_for_function_keys = 256 - 0xF700; io.KeyMap[ImGuiKey_Tab] = '\t'; @@ -117,6 +131,8 @@ bool ImGui_ImplOSX_Init() void ImGui_ImplOSX_Shutdown() { + ImGui_ImplOSX_ShutdownPlatformInterface(); + g_Window = nil; } static void ImGui_ImplOSX_UpdateMouseCursor() @@ -151,9 +167,10 @@ void ImGui_ImplOSX_NewFrame(NSView* view) { // Setup display size ImGuiIO& io = ImGui::GetIO(); - const float dpi = [view.window backingScaleFactor]; - io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height); - io.DisplayFramebufferScale = ImVec2(dpi, dpi); + NSSize size = [view convertRectToBacking:[view bounds]].size; + io.DisplaySize = ImVec2(size.width, size.height); + if (g_WantUpdateMonitors) + ImGui_ImplOSX_UpdateMonitors(); // Setup time step if (g_Time == 0.0) @@ -207,9 +224,21 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged) { - NSPoint mousePoint = event.locationInWindow; - mousePoint = [view convertPoint:mousePoint fromView:nil]; - mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y); + NSSize size; + NSPoint mousePoint; + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + NSScreen* screen = [[view window] screen]; + size = [screen convertRectToBacking:[screen frame]].size; + mousePoint = [NSEvent mouseLocation]; + } + else + { + size = [view convertRectToBacking:[view bounds]].size; + mousePoint = event.locationInWindow; + } + mousePoint = [view convertPointToBacking:mousePoint]; + mousePoint = NSMakePoint(mousePoint.x, size.height - mousePoint.y); io.MousePos = ImVec2(mousePoint.x, mousePoint.y); } @@ -300,3 +329,269 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) return false; } + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +struct ImGuiViewportDataOSX +{ + NSWindow* window; + bool windowOwned; + + ImGuiViewportDataOSX() { windowOwned = false; } + ~ImGuiViewportDataOSX() { IM_ASSERT(window == nil); } +}; + +@interface ImGui_ImplOSX_View : NSOpenGLView +@end + +@implementation ImGui_ImplOSX_View +-(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +@end + +static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)(); + viewport->PlatformUserData = data; + + NSScreen* screen = [g_Window screen]; + NSSize size = [screen convertRectToBacking:[screen frame]].size; + NSRect rect = NSMakeRect(viewport->Pos.x, size.height - viewport->Pos.y - viewport->Size.y, viewport->Size.x, viewport->Size.y); + rect = [screen convertRectFromBacking:rect]; + + NSWindow* window = [[NSWindow alloc] initWithContentRect:rect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]; + [window setTitle:@"Untitled"]; + [window setAcceptsMouseMovedEvents:YES]; + [window setOpaque:NO]; + [window orderFront:NSApp]; + [window setLevel:NSFloatingWindowLevel]; + + ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:window.frame]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [view setWantsBestResolutionOpenGLSurface:YES]; +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + [window setContentView:view]; + + data->window = window; + data->windowOwned = true; + viewport->PlatformRequestResize = false; + viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window; +} + +static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) +{ + NSWindow* window = (__bridge_transfer NSWindow*)viewport->PlatformHandleRaw; + window = nil; + + if (ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData) + { + NSWindow* window = data->window; + if (window != nil && data->windowOwned) + { + [window setContentView:nil]; + [window orderOut:nil]; + } + data->window = nil; + IM_DELETE(data); + } + viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = NULL; +} + +static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != nil); +} + +static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) +{ +} + +static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + NSWindow* window = data->window; + NSScreen* screen = [window screen]; + NSSize size = [screen convertRectToBacking:[screen frame]].size; + NSRect frame = [window convertRectToBacking:[window frame]]; + NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; + return ImVec2(frame.origin.x, size.height - frame.origin.y - rect.size.height); +} + +static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + NSWindow* window = data->window; + NSScreen* screen = [window screen]; + NSSize size = [screen convertRectToBacking:[screen frame]].size; + NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; + NSRect origin = NSMakeRect(0, 0, pos.x, size.height - pos.y - rect.size.height); + origin = [window convertRectFromBacking:origin]; + [window setFrameOrigin:origin.origin]; +} + +static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + NSWindow* window = data->window; + NSSize size = [window convertRectToBacking:[window contentLayoutRect]].size; + return ImVec2(size.width, size.width); +} + +static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + NSWindow* window = data->window; + NSRect rect = [window convertRectToBacking:[window frame]]; + rect.origin.y -= (size.y - rect.size.height); + rect.size.width = size.x; + rect.size.height = size.y; + rect = [window convertRectFromBacking:rect]; + [window setFrame:rect display:YES]; +} + +static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + [data->window orderFront:NSApp]; +} + +static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + return [NSApp orderedWindows].firstObject == data->window; +} + +static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + return [data->window isMiniaturized]; +} + +static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + [data->window setTitle:[NSString stringWithUTF8String:title]]; +} + +static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f); + + [data->window setAlphaValue:alpha]; +} + +static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport) +{ + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->window != 0); + + return [data->window backingScaleFactor]; +} + +// FIXME-DPI: Testing DPI related ideas +static void ImGui_ImplOSX_OnChangedViewport(ImGuiViewport* viewport) +{ + (void)viewport; +#if 0 + ImGuiStyle default_style; + //default_style.WindowPadding = ImVec2(0, 0); + //default_style.WindowBorderSize = 0.0f; + //default_style.ItemSpacing.y = 3.0f; + //default_style.FramePadding = ImVec2(0, 0); + default_style.ScaleAllSizes(viewport->DpiScale); + ImGuiStyle& style = ImGui::GetStyle(); + style = default_style; +#endif +} + +static void ImGui_ImplOSX_UpdateMonitors() +{ + ImGui::GetPlatformIO().Monitors.resize(0); + + NSArray* array = [NSScreen screens]; + for (NSUInteger i = 0; i < array.count; ++i) + { + NSScreen* screen = array[i]; + NSRect frame = [screen convertRectToBacking:[screen frame]]; + NSRect visibleFrame = [screen convertRectToBacking:[screen visibleFrame]]; + + ImGuiPlatformMonitor imgui_monitor; + imgui_monitor.MainPos = ImVec2(frame.origin.x, frame.origin.y); + imgui_monitor.MainSize = ImVec2(frame.size.width, frame.size.height); + imgui_monitor.WorkPos = ImVec2(visibleFrame.origin.x, visibleFrame.origin.y); + imgui_monitor.WorkSize = ImVec2(visibleFrame.size.width, visibleFrame.size.height); + imgui_monitor.DpiScale = [screen backingScaleFactor]; + + ImGuiPlatformIO& io = ImGui::GetPlatformIO(); + io.Monitors.push_back(imgui_monitor); + } + + g_WantUpdateMonitors = false; +} + +static void ImGui_ImplOSX_InitPlatformInterface() +{ + ImGui_ImplOSX_UpdateMonitors(); + + // Register platform interface (will be coupled with a renderer interface) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Platform_CreateWindow = ImGui_ImplOSX_CreateWindow; + platform_io.Platform_DestroyWindow = ImGui_ImplOSX_DestroyWindow; + platform_io.Platform_ShowWindow = ImGui_ImplOSX_ShowWindow; + platform_io.Platform_SetWindowPos = ImGui_ImplOSX_SetWindowPos; + platform_io.Platform_GetWindowPos = ImGui_ImplOSX_GetWindowPos; + platform_io.Platform_SetWindowSize = ImGui_ImplOSX_SetWindowSize; + platform_io.Platform_GetWindowSize = ImGui_ImplOSX_GetWindowSize; + platform_io.Platform_SetWindowFocus = ImGui_ImplOSX_SetWindowFocus; + platform_io.Platform_GetWindowFocus = ImGui_ImplOSX_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplOSX_GetWindowMinimized; + platform_io.Platform_SetWindowTitle = ImGui_ImplOSX_SetWindowTitle; + platform_io.Platform_SetWindowAlpha = ImGui_ImplOSX_SetWindowAlpha; + platform_io.Platform_UpdateWindow = ImGui_ImplOSX_UpdateWindow; + platform_io.Platform_GetWindowDpiScale = ImGui_ImplOSX_GetWindowDpiScale; // FIXME-DPI + platform_io.Platform_OnChangedViewport = ImGui_ImplOSX_OnChangedViewport; // FIXME-DPI + + // Register main window handle (which is owned by the main application, not by us) + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)(); + data->window = g_Window; + data->windowOwned = false; + main_viewport->PlatformUserData = data; + main_viewport->PlatformHandle = (__bridge void*)g_Window; +} + +static void ImGui_ImplOSX_ShutdownPlatformInterface() +{ + +} + From cbe0446481ddbfa7583ee80683f0e0901d61260b Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Sat, 7 Sep 2019 00:30:49 +0800 Subject: [PATCH 02/42] Fix wrong parameter --- examples/imgui_impl_osx.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index e3f94b7d72f1..632dc7b5e56d 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -440,7 +440,7 @@ static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) NSScreen* screen = [window screen]; NSSize size = [screen convertRectToBacking:[screen frame]].size; NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; - NSRect origin = NSMakeRect(0, 0, pos.x, size.height - pos.y - rect.size.height); + NSRect origin = NSMakeRect(pos.x, size.height - pos.y - rect.size.height, 0, 0); origin = [window convertRectFromBacking:origin]; [window setFrameOrigin:origin.origin]; } From bd865c95131e7c9c56bfc1a8dea01bd5dd40fb32 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Sat, 7 Sep 2019 02:20:39 +0800 Subject: [PATCH 03/42] Fix compile error --- examples/example_apple_metal/Shared/ViewController.mm | 2 +- examples/example_apple_opengl2/main.mm | 2 +- examples/imgui_impl_osx.h | 3 +-- examples/imgui_impl_osx.mm | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 73040addecb4..3afe3fdb8263 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -58,7 +58,7 @@ - (void)viewDidLoad }]; - ImGui_ImplOSX_Init(); + ImGui_ImplOSX_Init(self.view); #endif } diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 6544f67f21a1..2aa541539eba 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -265,7 +265,7 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings - ImGui_ImplOSX_Init(self.window); + ImGui_ImplOSX_Init(view); ImGui_ImplOpenGL2_Init(); // Load Fonts diff --git a/examples/imgui_impl_osx.h b/examples/imgui_impl_osx.h index eb202b7b885c..bd26fa3aceea 100644 --- a/examples/imgui_impl_osx.h +++ b/examples/imgui_impl_osx.h @@ -11,9 +11,8 @@ @class NSEvent; @class NSView; -@class NSWindow; -IMGUI_API bool ImGui_ImplOSX_Init(NSWindow *_Nonnull window); +IMGUI_API bool ImGui_ImplOSX_Init(NSView *_Nonnull view); IMGUI_API void ImGui_ImplOSX_Shutdown(); IMGUI_API void ImGui_ImplOSX_NewFrame(NSView *_Nonnull view); IMGUI_API bool ImGui_ImplOSX_HandleEvent(NSEvent *_Nonnull event, NSView *_Nullable view); diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 632dc7b5e56d..1d2dd242ce27 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -43,7 +43,7 @@ + (id)_windowResizeEastWestCursor; @end // Functions -bool ImGui_ImplOSX_Init(NSWindow* window) +bool ImGui_ImplOSX_Init(NSView* view) { ImGuiIO& io = ImGui::GetIO(); @@ -55,7 +55,7 @@ bool ImGui_ImplOSX_Init(NSWindow* window) io.BackendPlatformName = "imgui_impl_osx"; // Our mouse update function expect PlatformHandle to be filled for the main viewport - g_Window = window; + g_Window = [view window]; ImGuiViewport* main_viewport = ImGui::GetMainViewport(); main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)g_Window; if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) From d997eefc81b98b38f6ef6829aae3c65bcdef8622 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Wed, 18 Sep 2019 01:40:31 +0800 Subject: [PATCH 04/42] Rename window -> Window --- .../example_apple_metal/Shared/Renderer.mm | 27 ++++++++ .../Shared/ViewController.mm | 2 - examples/example_apple_opengl2/main.mm | 3 + examples/imgui_impl_osx.mm | 64 +++++++++---------- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/examples/example_apple_metal/Shared/Renderer.mm b/examples/example_apple_metal/Shared/Renderer.mm index efc3332bf90a..a1d99adc7e27 100644 --- a/examples/example_apple_metal/Shared/Renderer.mm +++ b/examples/example_apple_metal/Shared/Renderer.mm @@ -25,9 +25,29 @@ -(nonnull instancetype)initWithView:(nonnull MTKView *)view; IMGUI_CHECKVERSION(); ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + + // Setup Dear ImGui style ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer bindings ImGui_ImplMetal_Init(_device); +#if TARGET_OS_OSX + ImGui_ImplOSX_Init(view); +#endif } return self; @@ -120,6 +140,13 @@ - (void)drawInMTKView:(MTKView *)view } [commandBuffer commit]; + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } } - (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 3afe3fdb8263..17aae6873c43 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -57,8 +57,6 @@ - (void)viewDidLoad } }]; - - ImGui_ImplOSX_Init(self.view); #endif } diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 2aa541539eba..2ee1a23a9b3b 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -158,6 +158,8 @@ -(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self) -(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } @end @@ -190,6 +192,7 @@ -(NSWindow*)window [_window setOpaque:YES]; [_window makeKeyAndOrderFront:NSApp]; [_window setDelegate:self]; + [_window setAcceptsMouseMovedEvents:YES]; return (_window); } diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 1d2dd242ce27..4579e09ee43b 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -338,11 +338,11 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) struct ImGuiViewportDataOSX { - NSWindow* window; - bool windowOwned; + NSWindow* Window; + bool WindowOwned; - ImGuiViewportDataOSX() { windowOwned = false; } - ~ImGuiViewportDataOSX() { IM_ASSERT(window == nil); } + ImGuiViewportDataOSX() { WindowOwned = false; } + ~ImGuiViewportDataOSX() { IM_ASSERT(Window == nil); } }; @interface ImGui_ImplOSX_View : NSOpenGLView @@ -383,8 +383,8 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 [window setContentView:view]; - data->window = window; - data->windowOwned = true; + data->Window = window; + data->WindowOwned = true; viewport->PlatformRequestResize = false; viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window; } @@ -396,13 +396,13 @@ static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) if (ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData) { - NSWindow* window = data->window; - if (window != nil && data->windowOwned) + NSWindow* window = data->Window; + if (window != nil && data->WindowOwned) { [window setContentView:nil]; [window orderOut:nil]; } - data->window = nil; + data->Window = nil; IM_DELETE(data); } viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = NULL; @@ -411,7 +411,7 @@ static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != nil); + IM_ASSERT(data->Window != nil); } static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) @@ -421,9 +421,9 @@ static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - NSWindow* window = data->window; + NSWindow* window = data->Window; NSScreen* screen = [window screen]; NSSize size = [screen convertRectToBacking:[screen frame]].size; NSRect frame = [window convertRectToBacking:[window frame]]; @@ -434,9 +434,9 @@ static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - NSWindow* window = data->window; + NSWindow* window = data->Window; NSScreen* screen = [window screen]; NSSize size = [screen convertRectToBacking:[screen frame]].size; NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; @@ -448,9 +448,9 @@ static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - NSWindow* window = data->window; + NSWindow* window = data->Window; NSSize size = [window convertRectToBacking:[window contentLayoutRect]].size; return ImVec2(size.width, size.width); } @@ -458,9 +458,9 @@ static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport) static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - NSWindow* window = data->window; + NSWindow* window = data->Window; NSRect rect = [window convertRectToBacking:[window frame]]; rect.origin.y -= (size.y - rect.size.height); rect.size.width = size.x; @@ -472,50 +472,50 @@ static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - [data->window orderFront:NSApp]; + [data->Window orderFront:NSApp]; } static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - return [NSApp orderedWindows].firstObject == data->window; + return [NSApp orderedWindows].firstObject == data->Window; } static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - return [data->window isMiniaturized]; + return [data->Window isMiniaturized]; } static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - [data->window setTitle:[NSString stringWithUTF8String:title]]; + [data->Window setTitle:[NSString stringWithUTF8String:title]]; } static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f); - [data->window setAlphaValue:alpha]; + [data->Window setAlphaValue:alpha]; } static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; - IM_ASSERT(data->window != 0); + IM_ASSERT(data->Window != 0); - return [data->window backingScaleFactor]; + return [data->Window backingScaleFactor]; } // FIXME-DPI: Testing DPI related ideas @@ -584,8 +584,8 @@ static void ImGui_ImplOSX_InitPlatformInterface() // Register main window handle (which is owned by the main application, not by us) ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)(); - data->window = g_Window; - data->windowOwned = false; + data->Window = g_Window; + data->WindowOwned = false; main_viewport->PlatformUserData = data; main_viewport->PlatformHandle = (__bridge void*)g_Window; } From d75bea290ec799449f37620ecaf1862455269be7 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Wed, 18 Sep 2019 01:41:17 +0800 Subject: [PATCH 05/42] Revert fix mouse position --- examples/imgui_impl_osx.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 4579e09ee43b..cbdfcf885320 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -167,8 +167,10 @@ void ImGui_ImplOSX_NewFrame(NSView* view) { // Setup display size ImGuiIO& io = ImGui::GetIO(); - NSSize size = [view convertRectToBacking:[view bounds]].size; + NSSize size = [view bounds].size; + NSSize scale = [view convertSizeToBacking:NSMakeSize(1, 1)]; io.DisplaySize = ImVec2(size.width, size.height); + io.DisplayFramebufferScale = ImVec2(scale.width, scale.height); if (g_WantUpdateMonitors) ImGui_ImplOSX_UpdateMonitors(); @@ -229,15 +231,14 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { NSScreen* screen = [[view window] screen]; - size = [screen convertRectToBacking:[screen frame]].size; + size = [screen frame].size; mousePoint = [NSEvent mouseLocation]; } else { - size = [view convertRectToBacking:[view bounds]].size; + size = [view bounds].size; mousePoint = event.locationInWindow; } - mousePoint = [view convertPointToBacking:mousePoint]; mousePoint = NSMakePoint(mousePoint.x, size.height - mousePoint.y); io.MousePos = ImVec2(mousePoint.x, mousePoint.y); } From 7567dd0fcfe7b5463a837b1f541ecf85c4676242 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Wed, 18 Sep 2019 02:23:04 +0800 Subject: [PATCH 06/42] Fix NSWindow not found --- examples/imgui_impl_osx.mm | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index cbdfcf885320..0b9f1b94b5c8 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -56,6 +56,10 @@ bool ImGui_ImplOSX_Init(NSView* view) // Our mouse update function expect PlatformHandle to be filled for the main viewport g_Window = [view window]; + if (g_Window == nil) + { + g_Window = [NSApp orderedWindows].firstObject; + } ImGuiViewport* main_viewport = ImGui::GetMainViewport(); main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)g_Window; if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) @@ -366,9 +370,8 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) viewport->PlatformUserData = data; NSScreen* screen = [g_Window screen]; - NSSize size = [screen convertRectToBacking:[screen frame]].size; + NSSize size = [screen frame].size; NSRect rect = NSMakeRect(viewport->Pos.x, size.height - viewport->Pos.y - viewport->Size.y, viewport->Size.x, viewport->Size.y); - rect = [screen convertRectFromBacking:rect]; NSWindow* window = [[NSWindow alloc] initWithContentRect:rect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]; [window setTitle:@"Untitled"]; @@ -426,9 +429,9 @@ static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) NSWindow* window = data->Window; NSScreen* screen = [window screen]; - NSSize size = [screen convertRectToBacking:[screen frame]].size; - NSRect frame = [window convertRectToBacking:[window frame]]; - NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; + NSSize size = [screen frame].size; + NSRect frame = [window frame]; + NSRect rect = [window contentLayoutRect]; return ImVec2(frame.origin.x, size.height - frame.origin.y - rect.size.height); } @@ -439,10 +442,9 @@ static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) NSWindow* window = data->Window; NSScreen* screen = [window screen]; - NSSize size = [screen convertRectToBacking:[screen frame]].size; - NSRect rect = [window convertRectToBacking:[window contentLayoutRect]]; + NSSize size = [screen frame].size; + NSRect rect = [window contentLayoutRect]; NSRect origin = NSMakeRect(pos.x, size.height - pos.y - rect.size.height, 0, 0); - origin = [window convertRectFromBacking:origin]; [window setFrameOrigin:origin.origin]; } @@ -452,7 +454,7 @@ static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport) IM_ASSERT(data->Window != 0); NSWindow* window = data->Window; - NSSize size = [window convertRectToBacking:[window contentLayoutRect]].size; + NSSize size = [window contentLayoutRect].size; return ImVec2(size.width, size.width); } @@ -462,11 +464,10 @@ static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) IM_ASSERT(data->Window != 0); NSWindow* window = data->Window; - NSRect rect = [window convertRectToBacking:[window frame]]; + NSRect rect = [window frame]; rect.origin.y -= (size.y - rect.size.height); rect.size.width = size.x; rect.size.height = size.y; - rect = [window convertRectFromBacking:rect]; [window setFrame:rect display:YES]; } @@ -543,8 +544,8 @@ static void ImGui_ImplOSX_UpdateMonitors() for (NSUInteger i = 0; i < array.count; ++i) { NSScreen* screen = array[i]; - NSRect frame = [screen convertRectToBacking:[screen frame]]; - NSRect visibleFrame = [screen convertRectToBacking:[screen visibleFrame]]; + NSRect frame = [screen frame]; + NSRect visibleFrame = [screen visibleFrame]; ImGuiPlatformMonitor imgui_monitor; imgui_monitor.MainPos = ImVec2(frame.origin.x, frame.origin.y); From 78ad75a2e1b3140bad44cad23f7b6ce07a78363a Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Wed, 18 Sep 2019 03:38:52 +0800 Subject: [PATCH 07/42] Implement Multi-Viewport for Metal --- .../example_apple_metal/Shared/Renderer.mm | 2 +- examples/imgui_impl_metal.mm | 148 +++++++++++++++++- examples/imgui_impl_osx.mm | 3 +- 3 files changed, 148 insertions(+), 5 deletions(-) diff --git a/examples/example_apple_metal/Shared/Renderer.mm b/examples/example_apple_metal/Shared/Renderer.mm index a1d99adc7e27..1f3640cca8bd 100644 --- a/examples/example_apple_metal/Shared/Renderer.mm +++ b/examples/example_apple_metal/Shared/Renderer.mm @@ -29,7 +29,7 @@ -(nonnull instancetype)initWithView:(nonnull MTKView *)view; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking - //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows // Setup Dear ImGui style ImGui::StyleColorsDark(); diff --git a/examples/imgui_impl_metal.mm b/examples/imgui_impl_metal.mm index abfeb169bc69..305d071fe8d1 100644 --- a/examples/imgui_impl_metal.mm +++ b/examples/imgui_impl_metal.mm @@ -4,8 +4,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices. -// Missing features: -// [ ] Renderer: Multi-viewport / platform windows. +// [X] Renderer: Multi-viewport / platform windows. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. @@ -13,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-09-17: Metal: Added support for Multi-viewport. // 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. @@ -23,8 +23,17 @@ #include "imgui_impl_metal.h" #import -// #import // Not supported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...) +#import #import +#if TARGET_OS_OSX +#import +#endif + +// Forward Declarations +static void ImGui_ImplMetal_InitPlatformInterface(); +static void ImGui_ImplMetal_ShutdownPlatformInterface(); +static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); +static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows(); #pragma mark - Support classes @@ -49,6 +58,7 @@ - (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPa // renderer backend. Stores the render pipeline state cache and the default // font texture, and manages the reusable buffer cache. @interface MetalContext : NSObject +@property (nonatomic, strong) id device; @property (nonatomic, strong) id depthStencilState; @property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient @property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors @@ -81,6 +91,7 @@ bool ImGui_ImplMetal_Init(id device) ImGuiIO& io = ImGui::GetIO(); io.BackendRendererName = "imgui_impl_metal"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -89,11 +100,15 @@ bool ImGui_ImplMetal_Init(id device) ImGui_ImplMetal_CreateDeviceObjects(device); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplMetal_InitPlatformInterface(); + return true; } void ImGui_ImplMetal_Shutdown() { + ImGui_ImplMetal_ShutdownPlatformInterface(); ImGui_ImplMetal_DestroyDeviceObjects(); } @@ -130,6 +145,8 @@ void ImGui_ImplMetal_DestroyFontsTexture() bool ImGui_ImplMetal_CreateDeviceObjects(id device) { [g_sharedMetalContext makeDeviceObjectsWithDevice:device]; + g_sharedMetalContext.device = device; + ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); ImGui_ImplMetal_CreateFontsTexture(device); @@ -140,6 +157,131 @@ void ImGui_ImplMetal_DestroyDeviceObjects() { ImGui_ImplMetal_DestroyFontsTexture(); [g_sharedMetalContext emptyRenderPipelineStateCache]; + ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +struct ImGuiViewportDataMetal +{ + CAMetalLayer* MetalLayer; + id CommandQueue; + MTLRenderPassDescriptor* RenderPassDescriptor; + void* Handle; + + ImGuiViewportDataMetal() { Handle = nullptr; } + ~ImGuiViewportDataMetal() {} +}; + +static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport) +{ + ImGuiViewportDataMetal* data = IM_NEW(ImGuiViewportDataMetal)(); + viewport->RendererUserData = data; + + // PlatformHandleRaw should always be a NSWindow*, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). + // Some back-ends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the NSWindow*. + void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle; + IM_ASSERT(handle != 0); + + id device = g_sharedMetalContext.device; + + float contentsScale = 1.0f; +#if TARGET_OS_OSX + NSWindow* window = (__bridge NSWindow*)handle; + contentsScale = [window backingScaleFactor]; +#endif + CAMetalLayer* layer = [CAMetalLayer layer]; + layer.contentsScale = contentsScale; + layer.device = device; + layer.framebufferOnly = YES; + layer.pixelFormat = MTLPixelFormatBGRA8Unorm; +#if TARGET_OS_OSX + NSView* view = nil; + if (view == nil) + view = [window contentView]; + if (view == nil) + view = [[window contentViewController] view]; + [view setLayer:layer]; + [view setWantsLayer:YES]; +#endif + data->MetalLayer = layer; + data->CommandQueue = [device newCommandQueue]; + data->RenderPassDescriptor = [[MTLRenderPassDescriptor alloc] init]; + data->Handle = handle; +} + +static void ImGui_ImplMetal_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. + if (ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData) + { + IM_DELETE(data); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData; + + size.x *= data->MetalLayer.contentsScale; + size.y *= data->MetalLayer.contentsScale; + data->MetalLayer.drawableSize = CGSizeMake(size.x, size.y); +} + +static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData; + + id drawable = [data->MetalLayer nextDrawable]; + id commandBuffer = [data->CommandQueue commandBuffer]; + + MTLRenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor; + renderPassDescriptor.colorAttachments[0].texture = [drawable texture]; + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); + + id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + + ImGui_ImplMetal_RenderDrawData(viewport->DrawData, commandBuffer, renderEncoder); + + [renderEncoder endEncoding]; + + [commandBuffer presentDrawable:drawable]; + [commandBuffer commit]; +} + +static void ImGui_ImplMetal_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplMetal_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplMetal_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow; +} + +static void ImGui_ImplMetal_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + +static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int i = 1; i < platform_io.Viewports.Size; i++) + if (!platform_io.Viewports[i]->RendererUserData) + ImGui_ImplMetal_CreateWindow(platform_io.Viewports[i]); +} + +static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int i = 1; i < platform_io.Viewports.Size; i++) + if (platform_io.Viewports[i]->RendererUserData) + ImGui_ImplMetal_DestroyWindow(platform_io.Viewports[i]); } #pragma mark - MetalBuffer implementation diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 0b9f1b94b5c8..fea47e7b9569 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -7,7 +7,7 @@ // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this back-end). // Issues: // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. -// [ ] Platform: Multi-viewport / platform windows. +// [X] Platform: Multi-viewport / platform windows. #include "imgui.h" #include "imgui_impl_osx.h" @@ -15,6 +15,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-09-07: Implement Multi-viewport. // 2019-07-21: Readded clipboard handlers as they are not enabled by default in core imgui.cpp (reverted 2019-05-18 change). // 2019-05-28: Inputs: Added mouse cursor shape and visibility support. // 2019-05-18: Misc: Removed clipboard handlers as they are now supported by core imgui.cpp. From 4a2394d7cebf852108918317a7d505aabb970459 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Wed, 18 Sep 2019 03:48:50 +0800 Subject: [PATCH 08/42] Move some code --- examples/imgui_impl_metal.mm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/imgui_impl_metal.mm b/examples/imgui_impl_metal.mm index 305d071fe8d1..0f8f0d1fa8c1 100644 --- a/examples/imgui_impl_metal.mm +++ b/examples/imgui_impl_metal.mm @@ -91,7 +91,7 @@ bool ImGui_ImplMetal_Init(id device) ImGuiIO& io = ImGui::GetIO(); io.BackendRendererName = "imgui_impl_metal"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. - io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -139,15 +139,15 @@ void ImGui_ImplMetal_DestroyFontsTexture() { ImGuiIO& io = ImGui::GetIO(); g_sharedMetalContext.fontTexture = nil; - io.Fonts->TexID = nullptr; + io.Fonts->TexID = NULL; } bool ImGui_ImplMetal_CreateDeviceObjects(id device) { [g_sharedMetalContext makeDeviceObjectsWithDevice:device]; g_sharedMetalContext.device = device; - ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); + ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); ImGui_ImplMetal_CreateFontsTexture(device); return true; @@ -156,8 +156,9 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id device) void ImGui_ImplMetal_DestroyDeviceObjects() { ImGui_ImplMetal_DestroyFontsTexture(); - [g_sharedMetalContext emptyRenderPipelineStateCache]; ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows(); + + [g_sharedMetalContext emptyRenderPipelineStateCache]; } //-------------------------------------------------------------------------------------------------------- @@ -173,7 +174,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects() MTLRenderPassDescriptor* RenderPassDescriptor; void* Handle; - ImGuiViewportDataMetal() { Handle = nullptr; } + ImGuiViewportDataMetal() { Handle = NULL; } ~ImGuiViewportDataMetal() {} }; @@ -238,16 +239,14 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData; id drawable = [data->MetalLayer nextDrawable]; - id commandBuffer = [data->CommandQueue commandBuffer]; MTLRenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor; renderPassDescriptor.colorAttachments[0].texture = [drawable texture]; renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); + id commandBuffer = [data->CommandQueue commandBuffer]; id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - ImGui_ImplMetal_RenderDrawData(viewport->DrawData, commandBuffer, renderEncoder); - [renderEncoder endEncoding]; [commandBuffer presentDrawable:drawable]; From 32077a0d8bf5c4df652eea33b37d3db03f79ee89 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Tue, 5 Nov 2019 17:47:26 +0800 Subject: [PATCH 09/42] Compatible for Xcode version below 12.X --- examples/imgui_impl_metal.mm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/examples/imgui_impl_metal.mm b/examples/imgui_impl_metal.mm index 260abdcfbc1a..36a7bdff79b7 100644 --- a/examples/imgui_impl_metal.mm +++ b/examples/imgui_impl_metal.mm @@ -23,7 +23,22 @@ #include "imgui_impl_metal.h" #import +#if TARGET_OS_SIMULATOR == 0 || __IPHONE_13_0 #import +#else +// Compatible for Xcode version below 12.X +#import +@protocol CAMetalDrawable +@property(readonly) id texture; +@end +@interface CAMetalLayer : CALayer +@property(nullable, retain) id device; +@property MTLPixelFormat pixelFormat; +@property BOOL framebufferOnly; +@property CGSize drawableSize; +- (nullable id)nextDrawable; +@end +#endif #import #if TARGET_OS_OSX #import From 00d62fdca6776a72d86fa0c078f66f8659776181 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Mon, 26 Oct 2020 20:14:07 +0800 Subject: [PATCH 10/42] Merge commit '455c21df7100a4727dd6e4c8e69249b7de21d24c' into docking --- examples/example_apple_metal/Shared/Renderer.mm | 6 ++---- examples/example_apple_opengl2/main.mm | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/examples/example_apple_metal/Shared/Renderer.mm b/examples/example_apple_metal/Shared/Renderer.mm index 10d0aeb7e1ef..11d46ac12857 100644 --- a/examples/example_apple_metal/Shared/Renderer.mm +++ b/examples/example_apple_metal/Shared/Renderer.mm @@ -45,13 +45,11 @@ -(nonnull instancetype)initWithView:(nonnull MTKView*)view; style.Colors[ImGuiCol_WindowBg].w = 1.0f; } - // Setup Renderer backend - ImGui_ImplMetal_Init(_device); - + // Setup Platform/Renderer backends #if TARGET_OS_OSX - // Setup Platform backend ImGui_ImplOSX_Init(view); #endif + ImGui_ImplMetal_Init(_device); // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 6ec6bcb86328..07dfab79d96f 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -272,13 +272,8 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); -<<<<<<< HEAD - // Setup Platform/Renderer bindings - ImGui_ImplOSX_Init(view); -======= // Setup Platform/Renderer backends - ImGui_ImplOSX_Init(); ->>>>>>> 455c21df7100a4727dd6e4c8e69249b7de21d24c + ImGui_ImplOSX_Init(view); ImGui_ImplOpenGL2_Init(); // Load Fonts From ff9b5148c9aadb5b626ffe9e1b9b04750b6d57ac Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Tue, 27 Oct 2020 21:32:11 +0800 Subject: [PATCH 11/42] Fix render problem when using between LowDPI and HiDPI monitors --- backends/imgui_impl_metal.mm | 18 +++++++++++++++++- imgui.cpp | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 74ffa48fe06b..f0d29dea8602 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -253,6 +253,23 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) { ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData; +#if TARGET_OS_OSX + void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle; + NSWindow* window = (__bridge NSWindow*)handle; + if (data->MetalLayer.contentsScale != [window backingScaleFactor]) + { + ImVec2 size; + size.x = data->MetalLayer.drawableSize.width / data->MetalLayer.contentsScale; + size.y = data->MetalLayer.drawableSize.height / data->MetalLayer.contentsScale; + + data->MetalLayer.contentsScale = [window backingScaleFactor]; + + size.x *= data->MetalLayer.contentsScale; + size.y *= data->MetalLayer.contentsScale; + data->MetalLayer.drawableSize = CGSizeMake(size.x, size.y); + } +#endif + id drawable = [data->MetalLayer nextDrawable]; MTLRenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor; @@ -676,7 +693,6 @@ - (void)renderDrawData:(ImDrawData *)drawData }; [commandEncoder setScissorRect:scissorRect]; - // Bind texture, Draw if (pcmd->TextureId != NULL) [commandEncoder setFragmentTexture:(__bridge id)(pcmd->TextureId) atIndex:0]; diff --git a/imgui.cpp b/imgui.cpp index 2762c1511b50..fbb19a8b2ca6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4390,7 +4390,7 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVectorTotalVtxCount = draw_data->TotalIdxCount = 0; draw_data->DisplayPos = viewport->Pos; draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size; - draw_data->FramebufferScale = ImGui::GetIO().DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? + draw_data->FramebufferScale = ImVec2(viewport->DpiScale, viewport->DpiScale); // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? draw_data->OwnerViewport = viewport; for (int n = 0; n < draw_lists->Size; n++) { From ba453e999083f7584b11bc1fb30906647048e5e6 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Wed, 28 Oct 2020 09:33:57 +0800 Subject: [PATCH 12/42] FIX Miss to add tracking area on other windows --- backends/imgui_impl_osx.h | 4 +- backends/imgui_impl_osx.mm | 66 +++++++++++++++---- .../Shared/ViewController.mm | 23 +------ 3 files changed, 56 insertions(+), 37 deletions(-) diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index efa14a0d3c80..473e5266e171 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -5,9 +5,9 @@ // Implemented features: // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Multi-viewport / platform windows. // Issues: // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. -// [ ] Platform: Multi-viewport / platform windows. // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. @@ -17,8 +17,10 @@ @class NSEvent; @class NSView; +@class NSViewController; IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nullable view); IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view); IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view); +IMGUI_IMPL_API void ImGui_ImplOSX_TrackingArea(NSViewController* _Nonnull controller); diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index a10556556205..ea1c5f56ead5 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -5,9 +5,9 @@ // Implemented features: // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Multi-viewport / platform windows. // Issues: // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. -// [X] Platform: Multi-viewport / platform windows. // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. @@ -60,7 +60,7 @@ bool ImGui_ImplOSX_Init(NSView* view) // Setup backend capabilities flags io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy) io.BackendPlatformName = "imgui_impl_osx"; @@ -192,8 +192,9 @@ void ImGui_ImplOSX_NewFrame(NSView* view) ImGuiIO& io = ImGui::GetIO(); if (view) { + NSSize size = [view bounds].size; const float dpi = [view.window backingScaleFactor]; - io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height); + io.DisplaySize = ImVec2(size.width, size.height); io.DisplayFramebufferScale = ImVec2(dpi, dpi); } if (g_WantUpdateMonitors) @@ -356,6 +357,31 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) return false; } +void ImGui_ImplOSX_TrackingArea(NSViewController* _Nonnull controller) +{ + // Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view + NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect + options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways + owner:controller + userInfo:nil]; + [controller.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, though we + // do make an effort to be good citizens by passing along events when Dear ImGui doesn't want to capture. + NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel; + [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) { + BOOL wantsCapture = ImGui_ImplOSX_HandleEvent(event, controller.view); + if (event.type == NSEventTypeKeyDown && wantsCapture) { + return nil; + } else { + return event; + } + }]; +} + //-------------------------------------------------------------------------------------------------------- // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT // This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. @@ -371,18 +397,25 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) ~ImGuiViewportDataOSX() { IM_ASSERT(Window == nil); } }; -@interface ImGui_ImplOSX_View : NSOpenGLView +@interface ImGui_ImplOSX_View : NSView @end @implementation ImGui_ImplOSX_View --(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +@end + +@interface ImGui_ImplOSX_ViewController : NSViewController +@end + +@implementation ImGui_ImplOSX_ViewController +-(void)loadView { self.view = [NSView new]; } +-(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } @end static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) @@ -401,12 +434,16 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window orderFront:NSApp]; [window setLevel:NSFloatingWindowLevel]; - ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:window.frame]; + ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) [view setWantsBestResolutionOpenGLSurface:YES]; #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - [window setContentView:view]; + + ImGui_ImplOSX_ViewController* viewController = [ImGui_ImplOSX_ViewController new]; + window.contentViewController = viewController; + window.contentViewController.view = view; + ImGui_ImplOSX_TrackingArea(viewController); data->Window = window; data->WindowOwned = true; @@ -425,6 +462,7 @@ static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) if (window != nil && data->WindowOwned) { [window setContentView:nil]; + [window setContentViewController:nil]; [window orderOut:nil]; } data->Window = nil; diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index d3cd7bed4b37..2d706c058be3 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -35,28 +35,7 @@ - (void)viewDidLoad self.mtkView.delegate = self.renderer; #if TARGET_OS_OSX - // Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view - NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect - options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways - owner:self - 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, though we - // do make an effort to be good citizens by passing along events when Dear ImGui doesn't want to capture. - NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel; - [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) { - BOOL wantsCapture = ImGui_ImplOSX_HandleEvent(event, self.view); - if (event.type == NSEventTypeKeyDown && wantsCapture) { - return nil; - } else { - return event; - } - - }]; + ImGui_ImplOSX_TrackingArea(self); #endif } From 0dcd2022e12a2f584491a8269a535a0af2e4c57d Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Wed, 28 Oct 2020 10:22:32 +0800 Subject: [PATCH 13/42] FIX Miss to call shutdown when closing --- examples/example_apple_metal/Shared/ViewController.h | 2 +- examples/example_apple_metal/Shared/ViewController.mm | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/example_apple_metal/Shared/ViewController.h b/examples/example_apple_metal/Shared/ViewController.h index 137f93e1304f..7fe9e0394c17 100644 --- a/examples/example_apple_metal/Shared/ViewController.h +++ b/examples/example_apple_metal/Shared/ViewController.h @@ -13,7 +13,7 @@ #import -@interface ViewController : NSViewController +@interface ViewController : NSViewController @end #endif diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 2d706c058be3..4a7ed5bc7fc0 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -3,6 +3,7 @@ #include "imgui.h" #if TARGET_OS_OSX +#include "imgui_impl_metal.h" #include "imgui_impl_osx.h" #endif @@ -41,6 +42,16 @@ - (void)viewDidLoad #if TARGET_OS_OSX +- (void)viewWillAppear { + [super viewWillAppear]; + self.view.window.delegate = self; +} + +- (void)windowWillClose:(NSNotification *)notification { + ImGui_ImplMetal_Shutdown(); + ImGui_ImplOSX_Shutdown(); +} + - (void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } From d5969abef9fa69c63812b4e33d0aa652cbd020bc Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Wed, 28 Oct 2020 19:10:41 +0800 Subject: [PATCH 14/42] Rename ImGui_ImplOSX_TrackingArea to ImGui_ImplOSX_AddTrackingArea --- backends/imgui_impl_osx.h | 2 +- backends/imgui_impl_osx.mm | 4 ++-- examples/example_apple_metal/Shared/ViewController.mm | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index 473e5266e171..c16542544f6e 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -23,4 +23,4 @@ IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nullable view); IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view); IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view); -IMGUI_IMPL_API void ImGui_ImplOSX_TrackingArea(NSViewController* _Nonnull controller); +IMGUI_IMPL_API void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller); diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index ea1c5f56ead5..b19fee419e02 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -357,7 +357,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) return false; } -void ImGui_ImplOSX_TrackingArea(NSViewController* _Nonnull controller) +void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) { // Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect @@ -443,7 +443,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) ImGui_ImplOSX_ViewController* viewController = [ImGui_ImplOSX_ViewController new]; window.contentViewController = viewController; window.contentViewController.view = view; - ImGui_ImplOSX_TrackingArea(viewController); + ImGui_ImplOSX_AddTrackingArea(viewController); data->Window = window; data->WindowOwned = true; diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 4a7ed5bc7fc0..3e458e1bfa3d 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -36,7 +36,7 @@ - (void)viewDidLoad self.mtkView.delegate = self.renderer; #if TARGET_OS_OSX - ImGui_ImplOSX_TrackingArea(self); + ImGui_ImplOSX_AddTrackingArea(self); #endif } From fea123f010a07ce7099f336630e60404d05a9c1a Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Wed, 28 Oct 2020 22:33:17 +0800 Subject: [PATCH 15/42] FIX validateMTLScissorRect problem when dragging window between LowDPI and HiDPI --- backends/imgui_impl_metal.mm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index f0d29dea8602..188c131ef414 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -205,13 +205,14 @@ static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport) id device = g_sharedMetalContext.device; - float contentsScale = 1.0f; + float dpiScale = 1.0f; #if TARGET_OS_OSX NSWindow* window = (__bridge NSWindow*)handle; - contentsScale = [window backingScaleFactor]; + dpiScale = [window backingScaleFactor]; + viewport->DpiScale = dpiScale; #endif CAMetalLayer* layer = [CAMetalLayer layer]; - layer.contentsScale = contentsScale; + layer.contentsScale = dpiScale; layer.device = device; layer.framebufferOnly = YES; layer.pixelFormat = MTLPixelFormatBGRA8Unorm; @@ -256,17 +257,20 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) #if TARGET_OS_OSX void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle; NSWindow* window = (__bridge NSWindow*)handle; - if (data->MetalLayer.contentsScale != [window backingScaleFactor]) + float dpiScale = viewport->DpiScale = [window backingScaleFactor]; + if (data->MetalLayer.contentsScale != dpiScale) { ImVec2 size; size.x = data->MetalLayer.drawableSize.width / data->MetalLayer.contentsScale; size.y = data->MetalLayer.drawableSize.height / data->MetalLayer.contentsScale; - data->MetalLayer.contentsScale = [window backingScaleFactor]; + data->MetalLayer.contentsScale = dpiScale; size.x *= data->MetalLayer.contentsScale; size.y *= data->MetalLayer.contentsScale; data->MetalLayer.drawableSize = CGSizeMake(size.x, size.y); + + viewport->DrawData->FramebufferScale = ImVec2(dpiScale, dpiScale); } #endif From 50138019e147e907038998a001c823d429f496b9 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 29 Oct 2020 01:01:54 +0800 Subject: [PATCH 16/42] Remove some unused codes --- backends/imgui_impl_metal.mm | 35 +++++++------------ .../example_apple_metal/Shared/Renderer.mm | 1 + examples/example_apple_opengl2/main.mm | 12 ++++++- imgui.cpp | 2 +- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 188c131ef414..4655368746c2 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -205,18 +205,12 @@ static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport) id device = g_sharedMetalContext.device; - float dpiScale = 1.0f; -#if TARGET_OS_OSX - NSWindow* window = (__bridge NSWindow*)handle; - dpiScale = [window backingScaleFactor]; - viewport->DpiScale = dpiScale; -#endif CAMetalLayer* layer = [CAMetalLayer layer]; - layer.contentsScale = dpiScale; layer.device = device; layer.framebufferOnly = YES; layer.pixelFormat = MTLPixelFormatBGRA8Unorm; #if TARGET_OS_OSX + NSWindow* window = (__bridge NSWindow*)handle; NSView* view = nil; if (view == nil) view = [window contentView]; @@ -245,9 +239,10 @@ static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) { ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData; - size.x *= data->MetalLayer.contentsScale; - size.y *= data->MetalLayer.contentsScale; - data->MetalLayer.drawableSize = CGSizeMake(size.x, size.y); + CGSize drawableSize = CGSizeMake(size.x, size.y); + drawableSize.width *= viewport->DpiScale; + drawableSize.height *= viewport->DpiScale; + data->MetalLayer.drawableSize = drawableSize; } static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) @@ -257,21 +252,17 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*) #if TARGET_OS_OSX void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle; NSWindow* window = (__bridge NSWindow*)handle; - float dpiScale = viewport->DpiScale = [window backingScaleFactor]; - if (data->MetalLayer.contentsScale != dpiScale) + viewport->DpiScale = [window backingScaleFactor]; + if (data->MetalLayer.contentsScale != viewport->DpiScale) { - ImVec2 size; - size.x = data->MetalLayer.drawableSize.width / data->MetalLayer.contentsScale; - size.y = data->MetalLayer.drawableSize.height / data->MetalLayer.contentsScale; - - data->MetalLayer.contentsScale = dpiScale; - - size.x *= data->MetalLayer.contentsScale; - size.y *= data->MetalLayer.contentsScale; - data->MetalLayer.drawableSize = CGSizeMake(size.x, size.y); + data->MetalLayer.contentsScale = viewport->DpiScale; - viewport->DrawData->FramebufferScale = ImVec2(dpiScale, dpiScale); + CGSize drawableSize = [window frame].size; + drawableSize.width *= viewport->DpiScale; + drawableSize.height *= viewport->DpiScale; + data->MetalLayer.drawableSize = drawableSize; } + viewport->DrawData->FramebufferScale = ImVec2(viewport->DpiScale, viewport->DpiScale); #endif id drawable = [data->MetalLayer nextDrawable]; diff --git a/examples/example_apple_metal/Shared/Renderer.mm b/examples/example_apple_metal/Shared/Renderer.mm index 11d46ac12857..25679cf0d0ed 100644 --- a/examples/example_apple_metal/Shared/Renderer.mm +++ b/examples/example_apple_metal/Shared/Renderer.mm @@ -149,6 +149,7 @@ - (void)drawInMTKView:(MTKView*)view // Rendering ImGui::Render(); ImDrawData* drawData = ImGui::GetDrawData(); + drawData->FramebufferScale = ImVec2(framebufferScale, framebufferScale); ImGui_ImplMetal_RenderDrawData(drawData, commandBuffer, renderEncoder); [renderEncoder popDebugGroup]; diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 07dfab79d96f..e8c99535069f 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -41,6 +41,16 @@ -(void)prepareOpenGL -(void)updateAndDrawDemoView { + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize.x = self.bounds.size.width; + io.DisplaySize.y = self.bounds.size.height; + +#if TARGET_OS_OSX + CGFloat framebufferScale = self.window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor; +#else + CGFloat framebufferScale = self.window.screen.scale ?: UIScreen.mainScreen.scale; +#endif + // Start the Dear ImGui frame ImGui_ImplOpenGL2_NewFrame(); ImGui_ImplOSX_NewFrame(self); @@ -93,6 +103,7 @@ -(void)updateAndDrawDemoView [[self openGLContext] makeCurrentContext]; ImDrawData* draw_data = ImGui::GetDrawData(); + draw_data->FramebufferScale = ImVec2(framebufferScale, framebufferScale); GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); glViewport(0, 0, width, height); @@ -105,7 +116,6 @@ -(void)updateAndDrawDemoView [[self openGLContext] flushBuffer]; // Update and Render additional Platform Windows - ImGuiIO& io = ImGui::GetIO(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); diff --git a/imgui.cpp b/imgui.cpp index fbb19a8b2ca6..dba05d2fa151 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4390,7 +4390,7 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVectorTotalVtxCount = draw_data->TotalIdxCount = 0; draw_data->DisplayPos = viewport->Pos; draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size; - draw_data->FramebufferScale = ImVec2(viewport->DpiScale, viewport->DpiScale); // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? + draw_data->FramebufferScale = ImGuiIO().DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? draw_data->OwnerViewport = viewport; for (int n = 0; n < draw_lists->Size; n++) { From 39d4005deb8ee224879d679b4ba9b4ffccdbcba6 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 29 Oct 2020 01:03:13 +0800 Subject: [PATCH 17/42] Revert --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index dba05d2fa151..2762c1511b50 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4390,7 +4390,7 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVectorTotalVtxCount = draw_data->TotalIdxCount = 0; draw_data->DisplayPos = viewport->Pos; draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size; - draw_data->FramebufferScale = ImGuiIO().DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? + draw_data->FramebufferScale = ImGui::GetIO().DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? draw_data->OwnerViewport = viewport; for (int n = 0; n < draw_lists->Size; n++) { From 95f0c200e7084234390fbda8ce0522d6c0f2d969 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 29 Oct 2020 01:15:46 +0800 Subject: [PATCH 18/42] Remove some unused codes --- examples/example_apple_metal/Shared/ViewController.mm | 3 ++- examples/example_apple_opengl2/main.mm | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 3e458e1bfa3d..c1cf636105ac 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -47,9 +47,10 @@ - (void)viewWillAppear { self.view.window.delegate = self; } -- (void)windowWillClose:(NSNotification *)notification { +- (void)applicationWillTerminate:(NSNotification *)notification { ImGui_ImplMetal_Shutdown(); ImGui_ImplOSX_Shutdown(); + ImGui::DestroyContext(); } - (void)mouseMoved:(NSEvent *)event { diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index e8c99535069f..5d012993698f 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -206,16 +206,10 @@ -(NSWindow*)window [_window setOpaque:YES]; [_window makeKeyAndOrderFront:NSApp]; [_window setDelegate:self]; - [_window setAcceptsMouseMovedEvents:YES]; return (_window); } --(void)windowWillClose:(NSNotification *)notification -{ - [NSApp terminate:self]; -} - -(void)setupMenu { NSMenu* mainMenuBar = [[NSMenu alloc] init]; From 97cb8fe08d3c9de9e86bd8e1a763db19ab4c5115 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 29 Oct 2020 01:20:08 +0800 Subject: [PATCH 19/42] Oops --- examples/example_apple_metal/Shared/ViewController.mm | 2 +- examples/example_apple_opengl2/main.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index c1cf636105ac..8b33f4a78501 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -47,7 +47,7 @@ - (void)viewWillAppear { self.view.window.delegate = self; } -- (void)applicationWillTerminate:(NSNotification *)notification { +- (void)windowWillClose:(NSNotification *)notification { ImGui_ImplMetal_Shutdown(); ImGui_ImplOSX_Shutdown(); ImGui::DestroyContext(); diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 5d012993698f..7ec93927ecdc 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -296,7 +296,7 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification //IM_ASSERT(font != NULL); } --(void)applicationWillTerminate:(NSNotification *)notification; +-(void)windowWillClose:(NSNotification *)notification { ImGui_ImplOpenGL2_Shutdown(); ImGui_ImplOSX_Shutdown(); From c7877a6dfa544173f53a1082eb0dbc9a7074aec2 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 29 Oct 2020 19:37:53 +0800 Subject: [PATCH 20/42] Oops --- examples/imgui_impl_osx.h | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 examples/imgui_impl_osx.h diff --git a/examples/imgui_impl_osx.h b/examples/imgui_impl_osx.h deleted file mode 100644 index 38719e0e33bf..000000000000 --- a/examples/imgui_impl_osx.h +++ /dev/null @@ -1,18 +0,0 @@ -// dear imgui: Platform Binding for OSX / Cocoa -// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..) -// [ALPHA] Early bindings, not well tested. If you want a portable application, prefer using the GLFW or SDL platform bindings on Mac. - -// Implemented features: -// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this back-end). -// Issues: -// [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. -// [ ] Platform: Multi-viewport / platform windows. - -@class NSEvent; -@class NSView; - -IMGUI_API bool ImGui_ImplOSX_Init(NSView *_Nonnull view); -IMGUI_API void ImGui_ImplOSX_Shutdown(); -IMGUI_API void ImGui_ImplOSX_NewFrame(NSView *_Nullable view); -IMGUI_API bool ImGui_ImplOSX_HandleEvent(NSEvent *_Nonnull event, NSView *_Nullable view); From 5756bd445945c93bb735cbcbf7bf7e3d330843da Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 31 Oct 2020 10:01:39 +0800 Subject: [PATCH 21/42] Oops --- .../example_apple_metal/Shared/Renderer.mm | 175 ------------------ .../Shared/ViewController.h | 19 -- .../Shared/ViewController.mm | 142 -------------- 3 files changed, 336 deletions(-) delete mode 100644 examples/example_apple_metal/Shared/Renderer.mm delete mode 100644 examples/example_apple_metal/Shared/ViewController.h delete mode 100644 examples/example_apple_metal/Shared/ViewController.mm diff --git a/examples/example_apple_metal/Shared/Renderer.mm b/examples/example_apple_metal/Shared/Renderer.mm deleted file mode 100644 index 25679cf0d0ed..000000000000 --- a/examples/example_apple_metal/Shared/Renderer.mm +++ /dev/null @@ -1,175 +0,0 @@ -#import "Renderer.h" -#import - -#include "imgui.h" -#include "imgui_impl_metal.h" - -#if TARGET_OS_OSX -#include "imgui_impl_osx.h" -#endif - -@interface Renderer () -@property (nonatomic, strong) id device; -@property (nonatomic, strong) id commandQueue; -@end - -@implementation Renderer - --(nonnull instancetype)initWithView:(nonnull MTKView*)view; -{ - self = [super init]; - if(self) - { - _device = view.device; - _commandQueue = [_device newCommandQueue]; - - // Setup Dear ImGui context - // FIXME: This example doesn't have proper cleanup... - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - //ImGui::StyleColorsClassic(); - - // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. - ImGuiStyle& style = ImGui::GetStyle(); - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - style.WindowRounding = 0.0f; - style.Colors[ImGuiCol_WindowBg].w = 1.0f; - } - - // Setup Platform/Renderer backends -#if TARGET_OS_OSX - ImGui_ImplOSX_Init(view); -#endif - ImGui_ImplMetal_Init(_device); - - // Load Fonts - // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. - // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. - // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). - // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. - // - Read 'docs/FONTS.txt' for more instructions and details. - // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); - //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - //IM_ASSERT(font != NULL); - } - - return self; -} - -- (void)drawInMTKView:(MTKView*)view -{ - ImGuiIO &io = ImGui::GetIO(); - io.DisplaySize.x = view.bounds.size.width; - io.DisplaySize.y = view.bounds.size.height; - -#if TARGET_OS_OSX - CGFloat framebufferScale = view.window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor; -#else - CGFloat framebufferScale = view.window.screen.scale ?: UIScreen.mainScreen.scale; -#endif - io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale); - - io.DeltaTime = 1 / float(view.preferredFramesPerSecond ?: 60); - - id commandBuffer = [self.commandQueue commandBuffer]; - - // Our state (make them static = more or less global) as a convenience to keep the example terse. - static bool show_demo_window = true; - static bool show_another_window = false; - static float clear_color[4] = { 0.28f, 0.36f, 0.5f, 1.0f }; - - MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor; - if (renderPassDescriptor != nil) - { - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); - - // Here, you could do additional rendering work, including other passes as necessary. - - id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - [renderEncoder pushDebugGroup:@"ImGui demo"]; - - // Start the Dear ImGui frame - ImGui_ImplMetal_NewFrame(renderPassDescriptor); -#if TARGET_OS_OSX - ImGui_ImplOSX_NewFrame(view); -#endif - ImGui::NewFrame(); - - // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). - if (show_demo_window) - ImGui::ShowDemoWindow(&show_demo_window); - - // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. - { - static float f = 0.0f; - static int counter = 0; - - ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. - - ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) - ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state - ImGui::Checkbox("Another Window", &show_another_window); - - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f - ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color - - if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) - counter++; - ImGui::SameLine(); - ImGui::Text("counter = %d", counter); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::End(); - } - - // 3. Show another simple window. - if (show_another_window) - { - ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) - ImGui::Text("Hello from another window!"); - if (ImGui::Button("Close Me")) - show_another_window = false; - ImGui::End(); - } - - // Rendering - ImGui::Render(); - ImDrawData* drawData = ImGui::GetDrawData(); - drawData->FramebufferScale = ImVec2(framebufferScale, framebufferScale); - ImGui_ImplMetal_RenderDrawData(drawData, commandBuffer, renderEncoder); - - [renderEncoder popDebugGroup]; - [renderEncoder endEncoding]; - - [commandBuffer presentDrawable:view.currentDrawable]; - } - - [commandBuffer commit]; - - // Update and Render additional Platform Windows - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - } -} - -- (void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size -{ -} - -@end diff --git a/examples/example_apple_metal/Shared/ViewController.h b/examples/example_apple_metal/Shared/ViewController.h deleted file mode 100644 index 7fe9e0394c17..000000000000 --- a/examples/example_apple_metal/Shared/ViewController.h +++ /dev/null @@ -1,19 +0,0 @@ -#import -#import -#import "Renderer.h" - -#if TARGET_OS_IPHONE - -#import - -@interface ViewController : UIViewController -@end - -#else - -#import - -@interface ViewController : NSViewController -@end - -#endif diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm deleted file mode 100644 index 8b33f4a78501..000000000000 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ /dev/null @@ -1,142 +0,0 @@ -#import "ViewController.h" -#import "Renderer.h" -#include "imgui.h" - -#if TARGET_OS_OSX -#include "imgui_impl_metal.h" -#include "imgui_impl_osx.h" -#endif - -@interface ViewController () -@property (nonatomic, readonly) MTKView *mtkView; -@property (nonatomic, strong) Renderer *renderer; -@end - -@implementation ViewController - -- (MTKView *)mtkView { - return (MTKView *)self.view; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.mtkView.device = MTLCreateSystemDefaultDevice(); - - if (!self.mtkView.device) { - NSLog(@"Metal is not supported"); - abort(); - } - - self.renderer = [[Renderer alloc] initWithView:self.mtkView]; - - [self.renderer mtkView:self.mtkView drawableSizeWillChange:self.mtkView.bounds.size]; - - self.mtkView.delegate = self.renderer; - -#if TARGET_OS_OSX - ImGui_ImplOSX_AddTrackingArea(self); -#endif -} - -#if TARGET_OS_OSX - -- (void)viewWillAppear { - [super viewWillAppear]; - self.view.window.delegate = self; -} - -- (void)windowWillClose:(NSNotification *)notification { - ImGui_ImplMetal_Shutdown(); - ImGui_ImplOSX_Shutdown(); - ImGui::DestroyContext(); -} - -- (void)mouseMoved:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (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); -} - -- (void)mouseUp:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)rightMouseUp:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)otherMouseUp:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)mouseDragged:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)rightMouseDragged:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)otherMouseDragged:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)scrollWheel:(NSEvent *)event { - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -#elif TARGET_OS_IOS - -// This touch mapping is super cheesy/hacky. We treat any touch on the screen -// as if it were a depressed left mouse button, and we don't bother handling -// multitouch correctly at all. This causes the "cursor" to behave very erratically -// when there are multiple active touches. But for demo purposes, single-touch -// interaction actually works surprisingly well. -- (void)updateIOWithTouchEvent:(UIEvent *)event { - UITouch *anyTouch = event.allTouches.anyObject; - CGPoint touchLocation = [anyTouch locationInView:self.view]; - ImGuiIO &io = ImGui::GetIO(); - io.MousePos = ImVec2(touchLocation.x, touchLocation.y); - - BOOL hasActiveTouch = NO; - for (UITouch *touch in event.allTouches) { - if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) { - hasActiveTouch = YES; - break; - } - } - io.MouseDown[0] = hasActiveTouch; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateIOWithTouchEvent:event]; -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateIOWithTouchEvent:event]; -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateIOWithTouchEvent:event]; -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateIOWithTouchEvent:event]; -} - -#endif - -@end - From 614519f069385c531ac3264ab05691a519d5b2ed Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 31 Oct 2020 10:03:10 +0800 Subject: [PATCH 22/42] Oops --- examples/example_apple_metal/main.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 52e5c2bae03f..523641ec399c 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -105,7 +105,7 @@ - (void)viewDidLoad #if TARGET_OS_OSX ImGui_ImplOSX_AddTrackingArea(self); - ImGui_ImplOSX_Init(); + ImGui_ImplOSX_Init(self.mtkView); #endif } From f50b219e9b62b46af222bae81cbbc477dd1e420c Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 31 Oct 2020 10:05:39 +0800 Subject: [PATCH 23/42] Oops --- examples/example_apple_metal/main.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 523641ec399c..6a29cd243b25 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -66,7 +66,7 @@ - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullab // Setup Platform/Renderer backends #if TARGET_OS_OSX - ImGui_ImplOSX_Init(view); + ImGui_ImplOSX_Init(self.view); #endif ImGui_ImplMetal_Init(_device); @@ -105,7 +105,7 @@ - (void)viewDidLoad #if TARGET_OS_OSX ImGui_ImplOSX_AddTrackingArea(self); - ImGui_ImplOSX_Init(self.mtkView); + ImGui_ImplOSX_Init(self.view); #endif } From 223847733474bbfccd454caabd2a80e432328893 Mon Sep 17 00:00:00 2001 From: TAiGA <> Date: Sat, 31 Oct 2020 10:33:02 +0800 Subject: [PATCH 24/42] Add QuartzCore for CAMetalLayer --- .../example_apple_metal.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj index f382520f785c..e533d951cf4d 100644 --- a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj +++ b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ 83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0220EB54E700295997 /* imgui_demo.cpp */; }; 83BBEA0920EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; }; 83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; }; + D6F5BA11254D0334007A0769 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6F5BA10254D0334007A0769 /* QuartzCore.framework */; }; + D6F5BA13254D03ED007A0769 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6F5BA12254D03ED007A0769 /* QuartzCore.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -55,6 +57,8 @@ 83BBEA0220EB54E700295997 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = ""; }; 83BBEA0320EB54E700295997 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; 83BBEA0420EB54E700295997 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + D6F5BA10254D0334007A0769 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + D6F5BA12254D03ED007A0769 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -65,6 +69,7 @@ 8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */, 83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */, 83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */, + D6F5BA13254D03ED007A0769 /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -75,6 +80,7 @@ 8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */, 83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */, 83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */, + D6F5BA11254D0334007A0769 /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -131,6 +137,8 @@ 83BBE9E320EB46B800295997 /* Frameworks */ = { isa = PBXGroup; children = ( + D6F5BA10254D0334007A0769 /* QuartzCore.framework */, + D6F5BA12254D03ED007A0769 /* QuartzCore.framework */, 8309BDC5253CCCFE0045E2A1 /* AppKit.framework */, 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */, 83BBE9EE20EB471C00295997 /* ModelIO.framework */, From d4bb05017e19292105a746cd3d2052f72b791e4c Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Mon, 9 Nov 2020 19:53:53 +0800 Subject: [PATCH 25/42] Reduce modified codes --- examples/example_apple_metal/main.mm | 2 +- examples/example_apple_opengl2/main.mm | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 879e63128e4f..bbd804dbf78a 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -69,7 +69,7 @@ - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullab style.Colors[ImGuiCol_WindowBg].w = 1.0f; } - // Setup Renderer backends + // Setup Renderer backend ImGui_ImplMetal_Init(_device); // Load Fonts diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index fd088a2700f4..e294698baf81 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -41,10 +41,6 @@ -(void)prepareOpenGL -(void)updateAndDrawDemoView { - ImGuiIO &io = ImGui::GetIO(); - io.DisplaySize.x = self.bounds.size.width; - io.DisplaySize.y = self.bounds.size.height; - #if TARGET_OS_OSX CGFloat framebufferScale = self.window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor; #else @@ -116,6 +112,7 @@ -(void)updateAndDrawDemoView [[self openGLContext] flushBuffer]; // Update and Render additional Platform Windows + ImGuiIO &io = ImGui::GetIO(); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); From db5d317749e6e55711fb78183cebcfb3c4b88668 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Thu, 12 Nov 2020 23:28:39 +0800 Subject: [PATCH 26/42] Try to fix top floating windows --- backends/imgui_impl_osx.mm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 4bbc3ecbe5e7..294bcfae4826 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -430,7 +430,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setTitle:@"Untitled"]; [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; - [window orderFront:NSApp]; + [window orderFront:g_Window]; [window setLevel:NSFloatingWindowLevel]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; @@ -478,6 +478,21 @@ static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport) static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) { + ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; + IM_ASSERT(data->Window != 0); + + if (ImGui::GetMainViewport() != viewport) + { + [data->Window orderFront:g_Window]; + if ([NSApp isActive]) + { + [data->Window setLevel:NSFloatingWindowLevel]; + } + else + { + [data->Window setLevel:NSNormalWindowLevel]; + } + } } static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) From a92ab947f9c98eb4383ae3d6798735571c4411a6 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Fri, 13 Nov 2020 00:41:49 +0800 Subject: [PATCH 27/42] Try to fix hide floating windows when the main window is minimized --- backends/imgui_impl_osx.mm | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 294bcfae4826..401c0b28546a 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -430,7 +430,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setTitle:@"Untitled"]; [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; - [window orderFront:g_Window]; + [window orderFront:NSApp]; [window setLevel:NSFloatingWindowLevel]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; @@ -483,7 +483,14 @@ static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) if (ImGui::GetMainViewport() != viewport) { - [data->Window orderFront:g_Window]; + if ([g_Window isMiniaturized]) + { + [data->Window orderOut:NSApp]; + } + else + { + [data->Window orderFront:NSApp]; + } if ([NSApp isActive]) { [data->Window setLevel:NSFloatingWindowLevel]; @@ -493,6 +500,10 @@ static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) [data->Window setLevel:NSNormalWindowLevel]; } } + else + { + [data->Window orderBack:NSApp]; + } } static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) @@ -557,7 +568,17 @@ static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - return [NSApp orderedWindows].firstObject == data->Window; + NSArray* orderedWindows = [NSApp orderedWindows]; + for (NSUInteger i = 0; i < [orderedWindows count]; ++i) + { + NSWindow* window = [orderedWindows objectAtIndex:i]; + if (window == g_Window) + return false; + if (window == data->Window) + return true; + } + + return false; } static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport) From 7748d4adf5d3715a1ba0cefc4a4cce9ac68ae6ef Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Fri, 13 Nov 2020 00:53:54 +0800 Subject: [PATCH 28/42] The floating windows is not always on top --- backends/imgui_impl_osx.mm | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 401c0b28546a..560269b49281 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -431,7 +431,6 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; [window orderFront:NSApp]; - [window setLevel:NSFloatingWindowLevel]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -485,24 +484,12 @@ static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) { if ([g_Window isMiniaturized]) { - [data->Window orderOut:NSApp]; + [data->Window setIsVisible:NO]; } else { - [data->Window orderFront:NSApp]; + [data->Window setIsVisible:YES]; } - if ([NSApp isActive]) - { - [data->Window setLevel:NSFloatingWindowLevel]; - } - else - { - [data->Window setLevel:NSNormalWindowLevel]; - } - } - else - { - [data->Window orderBack:NSApp]; } } @@ -568,17 +555,7 @@ static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - NSArray* orderedWindows = [NSApp orderedWindows]; - for (NSUInteger i = 0; i < [orderedWindows count]; ++i) - { - NSWindow* window = [orderedWindows objectAtIndex:i]; - if (window == g_Window) - return false; - if (window == data->Window) - return true; - } - - return false; + return [NSApp orderedWindows].firstObject == data->Window; } static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport) From bf2770b23fa62226b666272f9d548ddee3ec03e6 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 6 Mar 2021 19:59:23 +0800 Subject: [PATCH 29/42] Try the method but it would be flashing when click main window --- backends/imgui_impl_osx.mm | 45 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 67ff854df717..480e8ba5a948 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -190,6 +190,24 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() void ImGui_ImplOSX_NewFrame(NSView* view) { + // Bug - Flashing when click the main window + bool found_parent_window = false; + NSArray* array = [NSApp orderedWindows]; + for (NSUInteger i = 0; i < array.count; ++i) + { + NSWindow* window = array[i]; + if (window == g_Window) + { + found_parent_window = true; + continue; + } + if (found_parent_window && window.parentWindow == g_Window) + { + [window orderFront:g_Window]; + break; + } + } + // Setup display size ImGuiIO& io = ImGui::GetIO(); if (view) @@ -428,7 +446,8 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setTitle:@"Untitled"]; [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; - [window orderFront:NSApp]; + [window orderFront:g_Window]; + [window setParentWindow:g_Window]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -477,18 +496,6 @@ static void ImGui_ImplOSX_UpdateWindow(ImGuiViewport* viewport) { ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - - if (ImGui::GetMainViewport() != viewport) - { - if ([g_Window isMiniaturized]) - { - [data->Window setIsVisible:NO]; - } - else - { - [data->Window setIsVisible:YES]; - } - } } static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport) @@ -545,7 +552,7 @@ static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - [data->Window orderFront:NSApp]; + [data->Window orderFront:g_Window]; } static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) @@ -553,7 +560,15 @@ static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - return [NSApp orderedWindows].firstObject == data->Window; + NSArray* array = [NSApp orderedWindows]; + for (NSInteger i = 0; i < array.count; ++i) + { + NSWindow* window = array[i]; + if (window != g_Window && window.parentWindow != g_Window) + continue; + return (window == data->Window); + } + return false; } static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport) From cff67148f297ba9842765ba4290c7c3f4b69f0fa Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 6 Mar 2021 21:14:23 +0800 Subject: [PATCH 30/42] Or try the method --- backends/imgui_impl_osx.h | 2 + backends/imgui_impl_osx.mm | 80 +++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index c16542544f6e..11da0edda208 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -24,3 +24,5 @@ IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view); IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view); IMGUI_IMPL_API void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller); +IMGUI_IMPL_API void ImGui_ImplOSX_WindowWillMove(NSView* _Nullable view); +IMGUI_IMPL_API void ImGui_ImplOSX_WindowFinishMove(NSView* _Nullable view); diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 480e8ba5a948..0422f04b8181 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -34,6 +34,8 @@ // Data static NSWindow* g_Window = nil; +static NSArray* g_Children = nil; +static bool g_IsMoving = false; static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; @@ -190,23 +192,7 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() void ImGui_ImplOSX_NewFrame(NSView* view) { - // Bug - Flashing when click the main window - bool found_parent_window = false; - NSArray* array = [NSApp orderedWindows]; - for (NSUInteger i = 0; i < array.count; ++i) - { - NSWindow* window = array[i]; - if (window == g_Window) - { - found_parent_window = true; - continue; - } - if (found_parent_window && window.parentWindow == g_Window) - { - [window orderFront:g_Window]; - break; - } - } + ImGui_ImplOSX_WindowFinishMove(view); // Setup display size ImGuiIO& io = ImGui::GetIO(); @@ -253,6 +239,27 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) { ImGuiIO& io = ImGui::GetIO(); + if (event.type == NSEventTypeLeftMouseDown) + { + if (event.window == g_Window) + { + ImGui_ImplOSX_WindowWillMove(view); + } + if (event.window != g_Window) + { + if ([g_Window childWindows].lastObject != event.window) + { + [g_Window removeChildWindow:event.window]; + [g_Window addChildWindow:event.window ordered:NSWindowAbove]; + } + } + } + + if (event.type == NSEventTypeLeftMouseUp) + { + g_IsMoving = false; + } + if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) { int button = (int)[event buttonNumber]; @@ -397,6 +404,41 @@ void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) }]; } +void ImGui_ImplOSX_WindowWillMove(NSView* _Nullable view) +{ + if (view.window != g_Window) + return; + if (g_IsMoving) + return; + g_IsMoving = true; + if (g_Children) + return; + g_Children = [g_Window childWindows].copy; + for (NSUInteger i = 0; i < g_Children.count; ++i) + { + NSWindow* child = g_Children[i]; + [g_Window removeChildWindow:child]; + } +} + +void ImGui_ImplOSX_WindowFinishMove(NSView* _Nullable view) +{ + if (view.window != g_Window) + return; + if (g_IsMoving) + return; + if (g_Children == nil) + return; + for (NSUInteger i = 0; i < g_Children.count; ++i) + { + NSWindow* child = g_Children[i]; + if (child.contentView == nil) + continue; + [g_Window addChildWindow:child ordered:NSWindowAbove]; + } + g_Children = nil; +} + //-------------------------------------------------------------------------------------------------------- // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT // This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. @@ -447,7 +489,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; [window orderFront:g_Window]; - [window setParentWindow:g_Window]; + [g_Window addChildWindow:window ordered:NSWindowAbove]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -566,7 +608,7 @@ static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) NSWindow* window = array[i]; if (window != g_Window && window.parentWindow != g_Window) continue; - return (window == data->Window); + return true; } return false; } From d264c9d4b1f054e11328098a671eb083937d5a0a Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sat, 6 Mar 2021 21:46:13 +0800 Subject: [PATCH 31/42] Prevent to add many monitors --- backends/imgui_impl_osx.mm | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 0422f04b8181..0eae5572880d 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -36,6 +36,7 @@ static NSWindow* g_Window = nil; static NSArray* g_Children = nil; static bool g_IsMoving = false; +static id g_Monitor = nil; static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; @@ -152,6 +153,13 @@ void ImGui_ImplOSX_Shutdown() { ImGui_ImplOSX_ShutdownPlatformInterface(); g_Window = nil; + g_Children = nil; + g_IsMoving = false; + if (g_Monitor != nil) + { + [NSEvent removeMonitor:g_Monitor]; + g_Monitor = nil; + } } static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() @@ -396,8 +404,10 @@ void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) // 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. + if (g_Monitor) + return; NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel; - [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) + g_Monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) { ImGui_ImplOSX_HandleEvent(event, controller.view); return event; From 47edd026d9f17f585fbc6973e5c019a075891cea Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 00:55:23 +0800 Subject: [PATCH 32/42] More stable --- backends/imgui_impl_osx.h | 2 - backends/imgui_impl_osx.mm | 98 +++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 57 deletions(-) diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index 11da0edda208..c16542544f6e 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -24,5 +24,3 @@ IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view); IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view); IMGUI_IMPL_API void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller); -IMGUI_IMPL_API void ImGui_ImplOSX_WindowWillMove(NSView* _Nullable view); -IMGUI_IMPL_API void ImGui_ImplOSX_WindowFinishMove(NSView* _Nullable view); diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 0eae5572880d..4ec209af1596 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -35,7 +35,6 @@ // Data static NSWindow* g_Window = nil; static NSArray* g_Children = nil; -static bool g_IsMoving = false; static id g_Monitor = nil; static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; @@ -154,7 +153,6 @@ void ImGui_ImplOSX_Shutdown() ImGui_ImplOSX_ShutdownPlatformInterface(); g_Window = nil; g_Children = nil; - g_IsMoving = false; if (g_Monitor != nil) { [NSEvent removeMonitor:g_Monitor]; @@ -200,7 +198,44 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() void ImGui_ImplOSX_NewFrame(NSView* view) { - ImGui_ImplOSX_WindowFinishMove(view); + // Set other windows to floating when mouse hit the titlebar + NSRect rect = [g_Window frame]; + NSPoint mouse = [NSEvent mouseLocation]; + if (mouse.x >= rect.origin.x && mouse.x <= rect.origin.x + rect.size.width && + mouse.y >= rect.origin.y && mouse.y <= rect.origin.y + rect.size.height) + { + NSRect contentRect = [g_Window contentRectForFrameRect:rect]; + if (mouse.y >= contentRect.origin.y && mouse.y <= contentRect.origin.y + contentRect.size.height) + { + NSUInteger pressed = [NSEvent pressedMouseButtons]; + if (g_Children && (pressed & 1) == 0) + { + for (NSUInteger i = 0; i < g_Children.count; ++i) + { + NSWindow* window = g_Children[i]; + if ([window contentView] == nil) + continue; + [g_Window addChildWindow:window ordered:NSWindowAbove]; + [window setLevel:NSNormalWindowLevel]; + } + g_Children = nil; + } + } + else + { + if (g_Children == nil) + { + g_Children = [g_Window childWindows].copy; + for (NSUInteger i = 0; i < g_Children.count; ++i) + { + NSWindow* window = g_Children[i]; + [g_Window removeChildWindow:window]; + [window setParentWindow:g_Window]; + [window setLevel:NSFloatingWindowLevel]; + } + } + } + } // Setup display size ImGuiIO& io = ImGui::GetIO(); @@ -247,25 +282,14 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) { ImGuiIO& io = ImGui::GetIO(); + // Bring the window to top if (event.type == NSEventTypeLeftMouseDown) { - if (event.window == g_Window) + if (event.window.parentWindow == g_Window && event.window != [g_Window childWindows].lastObject) { - ImGui_ImplOSX_WindowWillMove(view); + [g_Window removeChildWindow:event.window]; + [g_Window addChildWindow:event.window ordered:NSWindowAbove]; } - if (event.window != g_Window) - { - if ([g_Window childWindows].lastObject != event.window) - { - [g_Window removeChildWindow:event.window]; - [g_Window addChildWindow:event.window ordered:NSWindowAbove]; - } - } - } - - if (event.type == NSEventTypeLeftMouseUp) - { - g_IsMoving = false; } if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) @@ -414,41 +438,6 @@ void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) }]; } -void ImGui_ImplOSX_WindowWillMove(NSView* _Nullable view) -{ - if (view.window != g_Window) - return; - if (g_IsMoving) - return; - g_IsMoving = true; - if (g_Children) - return; - g_Children = [g_Window childWindows].copy; - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* child = g_Children[i]; - [g_Window removeChildWindow:child]; - } -} - -void ImGui_ImplOSX_WindowFinishMove(NSView* _Nullable view) -{ - if (view.window != g_Window) - return; - if (g_IsMoving) - return; - if (g_Children == nil) - return; - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* child = g_Children[i]; - if (child.contentView == nil) - continue; - [g_Window addChildWindow:child ordered:NSWindowAbove]; - } - g_Children = nil; -} - //-------------------------------------------------------------------------------------------------------- // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT // This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. @@ -498,7 +487,6 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setTitle:@"Untitled"]; [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; - [window orderFront:g_Window]; [g_Window addChildWindow:window ordered:NSWindowAbove]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; @@ -618,7 +606,7 @@ static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) NSWindow* window = array[i]; if (window != g_Window && window.parentWindow != g_Window) continue; - return true; + return (window == data->Window); } return false; } From a757b0ff4a570d622ea1b95a353d15ab8b935a04 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 01:11:54 +0800 Subject: [PATCH 33/42] Fix problem when mouse move titlebar and up to click other application --- backends/imgui_impl_osx.mm | 45 ++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 4ec209af1596..b1209ce4e379 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -200,40 +200,37 @@ void ImGui_ImplOSX_NewFrame(NSView* view) { // Set other windows to floating when mouse hit the titlebar NSRect rect = [g_Window frame]; + NSRect contentRect = [g_Window contentRectForFrameRect:rect]; NSPoint mouse = [NSEvent mouseLocation]; if (mouse.x >= rect.origin.x && mouse.x <= rect.origin.x + rect.size.width && - mouse.y >= rect.origin.y && mouse.y <= rect.origin.y + rect.size.height) + mouse.y >= rect.origin.y + contentRect.size.height && mouse.y <= rect.origin.y + rect.size.height) { - NSRect contentRect = [g_Window contentRectForFrameRect:rect]; - if (mouse.y >= contentRect.origin.y && mouse.y <= contentRect.origin.y + contentRect.size.height) + if (g_Children == nil && [NSApp isActive]) { - NSUInteger pressed = [NSEvent pressedMouseButtons]; - if (g_Children && (pressed & 1) == 0) + g_Children = [g_Window childWindows].copy; + for (NSUInteger i = 0; i < g_Children.count; ++i) { - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* window = g_Children[i]; - if ([window contentView] == nil) - continue; - [g_Window addChildWindow:window ordered:NSWindowAbove]; - [window setLevel:NSNormalWindowLevel]; - } - g_Children = nil; + NSWindow* window = g_Children[i]; + [g_Window removeChildWindow:window]; + [window setParentWindow:g_Window]; + [window setLevel:NSFloatingWindowLevel]; } } - else + } + else + { + NSUInteger pressed = [NSEvent pressedMouseButtons]; + if (g_Children && (pressed & 1) == 0) { - if (g_Children == nil) + for (NSUInteger i = 0; i < g_Children.count; ++i) { - g_Children = [g_Window childWindows].copy; - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* window = g_Children[i]; - [g_Window removeChildWindow:window]; - [window setParentWindow:g_Window]; - [window setLevel:NSFloatingWindowLevel]; - } + NSWindow* window = g_Children[i]; + if ([window contentView] == nil) + continue; + [g_Window addChildWindow:window ordered:NSWindowAbove]; + [window setLevel:NSNormalWindowLevel]; } + g_Children = nil; } } From 2c71cde553764699b95d6e9c0b1592a2f508ca6a Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 01:24:15 +0800 Subject: [PATCH 34/42] Revert merged --- backends/imgui_impl_metal.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 65c1d080a4ec..7c928d4bd079 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -147,7 +147,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id device) [g_sharedMetalContext makeFontTextureWithDevice:device]; ImGuiIO& io = ImGui::GetIO(); - io.Fonts->TexID = (__bridge void *)g_sharedMetalContext.fontTexture; // ImTextureID == void* + io.Fonts->SetTexID((__bridge void *)g_sharedMetalContext.fontTexture); // ImTextureID == void* return (g_sharedMetalContext.fontTexture != nil); } @@ -156,7 +156,7 @@ void ImGui_ImplMetal_DestroyFontsTexture() { ImGuiIO& io = ImGui::GetIO(); g_sharedMetalContext.fontTexture = nil; - io.Fonts->TexID = NULL; + io.Fonts->SetTexID(nullptr); } bool ImGui_ImplMetal_CreateDeviceObjects(id device) @@ -410,7 +410,7 @@ - (void)makeFontTextureWithDevice:(id)device height:(NSUInteger)height mipmapped:NO]; textureDescriptor.usage = MTLTextureUsageShaderRead; -#if TARGET_OS_OSX +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST textureDescriptor.storageMode = MTLStorageModeManaged; #else textureDescriptor.storageMode = MTLStorageModeShared; @@ -557,10 +557,10 @@ - (void)enqueueReusableBuffer:(MetalBuffer *)buffer pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat; pipelineDescriptor.colorAttachments[0].blendingEnabled = YES; pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; - pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat; pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat; From b28f4a6da23d4ca6d5b1d83d9e91d76b274609de Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 01:27:01 +0800 Subject: [PATCH 35/42] Reduce modified codes --- backends/imgui_impl_metal.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 7c928d4bd079..428433d711e7 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -75,7 +75,6 @@ - (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPa // renderer backend. Stores the render pipeline state cache and the default // font texture, and manages the reusable buffer cache. @interface MetalContext : NSObject -@property (nonatomic, strong) id device; @property (nonatomic, strong) id depthStencilState; @property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient @property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors @@ -162,7 +161,6 @@ void ImGui_ImplMetal_DestroyFontsTexture() bool ImGui_ImplMetal_CreateDeviceObjects(id device) { [g_sharedMetalContext makeDeviceObjectsWithDevice:device]; - g_sharedMetalContext.device = device; ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); ImGui_ImplMetal_CreateFontsTexture(device); @@ -205,7 +203,7 @@ static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport) void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle; IM_ASSERT(handle != 0); - id device = g_sharedMetalContext.device; + id device = [g_sharedMetalContext.depthStencilState device]; CAMetalLayer* layer = [CAMetalLayer layer]; layer.device = device; From 2de9bf818a86ee1e006c4a033837978dc69414dc Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 02:57:11 +0800 Subject: [PATCH 36/42] Hide other windows when the main window is minimized --- backends/imgui_impl_osx.mm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index b1209ce4e379..07c9cf9b2c3c 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -214,6 +214,19 @@ void ImGui_ImplOSX_NewFrame(NSView* view) [g_Window removeChildWindow:window]; [window setParentWindow:g_Window]; [window setLevel:NSFloatingWindowLevel]; + [window setIsVisible:YES]; + } + } + } + else if ([g_Window isMiniaturized]) + { + if (g_Children) + { + for (NSUInteger i = 0; i < g_Children.count; ++i) + { + NSWindow* window = g_Children[i]; + [window setLevel:NSNormalWindowLevel]; + [window setIsVisible:NO]; } } } @@ -229,6 +242,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view) continue; [g_Window addChildWindow:window ordered:NSWindowAbove]; [window setLevel:NSNormalWindowLevel]; + [window setIsVisible:YES]; } g_Children = nil; } From 8ffa379f8d45d5463141f76f19266ab4ab0a515b Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Sun, 7 Mar 2021 12:08:56 +0800 Subject: [PATCH 37/42] NSWindow may leak when destroying --- backends/imgui_impl_osx.mm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 07c9cf9b2c3c..6fd0e6102a59 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -530,6 +530,7 @@ static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) [window setContentView:nil]; [window setContentViewController:nil]; [window orderOut:nil]; + [g_Window removeChildWindow:window]; } data->Window = nil; IM_DELETE(data); @@ -603,7 +604,15 @@ static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - [data->Window orderFront:g_Window]; + if (data->Window == g_Window) + { + [g_Window orderWindow:NSWindowAbove relativeTo:0]; + } + else if (data->Window.parentWindow == g_Window) + { + [g_Window removeChildWindow:data->Window]; + [g_Window addChildWindow:data->Window ordered:NSWindowAbove]; + } } static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) From b836d10f79031ea86054bc50bdba84109f1161a7 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Mon, 8 Mar 2021 10:32:19 +0800 Subject: [PATCH 38/42] Remove addChildWindow because it can't show in multiple screens --- backends/imgui_impl_osx.mm | 84 +++++++++++++------------------------- 1 file changed, 29 insertions(+), 55 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 6fd0e6102a59..0917193fb8fa 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -34,7 +34,6 @@ // Data static NSWindow* g_Window = nil; -static NSArray* g_Children = nil; static id g_Monitor = nil; static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; @@ -152,7 +151,6 @@ void ImGui_ImplOSX_Shutdown() { ImGui_ImplOSX_ShutdownPlatformInterface(); g_Window = nil; - g_Children = nil; if (g_Monitor != nil) { [NSEvent removeMonitor:g_Monitor]; @@ -198,53 +196,48 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() void ImGui_ImplOSX_NewFrame(NSView* view) { - // Set other windows to floating when mouse hit the titlebar + // Set other windows to floating when mouse hit the main window NSRect rect = [g_Window frame]; - NSRect contentRect = [g_Window contentRectForFrameRect:rect]; NSPoint mouse = [NSEvent mouseLocation]; - if (mouse.x >= rect.origin.x && mouse.x <= rect.origin.x + rect.size.width && - mouse.y >= rect.origin.y + contentRect.size.height && mouse.y <= rect.origin.y + rect.size.height) + NSArray* orderedWindows = [NSApp orderedWindows]; + if ([g_Window isMiniaturized]) { - if (g_Children == nil && [NSApp isActive]) + for (NSUInteger i = orderedWindows.count; i > 0; --i) { - g_Children = [g_Window childWindows].copy; - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* window = g_Children[i]; - [g_Window removeChildWindow:window]; - [window setParentWindow:g_Window]; - [window setLevel:NSFloatingWindowLevel]; - [window setIsVisible:YES]; - } + NSWindow* window = orderedWindows[i - 1]; + if (window.parentWindow != g_Window) + continue; + [window setLevel:NSNormalWindowLevel]; + [window setIsVisible:NO]; + [window setParentWindow:g_Window]; } } - else if ([g_Window isMiniaturized]) + else if (mouse.x >= rect.origin.x && mouse.x <= rect.origin.x + rect.size.width && + mouse.y >= rect.origin.y && mouse.y <= rect.origin.y + rect.size.height) { - if (g_Children) + if ([NSApp isActive] && [g_Window isMiniaturized] == NO) { - for (NSUInteger i = 0; i < g_Children.count; ++i) + for (NSUInteger i = orderedWindows.count; i > 0; --i) { - NSWindow* window = g_Children[i]; - [window setLevel:NSNormalWindowLevel]; - [window setIsVisible:NO]; + NSWindow* window = orderedWindows[i - 1]; + if (window.parentWindow != g_Window) + continue; + [window setLevel:NSFloatingWindowLevel]; + [window setIsVisible:YES]; + [window setParentWindow:g_Window]; } } } else { - NSUInteger pressed = [NSEvent pressedMouseButtons]; - if (g_Children && (pressed & 1) == 0) + for (NSUInteger i = orderedWindows.count; i > 0; --i) { - for (NSUInteger i = 0; i < g_Children.count; ++i) - { - NSWindow* window = g_Children[i]; - if ([window contentView] == nil) - continue; - [g_Window addChildWindow:window ordered:NSWindowAbove]; - [window setLevel:NSNormalWindowLevel]; - [window setIsVisible:YES]; - } - g_Children = nil; + NSWindow* window = orderedWindows[i - 1]; + if (window.parentWindow != g_Window) + continue; + [window setLevel:NSNormalWindowLevel]; + [window setIsVisible:YES]; + [window setParentWindow:g_Window]; } } @@ -293,16 +286,6 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) { ImGuiIO& io = ImGui::GetIO(); - // Bring the window to top - if (event.type == NSEventTypeLeftMouseDown) - { - if (event.window.parentWindow == g_Window && event.window != [g_Window childWindows].lastObject) - { - [g_Window removeChildWindow:event.window]; - [g_Window addChildWindow:event.window ordered:NSWindowAbove]; - } - } - if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) { int button = (int)[event buttonNumber]; @@ -498,7 +481,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) [window setTitle:@"Untitled"]; [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; - [g_Window addChildWindow:window ordered:NSWindowAbove]; + [window setParentWindow:g_Window]; ImGui_ImplOSX_View* view = [[ImGui_ImplOSX_View alloc] initWithFrame:rect]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -530,7 +513,6 @@ static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport) [window setContentView:nil]; [window setContentViewController:nil]; [window orderOut:nil]; - [g_Window removeChildWindow:window]; } data->Window = nil; IM_DELETE(data); @@ -604,15 +586,7 @@ static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport) ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData; IM_ASSERT(data->Window != 0); - if (data->Window == g_Window) - { - [g_Window orderWindow:NSWindowAbove relativeTo:0]; - } - else if (data->Window.parentWindow == g_Window) - { - [g_Window removeChildWindow:data->Window]; - [g_Window addChildWindow:data->Window ordered:NSWindowAbove]; - } + [data->Window orderWindow:NSWindowAbove relativeTo:0]; } static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport) From 69cd520148ffa0cc5da6547cedb413c4f73ce319 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Mon, 8 Mar 2021 11:40:03 +0800 Subject: [PATCH 39/42] Reorder other windows when the main window is focused --- backends/imgui_impl_osx.mm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 0917193fb8fa..bf4884164cb2 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -230,11 +230,22 @@ void ImGui_ImplOSX_NewFrame(NSView* view) } else { + bool foundMainWindow = false; for (NSUInteger i = orderedWindows.count; i > 0; --i) { NSWindow* window = orderedWindows[i - 1]; + if (window == g_Window) + { + foundMainWindow = true; + continue; + } if (window.parentWindow != g_Window) continue; + // Reorder other windows when the main window is focused + if (foundMainWindow == false) + { + [window orderWindow:NSWindowAbove relativeTo:0]; + } [window setLevel:NSNormalWindowLevel]; [window setIsVisible:YES]; [window setParentWindow:g_Window]; From 401717afb7f8a83e193c47b64ef9f480111860b7 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Tue, 16 Mar 2021 01:36:08 +0800 Subject: [PATCH 40/42] Prevent show windows randomly when NSApp deactivated --- backends/imgui_impl_osx.mm | 9 +++------ examples/example_apple_metal/main.mm | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index bf4884164cb2..1a0ca737661f 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -197,10 +197,8 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() void ImGui_ImplOSX_NewFrame(NSView* view) { // Set other windows to floating when mouse hit the main window - NSRect rect = [g_Window frame]; - NSPoint mouse = [NSEvent mouseLocation]; NSArray* orderedWindows = [NSApp orderedWindows]; - if ([g_Window isMiniaturized]) + if ([NSApp isActive] == false || [g_Window isMiniaturized]) { for (NSUInteger i = orderedWindows.count; i > 0; --i) { @@ -208,12 +206,11 @@ void ImGui_ImplOSX_NewFrame(NSView* view) if (window.parentWindow != g_Window) continue; [window setLevel:NSNormalWindowLevel]; - [window setIsVisible:NO]; + [window setIsVisible:[g_Window isMiniaturized] == NO]; [window setParentWindow:g_Window]; } } - else if (mouse.x >= rect.origin.x && mouse.x <= rect.origin.x + rect.size.width && - mouse.y >= rect.origin.y && mouse.y <= rect.origin.y + rect.size.height) + else if (NSPointInRect([NSEvent mouseLocation], [g_Window frame])) { if ([NSApp isActive] && [g_Window isMiniaturized] == NO) { diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index ac356a05ea32..64adf2fca698 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -111,6 +111,8 @@ - (void)viewDidLoad ImGui_ImplOSX_AddTrackingArea(self); ImGui_ImplOSX_Init(self.view); #endif + + [NSApp activateIgnoringOtherApps:YES]; } #pragma mark - Interaction From 437631620fd873a1fc9713343e7875d84e4f7dc1 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Tue, 16 Mar 2021 09:24:24 +0800 Subject: [PATCH 41/42] Use monitor instead of event for all mouse event --- backends/imgui_impl_osx.mm | 26 +++++++------ examples/example_apple_metal/main.mm | 57 +--------------------------- 2 files changed, 15 insertions(+), 68 deletions(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 1a0ca737661f..2ef375d5a7c2 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -227,6 +227,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view) } else { + // Reorder other windows when the main window is focused bool foundMainWindow = false; for (NSUInteger i = orderedWindows.count; i > 0; --i) { @@ -238,7 +239,6 @@ void ImGui_ImplOSX_NewFrame(NSView* view) } if (window.parentWindow != g_Window) continue; - // Reorder other windows when the main window is focused if (foundMainWindow == false) { [window orderWindow:NSWindowAbove relativeTo:0]; @@ -327,6 +327,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) } mousePoint = NSMakePoint(mousePoint.x, size.height - mousePoint.y); io.MousePos = ImVec2((float)mousePoint.x, (float)mousePoint.y); + return io.WantCaptureMouse; } if (event.type == NSEventTypeScrollWheel) @@ -432,7 +433,12 @@ void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) // To match the behavior of other backends, we pass every event down to the OS. if (g_Monitor) return; - NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel; + NSEventMask eventMask = 0; + eventMask |= NSEventMaskMouseMoved | NSEventTypeScrollWheel; + eventMask |= NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged; + eventMask |= NSEventMaskRightMouseDown | NSEventMaskRightMouseUp | NSEventMaskRightMouseDragged; + eventMask |= NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp | NSEventMaskOtherMouseDragged; + eventMask |= NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged; g_Monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) { ImGui_ImplOSX_HandleEvent(event, controller.view); @@ -465,15 +471,12 @@ @interface ImGui_ImplOSX_ViewController : NSViewController @end @implementation ImGui_ImplOSX_ViewController --(void)loadView { self.view = [NSView new]; } --(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } --(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } + +-(void)loadView +{ + self.view = [NSView new]; +} + @end static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) @@ -487,7 +490,6 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport) NSWindow* window = [[NSWindow alloc] initWithContentRect:rect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]; [window setTitle:@"Untitled"]; - [window setAcceptsMouseMovedEvents:YES]; [window setOpaque:NO]; [window setParentWindow:g_Window]; diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 64adf2fca698..f84d9c89111d 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -110,9 +110,9 @@ - (void)viewDidLoad #if TARGET_OS_OSX ImGui_ImplOSX_AddTrackingArea(self); ImGui_ImplOSX_Init(self.view); -#endif [NSApp activateIgnoringOtherApps:YES]; +#endif } #pragma mark - Interaction @@ -132,61 +132,6 @@ - (void)windowWillClose:(NSNotification *)notification ImGui::DestroyContext(); } -- (void)mouseMoved:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (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); -} - -- (void)mouseUp:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)rightMouseUp:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)otherMouseUp:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)mouseDragged:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)rightMouseDragged:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)otherMouseDragged:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - -- (void)scrollWheel:(NSEvent *)event -{ - ImGui_ImplOSX_HandleEvent(event, self.view); -} - #else // This touch mapping is super cheesy/hacky. We treat any touch on the screen From e03e992ca007cacfa802eb273db7b793f3d16219 Mon Sep 17 00:00:00 2001 From: TAiGA <@> Date: Fri, 19 Mar 2021 16:08:13 +0800 Subject: [PATCH 42/42] Fix typo --- backends/imgui_impl_osx.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 2ef375d5a7c2..5429f6e9846c 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -434,7 +434,7 @@ void ImGui_ImplOSX_AddTrackingArea(NSViewController* _Nonnull controller) if (g_Monitor) return; NSEventMask eventMask = 0; - eventMask |= NSEventMaskMouseMoved | NSEventTypeScrollWheel; + eventMask |= NSEventMaskMouseMoved | NSEventMaskScrollWheel; eventMask |= NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged; eventMask |= NSEventMaskRightMouseDown | NSEventMaskRightMouseUp | NSEventMaskRightMouseDragged; eventMask |= NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp | NSEventMaskOtherMouseDragged;