widespread changes to get the new (oldArdour binding scheme to be used for keyboard accelerators

This commit is contained in:
Paul Davis
2015-07-09 18:10:19 -04:00
parent 50e4ebff36
commit 37fce09a18
8 changed files with 126 additions and 141 deletions

View File

@@ -111,7 +111,6 @@ typedef uint64_t microseconds_t;
#include "audio_clock.h"
#include "audio_region_view.h"
#include "big_clock_window.h"
#include "binding_owners.h"
#include "bundle_manager.h"
#include "duplicate_routes_dialog.h"
#include "debug.h"
@@ -2067,6 +2066,7 @@ ARDOUR_UI::get_smart_mode() const
void
ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
{
PBD::stacktrace (cerr, 30);
if (!_session) {
return;
}
@@ -5132,29 +5132,28 @@ ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
/* see if it uses the ardour binding system */
HasBindings* bindable;
if ((bindable = dynamic_cast<HasBindings*> (w)) != 0) {
KeyboardKey k (ev->state, ev->keyval);
bindings = &bindable->bindings();
if (w) {
bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(w->get_data ("ardour-bindings"));
} else {
bindings = &_global_bindings;
}
} else if (window != 0) {
} else if (event_window != 0) {
window = event_window;
/* see if window uses ardour binding system */
} else {
window = &_main_window;
bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(window->get_data ("ardour-bindings"));
/* no window supplied, try our own bindings */
}
bindings = &_global_bindings;
/* An empty binding set is treated as if it doesn't exist */
if (bindings && bindings->empty()) {
bindings = 0;
}
return key_press_focus_accelerator_handler (*window, ev, bindings);
}
@@ -5164,39 +5163,33 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
GtkWindow* win = window.gobj();
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));
GdkModifierType modifier = GdkModifierType (ev->state);
modifier = GdkModifierType (modifier & gtk_accelerator_get_default_mod_mask());
Gtkmm2ext::possibly_translate_mod_to_make_legal_accelerator(modifier);
if (focus) {
if (focus) {
/* some widget has keyboard focus */
if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) {
/* A particular kind of focusable widget currently has keyboard
* focus. All unmodified key events should go to that widget
* first and not be used as an accelerator by default
*/
special_handling_of_unmodified_accelerators = true;
}
}
#ifdef GTKOSX
/* at one time this appeared to be necessary. As of July 2012, it does not
appear to be. if it ever is necessar, figure out if it should apply
to all platforms.
*/
#if 0
if (Keyboard::some_magic_widget_has_focus ()) {
allow_activating = false;
}
#endif
#endif
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 (%8) Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 allow_activation ? %6\n",
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 (%8) Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7\n",
win,
ev->keyval,
show_gdk_event_state (ev->state),
special_handling_of_unmodified_accelerators,
Keyboard::some_magic_widget_has_focus(),
allow_activating,
focus,
(focus ? gtk_widget_get_name (focus) : "no focus widget")));
@@ -5231,8 +5224,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
all "normal text" accelerators.
*/
if (!special_handling_of_unmodified_accelerators) {
if (!special_handling_of_unmodified_accelerators && !bindings) {
/* XXX note that for a brief moment, the conditional above
* included "|| (ev->state & mask)" so as to enforce the
@@ -5262,8 +5254,8 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
ev->keyval, fakekey));
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tmodified modifier was %1\n", show_gdk_event_state (modifier)));
if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, modifier)) {
if (gtk_accel_groups_activate(G_OBJECT(win), fakekey, modifier)) {
DEBUG_TRACE (DEBUG::Accelerators, "\taccel group activated by fakekey\n");
return true;
}
@@ -5278,38 +5270,78 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 name %7 string:%4 hardware_keycode:%5 group:%6\n",
ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group, gdk_keyval_name (ev->keyval)));
if (allow_activating) {
DEBUG_TRACE (DEBUG::Accelerators, "\tsending to window\n");
if (gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
DEBUG_TRACE (DEBUG::Accelerators, "\tsending to window\n");
if (bindings) {
DEBUG_TRACE (DEBUG::Accelerators, "\tusing Ardour bindings for this window\n");
KeyboardKey k (ev->state, ev->keyval);
if (bindings->activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
} else {
DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
DEBUG_TRACE (DEBUG::Accelerators, "\tusing GTK accelerators for this window\n");
if (gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
}
DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
return gtk_window_propagate_key_event (win, ev);
}
/* no modifiers, propagate first */
DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate, then activate\n");
if (!gtk_window_propagate_key_event (win, ev)) {
DEBUG_TRACE (DEBUG::Accelerators, "\tpropagation didn't handle, so activate\n");
if (allow_activating) {
return gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier);
} else {
DEBUG_TRACE (DEBUG::Accelerators, "\tactivation skipped\n");
}
if (gtk_window_propagate_key_event (win, ev)) {
DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n");
return true;
}
} else {
DEBUG_TRACE (DEBUG::Accelerators, "\thandled by propagate\n");
return true;
/* no modifiers, propagate first */
DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate, then activate\n");
if (!gtk_window_propagate_key_event (win, ev)) {
DEBUG_TRACE (DEBUG::Accelerators, "\tpropagation didn't handle, so activate\n");
if (bindings) {
DEBUG_TRACE (DEBUG::Accelerators, "\tusing Ardour bindings for this window\n");
KeyboardKey k (ev->state, ev->keyval);
if (bindings->activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
} else {
DEBUG_TRACE (DEBUG::Accelerators, "\tusing GTK accelerators for this window\n");
if (gtk_accel_groups_activate (G_OBJECT(win), ev->keyval, modifier)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
}
} else {
DEBUG_TRACE (DEBUG::Accelerators, "\thandled by propagate\n");
return true;
}
}
DEBUG_TRACE (DEBUG::Accelerators, "\tnot yet handled, try global bindings\n");
KeyboardKey k (ev->state, ev->keyval);
if (_global_bindings.activate (k, Bindings::Press)) {
DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
return true;
}
DEBUG_TRACE (DEBUG::Accelerators, "\tnot handled\n");
return true;
}

View File

@@ -1,43 +0,0 @@
/*
Copyright (C) 2015 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtk_ardour_binding_owners_h__
#define __gtk_ardour_binding_owners_h__
#include <gtkmm/box.h>
#include "gtkmm2ext/bindings.h"
class HasBindings {
public:
HasBindings (Gtkmm2ext::Bindings& b) : _bindings (b) {}
Gtkmm2ext::Bindings& bindings() const { return _bindings; }
protected:
Gtkmm2ext::Bindings& _bindings;
};
class VBoxWithBindings : public Gtk::VBox, public HasBindings
{
public:
VBoxWithBindings (Gtkmm2ext::Bindings& b) : HasBindings (b) {}
};
#endif /* __gtk_ardour_binding_owners_h__ */

View File

@@ -287,7 +287,6 @@ Editor::Editor ()
, track_edit_playlist_submenu (0)
, track_selection_edit_playlist_submenu (0)
, _popup_region_menu_item (0)
, global_vpacker (key_bindings)
, _track_canvas (0)
, _track_canvas_viewport (0)
, within_track_canvas (false)
@@ -476,6 +475,8 @@ Editor::Editor ()
last_event_time.tv_sec = 0;
last_event_time.tv_usec = 0;
global_hpacker.set_data ("ardour-bindings", &key_bindings);
selection_op_history.clear();
before.clear();
@@ -5946,6 +5947,7 @@ Editor::use_own_window (bool and_fill_it)
// win->signal_realize().connect (*this, &Editor::on_realize);
win->signal_event().connect (sigc::mem_fun (*this, &Editor::generic_event_handler));
win->set_data ("ardour-bindings", &key_bindings);
update_title ();
}

View File

@@ -54,7 +54,6 @@
#include "ardour_button.h"
#include "ardour_dialog.h"
#include "ardour_dropdown.h"
#include "binding_owners.h"
#include "public_editor.h"
#include "editing.h"
#include "enums.h"
@@ -780,8 +779,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void add_routes (ARDOUR::RouteList&);
void timeaxisview_deleted (TimeAxisView *);
Gtk::HBox global_hpacker;
VBoxWithBindings global_vpacker;
Gtk::HBox global_hpacker;
Gtk::VBox global_vpacker;
/* Cursor stuff. Do not use directly, use via CursorContext. */
friend class CursorContext;

View File

@@ -105,6 +105,8 @@ Mixer_UI::Mixer_UI ()
{
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_order_keys, this), gui_context());
_content.set_data ("ardour-bindings", &bindings);
scroller.set_can_default (true);
// set_default (scroller);
@@ -1929,39 +1931,6 @@ Mixer_UI::scroll_right ()
scroller.get_hscrollbar()->set_value (min (adj->get_upper(), adj->get_value() + adj->get_step_increment()));
}
bool
Mixer_UI::on_key_press_event (GdkEventKey* ev)
{
KeyboardKey k (ev->state, ev->keyval);
if (bindings.activate (k, Bindings::Press)) {
return true;
}
if (_parent_window) {
/* send it to the main window, since our own bindings didn't
* handle it
*/
return forward_key_press (ev);
}
return false;
}
bool
Mixer_UI::on_key_release_event (GdkEventKey* ev)
{
KeyboardKey k (ev->state, ev->keyval);
if (bindings.activate (k, Bindings::Release)) {
return true;
}
/* don't forward releases */
return true;
}
bool
Mixer_UI::on_scroll_event (GdkEventScroll* ev)
{

View File

@@ -153,8 +153,6 @@ class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, p
void set_window_pos_and_size ();
void get_window_pos_and_size ();
bool on_key_press_event (GdkEventKey*);
bool on_key_release_event (GdkEventKey*);
bool on_scroll_event (GdkEventScroll*);
void pane_allocation_handler (Gtk::Allocation&, Gtk::Paned*);

View File

@@ -227,6 +227,24 @@ Bindings::~Bindings()
{
}
bool
Bindings::empty_keys() const
{
return press_bindings.empty() && release_bindings.empty();
}
bool
Bindings::empty_mouse () const
{
return button_press_bindings.empty() && button_release_bindings.empty();
}
bool
Bindings::empty() const
{
return empty_keys() && empty_mouse ();
}
void
Bindings::set_action_map (ActionMap& am)
{
@@ -253,7 +271,7 @@ Bindings::activate (KeyboardKey kb, Operation op)
if (k == kbm->end()) {
/* no entry for this key in the state map */
return false;
return false;
}
/* lets do it ... */
@@ -281,7 +299,6 @@ Bindings::add (KeyboardKey kb, Operation op, RefPtr<Action> what)
if (k == kbm->end()) {
pair<KeyboardKey,RefPtr<Action> > newpair (kb, what);
kbm->insert (newpair);
// cerr << "Bindings added " << kb.key() << " w/ " << kb.state() << " => " << what->get_name() << endl;
} else {
k->second = what;
}
@@ -605,3 +622,8 @@ ActionMap::register_toggle_action (const char* path,
actions.insert (_ActionMap::value_type (fullpath, act));
return act;
}
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey& k) {
return out << "Key " << k.key() << " state " << k.state();
}

View File

@@ -98,6 +98,10 @@ class LIBGTKMM2EXT_API Bindings {
Bindings();
~Bindings ();
bool empty() const;
bool empty_keys () const;
bool empty_mouse () const;
void add (KeyboardKey, Operation, Glib::RefPtr<Gtk::Action>);
void remove (KeyboardKey, Operation);
bool activate (KeyboardKey, Operation);
@@ -134,4 +138,6 @@ class LIBGTKMM2EXT_API Bindings {
} // namespace
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey& k);
#endif /* __libgtkmm2ext_bindings_h__ */