diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-05-20 02:16:05 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-05-20 02:16:05 +0000 |
commit | 8730620fed4576c732c8818625861ad515fa3eb6 (patch) | |
tree | 8e35ea428401823730c8b6b83734d7468f680128 /gtk2_ardour | |
parent | c22d09f9ca90f14e5c8b3aa73313304d3f9bd460 (diff) |
make AU Cocoa plugin views with "client-side-windows" versions of GTK+; make keyboard event forwarding work for AU Cocoa plugin views
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@7124 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/au_pluginui.h | 8 | ||||
-rw-r--r-- | gtk2_ardour/au_pluginui.mm | 63 | ||||
-rw-r--r-- | gtk2_ardour/plugin_ui.cc | 34 | ||||
-rw-r--r-- | gtk2_ardour/plugin_ui.h | 7 |
4 files changed, 90 insertions, 22 deletions
diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h index ea257f4efd..429f768fb0 100644 --- a/gtk2_ardour/au_pluginui.h +++ b/gtk2_ardour/au_pluginui.h @@ -61,6 +61,7 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox bool on_map_event (GdkEventAny*); bool on_focus_in_event (GdkEventFocus*); bool on_focus_out_event (GdkEventFocus*); + void forward_key_event (GdkEventKey*); OSStatus carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event); @@ -69,9 +70,9 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox int prefheight; int prefwidth; - Gtk::HBox top_box; - Gtk::EventBox low_box; - Gtk::VBox vpacker; + Gtk::HBox top_box; + Gtk::HBox low_box; + Gtk::VBox vpacker; Gtk::Label automation_mode_label; Gtk::ComboBoxText automation_mode_selector; Gtk::Label preset_label; @@ -91,7 +92,6 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox WindowRef carbon_window; EventHandlerRef carbon_event_handler; bool _activating_from_app; - NSView* packView; NotificationObject* _notify; bool test_cocoa_view_support (); diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index f6ba181adf..100f137631 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -175,7 +175,6 @@ AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert) _notify = 0; cocoa_window = 0; au_view = 0; - packView = 0; editView = 0; /* prefer cocoa, fall back to cocoa, but use carbon if its there */ @@ -209,12 +208,12 @@ AUPluginUI::~AUPluginUI () CloseComponent (editView); } - if (packView) { + if (au_view) { /* remove whatever we packed into low_box so that GTK doesn't mess with it. */ - [packView removeFromSuperview]; + [au_view removeFromSuperview]; } } @@ -368,8 +367,6 @@ AUPluginUI::create_cocoa_view () [(AUGenericView *)au_view setShowsExpertParameters:YES]; } - packView = au_view; - // watch for size changes of the view [[NSNotificationCenter defaultCenter] addObserver:_notify @@ -382,6 +379,9 @@ AUPluginUI::create_cocoa_view () packFrame = [au_view frame]; prefwidth = packFrame.size.width; prefheight = packFrame.size.height; + low_box.set_size_request (prefwidth, prefheight); + + cerr << "AU Cocoa plugin PREF view is " << packFrame.size.width << " x " << packFrame.size.height << endl; return 0; } @@ -549,20 +549,61 @@ AUPluginUI::parent_cocoa_window () error << _("AUPluginUI: no top level window!") << endmsg; return -1; } + + cerr << "AU Cocoa plugin view is " << prefwidth << " x " << prefheight << endl; - // Get the size of the new AU View's frame - packFrame = [au_view frame]; + NSView* view = gdk_quartz_window_get_nsview (get_toplevel()->get_window()->gobj()); + GtkRequisition a = top_box.size_request (); - NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj()); + /* move the au_view down so that it doesn't overlap the top_box contents */ - [view setFrame:packFrame]; - [view addSubview:packView]; + NSPoint origin = { 0, a.height }; - low_box.set_size_request (packFrame.size.width, packFrame.size.height); + [au_view setFrameOrigin:origin]; + [view addSubview:au_view]; return 0; } +static void +dump_view_tree (NSView* view, int depth) +{ + NSArray* subviews = [view subviews]; + unsigned long cnt = [subviews count]; + + for (int d = 0; d < depth; d++) { + cerr << '\t'; + } + cerr << " view @ " << view << endl; + + for (unsigned long i = 0; i < cnt; ++i) { + NSView* subview = [subviews objectAtIndex:i]; + dump_view_tree (subview, depth+1); + } +} + +void +AUPluginUI::forward_key_event (GdkEventKey* ev) +{ + NSEvent* nsevent = gdk_quartz_event_get_nsevent ((GdkEvent*)ev); + + if (au_view && nsevent) { + + /* filter on nsevent type here because GDK massages FlagsChanged + messages into GDK_KEY_{PRESS,RELEASE} but Cocoa won't + handle a FlagsChanged message as a keyDown or keyUp + */ + + if ([nsevent type] == NSKeyDown) { + [[[au_view window] firstResponder] keyDown:nsevent]; + } else if ([nsevent type] == NSKeyUp) { + [[[au_view window] firstResponder] keyUp:nsevent]; + } else if ([nsevent type] == NSFlagsChanged) { + [[[au_view window] firstResponder] flagsChanged:nsevent]; + } + } +} + void AUPluginUI::on_realize () { diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 7cdd132d8a..4a006a1d45 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -71,8 +71,8 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert : parent (win) { bool have_gui = false; - non_gtk_gui = false; was_visible = false; + _keyboard_focused = false; if (insert->plugin()->has_editor()) { switch (insert->type()) { @@ -110,6 +110,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert GenericPluginUI* pu = new GenericPluginUI (insert, scrollable); _pluginui = pu; + _pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); add (*pu); set_wmclass (X_("ardour_plugin_editor"), PROGRAM_NAME); @@ -243,11 +244,11 @@ PluginUIWindow::create_vst_editor(boost::shared_ptr<PluginInsert> insert) VSTPluginUI* vpu = new VSTPluginUI (insert, vp); _pluginui = vpu; + _pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); add (*vpu); vpu->package (*this); } - non_gtk_gui = true; return true; #endif } @@ -260,8 +261,8 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr<PluginInsert> insert) #else VBox* box; _pluginui = create_au_gui (insert, &box); + _pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); add (*box); - non_gtk_gui = true; Application::instance()->ActivationChanged.connect (mem_fun (*this, &PluginUIWindow::app_activated)); @@ -309,21 +310,40 @@ PluginUIWindow::create_lv2_editor(boost::shared_ptr<PluginInsert> insert) lpu->package (*this); } - non_gtk_gui = false; return true; #endif } +void +PluginUIWindow::keyboard_focused (bool yn) +{ + _keyboard_focused = yn; +} + bool PluginUIWindow::on_key_press_event (GdkEventKey* event) { - return relay_key_press (event, this); + if (_keyboard_focused) { + if (_pluginui) { + _pluginui->forward_key_event (event); + } + return true; + } else { + return relay_key_press (event, this); + } } bool PluginUIWindow::on_key_release_event (GdkEventKey* event) { - return true; + if (_keyboard_focused) { + if (_pluginui) { + _pluginui->forward_key_event (event); + } + return false; + } else { + return true; + } } void @@ -466,12 +486,14 @@ PlugUIBase::focus_toggled (GdkEventButton* ev) focus_button.add (*focus_out_image); focus_out_image->show (); ARDOUR_UI::instance()->set_tip (&focus_button, string_compose (_("Click to allow the plugin to receive keyboard events that %1 would normally use as a shortcut"), PROGRAM_NAME).c_str(), ""); + KeyboardFocused (false); } else { Keyboard::the_keyboard().magic_widget_grab_focus(); focus_button.remove (); focus_button.add (*focus_in_image); focus_in_image->show (); ARDOUR_UI::instance()->set_tip (&focus_button, string_compose (_("Click to allow normal use of %1 keyboard shortcuts"), PROGRAM_NAME).c_str(), ""); + KeyboardFocused (true); } return true; diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index e0ea569207..be328f5e55 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -85,6 +85,10 @@ class PlugUIBase : public virtual sigc::trackable virtual bool on_window_show(const Glib::ustring& title) { return true; } virtual void on_window_hide() {} + virtual void forward_key_event (GdkEventKey*) {} + + sigc::signal<void,bool> KeyboardFocused; + protected: boost::shared_ptr<ARDOUR::PluginInsert> insert; boost::shared_ptr<ARDOUR::Plugin> plugin; @@ -241,8 +245,9 @@ class PluginUIWindow : public Gtk::Window sigc::connection death_connection; Gtk::Window* parent; Gtk::VBox vbox; - bool non_gtk_gui; bool was_visible; + bool _keyboard_focused; + void keyboard_focused (bool yn); void app_activated (bool); void plugin_going_away (); |