various OS X fixes, mostly related to AU support

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2836 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-01-07 20:41:51 +00:00
parent e6dc790374
commit 5284a1efca
16 changed files with 180 additions and 73 deletions

View file

@ -89,7 +89,7 @@ au_pluginui.mm
gtkosx_files=Split(""" gtkosx_files=Split("""
sync-menu.c sync-menu.c
cocoacarbon.cc cocoacarbon.mm
""") """)
x11_files=Split(""" x11_files=Split("""

View file

@ -245,6 +245,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
starting.connect (mem_fun(*this, &ARDOUR_UI::startup)); starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown)); stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
platform_setup ();
} }
int int
@ -2017,6 +2020,8 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e
Gtk::BUTTONS_NONE); Gtk::BUTTONS_NONE);
} }
cerr << "PDP = " << predetermined_path << endl;
int response = Gtk::RESPONSE_NONE; int response = Gtk::RESPONSE_NONE;
@ -2230,11 +2235,6 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e
} }
//XXX This is needed because session constructor wants a
//non-existant path. hopefully this will be fixed at some point.
session_path = Glib::build_filename (session_path, session_name);
if (!should_be_new) { if (!should_be_new) {
if (load_session (session_path, session_name)) { if (load_session (session_path, session_name)) {

View file

@ -749,6 +749,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
Gtk::MessageDialog* loading_dialog; Gtk::MessageDialog* loading_dialog;
void platform_specific (); void platform_specific ();
void platform_setup ();
void fontconfig_dialog (); void fontconfig_dialog ();
}; };

View file

@ -31,6 +31,9 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox
bool start_updating(GdkEventAny*); bool start_updating(GdkEventAny*);
bool stop_updating(GdkEventAny*); bool stop_updating(GdkEventAny*);
virtual void activate ();
virtual void deactivate ();
void on_realize (); void on_realize ();
void on_show (); void on_show ();
@ -45,6 +48,7 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox
NSWindow* cocoa_window; NSWindow* cocoa_window;
NSScrollView* scroll_view; NSScrollView* scroll_view;
NSView* au_view;
/* Carbon */ /* Carbon */

View file

@ -34,7 +34,7 @@ AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
bool has_carbon; bool has_carbon;
bool has_cocoa; bool has_cocoa;
carbon_parented = false; carbon_parented = false;
cocoa_parented = false; cocoa_parented = false;
cocoa_parent = 0; cocoa_parent = 0;
@ -42,12 +42,13 @@ AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
test_view_support (has_carbon, has_cocoa); test_view_support (has_carbon, has_cocoa);
cerr << "plugin has carbon ? " << has_carbon << " cocoa ? " << has_cocoa << endl;
if (has_cocoa) { if (has_cocoa) {
create_cocoa_view (); create_cocoa_view ();
} else { } else if (has_carbon) {
create_carbon_view (has_carbon); create_carbon_view (has_carbon);
} else {
/* fallback to cocoa */
create_cocoa_view ();
} }
} }
@ -71,7 +72,7 @@ AUPluginUI::test_view_support (bool& has_carbon, bool& has_cocoa)
bool bool
AUPluginUI::test_carbon_view_support () AUPluginUI::test_carbon_view_support ()
{ {
bool ret = true; // there is always the generic GUI bool ret = false;
carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType; carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType;
carbon_descriptor.componentSubType = 'gnrc'; carbon_descriptor.componentSubType = 'gnrc';
@ -126,7 +127,6 @@ AUPluginUI::plugin_class_valid (Class pluginClass)
int int
AUPluginUI::create_cocoa_view () AUPluginUI::create_cocoa_view ()
{ {
NSView *AUView = nil;
BOOL wasAbleToLoadCustomView = NO; BOOL wasAbleToLoadCustomView = NO;
AudioUnitCocoaViewInfo* cocoaViewInfo = NULL; AudioUnitCocoaViewInfo* cocoaViewInfo = NULL;
UInt32 numberOfClasses = 0; UInt32 numberOfClasses = 0;
@ -142,11 +142,6 @@ AUPluginUI::create_cocoa_view ()
&dataSize, &dataSize,
&isWritable ); &isWritable );
if (result != noErr) {
return -1;
}
numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef); numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
// Does view have custom Cocoa UI? // Does view have custom Cocoa UI?
@ -174,15 +169,7 @@ AUPluginUI::create_cocoa_view ()
} }
} }
cocoa_window = [NSWindow alloc]; NSRect crect = { { 0, 0 }, { 1, 1} };
NSRect frameRect = [[cocoa_window contentView] frame];
scroll_view = [[[NSScrollView alloc] initWithFrame:frameRect] autorelease];
[scroll_view setDrawsBackground:NO];
[scroll_view setHasHorizontalScroller:YES];
[scroll_view setHasVerticalScroller:YES];
[cocoa_window setContentView:scroll_view];
// [A] Show custom UI if view has it // [A] Show custom UI if view has it
@ -211,8 +198,7 @@ AUPluginUI::create_cocoa_view ()
} }
// make a view // make a view
AUView = [factoryInstance uiViewForAudioUnit:*au->get_au() au_view = [factoryInstance uiViewForAudioUnit:*au->get_au() withSize:crect.size];
withSize:[[scroll_view contentView] bounds].size];
// cleanup // cleanup
[CocoaViewBundlePath release]; [CocoaViewBundlePath release];
@ -229,32 +215,17 @@ AUPluginUI::create_cocoa_view ()
if (!wasAbleToLoadCustomView) { if (!wasAbleToLoadCustomView) {
// [B] Otherwise show generic Cocoa view // [B] Otherwise show generic Cocoa view
AUView = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()]; au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()];
[(AUGenericView *)AUView setShowsExpertParameters:YES]; [(AUGenericView *)au_view setShowsExpertParameters:YES];
} }
// Display view
NSRect viewFrame = [AUView frame];
NSSize frameSize = [NSScrollView frameSizeForContentSize:viewFrame.size
hasHorizontalScroller:[scroll_view hasHorizontalScroller]
hasVerticalScroller:[scroll_view hasVerticalScroller]
borderType:[scroll_view borderType]];
NSRect newFrame; /* make a child cocoa window */
newFrame.origin = [scroll_view frame].origin;
newFrame.size = frameSize;
NSRect currentFrame = [scroll_view frame]; cocoa_window = [[NSWindow alloc]
[scroll_view setFrame:newFrame]; initWithContentRect:crect
[scroll_view setDocumentView:AUView]; styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
NSSize oldContentSize = [[cocoa_window contentView] frame].size; defer:NO];
NSSize newContentSize = oldContentSize;
newContentSize.width += (newFrame.size.width - currentFrame.size.width);
newContentSize.height += (newFrame.size.height - currentFrame.size.height);
[cocoa_window setContentSize:newContentSize];
return 0; return 0;
} }
@ -279,7 +250,7 @@ AUPluginUI::create_carbon_view (bool generic)
kWindowNoShadowAttribute| kWindowNoShadowAttribute|
kWindowNoTitleBarAttribute); kWindowNoTitleBarAttribute);
if ((err = CreateNewWindow(kFloatingWindowClass, attr, &r, &carbon_window)) != noErr) { if ((err = CreateNewWindow(kDocumentWindowClass, attr, &r, &carbon_window)) != noErr) {
error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg; error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
return -1; return -1;
} }
@ -335,6 +306,24 @@ AUPluginUI::get_nswindow ()
return true_parent; return true_parent;
} }
void
AUPluginUI::activate ()
{
NSWindow* win = get_nswindow ();
[win setLevel:NSFloatingWindowLevel];
if (carbon_parented) {
[cocoa_parent makeKeyAndOrderFront:nil];
ActivateWindow (carbon_window, TRUE);
}
}
void
AUPluginUI::deactivate ()
{
/* nothing to do here */
}
OSStatus OSStatus
_carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData) _carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
@ -347,27 +336,25 @@ AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event)
{ {
UInt32 eventKind = GetEventKind(event); UInt32 eventKind = GetEventKind(event);
ClickActivationResult howToHandleClick; ClickActivationResult howToHandleClick;
NSWindow* win = get_nswindow ();
cerr << "Carbon event for " << au->name();
switch (eventKind) { switch (eventKind) {
case kEventWindowHandleActivate:
[win makeMainWindow];
return eventNotHandledErr;
break;
case kEventWindowHandleDeactivate: case kEventWindowHandleDeactivate:
// don't allow window to get deactivated while app is active return eventNotHandledErr;
// (do this only if you are a floating window that doesn't hide)
cerr << " deactivate!";
ActivateWindow(carbon_window, TRUE);
break; break;
case kEventWindowGetClickActivation: case kEventWindowGetClickActivation:
cerr << " click activate!";
howToHandleClick = kActivateAndHandleClick; howToHandleClick = kActivateAndHandleClick;
SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult, SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult,
sizeof(ClickActivationResult), &howToHandleClick); sizeof(ClickActivationResult), &howToHandleClick);
break; break;
} }
cerr << "\n";
return noErr; return noErr;
} }
@ -407,7 +394,8 @@ AUPluginUI::parent_carbon_window ()
EventTypeSpec windowEventTypes[] = { EventTypeSpec windowEventTypes[] = {
{kEventClassWindow, kEventWindowGetClickActivation }, {kEventClassWindow, kEventWindowGetClickActivation },
{kEventClassWindow, kEventWindowHandleDeactivate } {kEventClassWindow, kEventWindowHandleDeactivate },
{kEventClassWindow, kEventWindowHandleActivate }
}; };
EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event); EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event);
@ -420,6 +408,7 @@ AUPluginUI::parent_carbon_window ()
[win addChildWindow:cocoa_parent ordered:NSWindowAbove]; [win addChildWindow:cocoa_parent ordered:NSWindowAbove];
[win setLevel:NSFloatingWindowLevel]; [win setLevel:NSFloatingWindowLevel];
[win setHidesOnDeactivate:YES];
carbon_parented = true; carbon_parented = true;
@ -435,8 +424,90 @@ AUPluginUI::parent_cocoa_window ()
return -1; return -1;
} }
Gtk::Container* toplevel = get_toplevel();
if (!toplevel || !toplevel->is_toplevel()) {
error << _("AUPluginUI: no top level window!") << endmsg;
return -1;
}
// Get the size of the new AU View's frame
NSRect au_view_frame = [au_view frame];
if (au_view_frame.size.width > 500 || au_view_frame.size.height > 500) {
/* its too big - use a scrollview */
NSRect frameRect = [[cocoa_window contentView] frame];
scroll_view = [[[NSScrollView alloc] initWithFrame:frameRect] autorelease];
[scroll_view setDrawsBackground:NO];
[scroll_view setHasHorizontalScroller:YES];
[scroll_view setHasVerticalScroller:YES];
NSSize frameSize = [NSScrollView frameSizeForContentSize:au_view_frame.size
hasHorizontalScroller:[scroll_view hasHorizontalScroller]
hasVerticalScroller:[scroll_view hasVerticalScroller]
borderType:[scroll_view borderType]];
// Create a new frame with same origin as current
// frame but size equal to the size of the new view
NSRect newFrame;
newFrame.origin = [scroll_view frame].origin;
newFrame.size = frameSize;
// Set the new frame and document views on the scroll view
NSRect currentFrame = [scroll_view frame];
[scroll_view setFrame:newFrame];
[scroll_view setDocumentView:au_view];
cerr << "scroll view size is " << newFrame.size.width << " x " << newFrame.size.height << endl;
NSSize oldContentSize = [[cocoa_window contentView] frame].size;
NSSize newContentSize = oldContentSize;
cerr << "original size is " << newContentSize.width << " x " << newContentSize.height << endl;
newContentSize.width += (newFrame.size.width - currentFrame.size.width);
newContentSize.height += (newFrame.size.height - currentFrame.size.height);
[cocoa_window setContentSize:newContentSize];
[cocoa_window setContentView:scroll_view];
} else {
[cocoa_window setContentSize:au_view_frame.size];
[cocoa_window setContentView:au_view];
}
/* compute how tall the title bar is, because we have to offset the position of the child window
by that much.
*/
NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]];
NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]];
int titlebar_height = wm_frame.size.height - content_frame.size.height;
// move cocoa window into position relative to the toplevel window
NSRect view_frame = [[cocoa_window contentView] frame];
view_frame.origin.x = content_frame.origin.x;
view_frame.origin.y = content_frame.origin.y;
[cocoa_window setFrame:view_frame display:NO];
/* make top level window big enough to hold cocoa window and titlebar */
content_frame.size.width = view_frame.size.width;
content_frame.size.height = view_frame.size.height + titlebar_height;
[win setFrame:content_frame display:NO];
/* now make cocoa window a child of this top level */
[win addChildWindow:cocoa_window ordered:NSWindowAbove]; [win addChildWindow:cocoa_window ordered:NSWindowAbove];
[win setLevel:NSFloatingWindowLevel]; // [win setLevel:NSFloatingWindowLevel];
[win setHidesOnDeactivate:YES];
cocoa_parented = true; cocoa_parented = true;
@ -469,9 +540,9 @@ AUPluginUI::on_show ()
VBox::on_show (); VBox::on_show ();
if (cocoa_window) { if (cocoa_window) {
// [cocoa_window setIsVisible:YES]; [cocoa_window setIsVisible:YES];
} else if (carbon_window) { } else if (carbon_window) {
// [cocoa_parent setIsVisible:YES]; [cocoa_parent setIsVisible:YES];
} }
} }

View file

@ -21,8 +21,11 @@
#include "ardour_ui.h" #include "ardour_ui.h"
#include "actions.h" #include "actions.h"
#include "opts.h"
#include "sync-menu.h" #include "sync-menu.h"
#include <Appkit/Appkit.h>
sigc::signal<void,bool> ApplicationActivationChanged; sigc::signal<void,bool> ApplicationActivationChanged;
static EventHandlerRef application_event_handler_ref; static EventHandlerRef application_event_handler_ref;
@ -107,4 +110,13 @@ ARDOUR_UI::platform_specific ()
applicationEventTypes, 0, &application_event_handler_ref); applicationEventTypes, 0, &application_event_handler_ref);
} }
void
ARDOUR_UI::platform_setup ()
{
if (!ARDOUR_COMMAND_LINE::finder_invoked_ardour) {
/* if invoked from the command line, make sure we're visible */
[NSApp activateIgnoringOtherApps:YES];
}
}

View file

@ -40,6 +40,7 @@ char* ARDOUR_COMMAND_LINE::curvetest_file = 0;
bool ARDOUR_COMMAND_LINE::try_hw_optimization = true; bool ARDOUR_COMMAND_LINE::try_hw_optimization = true;
Glib::ustring ARDOUR_COMMAND_LINE::keybindings_path = ""; /* empty means use builtin default */ Glib::ustring ARDOUR_COMMAND_LINE::keybindings_path = ""; /* empty means use builtin default */
Glib::ustring ARDOUR_COMMAND_LINE::menus_file = "ardour.menus"; Glib::ustring ARDOUR_COMMAND_LINE::menus_file = "ardour.menus";
bool ARDOUR_COMMAND_LINE::finder_invoked_ardour = false;
using namespace ARDOUR_COMMAND_LINE; using namespace ARDOUR_COMMAND_LINE;
@ -142,6 +143,7 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[])
case 'p': case 'p':
//undocumented OS X finder -psn_XXXXX argument //undocumented OS X finder -psn_XXXXX argument
finder_invoked_ardour = true;
break; break;
case 'S': case 'S':

View file

@ -37,6 +37,7 @@ extern bool try_hw_optimization;
extern bool use_gtk_theme; extern bool use_gtk_theme;
extern Glib::ustring keybindings_path; extern Glib::ustring keybindings_path;
extern Glib::ustring menus_file; extern Glib::ustring menus_file;
extern bool finder_invoked_ardour;
extern int32_t parse_opts (int argc, char *argv[]); extern int32_t parse_opts (int argc, char *argv[]);

View file

@ -175,13 +175,11 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr<PluginInsert> insert)
void void
PluginUIWindow::app_activated (bool yn) PluginUIWindow::app_activated (bool yn)
{ {
#if defined(HAVE_AUDIOUNITS) && defined(GTKOSX) #if defined (HAVE_AUDIOUNITS) && defined(GTKOSX)
if (yn) { if (yn) {
ARDOUR_UI::instance()->the_editor().ensure_float (*this); _pluginui->activate ();
show ();
} else {
hide ();
} }
cerr << "activated ? " << yn << endl;
#endif #endif
} }

View file

@ -73,6 +73,9 @@ class PlugUIBase : public virtual sigc::trackable
virtual gint get_preferred_width () = 0; virtual gint get_preferred_width () = 0;
virtual bool start_updating(GdkEventAny*) = 0; virtual bool start_updating(GdkEventAny*) = 0;
virtual bool stop_updating(GdkEventAny*) = 0; virtual bool stop_updating(GdkEventAny*) = 0;
virtual void activate () {}
virtual void deactivate () {}
protected: protected:
boost::shared_ptr<ARDOUR::PluginInsert> insert; boost::shared_ptr<ARDOUR::PluginInsert> insert;

View file

@ -1078,8 +1078,6 @@ RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
/* it's an insert */ /* it's an insert */
cerr << "the plugin insert, that is\n";
boost::shared_ptr<PluginInsert> plugin_insert; boost::shared_ptr<PluginInsert> plugin_insert;
boost::shared_ptr<PortInsert> port_insert; boost::shared_ptr<PortInsert> port_insert;

View file

@ -4,3 +4,8 @@ void
ARDOUR_UI::platform_specific () ARDOUR_UI::platform_specific ()
{ {
} }
void
ARDOUR_UI::platform_setup ()
{
}

View file

@ -26,6 +26,9 @@
#include <glib/gconvert.h> #include <glib/gconvert.h>
#include <glib/gmessages.h> #include <glib/gmessages.h>
#include <glib/gunicode.h> #include <glib/gunicode.h>
#ifndef g_assert
#include <glib/gtestutils.h>
#endif
#include <glibmm/utility.h> #include <glibmm/utility.h>

View file

@ -25,6 +25,9 @@
#include <glib/gmem.h> #include <glib/gmem.h>
#include <glib/gmessages.h> #include <glib/gmessages.h>
#ifndef g_assert
#include <glib/gtestutils.h>
#endif
#include <ctime> #include <ctime>
#include <algorithm> #include <algorithm>

View file

@ -22,6 +22,9 @@
#include <glib/gerror.h> #include <glib/gerror.h>
#include <glib/gmessages.h> #include <glib/gmessages.h>
#ifndef g_assert
#include <glib/gtestutils.h>
#endif
#include <map> #include <map>
#include <glibmmconfig.h> #include <glibmmconfig.h>

View file

@ -21,6 +21,9 @@
*/ */
#include <glib/gmessages.h> #include <glib/gmessages.h>
#ifndef g_assert
#include <glib/gtestutils.h>
#endif
#include <glibmm/exception.h> #include <glibmm/exception.h>