From 68e943265edf04e63a8e8b8f62bab20f99d9c637 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 10 Sep 2008 15:03:30 +0000 Subject: merge from 2.0-ongoing @ 3581 git-svn-id: svn://localhost/ardour2/branches/3.0@3711 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/keyboard.cc | 78 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 5 deletions(-) (limited to 'gtk2_ardour/keyboard.cc') diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc index 22dd274306..ef8cc34389 100644 --- a/gtk2_ardour/keyboard.cc +++ b/gtk2_ardour/keyboard.cc @@ -17,6 +17,7 @@ */ +#include #include #include "ardour_ui.h" @@ -38,11 +39,14 @@ #include "keyboard.h" #include "gui_thread.h" #include "opts.h" +#include "actions.h" #include "i18n.h" using namespace PBD; using namespace ARDOUR; +using namespace Gtk; +using namespace std; #define KBD_DEBUG 1 bool debug_keyboard = false; @@ -75,8 +79,10 @@ bool Keyboard::_some_magic_widget_has_focus = false; std::string Keyboard::user_keybindings_path; bool Keyboard::can_save_keybindings = false; +bool Keyboard::bindings_changed_after_save_became_legal = false; map Keyboard::binding_files; -std::string Keyboard::_current_binding_name = _("Unknown"); +string Keyboard::_current_binding_name = _("Unknown"); +map,Keyboard::AccelKeyLess> Keyboard::release_keys; /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */ @@ -186,6 +192,7 @@ gint Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) { uint32_t keyval; + bool ret = false; #if 0 cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type @@ -215,7 +222,23 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) if (find (state.begin(), state.end(), keyval) == state.end()) { state.push_back (keyval); sort (state.begin(), state.end()); - } + + } else { + + /* key is already down. if its also used for release, + prevent auto-repeat events. + */ + + for (map::iterator k = release_keys.begin(); k != release_keys.end(); ++k) { + + const AccelKey& ak (k->first); + + if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) { + ret = true; + break; + } + } + } } else if (event->type == GDK_KEY_RELEASE) { @@ -226,6 +249,20 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) sort (state.begin(), state.end()); } + for (map::iterator k = release_keys.begin(); k != release_keys.end(); ++k) { + + const AccelKey& ak (k->first); + two_strings ts (k->second); + + if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) { + Glib::RefPtr act = ActionManager::get_action (ts.first.c_str(), ts.second.c_str()); + if (act) { + act->activate(); + ret = true; + } + break; + } + } } if (event->type == GDK_KEY_RELEASE && event->keyval == GDK_w && modifier_state_equals (event->state, PrimaryModifier)) { @@ -235,7 +272,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) } } - return false; + return ret; } bool @@ -388,6 +425,16 @@ accel_map_changed (GtkAccelMap* map, GdkModifierType mod, gpointer arg) { + Keyboard::keybindings_changed (); +} + +void +Keyboard::keybindings_changed () +{ + if (Keyboard::can_save_keybindings) { + Keyboard::bindings_changed_after_save_became_legal = true; + } + Keyboard::save_keybindings (); } @@ -400,7 +447,7 @@ Keyboard::set_can_save_keybindings (bool yn) void Keyboard::save_keybindings () { - if (can_save_keybindings) { + if (can_save_keybindings && bindings_changed_after_save_became_legal) { Gtk::AccelMap::save (user_keybindings_path); } } @@ -555,13 +602,34 @@ Keyboard::load_keybindings (string path) } } - return true; } catch (...) { error << string_compose (_("Ardour key bindings file not found at \"%1\" or contains errors."), path) << endmsg; return false; } + + /* now find all release-driven bindings */ + + vector groups; + vector names; + vector bindings; + + ActionManager::get_all_actions (groups, names, bindings); + + vector::iterator g; + vector::iterator b; + vector::iterator n; + + release_keys.clear (); + + for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) { + if ((*b).get_mod() & Gdk::RELEASE_MASK) { + release_keys.insert (pair (*b, two_strings (*g, *n))); + } + } + + return true; } -- cgit v1.2.3