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