Allow gestures to be distinguished by modifiers
+43 −13 · 6 files changed
-
gesture.cc+4 −2 -
gesture.h+11 −6 -
grabber.cc+7 −0 -
grabber.h+1 −0 -
main.cc+12 −4 -
win.cc+8 −1
@@ -28,7 +28,7 @@ RTriple create_triple(float x, float y, Time t) { return e; } -Stroke::Stroke(PreStroke &ps, int trigger_, int button_, bool timeout_) : button(button_), timeout(timeout_) { +Stroke::Stroke(PreStroke &ps, int trigger_, int button_, unsigned int modifiers_, bool timeout_) : button(button_), modifiers(modifiers_), timeout(timeout_) { trigger = (trigger_ == get_default_button()) ? 0 : trigger_; if (ps.valid()) { @@ -54,6 +54,8 @@ int Stroke::compare(RStroke a, RStroke b, double &score) { if (a->trigger + b->trigger != get_default_button()) return -1; } + if (a->modifiers != b->modifiers) + return -1; if (!a->stroke || !b->stroke) { if (!a->stroke && !b->stroke) { score = 1.0; @@ -102,5 +104,5 @@ RStroke Stroke::trefoil() { double r = exp(1.0 + sin(6.0*M_PI*i/n)) + 2.0; s.add(create_triple(r*cos(phi), r*sin(phi), i)); } - return Stroke::create(s, 0, 0, false); + return Stroke::create(s, 0, 0, AnyModifier, false); } @@ -24,7 +24,7 @@ #include <boost/serialization/version.hpp> #include <boost/serialization/split_member.hpp> -#include <X11/X.h> // Time +#include <X11/X.h> #define STROKE_SIZE 64 @@ -76,7 +76,7 @@ public: }; private: - Stroke(PreStroke &s, int trigger_, int button_, bool timeout_); + Stroke(PreStroke &s, int trigger_, int button_, unsigned int modifiers_, bool timeout_); Glib::RefPtr<Gdk::Pixbuf> draw_(int size, double width = 2.0, bool inv = false) const; mutable Glib::RefPtr<Gdk::Pixbuf> pb[2]; @@ -93,6 +93,7 @@ private: ar & button; ar & trigger; ar & timeout; + ar & modifiers; } template<class Archive> void load(Archive & ar, const unsigned int version) { std::vector<Point> ps; @@ -113,17 +114,21 @@ private: if (version < 3) return; ar & timeout; + if (version < 5) + return; + ar & modifiers; } public: int trigger; int button; + unsigned int modifiers; bool timeout; boost::shared_ptr<stroke_t> stroke; - Stroke() : trigger(0), button(0), timeout(false) {} - static RStroke create(PreStroke &s, int trigger_, int button_, bool timeout_) { - return RStroke(new Stroke(s, trigger_, button_, timeout_)); + Stroke() : trigger(0), button(0), modifiers(AnyModifier), timeout(false) {} + static RStroke create(PreStroke &s, int trigger_, int button_, unsigned int modifiers_, bool timeout_) { + return RStroke(new Stroke(s, trigger_, button_, modifiers_, timeout_)); } Glib::RefPtr<Gdk::Pixbuf> draw(int size, double width = 2.0, bool inv = false) const; void draw(Cairo::RefPtr<Cairo::Surface> surface, int x, int y, int w, int h, double width = 2.0, bool inv = false) const; @@ -141,7 +146,7 @@ public: double time(int n) const { return stroke_get_time(stroke.get(), n); } bool is_timeout() const { return timeout; } }; -BOOST_CLASS_VERSION(Stroke, 4) +BOOST_CLASS_VERSION(Stroke, 5) BOOST_CLASS_VERSION(Stroke::Point, 1) class PreStroke : public std::vector<RTriple> { @@ -503,6 +503,13 @@ bool Grabber::is_click_hold(guint b) { return false; } +guint Grabber::get_default_mods(guint button) { + for (std::vector<ButtonInfo>::const_iterator i = buttons.begin(); i != buttons.end(); ++i) + if (i->button == button) + return i->state; + return AnyModifier; +} + int get_default_button() { if (grabber) return grabber->get_default_button(); @@ -120,6 +120,7 @@ public: void hierarchy_changed(XIHierarchyEvent *); int get_default_button() { return grabbed_button.button; } + guint get_default_mods(guint button); void unminimize(); }; @@ -47,7 +47,7 @@ extern Source<bool> disabled; bool experimental = false; int verbosity = 0; const char *prefs_versions[] = { "-0.5.5", "-0.4.1", "-0.4.0", "", NULL }; -const char *actions_versions[] = { "-0.4.1", "-0.4.0", "", NULL }; +const char *actions_versions[] = { "-0.5.6", "-0.4.1", "-0.4.0", "", NULL }; Source<Window> current_app_window(None); std::string config_dir; Win *win = NULL; @@ -57,6 +57,7 @@ bool in_proximity = false; boost::shared_ptr<sigc::slot<void, RStroke> > stroke_action; Grabber::XiDevice *current_dev = 0; std::set<guint> xinput_pressed; // TODO get rid of +guint modifiers; static bool show_gui = false; static bool no_dbus = false; @@ -844,7 +845,7 @@ class StrokeHandler : public Handler, public sigc::trackable { c.reset(new PreStroke); if (b && prefs.advanced_ignore.get()) c.reset(new PreStroke); - return Stroke::create(*c, button, b, false); + return Stroke::create(*c, button, b, modifiers, false); } bool timeout() { @@ -856,7 +857,7 @@ class StrokeHandler : public Handler, public sigc::trackable { c.reset(new PreStroke); RStroke s; if (prefs.timeout_gestures.get() || grabber->is_click_hold(button)) - s = Stroke::create(*c, button, 0, true); + s = Stroke::create(*c, button, 0, modifiers, true); parent->replace_child(AdvancedHandler::create(s, last, button, 0, cur)); XFlush(dpy); return false; @@ -864,7 +865,7 @@ class StrokeHandler : public Handler, public sigc::trackable { void do_instant() { PreStroke ps; - RStroke s = Stroke::create(ps, button, button, false); + RStroke s = Stroke::create(ps, button, button, modifiers, false); parent->replace_child(AdvancedHandler::create(s, orig, button, button, cur)); } @@ -1466,6 +1467,13 @@ void Main::handle_xi2_event(XIDeviceEvent *event) { } if (current_dev->master) XISetClientPointer(dpy, None, current_dev->master); + if (!xinput_pressed.size()) { + guint default_mods = grabber->get_default_mods(event->detail); + if (default_mods == AnyModifier || default_mods == (guint)event->mods.base) + modifiers = AnyModifier; + else + modifiers = event->mods.base; + } xinput_pressed.insert(event->detail); H->press(event->detail, create_triple(event->root_x, event->root_y, event->time)); break; @@ -69,8 +69,15 @@ void Stroke::draw(Cairo::RefPtr<Cairo::Surface> surface, int x, int y, int w, in } ctx->restore(); Glib::ustring str; + if (modifiers != AnyModifier) { + str = Gtk::AccelGroup::get_label(0, (Gdk::ModifierType)modifiers); + if (str == "") + str = "<>"; + else + str = "<" + str.substr(0, str.size()-1) + ">"; + } if (trigger) - str = Glib::ustring::compose("%1\xE2\x86\x92", trigger); + str += Glib::ustring::compose("%1\xE2\x86\x92", trigger); if (timeout) str += "x"; if (button)