changes to Bindings and Keyboard API to support (mostly) GTK-free keyboard bindings
This commit is contained in:
parent
ad220df6b7
commit
0f17508e6c
|
@ -20,13 +20,19 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "pbd/gstdio_compat.h"
|
||||
#include <gtkmm/accelmap.h>
|
||||
#include <gtkmm/uimanager.h>
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/debug.h"
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
#include "gtkmm2ext/actions.h"
|
||||
#include "gtkmm2ext/bindings.h"
|
||||
#include "gtkmm2ext/debug.h"
|
||||
#include "gtkmm2ext/keyboard.h"
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -34,6 +40,7 @@ using namespace std;
|
|||
using namespace Glib;
|
||||
using namespace Gtk;
|
||||
using namespace Gtkmm2ext;
|
||||
using namespace PBD;
|
||||
|
||||
uint32_t Bindings::_ignored_state = 0;
|
||||
|
||||
|
@ -130,12 +137,6 @@ KeyboardKey::KeyboardKey (uint32_t state, uint32_t keycode)
|
|||
{
|
||||
uint32_t ignore = Bindings::ignored_state();
|
||||
|
||||
if (gdk_keyval_is_upper (keycode) && gdk_keyval_is_lower (keycode)) {
|
||||
/* key is not subject to case, so ignore SHIFT
|
||||
*/
|
||||
ignore |= GDK_SHIFT_MASK;
|
||||
}
|
||||
|
||||
_val = (state & ~ignore);
|
||||
_val <<= 32;
|
||||
_val |= keycode;
|
||||
|
@ -203,7 +204,7 @@ KeyboardKey::make_key (const string& str, KeyboardKey& k)
|
|||
|
||||
string::size_type lastmod = str.find_last_of ('-');
|
||||
guint keyval;
|
||||
|
||||
|
||||
if (lastmod == string::npos) {
|
||||
keyval = gdk_keyval_from_name (str.c_str());
|
||||
} else {
|
||||
|
@ -211,10 +212,11 @@ KeyboardKey::make_key (const string& str, KeyboardKey& k)
|
|||
}
|
||||
|
||||
if (keyval == GDK_VoidSymbol) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
k = KeyboardKey (s, keyval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -266,16 +268,19 @@ Bindings::activate (KeyboardKey kb, Operation op)
|
|||
kbm = &release_bindings;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
KeybindingMap::iterator k = kbm->find (kb);
|
||||
|
||||
if (k == kbm->end()) {
|
||||
/* no entry for this key in the state map */
|
||||
DEBUG_TRACE (DEBUG::Bindings, string_compose ("no binding for %1\n", kb));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* lets do it ... */
|
||||
|
||||
DEBUG_TRACE (DEBUG::Bindings, string_compose ("binding for %1: %2\n", kb, k->second->get_name()));
|
||||
|
||||
k->second->activate ();
|
||||
return true;
|
||||
}
|
||||
|
@ -287,7 +292,7 @@ Bindings::add (KeyboardKey kb, Operation op, RefPtr<Action> what)
|
|||
|
||||
switch (op) {
|
||||
case Press:
|
||||
kbm = &press_bindings;
|
||||
kbm = &press_bindings;
|
||||
break;
|
||||
case Release:
|
||||
kbm = &release_bindings;
|
||||
|
@ -297,11 +302,36 @@ Bindings::add (KeyboardKey kb, Operation op, RefPtr<Action> what)
|
|||
KeybindingMap::iterator k = kbm->find (kb);
|
||||
|
||||
if (k == kbm->end()) {
|
||||
pair<KeyboardKey,RefPtr<Action> > newpair (kb, what);
|
||||
pair<KeyboardKey,RefPtr<Action> > newpair (kb, what);
|
||||
kbm->insert (newpair);
|
||||
} else {
|
||||
k->second = what;
|
||||
}
|
||||
|
||||
Gtk::AccelKey gtk_key;
|
||||
|
||||
/* tweak the binding so that GTK will accept it and display something
|
||||
* acceptable
|
||||
*/
|
||||
|
||||
uint32_t gtk_legal_keyval = kb.key();
|
||||
possibly_translate_keyval_to_make_legal_accelerator (gtk_legal_keyval);
|
||||
KeyboardKey gtk_binding (kb.state(), gtk_legal_keyval);
|
||||
|
||||
|
||||
bool entry_exists = Gtk::AccelMap::lookup_entry (what->get_accel_path(), gtk_key);
|
||||
|
||||
if (!entry_exists || gtk_key.get_key() == 0) {
|
||||
Gtk::AccelMap::add_entry (what->get_accel_path(),
|
||||
gtk_binding.key(),
|
||||
(Gdk::ModifierType) gtk_binding.state());
|
||||
} else {
|
||||
warning << string_compose (_("There is more than one key binding defined for %1. Both will work, but only the first will be visible in menus"), what->get_accel_path()) << endmsg;
|
||||
}
|
||||
|
||||
if (!Gtk::AccelMap::lookup_entry (what->get_accel_path(), gtk_key) || gtk_key.get_key() == 0) {
|
||||
cerr << "GTK binding using " << gtk_binding << " failed for " << what->get_accel_path() << " existing = " << gtk_key.get_key() << " + " << gtk_key.get_mod() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -463,7 +493,7 @@ Bindings::save (XMLNode& root)
|
|||
}
|
||||
|
||||
bool
|
||||
Bindings::load (const string& path)
|
||||
Bindings::load (string const & name)
|
||||
{
|
||||
XMLTree tree;
|
||||
|
||||
|
@ -471,18 +501,46 @@ Bindings::load (const string& path)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!tree.read (path)) {
|
||||
return false;
|
||||
XMLNode const * node = Keyboard::bindings_node();
|
||||
|
||||
if (!node) {
|
||||
error << string_compose (_("No keyboard binding information when loading bindings for \"%1\""), name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
const XMLNodeList& children (node->children());
|
||||
bool found = false;
|
||||
|
||||
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
|
||||
|
||||
if ((*i)->name() == X_("Bindings")) {
|
||||
XMLProperty const * prop = (*i)->property (X_("name"));
|
||||
|
||||
if (!prop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop->value() == name) {
|
||||
found = true;
|
||||
node = *i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
error << string_compose (_("Bindings for \"%1\" not found in keyboard binding node\n"), name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
press_bindings.clear ();
|
||||
release_bindings.clear ();
|
||||
|
||||
XMLNode& root (*tree.root());
|
||||
const XMLNodeList& children (root.children());
|
||||
const XMLNodeList& bindings (node->children());
|
||||
|
||||
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
|
||||
load (**i);
|
||||
for (XMLNodeList::const_iterator i = bindings.begin(); i != bindings.end(); ++i) {
|
||||
/* each node could be Press or Release */
|
||||
load (**i);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -520,8 +578,8 @@ Bindings::load (const XMLNode& node)
|
|||
RefPtr<Action> act;
|
||||
|
||||
if (action_map) {
|
||||
act = action_map->find_action (ap->value());
|
||||
}
|
||||
act = action_map->find_action (ap->value());
|
||||
}
|
||||
|
||||
if (!act) {
|
||||
string::size_type slash = ap->value().find ('/');
|
||||
|
@ -565,8 +623,38 @@ ActionMap::find_action (const string& name)
|
|||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_action (const char* path,
|
||||
RefPtr<ActionGroup>
|
||||
ActionMap::create_action_group (const string& name)
|
||||
{
|
||||
RefPtr<ActionGroup> g = ActionGroup::create (name);
|
||||
return g;
|
||||
}
|
||||
|
||||
void
|
||||
ActionMap::install_action_group (RefPtr<ActionGroup> group)
|
||||
{
|
||||
ActionManager::ui_manager->insert_action_group (group);
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = Action::create (name, label);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
actions.insert (_ActionMap::value_type (fullpath, act));
|
||||
group->add (act);
|
||||
|
||||
return act;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
@ -575,17 +663,42 @@ ActionMap::register_action (const char* path,
|
|||
|
||||
act->signal_activate().connect (sl);
|
||||
|
||||
fullpath = path;
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
actions.insert (_ActionMap::value_type (fullpath, act));
|
||||
group->add (act, sl);
|
||||
|
||||
return act;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_radio_action (const char* path, Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
RefPtr<Action>
|
||||
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
|
||||
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
|
||||
|
||||
act->signal_activate().connect (sl);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
actions.insert (_ActionMap::value_type (fullpath, act));
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value)
|
||||
{
|
||||
|
@ -597,16 +710,17 @@ ActionMap::register_radio_action (const char* path, Gtk::RadioAction::Group& rgr
|
|||
|
||||
act->signal_activate().connect (sigc::bind (sl, act->gobj()));
|
||||
|
||||
fullpath = path;
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
actions.insert (_ActionMap::value_type (fullpath, act));
|
||||
group->add (act, sigc::bind (sl, act->gobj()));
|
||||
return act;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_toggle_action (const char* path,
|
||||
RefPtr<Action>
|
||||
ActionMap::register_toggle_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
@ -615,15 +729,16 @@ ActionMap::register_toggle_action (const char* path,
|
|||
|
||||
act->signal_activate().connect (sl);
|
||||
|
||||
fullpath = path;
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
actions.insert (_ActionMap::value_type (fullpath, act));
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey& k) {
|
||||
return out << "Key " << k.key() << " state " << k.state();
|
||||
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) {
|
||||
return out << "Key " << k.key() << " (" << (k.key() > 0 ? gdk_keyval_name (k.key()) : "no-key") << ") state " << k.state();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <stdint.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtkmm/action.h>
|
||||
#include <gtkmm/action.h>
|
||||
#include <gtkmm/radioaction.h>
|
||||
#include <gtkmm/toggleaction.h>
|
||||
|
||||
|
@ -72,13 +71,27 @@ class LIBGTKMM2EXT_API ActionMap {
|
|||
ActionMap() {}
|
||||
~ActionMap() {}
|
||||
|
||||
Glib::RefPtr<Gtk::Action> register_action (const char* path,
|
||||
Glib::RefPtr<Gtk::ActionGroup> create_action_group (const std::string& group_name);
|
||||
void install_action_group (Glib::RefPtr<Gtk::ActionGroup>);
|
||||
|
||||
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
|
||||
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
<<<<<<< HEAD
|
||||
Glib::RefPtr<Gtk::Action> register_radio_action (const char* path, Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
=======
|
||||
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
>>>>>>> changes to Bindings and Keyboard API to support (mostly) GTK-free keyboard bindings
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value);
|
||||
Glib::RefPtr<Gtk::Action> register_toggle_action (const char*path,
|
||||
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl);
|
||||
Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
|
||||
Glib::RefPtr<Gtk::Action> find_action (const std::string& name);
|
||||
|
@ -127,7 +140,7 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
|
||||
KeybindingMap press_bindings;
|
||||
KeybindingMap release_bindings;
|
||||
|
||||
|
||||
typedef std::map<MouseButton,Glib::RefPtr<Gtk::Action> > MouseButtonBindingMap;
|
||||
MouseButtonBindingMap button_press_bindings;
|
||||
MouseButtonBindingMap button_release_bindings;
|
||||
|
@ -138,6 +151,6 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
|
||||
} // namespace
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey& k);
|
||||
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k);
|
||||
|
||||
#endif /* __libgtkmm2ext_bindings_h__ */
|
||||
|
|
|
@ -161,24 +161,18 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful
|
|||
|
||||
static void keybindings_changed ();
|
||||
static void save_keybindings ();
|
||||
static bool load_keybindings (std::string path);
|
||||
static void set_can_save_keybindings (bool yn);
|
||||
static std::string current_binding_name () { return _current_binding_name; }
|
||||
static std::map<std::string,std::string> binding_files;
|
||||
|
||||
static bool catch_user_event_for_pre_dialog_focus (GdkEvent* ev, Gtk::Window* w);
|
||||
|
||||
int reset_bindings ();
|
||||
static bool load_keybindings (std::string const& path);
|
||||
static void save_keybindings (std::string const& path);
|
||||
|
||||
struct AccelKeyLess {
|
||||
bool operator() (const Gtk::AccelKey a, const Gtk::AccelKey b) const {
|
||||
if (a.get_key() != b.get_key()) {
|
||||
return a.get_key() < b.get_key();
|
||||
} else {
|
||||
return a.get_mod() < b.get_mod();
|
||||
}
|
||||
}
|
||||
};
|
||||
static XMLNode const * bindings_node() { return _bindings_node; }
|
||||
|
||||
int reset_bindings ();
|
||||
|
||||
sigc::signal0<void> ZoomVerticalModifierReleased;
|
||||
|
||||
|
@ -202,18 +196,21 @@ class LIBGTKMM2EXT_API Keyboard : public sigc::trackable, PBD::Stateful
|
|||
static bool can_save_keybindings;
|
||||
static bool bindings_changed_after_save_became_legal;
|
||||
static std::string _current_binding_name;
|
||||
static XMLNode* _bindings_node;
|
||||
|
||||
typedef std::pair<std::string,std::string> two_strings;
|
||||
|
||||
static std::map<Gtk::AccelKey,two_strings,AccelKeyLess> release_keys;
|
||||
|
||||
static gint _snooper (GtkWidget*, GdkEventKey*, gpointer);
|
||||
gint snooper (GtkWidget*, GdkEventKey*);
|
||||
|
||||
static void set_modifier (uint32_t newval, uint32_t& variable);
|
||||
|
||||
static bool _some_magic_widget_has_focus;
|
||||
|
||||
static Gtk::Window* pre_dialog_active_window;
|
||||
|
||||
static int read_keybindings (std::string const& path);
|
||||
static int store_keybindings (std::string const& path);
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
|
|
@ -110,8 +110,8 @@ bool Keyboard::can_save_keybindings = false;
|
|||
bool Keyboard::bindings_changed_after_save_became_legal = false;
|
||||
map<string,string> Keyboard::binding_files;
|
||||
string Keyboard::_current_binding_name;
|
||||
map<AccelKey,pair<string,string>,Keyboard::AccelKeyLess> Keyboard::release_keys;
|
||||
Gtk::Window* Keyboard::pre_dialog_active_window = 0;
|
||||
XMLNode* Keyboard::_bindings_node = 0;
|
||||
|
||||
/* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
|
||||
GdkModifierType Keyboard::RelevantModifierKeyMask;
|
||||
|
@ -368,6 +368,10 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
|
|||
prevent auto-repeat events.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* August 2015: we don't have any release bindings
|
||||
*/
|
||||
|
||||
for (map<AccelKey,two_strings,AccelKeyLess>::iterator k = release_keys.begin(); k != release_keys.end(); ++k) {
|
||||
|
||||
const AccelKey& ak (k->first);
|
||||
|
@ -378,32 +382,7 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (event->type == GDK_KEY_RELEASE) {
|
||||
|
||||
State::iterator i;
|
||||
|
||||
if ((i = find (state.begin(), state.end(), keyval)) != state.end()) {
|
||||
state.erase (i);
|
||||
sort (state.begin(), state.end());
|
||||
}
|
||||
|
||||
for (map<AccelKey,two_strings,AccelKeyLess>::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 & Keyboard::RelevantModifierKeyMask) | Gdk::RELEASE_MASK) == ak.get_mod()) {
|
||||
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (ts.first.c_str(), ts.second.c_str());
|
||||
if (act) {
|
||||
DEBUG_TRACE (DEBUG::Keyboard, string_compose ("Activate %1 %2\n", ts.first, ts.second));
|
||||
act->activate();
|
||||
DEBUG_TRACE (DEBUG::Keyboard, string_compose ("Use repeat, suppress other\n", ts.first, ts.second));
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,18 +654,20 @@ void
|
|||
Keyboard::save_keybindings ()
|
||||
{
|
||||
if (can_save_keybindings && bindings_changed_after_save_became_legal) {
|
||||
Gtk::AccelMap::save (user_keybindings_path);
|
||||
/* Call to specific implementation to save bindings to path */
|
||||
store_keybindings (user_keybindings_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Keyboard::load_keybindings (string path)
|
||||
Keyboard::load_keybindings (string const & path)
|
||||
{
|
||||
try {
|
||||
info << "Loading bindings from " << path << endl;
|
||||
|
||||
Gtk::AccelMap::load (path);
|
||||
|
||||
/* Call to specific implementation to load bindings from path */
|
||||
read_keybindings (path);
|
||||
|
||||
_current_binding_name = _("Unknown");
|
||||
|
||||
for (map<string,string>::iterator x = binding_files.begin(); x != binding_files.end(); ++x) {
|
||||
|
@ -703,43 +684,29 @@ Keyboard::load_keybindings (string path)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* now find all release-driven bindings */
|
||||
|
||||
vector<string> groups;
|
||||
vector<string> names;
|
||||
vector<string> tooltips;
|
||||
vector<AccelKey> bindings;
|
||||
|
||||
ActionManager::get_all_actions (groups, names, tooltips, bindings);
|
||||
|
||||
vector<string>::iterator g;
|
||||
vector<AccelKey>::iterator b;
|
||||
vector<string>::iterator n;
|
||||
|
||||
release_keys.clear ();
|
||||
|
||||
for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) {
|
||||
stringstream s;
|
||||
s << "Action: " << *n << " Group: " << *g << " Binding: ";
|
||||
|
||||
if ((*b).get_key() != GDK_VoidSymbol) {
|
||||
s << b->get_key() << " w/mod " << hex << b->get_mod() << dec << " = " << b->get_abbrev () << "\n";
|
||||
} else {
|
||||
s << "unbound\n";
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::Bindings, s.str ());
|
||||
}
|
||||
|
||||
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<AccelKey,two_strings> (*b, two_strings (*g, *n)));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
Keyboard::read_keybindings (string const & path)
|
||||
{
|
||||
XMLTree tree;
|
||||
|
||||
if (!tree.read (path.c_str())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_bindings_node = new XMLNode (*tree.root ()); /* copy operation. Sorry */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Keyboard::store_keybindings (string const & path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Keyboard::reset_bindings ()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user