various changes to window visibility mgmt, including use of the mixbus2 code for...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 7 May 2013 17:01:18 +0000 (13:01 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 7 May 2013 17:01:26 +0000 (13:01 -0400)
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/public_editor.cc
gtk2_ardour/public_editor.h
gtk2_ardour/window_manager.cc
gtk2_ardour/window_manager.h
libs/gtkmm2ext/utils.cc
libs/gtkmm2ext/visibility_tracker.cc

index 1d08d65215ac3785d86cee8587724f70315f4e0c..abf2d441451aa583ed0399d0b9009dc8ff5c0aae 100644 (file)
@@ -146,8 +146,15 @@ sigc::signal<void>      ARDOUR_UI::CloseAllDialogs;
 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
        : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp)
-
+       
        , gui_object_state (new GUIObjectState)
+
+       , _startup (0)
+       , engine (0)
+       , nsm (0)
+       , _was_dirty (false)
+       , _mixer_on_top (false)
+
        , primary_clock (new MainClock (X_("primary"), false, X_("transport"), true, true, true, false, true))
        , secondary_clock (new MainClock (X_("secondary"), false, X_("secondary"), true, true, false, false, true))
 
@@ -197,7 +204,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        Gtkmm2ext::init(localedir);
 
        splash = 0;
-       _startup = 0;
 
        if (theArdourUI == 0) {
                theArdourUI = this;
@@ -688,7 +694,6 @@ ARDOUR_UI::startup ()
        app->ready ();
 
        nsm_url = getenv ("NSM_URL");
-       nsm = 0;
 
        if (nsm_url) {
                nsm = new NSM_Client;
index f2b2029170d714558b9717bd9220c1daaa627c41..4d624377c65e23a2288dd32d7bdf289d4940d9b6 100644 (file)
@@ -301,6 +301,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
        Gtk::Tooltips        _tooltips;
        NSM_Client          *nsm;
        bool                 _was_dirty;
+        bool                 _mixer_on_top;
 
        void goto_editor_window ();
        void goto_mixer_window ();
index 2e0d017d0c48e5f6ee5141ba81951a6c79d31751..ad469ff160d9c7f4964bc04f3a4e527af158959d 100644 (file)
@@ -268,19 +268,21 @@ ARDOUR_UI::goto_editor_window ()
 
        editor->show_window ();
        editor->present ();
-       flush_pending ();
+       /* mixer should now be on top */
+       WindowManager::instance().set_transient_for (editor);
+       _mixer_on_top = false;
 }
 
 void
 ARDOUR_UI::goto_mixer_window ()
 {
-       if (!editor) {
-               return;
-       }
-
-       Glib::RefPtr<Gdk::Window> win = editor->get_window ();
+       Glib::RefPtr<Gdk::Window> win;
        Glib::RefPtr<Gdk::Screen> screen;
        
+       if (editor) {
+               win = editor->get_window ();
+       }
+
        if (win) {
                screen = win->get_screen();
        } else {
@@ -295,10 +297,11 @@ ARDOUR_UI::goto_mixer_window ()
 
        mixer->show_window ();
        mixer->present ();
-       flush_pending ();
+       /* mixer should now be on top */
+       WindowManager::instance().set_transient_for (mixer);
+       _mixer_on_top = true;
 }
 
-
 void
 ARDOUR_UI::toggle_mixer_window ()
 {
@@ -319,49 +322,80 @@ ARDOUR_UI::toggle_mixer_window ()
 void
 ARDOUR_UI::toggle_editor_mixer ()
 {
-       if (editor && mixer) {
-
-               if (editor->get_screen() != mixer->get_screen()) {
-                       // different screens, so don't do anything
-                       return;
-               }
-
-               /* See if they are obscuring each other */
-               
-               gint ex, ey, ew, eh;
-               gint mx, my, mw, mh;
-
-               editor->get_position (ex, ey);
-               editor->get_size (ew, eh);
-
-               mixer->get_position (mx, my);
-               mixer->get_size (mw, mh);
-
-               GdkRectangle e;
-               GdkRectangle m;
-               GdkRectangle r;
-
-               e.x = ex;
-               e.y = ey;
-               e.width = ew;
-               e.height = eh;
+       bool obscuring = false;
+       /* currently, if windows are on different
+          screens then we do nothing; but in the
+          future we may want to bring the window 
+          to the front or something, so I'm leaving this 
+          variable for future use
+       */
+        bool same_screen = true; 
+       
+        if (editor && mixer) {
 
-               m.x = mx;
-               m.y = my;
-               m.width = mw;
-               m.height = mh;
+               /* remeber: Screen != Monitor (Screen is a separately rendered
+                * continuous geometry that make include 1 or more monitors.
+                */
                
-               if (!gdk_rectangle_intersect (&e, &m, &r)) {
-                       /* they do not intersect so do not toggle */
-                       return;
+                if (editor->get_screen() != mixer->get_screen() && (mixer->get_screen() != 0) && (editor->get_screen() != 0)) {
+                        // different screens, so don't do anything
+                        same_screen = false;
+                } else {
+                        // they are on the same screen, see if they are obscuring each other
+
+                        gint ex, ey, ew, eh;
+                        gint mx, my, mw, mh;
+
+                        editor->get_position (ex, ey);
+                        editor->get_size (ew, eh);
+
+                        mixer->get_position (mx, my);
+                        mixer->get_size (mw, mh);
+
+                        GdkRectangle e;
+                        GdkRectangle m;
+                        GdkRectangle r;
+
+                        e.x = ex;
+                        e.y = ey;
+                        e.width = ew;
+                        e.height = eh;
+
+                        m.x = mx;
+                        m.y = my;
+                        m.width = mw;
+                        m.height = mh;
+
+                       if (gdk_rectangle_intersect (&e, &m, &r)) {
+                                obscuring = true;
+                        }
+                }
+        }
+
+        if (mixer && !mixer->not_visible() && mixer->property_has_toplevel_focus()) {
+                if (obscuring && same_screen) {
+                        goto_editor_window();
+                }
+        } else if (editor && !editor->not_visible() && editor->property_has_toplevel_focus()) {
+                if (obscuring && same_screen) {
+                        goto_mixer_window();
+                }
+        } else if (mixer && mixer->not_visible()) {
+                if (obscuring && same_screen) {
+                        goto_mixer_window ();
+                }
+        } else if (editor && editor->not_visible()) {
+                if (obscuring && same_screen) {
+                        goto_editor_window ();
+                }
+        } else if (obscuring && same_screen) {
+                //it's unclear what to do here, so just do the opposite of what we did last time  (old behavior)
+                if (_mixer_on_top) {
+                       goto_editor_window ();
+               } else {
+                       goto_mixer_window ();
                }
-       }
-               
-       if (mixer && mixer->fully_visible()) {
-               goto_editor_window ();
-       } else {
-               goto_mixer_window ();
-       }
+        }
 }
 
 void
index 170a14d2c845a9282e5641e55aceba4a8859f71e..761404ba18af84409cfae1c2e7940ed878f4f160 100644 (file)
@@ -229,8 +229,7 @@ pane_size_watcher (Paned* pane)
 }
 
 Editor::Editor ()
-       : VisibilityTracker (*((Gtk::Window*) this))
-       , _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
+       : _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
 
          /* time display buttons */
        , minsec_label (_("Mins:Secs"))
index 6c0a52fa4278270928e5ad06dc9db7e3b5962233..f9ce1da514cf20165316a2adda25e127d78f1238 100644 (file)
@@ -43,7 +43,6 @@
 #include "gtkmm2ext/dndtreeview.h"
 #include "gtkmm2ext/stateful_button.h"
 #include "gtkmm2ext/bindings.h"
-#include "gtkmm2ext/visibility_tracker.h"
 
 #include "pbd/stateful.h"
 #include "pbd/signals.h"
@@ -137,7 +136,7 @@ class TimeSelection;
 class RegionLayeringOrderEditor;
 class VerboseCursor;
 
-class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public Gtkmm2ext::VisibilityTracker
+class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr
 {
   public:
        Editor ();
index dc468e4a83e237f05c7837a7d3b0d3224a7113e9..6c5d528e1e9aad86d84496496955def2b5bc5c7f 100644 (file)
@@ -30,6 +30,7 @@ sigc::signal<void> PublicEditor::DropDownKeys;
 
 PublicEditor::PublicEditor ()
        : Window (Gtk::WINDOW_TOPLEVEL)
+       , VisibilityTracker (*((Gtk::Window*)this))
 {
 }
 
index a96e451a3172fe9de3ebf7187c07feda4cf02121..7a4dd5d59bfa1a1952c8bfb12505484f86c18606 100644 (file)
@@ -39,6 +39,8 @@
 
 #include "pbd/statefuldestructible.h"
 
+#include "gtkmm2ext/visibility_tracker.h"
+
 #include "editing.h"
 #include "canvas.h"
 #include "selection.h"
@@ -97,7 +99,7 @@ using ARDOUR::framecnt_t;
  * of PublicEditor need not be recompiled if private methods or member variables
  * change.
  */
-class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
+class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, public Gtkmm2ext::VisibilityTracker {
   public:
        PublicEditor ();
        virtual ~PublicEditor ();
index cb63f4f822cf855bb8e220089031f8b58ef6bcf6..627e9a1744e401aad42aa3cd5167e2ec3f4dc7bd 100644 (file)
@@ -112,6 +112,26 @@ WindowManager::set_session (ARDOUR::Session* s)
        }
 }
 
+void
+WindowManager::set_transient_for (Gtk::Window* parent)
+{
+       if (parent) {
+               for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
+                       Gtk::Window* win = (*i)->get();
+                       if (win) {
+                               win->set_transient_for (*parent);
+                       }
+               }
+       } else {
+               for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) {
+                       Gtk::Window* win = (*i)->get();
+                       if (win) {
+                               gtk_window_set_transient_for (win->gobj(), 0);
+                       }
+               }
+       }
+}
+
 /*-----------------------*/
 
 WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name)
index 9f4382725d70b0c0827f9087a768ba4e5393b8ec..082407b61d2e7924581d9382da091db2182ddd9f 100644 (file)
@@ -180,6 +180,9 @@ class WindowManager
     void set_session (ARDOUR::Session*);
     void add_state (XMLNode&) const;
 
+    /* HACK HACK HACK */
+    void set_transient_for (Gtk::Window*);
+
   private:
     typedef std::list<ProxyBase*> Windows;
     Windows _windows;
index 4bc9113875c04dca7b13823b2d1af29146694586..f0a09d56857a2dbfa3adfdbc2aeb7d98e0669c5e 100644 (file)
@@ -23,7 +23,6 @@
 #include <gtk/gtkpaned.h>
 #include <gtk/gtk.h>
 
-#include <gtkmm2ext/utils.h>
 #include <gtkmm/widget.h>
 #include <gtkmm/button.h>
 #include <gtkmm/window.h>
@@ -32,6 +31,8 @@
 #include <gtkmm/comboboxtext.h>
 #include <gtkmm/tooltip.h>
 
+#include "gtkmm2ext/utils.h"
+
 #include "i18n.h"
 
 using namespace std;
@@ -659,3 +660,4 @@ Gtkmm2ext::disable_tooltips ()
 {
        gtk_rc_parse_string ("gtk-enable-tooltips = 0");
 }
+
index 8c7c4938128d7ded06ec6c012f7e0787f6d801dc..aac76a5021ebaabe1fddabfc5a5e617cba1816a5 100644 (file)
@@ -35,7 +35,7 @@ bool
 VisibilityTracker::handle_visibility_notify_event (GdkEventVisibility* ev)
 {
        _visibility = ev->state;
-       std::cerr << "VT: " << _window.get_title() << " vis event, fv = " << fully_visible() << " pv = " << partially_visible() << " nv = " << not_visible() << std::endl;
+       // std::cerr << "VT: " << _window.get_title() << " vis event, fv = " << fully_visible() << " pv = " << partially_visible() << " nv = " << not_visible() << std::endl;
        return false;
 }