Vkeybd: add a mod-wheel
[ardour.git] / gtk2_ardour / startup_fsm.cc
index 2628f04fdfff151ed5952896771c76b5bd6770f0..9424160f4d7fb9f9e51cfc1ae76d8e1a680abd41 100644 (file)
@@ -41,7 +41,9 @@
 
 #include "gtkmm2ext/application.h"
 #include <gtkmm2ext/doi.h>
+#include <gtkmm2ext/keyboard.h>
 
+#include "ardour_message.h"
 #include "ardour_ui.h"
 #include "debug.h"
 #include "engine_dialog.h"
@@ -94,6 +96,8 @@ StartupFSM::StartupFSM (EngineControl& amd)
 
        app->ShouldQuit.connect (sigc::mem_fun (*this, &StartupFSM::queue_finish));
        app->ShouldLoad.connect (sigc::mem_fun (*this, &StartupFSM::load_from_application_api));
+
+       Gtkmm2ext::Keyboard::HideMightMeanQuit.connect (sigc::mem_fun (*this, &StartupFSM::dialog_hidden));
 }
 
 StartupFSM::~StartupFSM ()
@@ -104,6 +108,16 @@ StartupFSM::~StartupFSM ()
        delete new_user_dialog;
 }
 
+void
+StartupFSM::dialog_hidden (Gtk::Window* /* ignored */)
+{
+       /* since this object only exists during startup, any attempt to close
+        * any dialog that we manage with Ctrl/Cmd-w is assumed to indicate a
+        * desire to quit on the part of the user.
+        */
+       queue_finish ();
+}
+
 void
 StartupFSM::queue_finish ()
 {
@@ -128,35 +142,7 @@ StartupFSM::start ()
                show_new_user_dialog ();
                break;
        case WaitingForSessionPath:
-               if (ARDOUR_COMMAND_LINE::session_name.empty()) {
-
-                       /* nothing given on the command line ... show new session dialog */
-
-                       show_session_dialog (new_session_required);
-
-               } else {
-
-                       if (get_session_parameters_from_command_line (new_session_required)) {
-
-                               /* command line arguments all OK. Get engine parameters */
-
-                               if (!new_session_required && session_existing_sample_rate > 0) {
-                                       audiomidi_dialog.set_desired_sample_rate (session_existing_sample_rate);
-                               }
-
-                               start_audio_midi_setup ();
-
-                       } else {
-
-                               /* command line arguments not good. Use
-                                * dialog, but prime the dialog with
-                                * the information we set up in
-                                * get_session_parameters_from_command_line()
-                                */
-
-                               show_session_dialog (new_session_required);
-                       }
-               }
+               handle_waiting_for_session_path ();
                break;
        default:
                fatal << string_compose (_("Programming error: %1"), string_compose (X_("impossible starting state in StartupFSM (%1)"), enum_2_string (_state))) << endmsg;
@@ -166,12 +152,6 @@ StartupFSM::start ()
        }
 
        DEBUG_TRACE (DEBUG::GuiStartup, string_compose (X_("State after startup: %1\n"), enum_2_string (_state)));
-
-       /* this may cause the delivery of ShouldLoad etc if we were invoked in
-        * particular ways. It will happen when the event loop runs again.
-        */
-
-       Application::instance()->ready ();
 }
 
 void
@@ -230,7 +210,7 @@ StartupFSM::dialog_response_handler (int response, StartupFSM::DialogID dialog_i
                        if (NewUserWizard::required()) {
                                show_new_user_dialog ();
                        } else {
-                               show_session_dialog (new_session_required);
+                               handle_waiting_for_session_path ();
                        }
                        break;
                }
@@ -331,6 +311,40 @@ StartupFSM::dialog_response_handler (int response, StartupFSM::DialogID dialog_i
        }
 }
 
+void
+StartupFSM::handle_waiting_for_session_path ()
+{
+       if (ARDOUR_COMMAND_LINE::session_name.empty()) {
+
+               /* nothing given on the command line ... show new session dialog */
+
+               show_session_dialog (new_session_required);
+
+       } else {
+
+               if (get_session_parameters_from_command_line (new_session_required)) {
+
+                       /* command line arguments all OK. Get engine parameters */
+
+                       if (!new_session_required && session_existing_sample_rate > 0) {
+                               audiomidi_dialog.set_desired_sample_rate (session_existing_sample_rate);
+                       }
+
+                       start_audio_midi_setup ();
+
+               } else {
+
+                       /* command line arguments not good. Use
+                        * dialog, but prime the dialog with
+                        * the information we set up in
+                        * get_session_parameters_from_command_line()
+                        */
+
+                       show_session_dialog (new_session_required);
+               }
+       }
+}
+
 void
 StartupFSM::show_plugin_scan_dialog ()
 {
@@ -341,7 +355,7 @@ StartupFSM::show_plugin_scan_dialog ()
        */
 
        const bool cache_only = (!Config->get_discover_vst_on_start() || Profile->get_mixbus());
-       const bool verbose = (new_user || Config->get_discover_vst_on_start());
+       const bool verbose = new_user;
 
        plugin_scan_dialog = new PluginScanDialog (cache_only, verbose);
        current_dialog_connection = plugin_scan_dialog->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &StartupFSM::dialog_response_handler), PluginDialog));
@@ -412,11 +426,26 @@ StartupFSM::start_audio_midi_setup ()
        }
 
        if (setup_required) {
+
+               if (!session_is_new && (Config->get_try_autostart_engine () || g_getenv ("ARDOUR_TRY_AUTOSTART_ENGINE"))) {
+
+                       AudioEngine::instance()->set_sample_rate(session_existing_sample_rate);
+                       if (!AudioEngine::instance()->start ()) {
+                               if (ARDOUR::AudioEngine::instance()->running()) {
+                                       DEBUG_TRACE (DEBUG::GuiStartup, "autostart successful, audio/MIDI setup dialog not required\n");
+                                       engine_running ();
+                                       return;
+                               }
+                       }
+               }
+
                if (!session_is_new && session_existing_sample_rate > 0) {
                        audiomidi_dialog.set_desired_sample_rate (session_existing_sample_rate);
                }
+
                show_audiomidi_dialog ();
                DEBUG_TRACE (DEBUG::GuiStartup, "audiomidi shown and waiting\n");
+
        } else {
 
                DEBUG_TRACE (DEBUG::GuiStartup, "engine already running, audio/MIDI setup dialog not required\n");
@@ -606,7 +635,7 @@ StartupFSM::check_session_parameters (bool must_be_new)
 
                int rv = ARDOUR::inflate_session (session_name, Config->get_default_session_parent_dir(), session_path, session_name);
                if (rv < 0) {
-                       MessageDialog msg (*session_dialog, string_compose (_("Extracting session-archive failed: %1"), inflate_error (rv)));
+                       ArdourMessageDialog msg (*session_dialog, string_compose (_("Extracting session-archive failed: %1"), inflate_error (rv)));
                        msg.run ();
 
                        return 1;
@@ -673,10 +702,10 @@ StartupFSM::check_session_parameters (bool must_be_new)
        const char illegal = Session::session_name_is_legal (session_name);
 
        if (illegal) {
-               MessageDialog msg (*session_dialog,
-                                  string_compose (_("To ensure compatibility with various systems\n"
-                                                    "session names may not contain a '%1' character"),
-                                                  illegal));
+               ArdourMessageDialog msg (*session_dialog,
+                                        string_compose (_("To ensure compatibility with various systems\n"
+                                                          "session names may not contain a '%1' character"),
+                                                        illegal));
                msg.run ();
                ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
                return 1; /* keep running dialog */
@@ -706,8 +735,7 @@ StartupFSM::check_session_parameters (bool must_be_new)
                /* does not exist at present */
 
                if (!requested_new) {
-                       ARDOUR_UI::pop_back_splash (*session_dialog);
-                       MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
+                       ArdourMessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
                        msg.run ();
                        session_dialog->clear_name();
                        return 1;
@@ -784,55 +812,17 @@ StartupFSM::copy_demo_sessions ()
 void
 StartupFSM::load_from_application_api (const std::string& path)
 {
-       /* macOS El Capitan (and probably later) now somehow passes the command
-          line arguments to an app via the openFile delegate protocol. Ardour
-          already does its own command line processing, and having both
-          pathways active causes crashes. So, if the command line was already
-          set, do nothing here.
-       */
-
        if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
                return;
        }
 
-       /* Cancel SessionDialog if it's visible to make macOS delegates work.
-        *
-        * there's a race condition here: we connect to app->ShouldLoad
-        * and then at some point (might) show a session dialog. The race is
-        * caused by the non-deterministic interaction between the macOS event
-        * loop(s) and the GDK one(s).
-        *
-        *  - ShouldLoad does not arrive before we show the session dialog
-        *          -> here we should hide the session dialog, then use the
-        *             supplied path as if it was provided on the command line
-        *  - ShouldLoad signal arrives before we show a session dialog
-        *          -> don't bother showing the session dialog, just use the
-        *             supplied path as if it was provided on the command line
-        *
-        */
-
-       if (session_dialog) {
-               session_dialog->hide ();
-               delete_when_idle (session_dialog);
-               session_dialog = 0;
-       }
-
-       /* no command line argument given ... must just be via
-        * desktop/finder/window manager API (e.g. double click on "foo.ardour"
-        * icon)
-        */
-
-       if (get_session_parameters_from_path (path, string(), false)) {
-               _signal_response (LoadSession);
-               return;
-       }
-
-       /* given parameters failed for some reason. This is probably true
-        * anyway, but force it to be true and then carry on with whatever the
-        * main event loop is doing.
+       /* just set this as if it was given on the command line, rather than
+        * supplied via some desktop system (e.g. macOS application delegate
+        * and "openFile". Note that this relies on this being invoked before
+        * StartupFSM::start().
         */
 
-       set_state (WaitingForSessionPath);
+       ARDOUR_COMMAND_LINE::session_name = path;
 }
 
 bool
@@ -840,18 +830,17 @@ StartupFSM::ask_about_loading_existing_session (const std::string& session_path)
 {
        std::string str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
 
-       MessageDialog msg (str,
-                          false,
-                          Gtk::MESSAGE_WARNING,
-                          Gtk::BUTTONS_YES_NO,
-                          true);
+       ArdourMessageDialog msg (str,
+                                false,
+                                Gtk::MESSAGE_WARNING,
+                                Gtk::BUTTONS_YES_NO,
+                                true);
 
 
        msg.set_name (X_("OpenExistingDialog"));
        msg.set_title (_("Open Existing Session"));
        msg.set_wmclass (X_("existing_session"), PROGRAM_NAME);
        msg.set_position (Gtk::WIN_POS_CENTER);
-       ARDOUR_UI::pop_back_splash (msg);
 
        switch (msg.run()) {
        case RESPONSE_YES: