Attempt to fix some confusions caused by bundles containing
[ardour.git] / gtk2_ardour / utils.cc
index 8cdf5e0b58650b3a04083b6d97308c2146e8da19..7c711703079a752e83fc8c1ce09c06bf6fbb73bc 100644 (file)
@@ -27,6 +27,7 @@
 #include <cstdlib>
 #include <cctype>
 #include <fstream>
+#include <list>
 #include <sys/stat.h>
 #include <libart_lgpl/art_misc.h>
 #include <gtkmm/rc.h>
@@ -303,7 +304,7 @@ get_canvas_points (string /*who*/, uint32_t npoints)
        return new ArdourCanvas::Points (npoints);
 }
 
-Pango::FontDescription*
+Pango::FontDescription
 get_font_for_style (string widgetname)
 {
        Gtk::Window window (WINDOW_TOPLEVEL);
@@ -326,10 +327,10 @@ get_font_for_style (string widgetname)
 
                PangoContext* ctxt = (PangoContext*) pango_layout_get_context ((PangoLayout*) layout->gobj());
                pfd =  pango_context_get_font_description (ctxt);
-               return new Pango::FontDescription (pfd, true); /* make a copy */
+               return Pango::FontDescription (pfd); /* make a copy */
        }
 
-       return new Pango::FontDescription (pfd, true); /* make a copy */
+       return Pango::FontDescription (pfd); /* make a copy */
 }
 
 uint32_t
@@ -599,6 +600,8 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
        GtkWidget* focus = gtk_window_get_focus (win);
        bool special_handling_of_unmodified_accelerators = false;
        bool allow_activating = true;
+       /* consider all relevant modifiers but not LOCK or SHIFT */
+       const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
 
        if (focus) {
                if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) {
@@ -613,7 +616,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
        }
 #endif
 
-        
+
         DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 Key event: code = %2  state = %3 special handling ? %4 magic widget focus ? %5 allow_activation ? %6\n",
                                                           win,
                                                           ev->keyval,
@@ -621,7 +624,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
                                                           special_handling_of_unmodified_accelerators,
                                                           Keyboard::some_magic_widget_has_focus(),
                                                           allow_activating));
-        
+
        /* This exists to allow us to override the way GTK handles
           key events. The normal sequence is:
 
@@ -654,42 +657,54 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
        */
 
 #ifdef GTKOSX
-       if (!special_handling_of_unmodified_accelerators) {
-               if (ev->state & GDK_MOD1_MASK) {
-                       /* we're not in a text entry or "magic focus" widget so we don't want OS X "special-character" 
-                          text-style handling of alt-<key>. change the keyval back to what it would be without
-                          the alt key. this way, we see <alt>-v rather than <alt>-radical and so on.
-                       */
-                       guint keyval_without_alt = osx_keyval_without_alt (ev->keyval);
-
-                       if (keyval_without_alt != GDK_VoidSymbol) {
-                                DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Remapped %1 to %2\n", gdk_keyval_name (ev->keyval), gdk_keyval_name (keyval_without_alt)));
-                               ev->keyval = keyval_without_alt;
-                       }
+       if (!special_handling_of_unmodified_accelerators && (ev->state & Keyboard::SecondaryModifier)) {
+               /* we're not in a text entry or "magic focus" widget so we don't want OS X "special-character"
+                  text-style handling of alt-<key>. change the keyval back to what it would be without
+                  the alt key. this way, we see <alt>-v rather than <alt>-radical and so on.
+               */
+               guint keyval_without_alt = osx_keyval_without_alt (ev->keyval);
+               
+               if (keyval_without_alt != GDK_VoidSymbol) {
+                       DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Remapped %1 to %2\n", gdk_keyval_name (ev->keyval), gdk_keyval_name (keyval_without_alt)));
+                       ev->keyval = keyval_without_alt;
                }
        }
+       
 #endif
-
+       
        if (!special_handling_of_unmodified_accelerators) {
 
+               /* XXX note that for a brief moment, the conditional above
+                * included "|| (ev->state & mask)" so as to enforce the
+                * implication of special_handling_of_UNMODIFIED_accelerators.
+                * however, this forces any key that GTK doesn't allow and that
+                * we have an alternative (see next comment) for to be
+                * automatically sent through the accel groups activation
+                * pathway, which prevents individual widgets & canvas items
+                * from ever seeing it if is used by a key binding.
+                * 
+                * specifically, this hid Ctrl-down-arrow from MIDI region
+                * views because it is also bound to an action.
+                *
+                * until we have a robust, clean binding system, this
+                * quirk will have to remain in place.
+                */
+
                /* pretend that certain key events that GTK does not allow
                   to be used as accelerators are actually something that
-                  it does allow.
+                  it does allow. but only where there are no modifiers.
                */
 
                uint32_t fakekey = ev->keyval;
 
                if (Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
                        if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
+                               DEBUG_TRACE (DEBUG::Accelerators, "\taccel group activated by fakekey\n");
                                return true;
                        }
                }
        }
 
-       /* consider all relevant modifiers but not LOCK or SHIFT */
-
-       guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
-
        if (!special_handling_of_unmodified_accelerators || (ev->state & mask)) {
 
                /* no special handling or there are modifiers in effect: accelerate first */
@@ -700,6 +715,8 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
                        if (gtk_window_activate_key (win, ev)) {
                                return true;
                        }
+               } else {
+                       DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
                }
 
                 DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
@@ -715,6 +732,8 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
                 DEBUG_TRACE (DEBUG::Accelerators, "\tpropagation didn't handle, so activate\n");
                if (allow_activating) {
                        return gtk_window_activate_key (win, ev);
+               } else {
+                       DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
                }
 
        } else {
@@ -920,4 +939,42 @@ escape_underscores (string const & s)
        return o;
 }
 
-                                           
+Gdk::Color
+unique_random_color (list<Gdk::Color>& used_colors)
+{
+       Gdk::Color newcolor;
+
+       while (1) {
+
+               /* avoid neon/glowing tones by limiting them to the
+                  "inner section" (paler) of a color wheel/circle.
+               */
+
+               const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
+
+               newcolor.set_red (random() % max_saturation);
+               newcolor.set_blue (random() % max_saturation);
+               newcolor.set_green (random() % max_saturation);
+
+               if (used_colors.size() == 0) {
+                       used_colors.push_back (newcolor);
+                       return newcolor;
+               }
+
+               for (list<Gdk::Color>::iterator i = used_colors.begin(); i != used_colors.end(); ++i) {
+                 Gdk::Color c = *i;
+                       float rdelta, bdelta, gdelta;
+
+                       rdelta = newcolor.get_red() - c.get_red();
+                       bdelta = newcolor.get_blue() - c.get_blue();
+                       gdelta = newcolor.get_green() - c.get_green();
+
+                       if (sqrt (rdelta*rdelta + bdelta*bdelta + gdelta*gdelta) > 25.0) {
+                               used_colors.push_back (newcolor);
+                               return newcolor;
+                       }
+               }
+
+               /* XXX need throttle here to make sure we don't spin for ever */
+       }
+}