diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index b54f5d1897..8505655787 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -92,7 +92,6 @@ au_pluginui.mm """) gtkosx_files=Split(""" -sync-menu.c cocoacarbon.mm """) diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index 1e8ba7cc71..16f00955f3 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -66,7 +66,6 @@ - diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 5fda922f86..b671ac2a0f 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -338,7 +338,11 @@ ARDOUR_UI::post_engine () /* set default clock modes */ - primary_clock.set_mode (AudioClock::SMPTE); + if (Profile->get_sae()) { + primary_clock.set_mode (AudioClock::MinSec); + } else { + primary_clock.set_mode (AudioClock::SMPTE); + } secondary_clock.set_mode (AudioClock::BBT); /* start the time-of-day-clock */ diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index a78d4dc61c..98175c4009 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -37,7 +37,10 @@ #include "engine_dialog.h" #include "editor.h" #include "actions.h" -#include "sync-menu.h" + +#ifdef GTKOSX +#include +#endif #include #include diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h index 5bec967091..a1ee63be77 100644 --- a/gtk2_ardour/au_pluginui.h +++ b/gtk2_ardour/au_pluginui.h @@ -34,7 +34,8 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox virtual void activate (); virtual void deactivate (); - + + void lower_box_realized (); void on_realize (); void on_show (); void on_hide (); @@ -48,6 +49,10 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox boost::shared_ptr au; int prefheight; int prefwidth; + + Gtk::HBox top_box; + Gtk::EventBox low_box; + Gtk::VBox vpacker; /* Cocoa */ @@ -62,14 +67,11 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox AudioUnitCarbonView editView; WindowRef carbon_window; EventHandlerRef carbon_event_handler; - bool carbon_parented; - bool cocoa_parented; bool _activating_from_app; - void test_view_support (bool&, bool&); bool test_cocoa_view_support (); bool test_carbon_view_support (); - int create_carbon_view (bool generic); + int create_carbon_view (); int create_cocoa_view (); int parent_carbon_window (); diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index d2bdecfe60..988701a925 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -2,6 +2,9 @@ #include #include +#undef check // stupid gtk, stupid apple + +#include #include #include "au_pluginui.h" @@ -32,43 +35,54 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) throw failed_constructor (); } - bool has_carbon; - bool has_cocoa; + /* stuff some stuff into the top of the window */ + + Gtk::Button* button = manage (new Gtk::Button ("press me")); + Gtk::Label* label = manage (new Gtk::Label ("hello, world!")); + + top_box.set_spacing (6); + top_box.set_border_width (6); + top_box.pack_start (*button, false, false); + top_box.pack_start (*label, false, true); + + set_spacing (6); + pack_start (top_box, false, false); + pack_start (low_box, false, false); + + button->show (); + label->show (); + top_box.show (); + low_box.show (); _activating_from_app = false; - carbon_parented = false; - cocoa_parented = false; cocoa_parent = 0; cocoa_window = 0; au_view = 0; - test_view_support (has_carbon, has_cocoa); + /* prefer cocoa, fall back to cocoa, but use carbon if its there */ - if (has_cocoa) { + if (test_cocoa_view_support()) { create_cocoa_view (); - } else if (has_carbon) { - create_carbon_view (has_carbon); + } else if (test_carbon_view_support()) { + create_carbon_view (); } else { - /* fallback to cocoa */ create_cocoa_view (); } -} + low_box.signal_realize().connect (mem_fun (this, &AUPluginUI::lower_box_realized)); +} AUPluginUI::~AUPluginUI () { - if (carbon_parented) { + if (cocoa_parent) { NSWindow* win = get_nswindow(); RemoveEventHandler(carbon_event_handler); [win removeChildWindow:cocoa_parent]; + } else if (carbon_window) { + /* never parented */ + DisposeWindow (carbon_window); } -} -void -AUPluginUI::test_view_support (bool& has_carbon, bool& has_cocoa) -{ - has_carbon = test_carbon_view_support(); - has_cocoa = test_cocoa_view_support(); } bool @@ -216,24 +230,16 @@ AUPluginUI::create_cocoa_view () } if (!wasAbleToLoadCustomView) { - // [B] Otherwise show generic Cocoa view + // load generic Cocoa view au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()]; [(AUGenericView *)au_view setShowsExpertParameters:YES]; } - /* make a child cocoa window */ - - cocoa_window = [[NSWindow alloc] - initWithContentRect:crect - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO]; - return 0; } int -AUPluginUI::create_carbon_view (bool generic) +AUPluginUI::create_carbon_view () { OSStatus err; ControlRef root_control; @@ -252,7 +258,7 @@ AUPluginUI::create_carbon_view (bool generic) kWindowNoShadowAttribute| 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; return -1; } @@ -277,14 +283,13 @@ AUPluginUI::create_carbon_view (bool generic) GetControlBounds(viewPane, &bounds); size.x = bounds.right-bounds.left; size.y = bounds.bottom-bounds.top; - SizeWindow(carbon_window, (short) (size.x + 0.5), (short) (size.y + 0.5), true); prefwidth = (int) (size.x + 0.5); prefheight = (int) (size.y + 0.5); -#if 0 - mViewPaneResizer->WantEventTypes (GetControlEventTarget(mAUViewPane), GetEventTypeCount(resizeEvent), resizeEvent); -#endif + SizeWindow (carbon_window, prefwidth, prefheight, true); + low_box.set_size_request (prefwidth, prefheight); + return 0; } @@ -311,22 +316,24 @@ AUPluginUI::get_nswindow () void AUPluginUI::activate () { - NSWindow* win = get_nswindow (); - [win setLevel:NSFloatingWindowLevel]; - - if (carbon_parented) { - [cocoa_parent makeKeyAndOrderFront:nil]; - cerr << "APP activated, activate carbon window\n"; + cerr << "AUPluginUI:: activate!\n"; + + 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]; } } void AUPluginUI::deactivate () { - /* nothing to do here */ + cerr << "APP DEactivated, for " << insert->name() << endl; + _activating_from_app = true; + ActivateWindow (carbon_window, FALSE); + _activating_from_app = false; } @@ -339,15 +346,18 @@ _carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userDat OSStatus AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event) { + cerr << "CARBON EVENT\n"; + UInt32 eventKind = GetEventKind(event); ClickActivationResult howToHandleClick; + Gtk::Container* toplevel = get_toplevel(); NSWindow* win = get_nswindow (); cerr << "window " << win << " carbon event type " << eventKind << endl; switch (eventKind) { case kEventWindowHandleActivate: - cerr << "carbon window activated\n"; + cerr << "carbon window for " << insert->name() << " activated\n"; if (_activating_from_app) { cerr << "app activation, ignore window activation\n"; return noErr; @@ -357,12 +367,14 @@ AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event) break; case kEventWindowHandleDeactivate: - cerr << "carbon window deactivated\n"; - return eventNotHandledErr; + cerr << "carbon window for " << insert->name() << " 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); @@ -377,6 +389,8 @@ AUPluginUI::parent_carbon_window () { NSWindow* win = get_nswindow (); int x, y; + int tbx, tby; + if (!win) { return -1; @@ -400,7 +414,9 @@ AUPluginUI::parent_carbon_window () int titlebar_height = wm_frame.size.height - content_frame.size.height; - MoveWindow (carbon_window, x, y + titlebar_height, false); + int packing_extra = 6; // this is the total vertical packing in our top level window + + MoveWindow (carbon_window, x, y + titlebar_height + top_box.get_height() + packing_extra, false); ShowWindow (carbon_window); // create the cocoa window for the carbon one and make it visible @@ -408,8 +424,7 @@ AUPluginUI::parent_carbon_window () EventTypeSpec windowEventTypes[] = { {kEventClassWindow, kEventWindowGetClickActivation }, - {kEventClassWindow, kEventWindowHandleDeactivate }, - {kEventClassWindow, kEventWindowHandleActivate } + {kEventClassWindow, kEventWindowHandleDeactivate } }; EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event); @@ -421,11 +436,7 @@ AUPluginUI::parent_carbon_window () } [win addChildWindow:cocoa_parent ordered:NSWindowAbove]; - [win setLevel:NSFloatingWindowLevel]; - [win setHidesOnDeactivate:YES]; - carbon_parented = true; - return 0; } @@ -433,6 +444,8 @@ int AUPluginUI::parent_cocoa_window () { NSWindow* win = get_nswindow (); + NSView* packView = 0; + NSRect packFrame; if (!win) { return -1; @@ -446,9 +459,11 @@ AUPluginUI::parent_cocoa_window () } // Get the size of the new AU View's frame - NSRect au_view_frame = [au_view frame]; + packFrame = [au_view frame]; + packFrame.origin.x = 0; + packFrame.origin.y = 0; - if (au_view_frame.size.width > 500 || au_view_frame.size.height > 500) { + if (packFrame.size.width > 500 || packFrame.size.height > 500) { /* its too big - use a scrollview */ @@ -458,7 +473,7 @@ AUPluginUI::parent_cocoa_window () [scroll_view setHasHorizontalScroller:YES]; [scroll_view setHasVerticalScroller:YES]; - NSSize frameSize = [NSScrollView frameSizeForContentSize:au_view_frame.size + packFrame.size = [NSScrollView frameSizeForContentSize:packFrame.size hasHorizontalScroller:[scroll_view hasHorizontalScroller] hasVerticalScroller:[scroll_view hasVerticalScroller] borderType:[scroll_view borderType]]; @@ -467,77 +482,25 @@ AUPluginUI::parent_cocoa_window () // frame but size equal to the size of the new view NSRect newFrame; newFrame.origin = [scroll_view frame].origin; - newFrame.size = frameSize; + newFrame.size = packFrame.size; // 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); - -#ifdef PACK_COCOA_INTO_GTK_WINDOW - NSView* view = [win contentView]; + packView = scroll_view; - [win setContentSize:newContentSize]; - [view addSubview:scroll_view]; -#else - [cocoa_window setContentSize:newContentSize]; - [cocoa_window setContentView:scroll_view]; -#endif - } else { -#ifdef PACK_COCOA_INTO_GTK_WINDOW - NSView* view = [win contentView]; - - [win setContentSize:au_view_frame.size]; - [view addSubview:au_view]; -#else - [cocoa_window setContentSize:au_view_frame.size]; - [cocoa_window setContentView:au_view]; -#endif - + packView = 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 */ + NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj()); - [win addChildWindow:cocoa_window ordered:NSWindowAbove]; - [win setLevel:NSFloatingWindowLevel]; - [win setHidesOnDeactivate:YES]; + [view setFrame:packFrame]; + [view addSubview:packView]; - cocoa_parented = true; + low_box.set_size_request (packFrame.size.width, packFrame.size.height); return 0; } @@ -547,16 +510,21 @@ AUPluginUI::on_realize () { VBox::on_realize (); + /* our windows should not have that resize indicator */ + + NSWindow* win = get_nswindow (); + if (win) { + [win setShowsResizeIndicator:NO]; + } +} + +void +AUPluginUI::lower_box_realized () +{ if (au_view) { - - if (parent_cocoa_window ()) { - } - + parent_cocoa_window (); } else if (carbon_window) { - - if (parent_carbon_window ()) { - // ShowWindow (carbon_window); - } + parent_carbon_window (); } } @@ -572,12 +540,15 @@ AUPluginUI::on_map_event (GdkEventAny* ev) { cerr << "AU plugin map event\n"; - if (au_view) { - show_all (); - } else if (carbon_window) { - [cocoa_parent setIsVisible:YES]; - ShowWindow (carbon_window); + if (carbon_window) { + + // move top level GTK window to the correct level + // to keep the stack together and not be sliceable + + NSWindow* win = get_nswindow (); + // [win setLevel:NSFloatingWindowLevel]; } + return false; } @@ -588,6 +559,8 @@ AUPluginUI::on_show () VBox::on_show (); + gtk_widget_realize (GTK_WIDGET(low_box.gobj())); + if (au_view) { show_all (); } else if (carbon_window) { diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index b42a55ad52..c05f2a00c0 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "ardour_ui.h" @@ -1883,7 +1884,9 @@ AudioClock::build_ops_menu () MenuList& ops_items = ops_menu->items(); ops_menu->set_name ("ArdourContextMenu"); - ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); + if (!Profile->get_sae()) { + ops_items.push_back (MenuElem (_("Timecode"), bind (mem_fun(*this, &AudioClock::set_mode), SMPTE))); + } ops_items.push_back (MenuElem (_("Bars:Beats"), bind (mem_fun(*this, &AudioClock::set_mode), BBT))); ops_items.push_back (MenuElem (_("Minutes:Seconds"), bind (mem_fun(*this, &AudioClock::set_mode), MinSec))); ops_items.push_back (MenuElem (_("Samples"), bind (mem_fun(*this, &AudioClock::set_mode), Frames))); diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 7fcab4b493..ad4001b10c 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -771,6 +771,8 @@ AudioRegionView::create_waves () } uint32_t nchans = atv.get_diskstream()->n_channels(); + + cerr << "creating waves for " << _region->name() << " with wfd = " << wait_for_data << " and channels = " << nchans << endl; /* in tmp_waves, set up null pointers for each channel so the vector is allocated */ for (uint32_t n = 0; n < nchans; ++n) { @@ -787,14 +789,16 @@ AudioRegionView::create_waves () if (wait_for_data) { if (audio_region()->source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) { + cerr << "\tData is ready\n"; create_one_wave (n, true); } else { + cerr << "\tdata is not ready\n"; // we'll get a PeaksReady signal from the source in the future // and will call create_one_wave(n) then. } } else { - + cerr << "\tdon't delay, display today!\n"; create_one_wave (n, true); } diff --git a/gtk2_ardour/cocoacarbon.mm b/gtk2_ardour/cocoacarbon.mm index 6317cec6c6..75141d34f6 100644 --- a/gtk2_ardour/cocoacarbon.mm +++ b/gtk2_ardour/cocoacarbon.mm @@ -24,7 +24,7 @@ #include "ardour_ui.h" #include "actions.h" #include "opts.h" -#include "sync-menu.h" +#include #include diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index ad47e086e0..aa385eb7ae 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1142,7 +1142,7 @@ Editor::connect_to_session (Session *t) session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state))); session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change))); session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route))); - session_connections.push_back (session->AudioRegionAdded.connect (mem_fun(*this, &Editor::handle_new_audio_region))); + session_connections.push_back (session->AudioRegionsAdded.connect (mem_fun(*this, &Editor::handle_new_audio_regions))); session_connections.push_back (session->AudioRegionRemoved.connect (mem_fun(*this, &Editor::handle_audio_region_removed))); session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration))); session_connections.push_back (session->edit_group_added.connect (mem_fun(*this, &Editor::add_edit_group))); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 128b9b244e..7313f40df4 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -930,8 +930,10 @@ class Editor : public PublicEditor int ensure_cursor (nframes_t* pos); void handle_new_audio_region (boost::weak_ptr); + void handle_new_audio_regions (vector >& ); void handle_audio_region_removed (boost::weak_ptr); void add_audio_region_to_region_display (boost::shared_ptr); + void add_audio_regions_to_region_display (std::vector > & ); void region_hidden (boost::shared_ptr); void redisplay_regions (); void insert_into_tmp_audio_regionlist(boost::shared_ptr); @@ -961,7 +963,7 @@ class Editor : public PublicEditor void split_region_at (nframes_t); void split_regions_at (nframes_t, RegionSelection&); void split_region_at_transients (); - void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&); + void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret); void crop_region_to_selection (); void crop_region_to (nframes_t start, nframes_t end); void set_sync_point (nframes64_t, const RegionSelection&); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index c915d0c8da..df30834dff 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -1028,11 +1028,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MouseObject: switch (item_type) { case AutomationTrackItem: - dynamic_cast(clicked_trackview)->add_automation_event - (item, - event, - where, - event->button.y); + AutomationTimeAxisView* atv = dynamic_cast(clicked_trackview); + if (atv) { + atv->add_automation_event (item, event, where, event->button.y); + } return true; break; diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 5c3a1590be..92bb403166 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -5198,7 +5198,7 @@ Editor::split_region_at_transients () boost::shared_ptr ar = boost::dynamic_pointer_cast ((*i)->region()); if (ar && (ar->get_transients (positions) == 0)) { - split_region_at_points ((*i)->region(), positions); + split_region_at_points ((*i)->region(), positions, true); positions.clear (); } @@ -5210,10 +5210,11 @@ Editor::split_region_at_transients () } void -Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList& positions) +Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList& positions, bool can_ferret) { boost::shared_ptr ar = boost::dynamic_pointer_cast (r); - + bool use_rhythmic_rodent = false; + if (!ar) { return; } @@ -5227,7 +5228,41 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList if (positions.empty()) { return; } + + + if (positions.size() > 20) { + Glib::ustring msgstr = string_compose (_("You are about to split\n%1\ninto %2 pieces.\nThis could take a long time."), ar->name(), positions.size() + 1); + MessageDialog msg (msgstr, + false, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK_CANCEL); + + if (can_ferret) { + msg.add_button (_("Call for the Ferret!"), RESPONSE_APPLY); + } + + msg.set_title (_("Excessive split?")); + msg.set_secondary_text (_("Press OK to continue with this split operation\nor ask the Ferret dialog to tune the analysis")); + msg.present (); + + int response = msg.run(); + msg.hide (); + switch (response) { + case RESPONSE_OK: + break; + case RESPONSE_APPLY: + use_rhythmic_rodent = true; + break; + default: + return; + } + } + if (use_rhythmic_rodent) { + show_rhythm_ferret (); + return; + } + AnalysisFeatureList::const_iterator x; nframes64_t pos = ar->position(); @@ -5249,7 +5284,10 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList pl->freeze (); pl->remove_region (ar); + vector > new_regions; + cerr << "about to split using " << positions.size() << " positions" << endl; + while (x != positions.end()) { /* file start = original start + how far we from the initial position ? @@ -5276,8 +5314,14 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList continue; } - pl->add_region (RegionFactory::create (ar->get_sources(), file_start, len, new_name), pos); - + /* do NOT announce new regions 1 by one, just wait till they are all done */ + + boost::shared_ptr r = RegionFactory::create (ar->get_sources(), file_start, len, new_name, 0, Region::DefaultFlags, false); + pl->add_region (r, pos); + new_regions.push_back (r); + + cerr << "done at " << pos << endl; + pos += len; ++x; @@ -5287,7 +5331,8 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList } pl->thaw (); - + session->add_regions (new_regions); + XMLNode& after (pl->get_state()); session->add_command (new MementoCommand(*pl, &before, &after)); diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index 6f54165900..ec452559cd 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -58,20 +58,10 @@ Editor::handle_audio_region_removed (boost::weak_ptr wregion) } void -Editor::handle_new_audio_region (boost::weak_ptr wregion) +Editor::handle_new_audio_regions (vector >& v) { - ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), wregion)); - - /* don't copy region - the one we are being notified - about belongs to the session, and so it will - never be edited. - */ - - boost::shared_ptr region (wregion.lock()); - - if (region) { - add_audio_region_to_region_display (region); - } + ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_regions), v)); + add_audio_regions_to_region_display (v); } void @@ -82,6 +72,21 @@ Editor::region_hidden (boost::shared_ptr r) redisplay_regions (); } +void +Editor::add_audio_regions_to_region_display (vector >& regions) +{ + cerr << "Adding " << regions.size() << " to region list\n"; + + region_list_display.set_model (Glib::RefPtr(0)); + for (vector >::iterator x = regions.begin(); x != regions.end(); ++x) { + boost::shared_ptr region ((*x).lock()); + if (region) { + add_audio_region_to_region_display (region); + } + } + region_list_display.set_model (region_list_model); +} + void Editor::add_audio_region_to_region_display (boost::shared_ptr region) { diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index dc9c27c842..d140cc159e 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -87,6 +87,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr rt : AxisView(sess), RouteUI (rt, sess, _("Mute"), _("Solo"), _("Record")), _mixer(mx), + _mixer_owned (in_mixer), pre_redirect_box (PreFader, sess, rt, mx.plugin_selector(), mx.selection(), in_mixer), post_redirect_box (PostFader, sess, rt, mx.plugin_selector(), mx.selection(), in_mixer), gpm (_route, sess), @@ -661,12 +662,11 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c) void MixerStrip::update_diskstream_display () { + map_frozen (); + update_input_display (); + if (is_audio_track()) { - map_frozen (); - - update_input_display (); - if (input_selector) { input_selector->hide_all (); } @@ -675,9 +675,6 @@ MixerStrip::update_diskstream_display () } else { - map_frozen (); - - update_input_display (); show_passthru_color (); } } @@ -1144,9 +1141,11 @@ MixerStrip::map_frozen () pre_redirect_box.set_sensitive (true); post_redirect_box.set_sensitive (true); speed_spinner.set_sensitive (true); + // XXX need some way, maybe, to retoggle redirect editors break; } } + _route->foreach_redirect (this, &MixerStrip::hide_redirect_editor); } diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index e123b6a7d8..4e06a58fab 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -107,6 +107,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox bool _embedded; bool _packed; + bool _mixer_owned; Width _width; void* _width_owner; diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 1f6ed84660..4a74b39f0d 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -62,7 +62,6 @@ using namespace Gtk; using namespace sigc; PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scrollable) - : ArdourDialog ("plugin ui") { bool have_gui = false; non_gtk_gui = false; @@ -99,7 +98,7 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr GenericPluginUI* pu = new GenericPluginUI (insert, scrollable); _pluginui = pu; - get_vbox()->add (*pu); + add (*pu); set_wmclass (X_("ardour_plugin_editor"), "Ardour"); @@ -107,7 +106,7 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr signal_unmap_event().connect (mem_fun (*pu, &GenericPluginUI::stop_updating)); } - set_position (Gtk::WIN_POS_MOUSE); + // set_position (Gtk::WIN_POS_MOUSE); set_name ("PluginEditor"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); @@ -138,23 +137,14 @@ PluginUIWindow::on_show () { cerr << "PluginWindow shown\n"; - ArdourDialog::on_show (); - Glib::ListHandle kids (get_vbox()->get_children()); - - cerr << "send show to " << kids.size() << " children of this plugin UI\n"; - - for (Glib::ListHandle::iterator x = kids.begin(); x != kids.end(); ++x) { - cerr << "\tSend show to " << (*x) << endl; - (*x)->show (); - } - cerr << "!! send done\n"; + Window::on_show (); } void PluginUIWindow::on_hide () { cerr << "PluginWindow hidden\n"; - ArdourDialog::on_hide (); + Window::on_hide (); } bool @@ -174,7 +164,7 @@ PluginUIWindow::create_vst_editor(boost::shared_ptr insert) VSTPluginUI* vpu = new VSTPluginUI (insert, vp); _pluginui = vpu; - get_vbox()->add (*vpu); + add (*vpu); vpu->package (*this); } @@ -191,8 +181,7 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr insert) #else VBox* box; _pluginui = create_au_gui (insert, &box); - cerr << "#*#*#*#*#*#*#*#*## PACK " << box << " INTO PLUGIN UI\n"; - get_vbox()->add (*box); + add (*box); non_gtk_gui = true; extern sigc::signal ApplicationActivationChanged; @@ -206,12 +195,16 @@ void PluginUIWindow::app_activated (bool yn) { #if defined (HAVE_AUDIOUNITS) && defined(GTKOSX) - if (yn) { - if (_pluginui) { - _pluginui->activate (); - } - } cerr << "APP activated ? " << yn << endl; + if (_pluginui) { + if (yn) { + _pluginui->activate (); + present (); + } else { + hide (); + _pluginui->deactivate (); + } + } #endif } diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 19a6ad5092..0486109f4c 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -196,7 +196,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox void print_parameter (char *buf, uint32_t len, uint32_t param); }; -class PluginUIWindow : public ArdourDialog +class PluginUIWindow : public Gtk::Window { public: PluginUIWindow (boost::shared_ptr insert, bool scrollable=false); @@ -213,6 +213,7 @@ class PluginUIWindow : public ArdourDialog private: PlugUIBase* _pluginui; + Gtk::VBox vbox; bool non_gtk_gui; void app_activated (bool); void plugin_going_away (); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 4d045dbd62..7e3b55e44d 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -157,7 +157,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void restore_editing_space() = 0; virtual nframes64_t get_preferred_edit_position (bool ignore_playhead = false) = 0; virtual void toggle_meter_updating() = 0; - virtual void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&) = 0; + virtual void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret) = 0; sigc::signal ZoomFocusChanged; sigc::signal ZoomChanged; diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc index e508b75d58..0611c98e2a 100644 --- a/gtk2_ardour/redirect_box.cc +++ b/gtk2_ardour/redirect_box.cc @@ -1089,12 +1089,8 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) plugin_ui = new PluginUIWindow (plugin_insert); - if (_owner_is_mixer) { - ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui); - } else { - ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui); - } - + // plugin_ui->set_keep_above (true); + WindowTitle title(Glib::get_application_name()); title += generate_redirect_title (plugin_insert); plugin_ui->set_title (title.get_string()); diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc index d8d2f3c28b..83852b33b3 100644 --- a/gtk2_ardour/rhythm_ferret.cc +++ b/gtk2_ardour/rhythm_ferret.cc @@ -271,7 +271,7 @@ RhythmFerret::do_split_action () (*i)->get_time_axis_view().hide_temporary_lines (); - editor.split_region_at_points ((*i)->region(), current_results); + editor.split_region_at_points ((*i)->region(), current_results, false); /* i is invalid at this point */ diff --git a/libs/ardour/analyser.cc b/libs/ardour/analyser.cc index 7ddb5428e9..5768ce0005 100644 --- a/libs/ardour/analyser.cc +++ b/libs/ardour/analyser.cc @@ -108,6 +108,8 @@ Analyser::analyse_audio_file_source (boost::shared_ptr src) TransientDetector td (src->sample_rate()); + cerr << "analyzing " << src->name () << endl; + if (td.run (src->get_transients_path(), src.get(), 0, results) == 0) { src->set_been_analysed (true); } else { diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index c61137b4f3..9ad291662d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -554,7 +554,10 @@ class Session : public PBD::StatefulDestructible /* region info */ + void add_regions (std::vector >&); + sigc::signal > AudioRegionAdded; + sigc::signal >& > AudioRegionsAdded; sigc::signal > AudioRegionRemoved; int region_name (string& result, string base = string(""), bool newlevel = false) const; diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc index 88a93b4f01..6560cb892e 100644 --- a/libs/ardour/audiofilter.cc +++ b/libs/ardour/audiofilter.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "i18n.h" @@ -104,6 +105,10 @@ AudioFilter::finish (boost::shared_ptr region, SourceList& nsrcs, s afs->update_header (region->position(), *now, xnow); afs->mark_immutable (); } + + /* now that there is data there, requeue the file for analysis */ + + Analyser::queue_source_for_analysis (*si, false); } /* create a new region */ diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 4f9e70e334..bcb36ab85a 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -1576,6 +1576,8 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new) return 0; } + cerr << "startup analysis of " << _name << endl; + TransientDetector t (pl->session().frame_rate()); bool existing_results = !results.empty(); @@ -1588,10 +1590,14 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new) t.reset (); + cerr << "working on channel " << i << endl; + if (t.run ("", this, i, these_results)) { return -1; } + cerr << "done\n"; + /* translate all transients to give absolute position */ for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) { @@ -1617,6 +1623,11 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new) /* make sure ours are clean too */ TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0); + + } else { + + TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0); + results = _transients; } valid_transients = true; diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index cc1b7f4a05..7c8801845a 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -70,6 +70,7 @@ AudioSource::AudioSource (Session& s, ustring name) AudioSource::AudioSource (Session& s, const XMLNode& node) : Source (s, node) { + _peaks_built = false; _peak_byte_max = 0; peakfile = -1; @@ -141,6 +142,8 @@ AudioSource::peaks_ready (sigc::slot the_slot, sigc::connection& conn) con connect the slot while still holding the lock. */ + cerr << _name << " @ " << this << " peaks built = " << _peaks_built << endl; + if (!(ret = _peaks_built)) { conn = PeaksReady.connect (the_slot); } @@ -213,7 +216,7 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path) /* we found it in the peaks dir, so check it out */ - if (statbuf.st_size == 0) { + if (statbuf.st_size == 0 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) { // empty _peaks_built = false; } else { @@ -221,12 +224,22 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path) struct stat stat_file; int err = stat (audio_path.c_str(), &stat_file); - if (!err && stat_file.st_mtime > statbuf.st_mtime){ + if (err) { _peaks_built = false; _peak_byte_max = 0; } else { - _peaks_built = true; - _peak_byte_max = statbuf.st_size; + + /* allow 6 seconds slop on checking peak vs. file times because of various + disk action "races" + */ + + if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) { + _peaks_built = false; + _peak_byte_max = 0; + } else { + _peaks_built = true; + _peak_byte_max = statbuf.st_size; + } } } } diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index e7cb136a4e..3c3e63be90 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include "i18n.h" @@ -285,11 +286,14 @@ Session::import_audiofiles (import_status& status) /* flush the final length(s) to the header(s) */ - for (AudioSources::iterator x = all_new_sources.begin(); - x != all_new_sources.end(); ++x) + for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x) { (*x)->update_header(0, *now, xnow); (*x)->done_with_peakfile_writes (); + + /* now that there is data there, requeue the file for analysis */ + + Analyser::queue_source_for_analysis (boost::static_pointer_cast(*x), false); } /* save state so that we don't lose these new Sources */ diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 1f2ba8d61b..454a710236 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2567,6 +2567,14 @@ Session::region_name (string& result, string base, bool newlevel) const void Session::add_region (boost::shared_ptr region) +{ + vector > v; + v.push_back (region); + add_regions (v); +} + +void +Session::add_regions (vector >& new_regions) { boost::shared_ptr ar; boost::shared_ptr oar; @@ -2575,45 +2583,52 @@ Session::add_region (boost::shared_ptr region) { Glib::Mutex::Lock lm (region_lock); - if (region == 0) { - error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; - } else if ((ar = boost::dynamic_pointer_cast (region)) != 0) { + for (vector >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { + + boost::shared_ptr region = *ii; + + if (region == 0) { - AudioRegionList::iterator x; - - for (x = audio_regions.begin(); x != audio_regions.end(); ++x) { - - oar = boost::dynamic_pointer_cast (x->second); - - if (ar->region_list_equivalent (oar)) { - break; - } - } - - if (x == audio_regions.end()) { - - pair entry; - - entry.first = region->id(); - entry.second = ar; - - pair x = audio_regions.insert (entry); + error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; + } else if ((ar = boost::dynamic_pointer_cast (region)) != 0) { - if (!x.second) { - return; + AudioRegionList::iterator x; + + for (x = audio_regions.begin(); x != audio_regions.end(); ++x) { + + oar = boost::dynamic_pointer_cast (x->second); + + if (ar->region_list_equivalent (oar)) { + break; + } } + + if (x == audio_regions.end()) { + + pair entry; + + entry.first = region->id(); + entry.second = ar; + + pair x = audio_regions.insert (entry); + + + if (!x.second) { + return; + } + + added = true; + } - added = true; - } - - } else { - - fatal << _("programming error: ") - << X_("unknown region type passed to Session::add_region()") - << endmsg; - /*NOTREACHED*/ - + } else { + + fatal << _("programming error: ") + << X_("unknown region type passed to Session::add_region()") + << endmsg; + /*NOTREACHED*/ + + } } } @@ -2624,9 +2639,34 @@ Session::add_region (boost::shared_ptr region) set_dirty(); if (added) { - region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr(region))); - region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr(region))); - AudioRegionAdded (ar); /* EMIT SIGNAL */ + + vector > v; + boost::shared_ptr first_ar; + + for (vector >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { + + boost::shared_ptr region = *ii; + boost::shared_ptr ar; + + if (region == 0) { + + error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; + + } else if ((ar = boost::dynamic_pointer_cast (region)) != 0) { + v.push_back (ar); + + if (!first_ar) { + first_ar = ar; + } + } + + region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr(region))); + region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr(region))); + } + + if (!v.empty()) { + AudioRegionsAdded (v); /* EMIT SIGNAL */ + } } } diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript index 504801aa03..5a4dd649c7 100644 --- a/libs/gtkmm2ext/SConscript +++ b/libs/gtkmm2ext/SConscript @@ -31,6 +31,8 @@ gtkmm2ext.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") gtkmm2ext.Append(PACKAGE=domain) gtkmm2ext.Append(POTFILE=domain + '.pot') +extra_sources = [] + gtkmm2ext_files = Split(""" auto_spin.cc barcontroller.cc @@ -59,12 +61,21 @@ version.cc window_title.cc """) +gtkosx_files=Split(""" +sync-menu.c +""") + +if gtkmm2ext['GTKOSX']: + extra_sources += gtkosx_files + gtkmm2ext.Append (CCFLAGS="-DTOP_MENUBAR -DGTKOSX") + gtkmm2ext.Append (LINKFLAGS="-framework Carbon") + gtkmm2ext.VersionBuild(['version.cc','gtkmm2ext/version.h'], []) gtkmm2ext.Append(CCFLAGS="-D_REENTRANT") gtkmm2ext.Append(CCFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") -libgtkmm2ext = gtkmm2ext.SharedLibrary('gtkmm2ext', gtkmm2ext_files) +libgtkmm2ext = gtkmm2ext.SharedLibrary('gtkmm2ext', gtkmm2ext_files + extra_sources) Default(libgtkmm2ext) @@ -76,5 +87,6 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar env.Alias('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript', 'i18n.h', 'gettext.h'] + gtkmm2ext_files + + gtkosx_files + glob.glob('po/*.po') + glob.glob('gtkmm2ext/*.h'))) diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index 58178056c2..b85b3573fd 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -572,9 +572,31 @@ UI::popup_error (const char *text) msg.run (); } +#ifdef GTKOSX +extern "C" { + int gdk_quartz_in_carbon_menu_event_handler (); +} +#endif + void UI::flush_pending () { +#ifdef GTKOSX + /* as of february 11th 2008, gtk/osx has a problem in that mac menu events + are handled using Carbon with an "internal" event handling system that + doesn't pass things back to the glib/gtk main loop. this makes + gtk_main_iteration() block if we call it while in a menu event handler + because glib gets confused and thinks there are two threads running + g_main_poll_func(). + + this hack (relies on code in gtk2_ardour/sync-menu.c) works + around that. + */ + + if (gdk_quartz_in_carbon_menu_event_handler()) { + return; + } +#endif if (!caller_is_ui_thread()) { error << "non-UI threads cannot call UI::flush_pending()" << endmsg; diff --git a/gtk2_ardour/sync-menu.h b/libs/gtkmm2ext/gtkmm2ext/sync-menu.h similarity index 100% rename from gtk2_ardour/sync-menu.h rename to libs/gtkmm2ext/gtkmm2ext/sync-menu.h diff --git a/gtk2_ardour/sync-menu.c b/libs/gtkmm2ext/sync-menu.c similarity index 98% rename from gtk2_ardour/sync-menu.c rename to libs/gtkmm2ext/sync-menu.c index ec2b741d5a..cc76cb9511 100644 --- a/gtk2_ardour/sync-menu.c +++ b/libs/gtkmm2ext/sync-menu.c @@ -27,7 +27,7 @@ #include -#include "sync-menu.h" +#include /* TODO @@ -533,6 +533,14 @@ carbon_menu_item_connect (GtkWidget *menu_item, * carbon event handler */ +static int _in_carbon_menu_event_handler = 0; + +int +gdk_quartz_in_carbon_menu_event_handler () +{ + return _in_carbon_menu_event_handler; +} + static OSStatus menu_event_handler_func (EventHandlerCallRef event_handler_call_ref, EventRef event_ref, @@ -541,6 +549,9 @@ menu_event_handler_func (EventHandlerCallRef event_handler_call_ref, UInt32 event_class = GetEventClass (event_ref); UInt32 event_kind = GetEventKind (event_ref); MenuRef menu_ref; + OSStatus ret; + + _in_carbon_menu_event_handler = 1; switch (event_class) { @@ -572,6 +583,7 @@ menu_event_handler_func (EventHandlerCallRef event_handler_call_ref, if (err == noErr && GTK_IS_WIDGET (widget)) { gtk_menu_item_activate (GTK_MENU_ITEM (widget)); + _in_carbon_menu_event_handler = 0; return noErr; } } @@ -617,7 +629,9 @@ menu_event_handler_func (EventHandlerCallRef event_handler_call_ref, break; } - return CallNextEventHandler (event_handler_call_ref, event_ref); + ret = CallNextEventHandler (event_handler_call_ref, event_ref); + _in_carbon_menu_event_handler = 0; + return ret; } static void diff --git a/svn_revision.h b/svn_revision.h index fbc36cc3d9..d65f7e7dab 100644 --- a/svn_revision.h +++ b/svn_revision.h @@ -1,4 +1,4 @@ #ifndef __ardour_svn_revision_h__ #define __ardour_svn_revision_h__ -static const char* ardour_svn_revision = "3025"; +static const char* ardour_svn_revision = "3029"; #endif