From c62026b5679810d4633c1a2de841daf29dda9dc6 Mon Sep 17 00:00:00 2001 From: nick_m Date: Sun, 14 Aug 2016 01:16:48 +1000 Subject: [PATCH] Ensure RelevantModifierKeyMask is updated on each modifier change. - fixes bug where changing prefs in User Interaction only took effect on restart. --- gtk2_ardour/keyboard.cc | 38 +++++++----- gtk2_ardour/keyboard.h | 4 +- libs/gtkmm2ext/gtkmm2ext/keyboard.h | 2 + libs/gtkmm2ext/keyboard.cc | 92 +++++++++++++++-------------- 4 files changed, 76 insertions(+), 60 deletions(-) diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc index 6341071451..99ab415c7e 100644 --- a/gtk2_ardour/keyboard.cc +++ b/gtk2_ardour/keyboard.cc @@ -50,6 +50,11 @@ guint ArdourKeyboard::fine_adjust_mod = Keyboard::SecondaryModifier; guint ArdourKeyboard::push_points_mod = Keyboard::PrimaryModifier; guint ArdourKeyboard::note_size_relative_mod = Keyboard::PrimaryModifier; +ArdourKeyboard::ArdourKeyboard (ARDOUR_UI& ardour_ui) : ui (ardour_ui) +{ + Keyboard::RelevantModifierKeysChanged.connect (sigc::mem_fun (*this, &ArdourKeyboard::reset_relevant_modifier_key_mask)); +} + void ArdourKeyboard::find_bindings_files (map& files) { @@ -260,6 +265,18 @@ ArdourKeyboard::set_state (const XMLNode& node, int version) return Keyboard::set_state (node, version); } +void +ArdourKeyboard::reset_relevant_modifier_key_mask () +{ + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | constraint_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_contents_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_overlap_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_anchored_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | fine_adjust_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | push_points_mod); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | note_size_relative_mod); +} + /* Snap and snap delta modifiers may contain each other, so we use the * following two methods to sort that out: */ @@ -286,57 +303,50 @@ ArdourKeyboard::indicates_snap_delta (guint state) void ArdourKeyboard::set_constraint_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~constraint_mod); constraint_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | constraint_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_trim_contents_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~trim_contents_mod); trim_contents_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_contents_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_trim_overlap_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~trim_overlap_mod); trim_overlap_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_overlap_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_trim_anchored_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~trim_anchored_mod); trim_anchored_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | trim_anchored_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_fine_adjust_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~fine_adjust_mod); fine_adjust_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | fine_adjust_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_push_points_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~push_points_mod); push_points_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | push_points_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } void ArdourKeyboard::set_note_size_relative_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~note_size_relative_mod); note_size_relative_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | note_size_relative_mod); + the_keyboard().reset_relevant_modifier_key_mask(); } Selection::Operation diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h index c6a05abe2a..e008a40128 100644 --- a/gtk2_ardour/keyboard.h +++ b/gtk2_ardour/keyboard.h @@ -33,7 +33,7 @@ class ARDOUR_UI; class ArdourKeyboard : public Gtkmm2ext::Keyboard { public: - ArdourKeyboard(ARDOUR_UI& ardour_ui) : ui(ardour_ui) {} + ArdourKeyboard(ARDOUR_UI&); XMLNode& get_state (void); int set_state (const XMLNode&, int version); @@ -44,6 +44,8 @@ class ArdourKeyboard : public Gtkmm2ext::Keyboard ARDOUR_UI& ui; + void reset_relevant_modifier_key_mask (); + /** @param state The button state from a GdkEvent. * @return true if the modifier state indicates snap modifier */ diff --git a/libs/gtkmm2ext/gtkmm2ext/keyboard.h b/libs/gtkmm2ext/gtkmm2ext/keyboard.h index 58af25f9d2..316fdd7fe3 100644 --- a/libs/gtkmm2ext/gtkmm2ext/keyboard.h +++ b/libs/gtkmm2ext/gtkmm2ext/keyboard.h @@ -51,6 +51,7 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful int set_state (const XMLNode&, int version); virtual void setup_keybindings () = 0; + static void reset_relevant_modifier_key_mask (); typedef std::vector State; typedef uint32_t ModifierMask; @@ -183,6 +184,7 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful int reset_bindings (); sigc::signal0 ZoomVerticalModifierReleased; + static sigc::signal0 RelevantModifierKeysChanged; protected: static Keyboard* _the_keyboard; diff --git a/libs/gtkmm2ext/keyboard.cc b/libs/gtkmm2ext/keyboard.cc index 135e1fdc56..fe7303b290 100644 --- a/libs/gtkmm2ext/keyboard.cc +++ b/libs/gtkmm2ext/keyboard.cc @@ -127,6 +127,7 @@ Gtk::Window* Keyboard::pre_dialog_active_window = 0; /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */ GdkModifierType Keyboard::RelevantModifierKeyMask; +sigc::signal0 Keyboard::RelevantModifierKeysChanged; void Keyboard::magic_widget_grab_focus () @@ -153,39 +154,7 @@ Keyboard::Keyboard () _current_binding_name = _("Unknown"); } - RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask (); - - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | PrimaryModifier); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | SecondaryModifier); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | TertiaryModifier); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | Level4Modifier); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | CopyModifier); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | RangeSelectModifier); - - gtk_accelerator_set_default_mod_mask (RelevantModifierKeyMask); - -#ifdef __APPLE__ - /* Remove SUPER,HYPER,META. - * - * GTK on OS X adds META when Command is pressed for various indefensible reasons, since - * it also uses MOD2 to indicate Command. Our code assumes that each - * modifier (Primary, Secondary etc.) is represented by a single bit in - * the modifier mask, but GTK's (STUPID) design uses two (MOD2 + META) - * to represent the Command key. Some discussion about this is here: - * https://bugzilla.gnome.org/show_bug.cgi?id=692597 - * - * We cannot do this until AFTER we told GTK what the default modifier - * was, because otherwise it will fail to recognize MOD2-META- as - * an accelerator. - * - * Note that in the tabbed branch, we no longer use GTK accelerators - * for functional purposes, so this is as critical for that branch. - */ - - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_SUPER_MASK); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_HYPER_MASK); - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_META_MASK); -#endif + reset_relevant_modifier_key_mask(); snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this); } @@ -359,6 +328,45 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) return ret; } +void +Keyboard::reset_relevant_modifier_key_mask () +{ + RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask (); + + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | PrimaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | SecondaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | TertiaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | Level4Modifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | CopyModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | RangeSelectModifier); + + gtk_accelerator_set_default_mod_mask (RelevantModifierKeyMask); + +#ifdef __APPLE__ + /* Remove SUPER,HYPER,META. + * + * GTK on OS X adds META when Command is pressed for various indefensible reasons, since + * it also uses MOD2 to indicate Command. Our code assumes that each + * modifier (Primary, Secondary etc.) is represented by a single bit in + * the modifier mask, but GTK's (STUPID) design uses two (MOD2 + META) + * to represent the Command key. Some discussion about this is here: + * https://bugzilla.gnome.org/show_bug.cgi?id=692597 + * + * We cannot do this until AFTER we told GTK what the default modifier + * was, because otherwise it will fail to recognize MOD2-META- as + * an accelerator. + * + * Note that in the tabbed branch, we no longer use GTK accelerators + * for functional purposes, so this is as critical for that branch. + */ + + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_SUPER_MASK); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_HYPER_MASK); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~GDK_META_MASK); +#endif + RelevantModifierKeysChanged(); /* EMIT SIGNAL */ +} + void Keyboard::close_current_dialog () { @@ -471,9 +479,8 @@ Keyboard::set_edit_button (guint but) void Keyboard::set_edit_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~edit_mod); edit_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | edit_mod); + reset_relevant_modifier_key_mask(); } void @@ -485,9 +492,8 @@ Keyboard::set_delete_button (guint but) void Keyboard::set_delete_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~delete_mod); delete_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | delete_mod); + reset_relevant_modifier_key_mask(); } void @@ -499,34 +505,30 @@ Keyboard::set_insert_note_button (guint but) void Keyboard::set_insert_note_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~insert_note_mod); insert_note_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | insert_note_mod); + reset_relevant_modifier_key_mask(); } void Keyboard::set_modifier (uint32_t newval, uint32_t& var) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~var); var = newval; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | var); + reset_relevant_modifier_key_mask(); } void Keyboard::set_snap_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~snap_mod); snap_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | snap_mod); + reset_relevant_modifier_key_mask(); } void Keyboard::set_snap_delta_modifier (guint mod) { - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~snap_delta_mod); snap_delta_mod = mod; - RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | snap_delta_mod); + reset_relevant_modifier_key_mask(); } bool