Reenable proximity for supported devices
I'm not aware of any drivers that support this as of now
+49 −19 · 6 files changed
-
grabber.cc+4 −2 -
grabber.h+1 −0 -
gui.glade+1 −2 -
main.cc+37 −12 -
prefs.cc+5 −3 -
prefs.h+1 −0
@@ -277,7 +277,6 @@ bool Grabber::init_xi() { exit(EXIT_FAILURE); } - // TODO: Proximity device_mask.deviceid = XIAllDevices; device_mask.mask = device_mask_data; device_mask.mask_len = sizeof(device_mask_data); @@ -371,7 +370,8 @@ void Grabber::new_device(XIDeviceInfo *info) { } } -Grabber::XiDevice::XiDevice(Grabber *parent, XIDeviceInfo *info) : absolute(false), scale_x(1.0), scale_y(1.0), num_buttons(0) { +Grabber::XiDevice::XiDevice(Grabber *parent, XIDeviceInfo *info) : absolute(false), proximity_axis(-1), scale_x(1.0), scale_y(1.0), num_buttons(0) { + static XAtom PROXIMITY(AXIS_LABEL_PROP_ABS_DISTANCE); dev = info->deviceid; name = info->name; master = info->attachment; @@ -390,6 +390,8 @@ Grabber::XiDevice::XiDevice(Grabber *parent, XIDeviceInfo *info) : absolute(fals scale_y = (double)DisplayHeight(dpy, DefaultScreen(dpy)) / (double)(v->max - v->min); } + if (v->label == *PROXIMITY) + proximity_axis = v->number; } } @@ -69,6 +69,7 @@ public: std::string name; bool absolute; bool active; + int proximity_axis; double scale_x, scale_y; int num_buttons; int master; @@ -1766,8 +1766,7 @@ Van Diep Duong (Vietnamese)</property> </packing> </child> <child> - <object class="GtkFrame" id="frame_advanced2"> - <property name="visible">True</property> + <object class="GtkFrame" id="frame_tablet"> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="label_xalign">0</property> @@ -135,7 +135,6 @@ public: virtual void press(guint b, RTriple e) {} virtual void release(guint b, RTriple e) {} virtual void press_master(guint b, Time t) {} - virtual void proximity_out() {} virtual void pong() {} void replace_child(Handler *c) { if (child) @@ -214,8 +213,9 @@ std::list<OSD *> OSD::osd_stack; class IgnoreHandler : public Handler { RModifiers mods; + bool proximity; public: - IgnoreHandler(RModifiers mods_) : mods(mods_) {} + IgnoreHandler(RModifiers mods_) : mods(mods_), proximity(in_proximity && prefs.proximity.get()) {} virtual void press(guint b, RTriple e) { if (current_dev->master) { XTestFakeMotionEvent(dpy, DefaultScreen(dpy), e->x, e->y, 0); @@ -225,14 +225,15 @@ public: virtual void motion(RTriple e) { if (current_dev->master) XTestFakeMotionEvent(dpy, DefaultScreen(dpy), e->x, e->y, 0); + if (proximity && !in_proximity) + parent->replace_child(NULL); } - // TODO: Handle Proximity virtual void release(guint b, RTriple e) { if (current_dev->master) { XTestFakeMotionEvent(dpy, DefaultScreen(dpy), e->x, e->y, 0); XTestFakeButtonEvent(dpy, b, false, CurrentTime); } - if (!xinput_pressed.size()) + if (proximity ? !in_proximity : !xinput_pressed.size()) parent->replace_child(NULL); } virtual std::string name() { return "Ignore"; } @@ -242,8 +243,14 @@ public: class ButtonHandler : public Handler { RModifiers mods; guint button, real_button; + bool proximity; public: - ButtonHandler(RModifiers mods_, guint button_) : mods(mods_), button(button_), real_button(0) {} + ButtonHandler(RModifiers mods_, guint button_) : + mods(mods_), + button(button_), + real_button(0), + proximity(in_proximity && prefs.proximity.get()) + {} virtual void press(guint b, RTriple e) { if (current_dev->master) { if (!real_button) @@ -257,8 +264,9 @@ public: virtual void motion(RTriple e) { if (current_dev->master) XTestFakeMotionEvent(dpy, DefaultScreen(dpy), e->x, e->y, 0); + if (proximity && !in_proximity) + parent->replace_child(NULL); } - // TODO: Handle Proximity virtual void release(guint b, RTriple e) { if (current_dev->master) { if (real_button == b) @@ -266,7 +274,7 @@ public: XTestFakeMotionEvent(dpy, DefaultScreen(dpy), e->x, e->y, 0); XTestFakeButtonEvent(dpy, b, false, CurrentTime); } - if (!xinput_pressed.size()) + if (proximity ? !in_proximity : !xinput_pressed.size()) parent->replace_child(NULL); } virtual std::string name() { return "Button"; } @@ -453,12 +461,18 @@ class ScrollHandler : public AbstractScrollHandler { RModifiers mods; std::map<guint, guint> map; int orig_x, orig_y; + bool proximity; public: ScrollHandler(RModifiers mods_) : mods(mods_) { // If you want to use buttons > 9, you're on your own.. map[1] = 0; map[2] = 0; map[3] = 0; map[8] = 0; map[9] = 0; + proximity = in_proximity && prefs.proximity.get(); } virtual void raw_motion(RTriple e, bool abs_x, bool abs_y) { + if (proximity && !in_proximity) { + parent->replace_child(NULL); + move_back(); + } if (xinput_pressed.size()) AbstractScrollHandler::raw_motion(e, abs_x, abs_y); } @@ -466,15 +480,11 @@ public: fake_core_button(b, false); } virtual void release(guint b, RTriple e) { - if (in_proximity || xinput_pressed.size()) + if ((proximity && in_proximity) || xinput_pressed.size()) return; parent->replace_child(0); move_back(); } - virtual void proximity_out() { - parent->replace_child(0); - move_back(); - } virtual std::string name() { return "Scroll"; } virtual Grabber::State grab_mode() { return Grabber::RAW; } }; @@ -1467,6 +1477,16 @@ static void print_coordinates(XIValuatorState *valuators, double *values) { } } +static double get_axis(XIValuatorState &valuators, int axis) { + if (axis < 0 || !XIMaskIsSet(valuators.mask, axis)) + return 0.0; + double *val = valuators.values; + for (int i = 0; i < axis; i++) + if (XIMaskIsSet(valuators.mask, i)) + val++; + return *val; +} + void App::report_xi2_event(XIDeviceEvent *event, const char *type) { printf("%s (XI2): ", type); if (event->detail) @@ -1504,6 +1524,7 @@ void App::handle_xi2_event(XIDeviceEvent *event) { modifiers = event->mods.base; } xinput_pressed.insert(event->detail); + in_proximity = get_axis(event->valuators, current_dev->proximity_axis); H->press(event->detail, create_triple(event->root_x, event->root_y, event->time)); break; case XI_ButtonRelease: @@ -1512,6 +1533,7 @@ void App::handle_xi2_event(XIDeviceEvent *event) { if (!current_dev || current_dev->dev != event->deviceid) break; xinput_pressed.erase(event->detail); + in_proximity = get_axis(event->valuators, current_dev->proximity_axis); H->release(event->detail, create_triple(event->root_x, event->root_y, event->time)); break; case XI_Motion: @@ -1522,6 +1544,9 @@ void App::handle_xi2_event(XIDeviceEvent *event) { H->motion(create_triple(event->root_x, event->root_y, event->time)); break; case XI_RawMotion: + if (!current_dev) + break; + in_proximity = get_axis(((XIRawEvent *)event)->valuators, current_dev->proximity_axis); handle_raw_motion((XIRawEvent *)event); break; case XI_HierarchyChanged: @@ -281,6 +281,7 @@ Prefs::Prefs() { widgets->get_widget("treeview_exceptions", tv); widgets->get_widget("treeview_devices", dtv); widgets->get_widget("treeview_extra", etv); + widgets->get_widget("frame_tablet", frame_tablet); new Sensitive(*fun(&is_custom, prefs.timeout_profile), "hbox_timeout"); new Sensitive(*fun(&draw_trace, prefs.trace), "button_color"); @@ -348,9 +349,6 @@ Prefs::Prefs() { widgets->get_widget("hbox_timeout", hbox); hbox->hide(); } - Gtk::Frame *tablet_frame; - widgets->get_widget("frame_advanced2", tablet_frame); - tablet_frame->hide(); set_button_label(); @@ -364,10 +362,13 @@ Prefs::Prefs() { } void Prefs::update_device_list() { + bool proximity = false; ignore_device_toggled = true; dtm->clear(); std::set<std::string> names; for (Grabber::DeviceMap::iterator i = grabber->xi_devs.begin(); i != grabber->xi_devs.end(); ++i) { + if (i->second->proximity_axis >= 0) + proximity = true; std::string name = i->second->name; if (names.count(name)) continue; @@ -385,6 +386,7 @@ void Prefs::update_device_list() { row[dcs.timeout] = i->name; } ignore_device_toggled = false; + frame_tablet->set_visible(proximity); } void Prefs::update_extra_buttons() { @@ -79,6 +79,7 @@ private: Gtk::SpinButton *spin_radius; Gtk::Label* blabel; + Gtk::Frame *frame_tablet; bool ignore_device_toggled; };