Thanks for freshening up this thread. I'm facing the 64-bit conundrum again and am glad to see people have made progress. Are you doing this with Juce 1.51 or are you using tip code?
Thx
void* attachComponentToWindowRef(Component* comp, void* windowRef)
{
const ScopedAutoReleasePool pool;
comp->addToDesktop(0,windowRef);
return windowRef;
}
NSView* hostWindow = (NSView*)windowRef;
if ([hostWindow window] != 0)
{
[[hostWindow window] setAcceptsMouseMovedEvents: YES];
}
jules wrote:Did you also change setNativeHostWindowSize() ? - I'd have thought that you'd need to make that deal with an NSView too..
#include "../juce_IncludeCharacteristics.h"
#if JucePlugin_Build_VST
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
#include "../juce_PluginHeaders.h"
#ifndef __LP64__
#define ADD_CARBON_BODGE 1 // see note below..
#endif
//==============================================================================
BEGIN_JUCE_NAMESPACE
#if ADD_CARBON_BODGE
/* When you wrap a WindowRef as an NSWindow, it seems to bugger up the HideWindow
function, so when the host tries (and fails) to hide the window, this catches
the event and does the job properly.
*/
static pascal OSStatus windowVisibilityBodge (EventHandlerCallRef, EventRef e, void* user)
{
NSWindow* hostWindow = (NSWindow*) user;
switch (GetEventKind (e))
{
case kEventWindowShown:
[hostWindow orderFront: nil];
break;
case kEventWindowHidden:
[hostWindow orderOut: nil];
break;
}
return eventNotHandledErr;
}
#endif
#ifndef __LP64__
static void updateComponentPos (Component* const comp)
{
HIViewRef dummyView = (HIViewRef) (void*) (pointer_sized_int)
comp->getProperties() ["dummyViewRef"].toString().getHexValue64();
HIRect r;
HIViewGetFrame (dummyView, &r);
HIViewRef root;
HIViewFindByID (HIViewGetRoot (HIViewGetWindow (dummyView)), kHIViewWindowContentID, &root);
HIViewConvertRect (&r, HIViewGetSuperview (dummyView), root);
Rect windowPos;
GetWindowBounds (HIViewGetWindow (dummyView), kWindowContentRgn, &windowPos);
comp->setTopLeftPosition ((int) (windowPos.left + r.origin.x),
(int) (windowPos.top + r.origin.y));
}
static pascal OSStatus viewBoundsChangedEvent (EventHandlerCallRef, EventRef, void* user)
{
updateComponentPos ((Component*) user);
return noErr;
}
#endif // __LP64__
//==============================================================================
void initialiseMac()
{
#ifndef __LP64__
NSApplicationLoad();
#endif
}
void* attachComponentToWindowRef (Component* comp, void* windowRef)
{
const ScopedAutoReleasePool pool;
#ifndef __LP64__
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: windowRef];
[hostWindow retain];
[hostWindow setCanHide: YES];
[hostWindow setReleasedWhenClosed: YES];
HIViewRef parentView = 0;
WindowAttributes attributes;
GetWindowAttributes ((WindowRef) windowRef, &attributes);
if ((attributes & kWindowCompositingAttribute) != 0)
{
HIViewRef root = HIViewGetRoot ((WindowRef) windowRef);
HIViewFindByID (root, kHIViewWindowContentID, &parentView);
if (parentView == 0)
parentView = root;
}
else
{
GetRootControl ((WindowRef) windowRef, (ControlRef*) &parentView);
if (parentView == 0)
CreateRootControl ((WindowRef) windowRef, (ControlRef*) &parentView);
}
// It seems that the only way to successfully position our overlaid window is by putting a dummy
// HIView into the host's carbon window, and then catching events to see when it gets repositioned
HIViewRef dummyView = 0;
HIImageViewCreate (0, &dummyView);
HIRect r = { {0, 0}, {comp->getWidth(), comp->getHeight()} };
HIViewSetFrame (dummyView, &r);
HIViewAddSubview (parentView, dummyView);
comp->getProperties().set ("dummyViewRef", String::toHexString ((pointer_sized_int) (void*) dummyView));
EventHandlerRef ref;
const EventTypeSpec kControlBoundsChangedEvent = { kEventClassControl, kEventControlBoundsChanged };
InstallEventHandler (GetControlEventTarget (dummyView), NewEventHandlerUPP (viewBoundsChangedEvent), 1, &kControlBoundsChangedEvent, (void*) comp, &ref);
comp->getProperties().set ("boundsEventRef", String::toHexString ((pointer_sized_int) (void*) ref));
updateComponentPos (comp);
#if ! JucePlugin_EditorRequiresKeyboardFocus
comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
#else
comp->addToDesktop (ComponentPeer::windowIsTemporary);
#endif
comp->setVisible (true);
comp->toFront (false);
NSView* pluginView = (NSView*) comp->getWindowHandle();
NSWindow* pluginWindow = [pluginView window];
[pluginWindow setExcludedFromWindowsMenu: YES];
[pluginWindow setCanHide: YES];
[hostWindow addChildWindow: pluginWindow
ordered: NSWindowAbove];
[hostWindow orderFront: nil];
[pluginWindow orderFront: nil];
#if ADD_CARBON_BODGE
// Adds a callback bodge to work around some problems with wrapped
// carbon windows..
const EventTypeSpec eventsToCatch[] = {
{ kEventClassWindow, kEventWindowShown },
{ kEventClassWindow, kEventWindowHidden }
};
InstallWindowEventHandler ((WindowRef) windowRef,
NewEventHandlerUPP (windowVisibilityBodge),
GetEventTypeCount (eventsToCatch), eventsToCatch,
(void*) hostWindow, &ref);
comp->getProperties().set ("carbonEventRef", String::toHexString ((pointer_sized_int) (void*) ref));
#endif // ADD_CARBON_BODGE
return hostWindow;
#else // __LP64__
#if ! JucePlugin_EditorRequiresKeyboardFocus
comp->addToDesktop (ComponentPeer::windowIgnoresKeyPresses, windowRef);
#else
comp->addToDesktop (0,windowRef);
#endif
NSView* hostWindow = (NSView*)windowRef;
if ([hostWindow window] != 0)
{
[[hostWindow window] setAcceptsMouseMovedEvents: YES];
}
return windowRef;
#endif // __LP64__
}
void detachComponentFromWindowRef (Component* comp, void* nsWindow)
{
{
const ScopedAutoReleasePool pool;
#ifndef __LP64__
EventHandlerRef ref = (EventHandlerRef) (void*) (pointer_sized_int)
comp->getProperties() ["boundsEventRef"].toString().getHexValue64();
RemoveEventHandler (ref);
#if ADD_CARBON_BODGE
ref = (EventHandlerRef) (void*) (pointer_sized_int)
comp->getProperties() ["carbonEventRef"].toString().getHexValue64();
RemoveEventHandler (ref);
#endif
HIViewRef dummyView = (HIViewRef) (void*) (pointer_sized_int)
comp->getProperties() ["dummyViewRef"].toString().getHexValue64();
if (HIViewIsValid (dummyView))
CFRelease (dummyView);
NSWindow* hostWindow = (NSWindow*) nsWindow;
NSView* pluginView = (NSView*) comp->getWindowHandle();
NSWindow* pluginWindow = [pluginView window];
[hostWindow removeChildWindow: pluginWindow];
comp->removeFromDesktop();
[hostWindow release];
#else
comp->removeFromDesktop();
#endif __LP64__
}
// The event loop needs to be run between closing the window and deleting the plugin,
// presumably to let the cocoa objects get tidied up. Leaving out this line causes crashes
// in Live and Reaper when you delete the plugin with its window open.
// (Doing it this way rather than using a single longer timout means that we can guarantee
// how many messages will be dispatched, which seems to be vital in Reaper)
for (int i = 20; --i >= 0;)
MessageManager::getInstance()->runDispatchLoopUntil (1);
}
void checkWindowVisibility (void* nsWindow, Component* comp)
{
NSWindow* hostWindow = (NSWindow*) nsWindow;
comp->setVisible ([hostWindow isVisible]);
}
void forwardCurrentKeyEventToHost (Component* comp)
{
NSWindow* win = [(NSView*) comp->getWindowHandle() window];
[[win parentWindow] makeKeyWindow];
[NSApp postEvent: [NSApp currentEvent] atStart: YES];
}
END_JUCE_NAMESPACE
#endif
jules wrote:Thanks! I've checked in some quick (and completely untested!) changes that should hopefully have the same effect. I've not got a copy of 64-bit cubase so would appreciate it if anyone fancies giving it a whirl!
// xxx is this necessary, or do the hosts detect a change in the child view and do this automatically?
[hostView setSize: NSMakeSize ([hostView size].width + (newWidth - component->getWidth()),
[hostView size].height + (newHeight - component->getHeight()))];
// xxx is this necessary, or do the hosts detect a change in the child view and do this automatically?
[hostView setFrameSize: NSMakeSize ([hostView frame].size.width + (newWidth - component->getWidth()),
[hostView frame].size.height + (newHeight - component->getHeight()))];
void checkWindowVisibility (void* nsWindow, Component* comp)
{
#if JUCE_64BIT
NSView* hostWindow = (NSView*) nsWindow;
comp->setVisible ([[hostWindow window] isVisible]);
#else
NSWindow* hostWindow = (NSWindow*) nsWindow;
comp->setVisible ([hostWindow isVisible]);
#endif
void checkWindowVisibility (void* nsWindow, Component* comp)
{
#if ! JUCE_64BIT
comp->setVisible ([((NSWindow*) nsWindow) isVisible]);
#endif
}
Users browsing this forum: rbocquier and 1 guest