widespread changes to get the new (oldArdour binding scheme to be used for keyboard accelerators
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
Reference in New Issue
Block a user