| @@ -27,6 +27,10 @@ | |||||
| #include "water/files/File.h" | #include "water/files/File.h" | ||||
| #ifdef CARLA_OS_MAC | |||||
| # import <Cocoa/Cocoa.h> | |||||
| #endif | |||||
| #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | ||||
| # include "rtaudio/RtAudio.h" | # include "rtaudio/RtAudio.h" | ||||
| # include "rtmidi/RtMidi.h" | # include "rtmidi/RtMidi.h" | ||||
| @@ -711,7 +715,8 @@ const char* carla_get_library_folder() | |||||
| void carla_x11_reparent_window(uintptr_t winId1, uintptr_t winId2) | void carla_x11_reparent_window(uintptr_t winId1, uintptr_t winId2) | ||||
| { | { | ||||
| carla_debug("carla_x11_reparent_window()"); | |||||
| CARLA_SAFE_ASSERT_RETURN(winId1 != 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(winId2 != 0,); | |||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | if (::Display* const disp = XOpenDisplay(nullptr)) | ||||
| @@ -725,6 +730,8 @@ void carla_x11_reparent_window(uintptr_t winId1, uintptr_t winId2) | |||||
| void carla_x11_move_window(uintptr_t winId, int x, int y) | void carla_x11_move_window(uintptr_t winId, int x, int y) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(winId != 0,); | |||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | if (::Display* const disp = XOpenDisplay(nullptr)) | ||||
| { | { | ||||
| @@ -736,12 +743,15 @@ void carla_x11_move_window(uintptr_t winId, int x, int y) | |||||
| int* carla_x11_get_window_pos(uintptr_t winId) | int* carla_x11_get_window_pos(uintptr_t winId) | ||||
| { | { | ||||
| carla_debug("carla_x11_get_window_pos()"); | |||||
| static int pos[2]; | static int pos[2]; | ||||
| if (winId == 0) | |||||
| { | |||||
| pos[0] = 0; | |||||
| pos[1] = 0; | |||||
| } | |||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| else if (::Display* const disp = XOpenDisplay(nullptr)) | |||||
| { | { | ||||
| int x, y; | int x, y; | ||||
| Window child; | Window child; | ||||
| @@ -752,8 +762,8 @@ int* carla_x11_get_window_pos(uintptr_t winId) | |||||
| pos[0] = x - xwa.x; | pos[0] = x - xwa.x; | ||||
| pos[1] = y - xwa.y; | pos[1] = y - xwa.y; | ||||
| } | } | ||||
| else | |||||
| #endif | #endif | ||||
| else | |||||
| { | { | ||||
| pos[0] = 0; | pos[0] = 0; | ||||
| pos[1] = 0; | pos[1] = 0; | ||||
| @@ -762,6 +772,18 @@ int* carla_x11_get_window_pos(uintptr_t winId) | |||||
| return pos; | return pos; | ||||
| } | } | ||||
| int carla_cocoa_get_window(void* nsViewPtr) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(nsViewPtr != nullptr, 0); | |||||
| #ifdef CARLA_OS_MAC | |||||
| NSView* nsView = (NSView*)nsViewPtr; | |||||
| return [[nsView window] windowNumber]; | |||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| #include "CarlaPipeUtils.cpp" | #include "CarlaPipeUtils.cpp" | ||||
| @@ -248,6 +248,8 @@ CARLA_EXPORT void carla_x11_move_window(uintptr_t winId, int x, int y); | |||||
| CARLA_EXPORT int* carla_x11_get_window_pos(uintptr_t winId); | CARLA_EXPORT int* carla_x11_get_window_pos(uintptr_t winId); | ||||
| CARLA_EXPORT int carla_cocoa_get_window(void* nsViewPtr); | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| /** @} */ | /** @} */ | ||||
| @@ -110,6 +110,11 @@ $(OBJDIR)/CarlaStandalone.cpp.o: CarlaStandalone.cpp | |||||
| -@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
| @echo "Compiling $<" | @echo "Compiling $<" | ||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | ||||
| $(OBJDIR)/CarlaUtils.cpp.o: CarlaUtils.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling $<" | |||||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | |||||
| endif | endif | ||||
| $(OBJDIR)/%.cpp.o: %.cpp | $(OBJDIR)/%.cpp.o: %.cpp | ||||
| @@ -496,7 +496,7 @@ private: | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| class CarlaPluginLV2 : public CarlaPlugin, | class CarlaPluginLV2 : public CarlaPlugin, | ||||
| private CarlaPluginUI::CloseCallback | |||||
| private CarlaPluginUI::Callback | |||||
| { | { | ||||
| public: | public: | ||||
| CarlaPluginLV2(CarlaEngine* const engine, const uint id) | CarlaPluginLV2(CarlaEngine* const engine, const uint id) | ||||
| @@ -49,7 +49,7 @@ static const int32_t kVstMidiEventSize = static_cast<int32_t>(sizeof(VstMidiEven | |||||
| // ----------------------------------------------------- | // ----------------------------------------------------- | ||||
| class CarlaPluginVST2 : public CarlaPlugin, | class CarlaPluginVST2 : public CarlaPlugin, | ||||
| private CarlaPluginUI::CloseCallback | |||||
| private CarlaPluginUI::Callback | |||||
| { | { | ||||
| public: | public: | ||||
| CarlaPluginVST2(CarlaEngine* const engine, const uint id) | CarlaPluginVST2(CarlaEngine* const engine, const uint id) | ||||
| @@ -435,7 +435,7 @@ public: | |||||
| const char* msg = nullptr; | const char* msg = nullptr; | ||||
| const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); | const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId); | ||||
| #if defined(CARLA_OS_MAC) && defined(__LP64__) | |||||
| #if defined(CARLA_OS_MAC) && defined(CARLA_OS_64BIT) | |||||
| fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId, false); | fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId, false); | ||||
| #elif defined(CARLA_OS_WIN) | #elif defined(CARLA_OS_WIN) | ||||
| fUI.window = CarlaPluginUI::newWindows(this, frontendWinId, false); | fUI.window = CarlaPluginUI::newWindows(this, frontendWinId, false); | ||||
| @@ -178,7 +178,12 @@ public: | |||||
| for (; runMainLoopOnce() && ! gCloseNow;) | for (; runMainLoopOnce() && ! gCloseNow;) | ||||
| { | { | ||||
| gIdle(); | gIdle(); | ||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | |||||
| // MacOS and Win32 have event-loops to run, so minimize sleep time | |||||
| carla_msleep(1); | carla_msleep(1); | ||||
| #else | |||||
| carla_msleep(5); | |||||
| #endif | |||||
| } | } | ||||
| carla_set_engine_about_to_close(); | carla_set_engine_about_to_close(); | ||||
| @@ -17,15 +17,17 @@ | |||||
| #include "CarlaBridgeUI.hpp" | #include "CarlaBridgeUI.hpp" | ||||
| #include "CarlaBridgeToolkit.hpp" | #include "CarlaBridgeToolkit.hpp" | ||||
| #include "CarlaMainLoop.hpp" | |||||
| #include "CarlaPluginUI.hpp" | #include "CarlaPluginUI.hpp" | ||||
| CARLA_BRIDGE_START_NAMESPACE | CARLA_BRIDGE_START_NAMESPACE | ||||
| using CarlaBackend::runMainLoopOnce; | |||||
| // ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
| class CarlaBridgeToolkitPlugin : public CarlaBridgeToolkit, | class CarlaBridgeToolkitPlugin : public CarlaBridgeToolkit, | ||||
| private CarlaPluginUI::CloseCallback | |||||
| private CarlaPluginUI::Callback | |||||
| { | { | ||||
| public: | public: | ||||
| CarlaBridgeToolkitPlugin(CarlaBridgeUI* const u) | CarlaBridgeToolkitPlugin(CarlaBridgeUI* const u) | ||||
| @@ -50,9 +52,9 @@ public: | |||||
| const CarlaBridgeUI::Options& options(ui->getOptions()); | const CarlaBridgeUI::Options& options(ui->getOptions()); | ||||
| #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA) | #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA) | ||||
| fUI = nullptr; | |||||
| fUI = CarlaPluginUI::newCocoa(this, 0, options.isResizable); | |||||
| #elif defined(CARLA_OS_WIN) && defined(BRIDGE_HWND) | #elif defined(CARLA_OS_WIN) && defined(BRIDGE_HWND) | ||||
| fUI = nullptr; | |||||
| fUI = CarlaPluginUI::newWindows(this, 0, options.isResizable); | |||||
| #elif defined(HAVE_X11) && defined(BRIDGE_X11) | #elif defined(HAVE_X11) && defined(BRIDGE_X11) | ||||
| fUI = CarlaPluginUI::newX11(this, 0, options.isResizable); | fUI = CarlaPluginUI::newX11(this, 0, options.isResizable); | ||||
| #endif | #endif | ||||
| @@ -60,8 +62,11 @@ public: | |||||
| fUI->setTitle(options.windowTitle.buffer()); | fUI->setTitle(options.windowTitle.buffer()); | ||||
| #ifdef HAVE_X11 | |||||
| // Out-of-process reparenting only possible on X11 | |||||
| if (options.transientWindowId != 0) | if (options.transientWindowId != 0) | ||||
| fUI->setTransientWinId(options.transientWindowId); | fUI->setTransientWinId(options.transientWindowId); | ||||
| #endif | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -83,14 +88,19 @@ public: | |||||
| fIdling = true; | fIdling = true; | ||||
| for (; fIdling;) | |||||
| for (; runMainLoopOnce() && fIdling;) | |||||
| { | { | ||||
| if (ui->isPipeRunning()) | if (ui->isPipeRunning()) | ||||
| ui->idlePipe(); | ui->idlePipe(); | ||||
| ui->idleUI(); | ui->idleUI(); | ||||
| fUI->idle(); | fUI->idle(); | ||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | |||||
| // MacOS and Win32 have event-loops to run, so minimize sleep time | |||||
| carla_msleep(1); | |||||
| #else | |||||
| carla_msleep(20); | carla_msleep(20); | ||||
| #endif | |||||
| } | } | ||||
| } | } | ||||
| @@ -2129,7 +2129,11 @@ class HostWindow(QMainWindow): | |||||
| # set our gui as parent for all plugins UIs | # set our gui as parent for all plugins UIs | ||||
| if self.host.manageUIs and not (self.host.isControl or self.host.isPlugin): | if self.host.manageUIs and not (self.host.isControl or self.host.isPlugin): | ||||
| winIdStr = "%x" % int(self.winId()) | |||||
| if MACOS: | |||||
| nsViewPtr = int(self.winId()) | |||||
| winIdStr = "%x" % gCarla.utils.cocoa_get_window(nsViewPtr) | |||||
| else: | |||||
| winIdStr = "%x" % int(self.winId()) | |||||
| self.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr) | self.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr) | ||||
| def hideEvent(self, event): | def hideEvent(self, event): | ||||
| @@ -243,7 +243,7 @@ class CarlaSettingsW(QDialog): | |||||
| self.ui.ch_main_show_logs.setEnabled(False) | self.ui.ch_main_show_logs.setEnabled(False) | ||||
| self.ui.ch_main_show_logs.setVisible(False) | self.ui.ch_main_show_logs.setVisible(False) | ||||
| if MACOS or WINDOWS: | |||||
| if WINDOWS: | |||||
| self.ui.ch_engine_manage_uis.setEnabled(False) | self.ui.ch_engine_manage_uis.setEnabled(False) | ||||
| self.ui.ch_engine_manage_uis.setVisible(False) | self.ui.ch_engine_manage_uis.setVisible(False) | ||||
| @@ -224,6 +224,9 @@ class CarlaUtils(object): | |||||
| self.lib.carla_x11_get_window_pos.argtypes = [c_uintptr] | self.lib.carla_x11_get_window_pos.argtypes = [c_uintptr] | ||||
| self.lib.carla_x11_get_window_pos.restype = POINTER(c_int) | self.lib.carla_x11_get_window_pos.restype = POINTER(c_int) | ||||
| self.lib.carla_cocoa_get_window.argtypes = [c_uintptr] | |||||
| self.lib.carla_cocoa_get_window.restype = c_int | |||||
| # use _putenv on windows | # use _putenv on windows | ||||
| if not WINDOWS: | if not WINDOWS: | ||||
| self.msvcrt = None | self.msvcrt = None | ||||
| @@ -338,4 +341,7 @@ class CarlaUtils(object): | |||||
| data = self.lib.carla_x11_get_window_pos(winId) | data = self.lib.carla_x11_get_window_pos(winId) | ||||
| return (int(data[0]), int(data[1])) | return (int(data[0]), int(data[1])) | ||||
| def cocoa_get_window(self, winId): | |||||
| return self.lib.carla_cocoa_get_window(winId) | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| @@ -403,11 +403,7 @@ struct Window::PrivateData { | |||||
| SetFocus(hwnd); | SetFocus(hwnd); | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| if (mWindow != nullptr) | if (mWindow != nullptr) | ||||
| { | |||||
| // TODO | |||||
| //[NSApp activateIgnoringOtherApps:YES]; | |||||
| //[mWindow makeKeyAndOrderFront:mWindow]; | |||||
| } | |||||
| [mWindow makeKeyWindow]; | |||||
| #elif defined(DISTRHO_OS_LINUX) | #elif defined(DISTRHO_OS_LINUX) | ||||
| XRaiseWindow(xDisplay, xWindow); | XRaiseWindow(xDisplay, xWindow); | ||||
| XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime); | ||||
| @@ -626,12 +622,17 @@ struct Window::PrivateData { | |||||
| void setTransientWinId(const uintptr_t winId) | void setTransientWinId(const uintptr_t winId) | ||||
| { | { | ||||
| #if defined(DISTRHO_OS_LINUX) | |||||
| DISTRHO_SAFE_ASSERT_RETURN(winId != 0,); | |||||
| #if defined(DISTRHO_OS_MAC) | |||||
| NSWindow* window = [NSApp windowWithWindowNumber:winId]; | |||||
| DISTRHO_SAFE_ASSERT_RETURN(window != nullptr,); | |||||
| [window addChildWindow:mWindow | |||||
| ordered:NSWindowAbove]; | |||||
| [mWindow makeKeyWindow]; | |||||
| #elif defined(DISTRHO_OS_LINUX) | |||||
| XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId)); | ||||
| #else | |||||
| return; | |||||
| // unused | |||||
| (void)winId; | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -53,7 +53,7 @@ static int temporaryErrorHandler(Display*, XErrorEvent*) | |||||
| class X11PluginUI : public CarlaPluginUI | class X11PluginUI : public CarlaPluginUI | ||||
| { | { | ||||
| public: | public: | ||||
| X11PluginUI(CloseCallback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| X11PluginUI(Callback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| : CarlaPluginUI(cb, isResizable), | : CarlaPluginUI(cb, isResizable), | ||||
| fDisplay(nullptr), | fDisplay(nullptr), | ||||
| fWindow(0), | fWindow(0), | ||||
| @@ -330,16 +330,18 @@ private: | |||||
| @interface CarlaPluginWindow : NSWindow | @interface CarlaPluginWindow : NSWindow | ||||
| { | { | ||||
| @public | @public | ||||
| CarlaPluginUI::CloseCallback* callback; | |||||
| CarlaPluginUI::Callback* callback; | |||||
| NSView* view; | |||||
| } | } | ||||
| - (id) initWithContentRect:(NSRect)contentRect | - (id) initWithContentRect:(NSRect)contentRect | ||||
| styleMask:(unsigned int)aStyle | styleMask:(unsigned int)aStyle | ||||
| backing:(NSBackingStoreType)bufferingType | backing:(NSBackingStoreType)bufferingType | ||||
| defer:(BOOL)flag; | defer:(BOOL)flag; | ||||
| - (void) setCloseCallback:(CarlaPluginUI::CloseCallback*)cb; | |||||
| - (void) setup:(CarlaPluginUI::Callback*)cb view:(NSView*)v; | |||||
| - (BOOL) canBecomeKeyWindow; | - (BOOL) canBecomeKeyWindow; | ||||
| - (BOOL) windowShouldClose:(id)sender; | - (BOOL) windowShouldClose:(id)sender; | ||||
| - (NSSize) windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize; | |||||
| @end | @end | ||||
| @implementation CarlaPluginWindow | @implementation CarlaPluginWindow | ||||
| @@ -350,6 +352,7 @@ private: | |||||
| defer:(BOOL)flag | defer:(BOOL)flag | ||||
| { | { | ||||
| callback = nil; | callback = nil; | ||||
| view = nil; | |||||
| NSWindow* result = [super initWithContentRect:contentRect | NSWindow* result = [super initWithContentRect:contentRect | ||||
| styleMask:(NSClosableWindowMask | | styleMask:(NSClosableWindowMask | | ||||
| @@ -367,9 +370,10 @@ private: | |||||
| (void)aStyle; (void)bufferingType; (void)flag; | (void)aStyle; (void)bufferingType; (void)flag; | ||||
| } | } | ||||
| - (void)setCloseCallback:(CarlaPluginUI::CloseCallback*)cb | |||||
| - (void)setup:(CarlaPluginUI::Callback*)cb view:(NSView*)v | |||||
| { | { | ||||
| callback = cb; | callback = cb; | ||||
| view = v; | |||||
| } | } | ||||
| - (BOOL)canBecomeKeyWindow | - (BOOL)canBecomeKeyWindow | ||||
| @@ -379,23 +383,36 @@ private: | |||||
| - (BOOL)windowShouldClose:(id)sender | - (BOOL)windowShouldClose:(id)sender | ||||
| { | { | ||||
| if (callback) | |||||
| if (callback != nil) | |||||
| callback->handlePluginUIClosed(); | callback->handlePluginUIClosed(); | ||||
| return NO; | return NO; | ||||
| // unused | // unused | ||||
| (void)sender; | (void)sender; | ||||
| } | } | ||||
| - (NSSize) windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize | |||||
| { | |||||
| if (callback != nil) | |||||
| callback->handlePluginUIResized(frameSize.width, frameSize.height); | |||||
| return frameSize; | |||||
| // unused | |||||
| (void)sender; | |||||
| } | |||||
| @end | @end | ||||
| class CocoaPluginUI : public CarlaPluginUI | class CocoaPluginUI : public CarlaPluginUI | ||||
| { | { | ||||
| public: | public: | ||||
| CocoaPluginUI(CloseCallback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| CocoaPluginUI(Callback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| : CarlaPluginUI(cb, isResizable), | : CarlaPluginUI(cb, isResizable), | ||||
| fView(nullptr), | fView(nullptr), | ||||
| fWindow(0) | |||||
| fWindow(0), | |||||
| fParentId(parentId) | |||||
| { | { | ||||
| [NSAutoreleasePool new]; | [NSAutoreleasePool new]; | ||||
| [NSApplication sharedApplication]; | [NSApplication sharedApplication]; | ||||
| @@ -418,13 +435,16 @@ public: | |||||
| if (! isResizable) | if (! isResizable) | ||||
| [[fWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; | [[fWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; | ||||
| [fWindow setCloseCallback:cb]; | |||||
| [fWindow setup:cb view:fView]; | |||||
| [fWindow setContentView:fView]; | [fWindow setContentView:fView]; | ||||
| [fWindow makeFirstResponder:fView]; | [fWindow makeFirstResponder:fView]; | ||||
| [fWindow makeKeyAndOrderFront:fWindow]; | [fWindow makeKeyAndOrderFront:fWindow]; | ||||
| [NSApp activateIgnoringOtherApps:YES]; | [NSApp activateIgnoringOtherApps:YES]; | ||||
| [fWindow center]; | [fWindow center]; | ||||
| if (parentId != 0) | |||||
| setTransientWinId(parentId); | |||||
| } | } | ||||
| ~CocoaPluginUI() override | ~CocoaPluginUI() override | ||||
| @@ -443,6 +463,9 @@ public: | |||||
| [fView setHidden:NO]; | [fView setHidden:NO]; | ||||
| [fWindow setIsVisible:YES]; | [fWindow setIsVisible:YES]; | ||||
| if (fParentId != 0) | |||||
| setTransientWinId(fParentId); | |||||
| } | } | ||||
| void hide() override | void hide() override | ||||
| @@ -459,14 +482,14 @@ public: | |||||
| void focus() override | void focus() override | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); | |||||
| CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); | |||||
| // TODO | |||||
| [fWindow makeKeyWindow]; | |||||
| } | } | ||||
| void setSize(const uint width, const uint height, const bool forceUpdate) override | void setSize(const uint width, const uint height, const bool forceUpdate) override | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); | |||||
| CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(fView != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fView != nullptr,); | ||||
| [fView setFrame:NSMakeRect(0, 0, width, height)]; | [fView setFrame:NSMakeRect(0, 0, width, height)]; | ||||
| @@ -504,7 +527,12 @@ public: | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); | CARLA_SAFE_ASSERT_RETURN(fWindow != 0,); | ||||
| // TODO | |||||
| NSWindow* window = [NSApp windowWithWindowNumber:winId]; | |||||
| CARLA_SAFE_ASSERT_RETURN(window != nullptr,); | |||||
| [window addChildWindow:fWindow | |||||
| ordered:NSWindowAbove]; | |||||
| [fWindow makeKeyWindow]; | |||||
| } | } | ||||
| void* getPtr() const noexcept override | void* getPtr() const noexcept override | ||||
| @@ -520,6 +548,7 @@ public: | |||||
| private: | private: | ||||
| NSView* fView; | NSView* fView; | ||||
| id fWindow; | id fWindow; | ||||
| uintptr_t fParentId; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CocoaPluginUI) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CocoaPluginUI) | ||||
| }; | }; | ||||
| @@ -538,7 +567,7 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l | |||||
| class WindowsPluginUI : public CarlaPluginUI | class WindowsPluginUI : public CarlaPluginUI | ||||
| { | { | ||||
| public: | public: | ||||
| WindowsPluginUI(CloseCallback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| WindowsPluginUI(Callback* const cb, const uintptr_t parentId, const bool isResizable) noexcept | |||||
| : CarlaPluginUI(cb, isResizable), | : CarlaPluginUI(cb, isResizable), | ||||
| fWindow(0), | fWindow(0), | ||||
| fIsVisible(false), | fIsVisible(false), | ||||
| @@ -582,6 +611,9 @@ public: | |||||
| } | } | ||||
| SetWindowLongPtr(fWindow, GWLP_USERDATA, (LONG_PTR)this); | SetWindowLongPtr(fWindow, GWLP_USERDATA, (LONG_PTR)this); | ||||
| if (parentId != 0) | |||||
| setTransientWinId(parentId); | |||||
| } | } | ||||
| ~WindowsPluginUI() override | ~WindowsPluginUI() override | ||||
| @@ -963,21 +995,21 @@ bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* cons | |||||
| // ----------------------------------------------------- | // ----------------------------------------------------- | ||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| CarlaPluginUI* CarlaPluginUI::newX11(CloseCallback* cb, uintptr_t parentId, bool isResizable) | |||||
| CarlaPluginUI* CarlaPluginUI::newX11(Callback* cb, uintptr_t parentId, bool isResizable) | |||||
| { | { | ||||
| return new X11PluginUI(cb, parentId, isResizable); | return new X11PluginUI(cb, parentId, isResizable); | ||||
| } | } | ||||
| #endif | #endif | ||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback* cb, uintptr_t parentId, bool isResizable) | |||||
| CarlaPluginUI* CarlaPluginUI::newCocoa(Callback* cb, uintptr_t parentId, bool isResizable) | |||||
| { | { | ||||
| return new CocoaPluginUI(cb, parentId, isResizable); | return new CocoaPluginUI(cb, parentId, isResizable); | ||||
| } | } | ||||
| #endif | #endif | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| CarlaPluginUI* CarlaPluginUI::newWindows(CloseCallback* cb, uintptr_t parentId, bool isResizable) | |||||
| CarlaPluginUI* CarlaPluginUI::newWindows(Callback* cb, uintptr_t parentId, bool isResizable) | |||||
| { | { | ||||
| return new WindowsPluginUI(cb, parentId, isResizable); | return new WindowsPluginUI(cb, parentId, isResizable); | ||||
| } | } | ||||
| @@ -25,9 +25,9 @@ | |||||
| class CarlaPluginUI | class CarlaPluginUI | ||||
| { | { | ||||
| public: | public: | ||||
| class CloseCallback { | |||||
| class Callback { | |||||
| public: | public: | ||||
| virtual ~CloseCallback() {} | |||||
| virtual ~Callback() {} | |||||
| virtual void handlePluginUIClosed() = 0; | virtual void handlePluginUIClosed() = 0; | ||||
| virtual void handlePluginUIResized(const uint width, const uint height) = 0; | virtual void handlePluginUIResized(const uint width, const uint height) = 0; | ||||
| }; | }; | ||||
| @@ -48,21 +48,21 @@ public: | |||||
| static bool tryTransientWinIdMatch(const uintptr_t pid, const char* const uiTitle, const uintptr_t winId, const bool centerUI); | static bool tryTransientWinIdMatch(const uintptr_t pid, const char* const uiTitle, const uintptr_t winId, const bool centerUI); | ||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| static CarlaPluginUI* newCocoa(CloseCallback*, uintptr_t, bool); | |||||
| static CarlaPluginUI* newCocoa(Callback*, uintptr_t, bool); | |||||
| #endif | #endif | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| static CarlaPluginUI* newWindows(CloseCallback*, uintptr_t, bool); | |||||
| static CarlaPluginUI* newWindows(Callback*, uintptr_t, bool); | |||||
| #endif | #endif | ||||
| #ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
| static CarlaPluginUI* newX11(CloseCallback*, uintptr_t, bool); | |||||
| static CarlaPluginUI* newX11(Callback*, uintptr_t, bool); | |||||
| #endif | #endif | ||||
| protected: | protected: | ||||
| bool fIsIdling; | bool fIsIdling; | ||||
| bool fIsResizable; | bool fIsResizable; | ||||
| CloseCallback* fCallback; | |||||
| Callback* fCallback; | |||||
| CarlaPluginUI(CloseCallback* const cb, const bool isResizable) noexcept | |||||
| CarlaPluginUI(Callback* const cb, const bool isResizable) noexcept | |||||
| : fIsIdling(false), | : fIsIdling(false), | ||||
| fIsResizable(isResizable), | fIsResizable(isResizable), | ||||
| fCallback(cb) {} | fCallback(cb) {} | ||||