summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-01-13 02:08:37 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-01-13 02:08:37 +0000
commitbab9bc0bd2c3e1f0abf3bfb75c1777cda0506a8d (patch)
tree58be8194dde3eb6f397b03a8d3fb80b3d96dc534
parent52b3424649a3826fac372f1636ab08f280dc8fd3 (diff)
fix handling of carbon AU GUIs, and start to remove Carbon (so far: no more use of Carbon for app activation, or open files events)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6484 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/au_pluginui.h16
-rw-r--r--gtk2_ardour/au_pluginui.mm175
-rw-r--r--gtk2_ardour/cocoacarbon.mm156
-rw-r--r--gtk2_ardour/plugin_ui.cc8
4 files changed, 166 insertions, 189 deletions
diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h
index 481378e413..36c7226e72 100644
--- a/gtk2_ardour/au_pluginui.h
+++ b/gtk2_ardour/au_pluginui.h
@@ -28,6 +28,16 @@ namespace ARDOUR {
class Redirect;
}
+class AUPluginUI;
+
+@interface NotificationObject : NSObject {
+ @private
+ AUPluginUI* plugin_ui;
+ NSWindow* cocoa_parent;
+ NSWindow* top_level_parent;
+}
+@end
+
class AUPluginUI : public PlugUIBase, public Gtk::VBox
{
public:
@@ -42,10 +52,11 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox
void activate ();
void deactivate ();
+ bool on_window_show (const Glib::ustring&);
+ void on_window_hide ();
+
void lower_box_realized ();
void on_realize ();
- void on_show ();
- void on_hide ();
bool on_map_event (GdkEventAny*);
bool on_focus_in_event (GdkEventFocus*);
bool on_focus_out_event (GdkEventFocus*);
@@ -80,6 +91,7 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox
EventHandlerRef carbon_event_handler;
bool _activating_from_app;
NSView* packView;
+ NotificationObject* _notify;
bool test_cocoa_view_support ();
bool test_carbon_view_support ();
diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm
index 1a197c6672..08cd3bf09e 100644
--- a/gtk2_ardour/au_pluginui.mm
+++ b/gtk2_ardour/au_pluginui.mm
@@ -45,6 +45,70 @@ static const gchar* _automation_mode_strings[] = {
0
};
+@implementation NotificationObject
+
+- (NotificationObject*) initWithPluginUI: (AUPluginUI*) apluginui andCocoaParent: (NSWindow*) cp andTopLevelParent: (NSWindow*) tlp
+{
+ self = [ super init ];
+
+ if (self) {
+ plugin_ui = apluginui;
+ cocoa_parent = cp;
+ top_level_parent = tlp;
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(cocoaParentActivationHandler:)
+ name:NSWindowDidBecomeMainNotification
+ object:nil];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(cocoaParentBecameKeyHandler:)
+ name:NSWindowDidBecomeKeyNotification
+ object:nil];
+ }
+
+ return self;
+}
+
+- (void)cocoaParentActivationHandler:(NSNotification *)notification
+{
+ NSWindow* notification_window = (NSWindow *)[notification object];
+
+ if (top_level_parent == notification_window || cocoa_parent == notification_window) {
+ if ([notification_window isMainWindow]) {
+ plugin_ui->activate();
+ } else {
+ plugin_ui->deactivate();
+ }
+ }
+}
+
+- (void)cocoaParentBecameKeyHandler:(NSNotification *)notification
+{
+ NSWindow* notification_window = (NSWindow *)[notification object];
+
+ cerr << "KeyNotification Handler\n";
+
+ if (top_level_parent == notification_window || cocoa_parent == notification_window) {
+ cerr << "\tKeyHandler, top level parent is key: " << ([top_level_parent isKeyWindow] ? "yes" : "no") << endl;
+ cerr << "\tKeyHandler, cocoa parent is key: " << ([cocoa_parent isKeyWindow] ? "yes" : "no") << endl;
+
+ if ([notification_window isKeyWindow]) {
+ cerr << "\t\tActivating plugin UI\n";
+ plugin_ui->activate();
+ } else {
+ cerr << "\t\tDeActivating plugin UI\n";
+ plugin_ui->deactivate();
+ }
+ } else {
+ cerr << "\tsome other window become Key (" << notification_window << ") CP is " << cocoa_parent << "\n";
+ }
+}
+
+
+
+@end
+
AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
: PlugUIBase (insert)
, automation_mode_label (_("Automation"))
@@ -102,6 +166,7 @@ AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
_activating_from_app = false;
cocoa_parent = 0;
+ _notify = 0;
cocoa_window = 0;
au_view = 0;
packView = 0;
@@ -124,8 +189,9 @@ AUPluginUI::~AUPluginUI ()
{
if (cocoa_parent) {
NSWindow* win = get_nswindow();
- RemoveEventHandler(carbon_event_handler);
+ [[NSNotificationCenter defaultCenter] removeObserver:_notify];
[win removeChildWindow:cocoa_parent];
+
} else if (carbon_window) {
/* not parented, just overlaid on top of our window */
DisposeWindow (carbon_window);
@@ -389,70 +455,14 @@ AUPluginUI::get_nswindow ()
void
AUPluginUI::activate ()
{
- if (carbon_window && cocoa_parent) {
- cerr << "APP activated, activate carbon window " << insert->name() << endl;
- _activating_from_app = true;
- ActivateWindow (carbon_window, TRUE);
- _activating_from_app = false;
- [cocoa_parent makeKeyAndOrderFront:nil];
- }
+ ActivateWindow (carbon_window, TRUE);
+ // [cocoa_parent makeKeyAndOrderFront:nil];
}
void
AUPluginUI::deactivate ()
{
- return;
- cerr << "APP DEactivated, for " << insert->name() << endl;
- _activating_from_app = true;
ActivateWindow (carbon_window, FALSE);
- _activating_from_app = false;
-}
-
-
-OSStatus
-_carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
-{
- return ((AUPluginUI*)userData)->carbon_event (nextHandlerRef, event);
-}
-
-OSStatus
-AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event)
-{
- cerr << "CARBON EVENT\n";
-
- UInt32 eventKind = GetEventKind(event);
- ClickActivationResult howToHandleClick;
- NSWindow* win = get_nswindow ();
-
- cerr << "window " << win << " carbon event type " << eventKind << endl;
-
- switch (eventKind) {
- case kEventWindowHandleActivate:
- cerr << "carbon window for " << insert->name() << " activated\n";
- if (_activating_from_app) {
- cerr << "app activation, ignore window activation\n";
- return noErr;
- }
- [win makeMainWindow];
- return eventNotHandledErr;
- break;
-
- case kEventWindowHandleDeactivate:
- cerr << "carbon window for " << insert->name() << " would have been deactivated\n";
- // never deactivate the carbon window
- return noErr;
- break;
-
- case kEventWindowGetClickActivation:
- cerr << "carbon window CLICK activated\n";
- [win makeKeyAndOrderFront:nil];
- howToHandleClick = kActivateAndHandleClick;
- SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult,
- sizeof(ClickActivationResult), &howToHandleClick);
- break;
- }
-
- return noErr;
}
int
@@ -491,18 +501,9 @@ AUPluginUI::parent_carbon_window ()
// create the cocoa window for the carbon one and make it visible
cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
- EventTypeSpec windowEventTypes[] = {
- {kEventClassWindow, kEventWindowGetClickActivation },
- {kEventClassWindow, kEventWindowHandleDeactivate }
- };
-
- EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event);
- OSStatus result = InstallWindowEventHandler (carbon_window, ehUPP,
- sizeof(windowEventTypes) / sizeof(EventTypeSpec),
- windowEventTypes, this, &carbon_event_handler);
- if (result != noErr) {
- return -1;
- }
+ SetWindowActivationScope (carbon_window, kWindowActivationScopeNone);
+
+ _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ];
[win addChildWindow:cocoa_parent ordered:NSWindowAbove];
@@ -564,13 +565,6 @@ AUPluginUI::lower_box_realized ()
}
}
-void
-AUPluginUI::on_hide ()
-{
- // VBox::on_hide ();
- cerr << "AU plugin window hidden\n";
-}
-
bool
AUPluginUI::on_map_event (GdkEventAny* ev)
{
@@ -578,20 +572,31 @@ AUPluginUI::on_map_event (GdkEventAny* ev)
}
void
-AUPluginUI::on_show ()
+AUPluginUI::on_window_hide ()
{
- cerr << "AU plugin window shown\n";
+ if (carbon_window) {
+ HideWindow (carbon_window);
+ ActivateWindow (carbon_window, FALSE);
+ }
- VBox::on_show ();
+ hide_all ();
+}
+
+bool
+AUPluginUI::on_window_show (const Glib::ustring& title)
+{
+ /* this is idempotent so just call it every time we show the window */
gtk_widget_realize (GTK_WIDGET(low_box.gobj()));
- if (au_view) {
- show_all ();
- } else if (carbon_window) {
- [cocoa_parent setIsVisible:YES];
+ show_all ();
+
+ if (carbon_window) {
ShowWindow (carbon_window);
+ ActivateWindow (carbon_window, TRUE);
}
+
+ return true;
}
bool
diff --git a/gtk2_ardour/cocoacarbon.mm b/gtk2_ardour/cocoacarbon.mm
index e4f833dd26..c39bbe5ed9 100644
--- a/gtk2_ardour/cocoacarbon.mm
+++ b/gtk2_ardour/cocoacarbon.mm
@@ -16,145 +16,94 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <Carbon/Carbon.h>
-#undef check // stupid, stupid carbon
-#undef YES // stupid, stupid gtkmm and/or NSObjC
-#undef NO // ditto
+#include <Carbon/Carbon.h> // bring it in early
+#undef check // nuke this stupidity
+#define APPLE_SAYS_YES YES
+#undef YES // and this
+#undef NO // and this
#include "ardour_ui.h"
#include "actions.h"
#include "opts.h"
#include <gtkmm2ext/sync-menu.h>
-
-#include <Appkit/Appkit.h>
#include <gdk/gdkquartz.h>
sigc::signal<void,bool> ApplicationActivationChanged;
-static EventHandlerRef application_event_handler_ref;
-/* Called for clicks on the dock icon. Can be used to unminimize or
- * create a new window for example.
- */
+@interface AppNotificationObject : NSObject {}
+- (AppNotificationObject*) init;
+@end
-static OSErr
-handle_reopen_application (const AppleEvent *inAppleEvent,
- AppleEvent *outAppleEvent,
- long inHandlerRefcon)
+@implementation AppNotificationObject
+- (AppNotificationObject*) init
{
- return noErr;
-}
-
+ self = [ super init ];
+
+ if (self) {
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(appDidBecomeActive:)
+ name:NSApplicationDidBecomeActiveNotification
+ object:[NSApplication sharedApplication]];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(appDidBecomeInactive:)
+ name:NSApplicationWillResignActiveNotification
+ object:[NSApplication sharedApplication]];
+ }
-static OSErr
-handle_print_documents (const AppleEvent *inAppleEvent,
- AppleEvent *outAppleEvent,
- long inHandlerRefcon)
-{
- return noErr;
+ return self;
}
-
-static OSErr
-handle_open_documents (const AppleEvent *inAppleEvent,
- AppleEvent *outAppleEvent,
- long inHandlerRefcon)
+- (void)appDidBecomeActive:(NSNotification *)notification
{
- AEDescList docs;
-
- if (AEGetParamDesc(inAppleEvent, keyDirectObject, typeAEList, &docs) == noErr) {
- long n = 0;
- AECountItems(&docs, &n);
- UInt8 strBuffer[PATH_MAX+1];
-
- /* ardour only opens 1 session at a time */
-
- FSRef ref;
-
- if (AEGetNthPtr(&docs, 1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) == noErr) {
- if (FSRefMakePath(&ref, strBuffer, sizeof(strBuffer)) == noErr) {
- Glib::ustring utf8_path ((const char*) strBuffer);
- ARDOUR_UI::instance()->idle_load (utf8_path);
- }
- }
- }
-
- return noErr;
+ ApplicationActivationChanged (true);
}
-static OSErr
-handle_open_application (const AppleEvent *inAppleEvent,
- AppleEvent *outAppleEvent,
- long inHandlerRefcon)
+- (void)appDidBecomeInactive:(NSNotification *)notification
{
- return noErr;
+ ApplicationActivationChanged (false);
}
-static OSStatus
-application_event_handler (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
+@end
+
+@interface ArdourApplicationDelegate : NSObject {}
+@end
+
+@implementation ArdourApplicationDelegate
+-(BOOL) application:(NSApplication*) theApplication openFile:(NSString*) file
{
- UInt32 eventKind = GetEventKind (event);
-
- switch (eventKind) {
- case kEventAppActivated:
- ApplicationActivationChanged (true); // EMIT SIGNAL
- return eventNotHandledErr;
-
- case kEventAppDeactivated:
- ApplicationActivationChanged (false); // EMIT SIGNAL
- return eventNotHandledErr;
-
- default:
- // pass-thru all kEventClassApplication events we're not interested in.
- break;
- }
- return eventNotHandledErr;
+ Glib::ustring utf8_path ([file UTF8String]);
+ ARDOUR_UI::instance()->idle_load (utf8_path);
+ return APPLE_SAYS_YES;
}
+@end
void
ARDOUR_UI::platform_specific ()
{
- Gtk::Widget* widget = ActionManager::get_widget ("/ui/Main/Session/Quit");
+ Gtk::Widget* widget;
+
+ cerr << "Plaform specific GUI stuff\n";
+
+ widget = ActionManager::get_widget ("/ui/Main/Session/Quit");
if (widget) {
ige_mac_menu_set_quit_menu_item ((GtkMenuItem*) widget->gobj());
}
IgeMacMenuGroup* group = ige_mac_menu_add_app_menu_group ();
- widget = ActionManager::get_widget ("/ui/Main/Session/About");
+ widget = ActionManager::get_widget ("/ui/Main/Help/About");
if (widget) {
ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0);
}
- widget = ActionManager::get_widget ("/ui/Main/Session/ToggleOptionsEditor");
+ widget = ActionManager::get_widget ("/ui/Main/WindowMenu/ToggleOptionsEditor");
if (widget) {
ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0);
}
-}
-void
-ARDOUR_UI::platform_setup ()
-{
- AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
- handle_open_documents, 0, true);
+ [ NSApp finishLaunching ];
- AEInstallEventHandler (kCoreEventClass, kAEOpenApplication,
- handle_open_application, 0, true);
-
- AEInstallEventHandler (kCoreEventClass, kAEReopenApplication,
- handle_reopen_application, 0, true);
-
- AEInstallEventHandler (kCoreEventClass, kAEPrintDocuments,
- handle_print_documents, 0, true);
-
- EventTypeSpec applicationEventTypes[] = {
- {kEventClassApplication, kEventAppActivated },
- {kEventClassApplication, kEventAppDeactivated }
- };
-
- EventHandlerUPP ehUPP = NewEventHandlerUPP (application_event_handler);
-
- InstallApplicationEventHandler (ehUPP, sizeof(applicationEventTypes) / sizeof(EventTypeSpec),
- applicationEventTypes, 0, &application_event_handler_ref);
if (!ARDOUR_COMMAND_LINE::finder_invoked_ardour) {
/* if invoked from the command line, make sure we're visible */
@@ -163,6 +112,17 @@ ARDOUR_UI::platform_setup ()
}
}
+void
+ARDOUR_UI::platform_setup ()
+{
+ /* this will stick around for ever ... is that OK ? */
+
+ [ [AppNotificationObject alloc] init];
+
+ [ NSApp setDelegate: [ArdourApplicationDelegate new]];
+
+}
+
bool
cocoa_open_url (const char* uri)
{
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index f38776d55c..c0189bbc05 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -191,7 +191,7 @@ void
PluginUIWindow::on_show ()
{
set_role("plugin_ui");
-
+
if (_pluginui) {
_pluginui->update_presets ();
}
@@ -200,7 +200,7 @@ PluginUIWindow::on_show ()
if (_pluginui->on_window_show (_title)) {
Window::on_show ();
}
- }
+ }
if (parent) {
// set_transient_for (*parent);
@@ -273,12 +273,12 @@ void
PluginUIWindow::app_activated (bool yn)
{
#if defined (HAVE_AUDIOUNITS) && defined(GTKOSX)
- cerr << "APP activated ? " << yn << endl;
if (_pluginui) {
if (yn) {
if (was_visible) {
_pluginui->activate ();
- present ();
+ // present ();
+ show ();
was_visible = true;
}
} else {