diff --git a/gtk2_ardour/about_dialog.cc b/gtk2_ardour/about_dialog.cc index 81a5e38128..f78aa87c23 100644 --- a/gtk2_ardour/about_dialog.cc +++ b/gtk2_ardour/about_dialog.cc @@ -89,7 +89,7 @@ About::on_esc_pressed () void About::about_button_pressed (WavesButton*) { - MainMenuDisabled m; + MainMenuDisabler m; LicenseDialog license_dialog; license_dialog.set_position (WIN_POS_CENTER); license_dialog.run (); diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index b0ee7c4da7..596b7789ec 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -471,7 +471,7 @@ void ARDOUR_UI::device_reset_started () { if (!_audio_engine_reset_menu_disabler) { - _audio_engine_reset_menu_disabler = new MainMenuDisabled (); + _audio_engine_reset_menu_disabler = new MainMenuDisabler (); } if (!_audio_engine_reset_info_dialog) { _audio_engine_reset_info_dialog = new WavesDialog ("audio_engine_reset_info_dialog.xml"); // HOT FIX. (REWORK IT) @@ -3756,7 +3756,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) int r = _add_tracks_dialog->run(); diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 2612b5f301..7c907be24e 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -123,7 +123,7 @@ class MidiTracer; class NSM_Client; class LevelMeterHBox; class GUIObjectState; -class MainMenuDisabled; +class MainMenuDisabler; namespace Gtkmm2ext { class TearOff; @@ -481,7 +481,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr Gtk::HBox transport_hbox; Gtk::Fixed transport_base; WavesDialog *_audio_engine_reset_info_dialog; // HOT FIX. (REWORK IT) - MainMenuDisabled *_audio_engine_reset_menu_disabler; // HOT FIX. (REWORK IT) + MainMenuDisabler *_audio_engine_reset_menu_disabler; // HOT FIX. (REWORK IT) struct TransportControllable : public PBD::Controllable { enum ToggleType { diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index f94e559d61..95b4fbb4c0 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -3367,7 +3367,7 @@ Editor::duplicate_range (bool with_dialog) } // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) if (with_dialog) { diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 0f823564f1..d6345e8a46 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -65,7 +65,7 @@ void Editor::export_audio () { // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) if (Config->get_output_auto_connect() & AutoConnectPhysical) { WavesMessageDialog read_only_session_dialog ("", @@ -84,7 +84,7 @@ void Editor::stem_export () { // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) WavesStemExportDialog dialog (*this); dialog.set_session (_session); @@ -132,7 +132,7 @@ Editor::export_region () boost::shared_ptr midi_region = boost::dynamic_pointer_cast(r); // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) if (audio_region) { diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index ee01495bf5..c41e9c2b1d 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2569,7 +2569,7 @@ Editor::rename_region () waves_edit_dialog.set_entry_text (rs.front()->region()->name()); // disable Main menu - MainMenuDisabled m; // HOT FIX. (REWORK IT) + MainMenuDisabler m; // HOT FIX. (REWORK IT) int const ret = waves_edit_dialog.run (); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 0459b12f26..84478e3b8d 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -445,20 +445,20 @@ class DisplaySuspender { } }; -class MainMenuDisabled { +class MainMenuDisabler { public: - MainMenuDisabled() { + MainMenuDisabler () { #ifdef __APPLE__ /* The global menu bar continues to be accessible to applications with modal dialogs on mac, which means that we need to desensitize all items in the menu bar. */ - ActionManager::disable_all_actions (); // HOT FIX. (REWORK IT) + ActionManager::disable_active_actions (); // HOT FIX. (REWORK IT) #endif } - ~MainMenuDisabled () { + ~MainMenuDisabler () { #ifdef __APPLE__ - ActionManager::pop_action_state (); // HOT FIX. (REWORK IT) + ActionManager::enable_active_actions (); // HOT FIX. (REWORK IT) #endif } }; diff --git a/gtk2_ardour/session_lock_dialog.cc b/gtk2_ardour/session_lock_dialog.cc index c6e2197e85..e3be1b8dd4 100644 --- a/gtk2_ardour/session_lock_dialog.cc +++ b/gtk2_ardour/session_lock_dialog.cc @@ -33,6 +33,7 @@ #include "dbg_msg.h" #include "actions.h" #include "ardour_ui.h" +#include "public_editor.h" using namespace std; using namespace Gtk; @@ -44,6 +45,7 @@ using namespace ARDOUR; SessionLockDialog::SessionLockDialog () : WavesDialog (_("session_lock_dialog.xml"), true, false) , _ok_button (get_waves_button ("ok_button")) + , _session_lock_dialog_menu_disabler (0) { set_keep_above (true); set_position (WIN_POS_CENTER); @@ -66,15 +68,9 @@ SessionLockDialog::on_ok (WavesButton*) void SessionLockDialog::on_show () { -#ifdef __APPLE__ - /* The global menu bar continues to be accessible to applications - with modal dialogs, which means that we need to desensitize - all items in the menu bar. Since those items are really just - proxies for actions, that means disabling all actions. - */ - ActionManager::disable_all_actions (); -#endif - + if (!_session_lock_dialog_menu_disabler) { + _session_lock_dialog_menu_disabler = new MainMenuDisabler (); + } WavesDialog::on_show (); ARDOUR_UI::instance()->on_lock_session (); } @@ -85,10 +81,10 @@ SessionLockDialog::on_hide () ARDOUR_UI::instance()->on_unlock_session (); WavesDialog::on_hide (); -#ifdef __APPLE__ - // enable Main menu on mac - ActionManager::pop_action_state (); -#endif + if (_session_lock_dialog_menu_disabler) { + delete _session_lock_dialog_menu_disabler; + _session_lock_dialog_menu_disabler = 0; + } } bool diff --git a/gtk2_ardour/session_lock_dialog.h b/gtk2_ardour/session_lock_dialog.h index c0b3f829ad..305974a4e2 100644 --- a/gtk2_ardour/session_lock_dialog.h +++ b/gtk2_ardour/session_lock_dialog.h @@ -43,6 +43,7 @@ //#include "ardour/utils.h" class EngineControl; +class MainMenuDisabler; #define MAX_RECENT_SESSION_COUNT 10 class SessionLockDialog : public WavesDialog { public: @@ -57,6 +58,7 @@ class SessionLockDialog : public WavesDialog { private: WavesButton& _ok_button; void on_ok(WavesButton*); + MainMenuDisabler *_session_lock_dialog_menu_disabler; // HOT FIX. (REWORK IT) }; #endif /* __gtk2_session_lock_dialog_h__ */ diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc index 5f853b0170..d64d8de46e 100644 --- a/libs/gtkmm2ext/actions.cc +++ b/libs/gtkmm2ext/actions.cc @@ -289,71 +289,63 @@ struct ActionState { typedef std::vector ActionStates; -static std::stack > state_stack; +static ActionStates action_states_to_restore; +static bool actions_disabled = false; -static boost::shared_ptr -get_action_state () +void +ActionManager::save_action_states () { - boost::shared_ptr state = boost::shared_ptr(new ActionStates); - - /* the C++ API for functions used here appears to be broken in - gtkmm2.6, so we fall back to the C level. - */ - - GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj()); - GList* node; - GList* acts; - - for (node = list; node; node = g_list_next (node)) { - - GtkActionGroup* group = (GtkActionGroup*) node->data; - - /* first pass: collect them all */ - - typedef std::list > action_list; - action_list the_acts; - - for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) { - GtkAction* action = (GtkAction*) acts->data; - - state->push_back (ActionState (action, gtk_action_get_sensitive (action))); - } - } - - return state; + /* the C++ API for functions used here appears to be broken in + gtkmm2.6, so we fall back to the C level. + */ + GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj()); + GList* node; + GList* acts; + + for (node = list; node; node = g_list_next (node)) { + + GtkActionGroup* group = (GtkActionGroup*) node->data; + + for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) { + GtkAction* action = (GtkAction*) acts->data; + action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action))); + } + } } void -ActionManager::push_action_state () +ActionManager::enable_active_actions () { - state_stack.push (get_action_state()); + if (!actions_disabled) { + return ; + } + + for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) { + if ((*i).action && (*i).sensitive) { + gtk_action_set_sensitive ((*i).action, true); + } + } + + action_states_to_restore.clear (); + actions_disabled = false; } void -ActionManager::pop_action_state () +ActionManager::disable_active_actions () { - if (state_stack.empty()) { - warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg; - return; - } - - boost::shared_ptr as = state_stack.top (); - state_stack.pop (); + if (actions_disabled == true ) { + return ; + } + // save all action's states to action_states_to_restore + save_action_states (); - for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) { - gtk_action_set_sensitive ((*i).action, (*i).sensitive); - } -} - -void -ActionManager::disable_all_actions () -{ - push_action_state (); - boost::shared_ptr as = state_stack.top (); - - for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) { - gtk_action_set_sensitive ((*i).action, false); + // set all action's states disabled + for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) { + if ((*i).sensitive) { + gtk_action_set_sensitive ((*i).action, false); + } } + actions_disabled = true; } void @@ -464,9 +456,25 @@ ActionManager::get_action_from_name (const char* name) void ActionManager::set_sensitive (vector >& actions, bool state) { - for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { - (*i)->set_sensitive (state); - } + // if actions weren't disabled + if (!actions_disabled) { + for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { + (*i)->set_sensitive (state); + } + } + else { + // actions were disabled + // so we should just set necessary action's states in action_states_to_restore + for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { + // go through action_states_to_restore and set state of actions + for (ActionStates::iterator j = action_states_to_restore.begin(); j != action_states_to_restore.end(); ++j) { + // all actions should have their individual name, so we can use it for comparison + if (gtk_action_get_name ((*j).action) == (*i)->get_name ()) { + (*j).sensitive = state; + } + } + } + } } void diff --git a/libs/gtkmm2ext/gtkmm2ext/actions.h b/libs/gtkmm2ext/gtkmm2ext/actions.h index d13a16f2d5..9ed1480546 100644 --- a/libs/gtkmm2ext/gtkmm2ext/actions.h +++ b/libs/gtkmm2ext/gtkmm2ext/actions.h @@ -94,9 +94,9 @@ namespace ActionManager { LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool); - LIBGTKMM2EXT_API extern void push_action_state (); - LIBGTKMM2EXT_API extern void pop_action_state (); - LIBGTKMM2EXT_API extern void disable_all_actions (); + LIBGTKMM2EXT_API extern void save_action_states (); + LIBGTKMM2EXT_API extern void enable_active_actions (); + LIBGTKMM2EXT_API extern void disable_active_actions (); }; #endif /* __libgtkmm2ext_actions_h__ */