Skip to content

Commit

Permalink
Tap drag lock timeout: cleaner implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
p2rkw committed Jan 21, 2018
1 parent 857205a commit da1adc9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
4 changes: 4 additions & 0 deletions include/mconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ struct MConfig {
int drag_timeout; // How long to wait for a move after tapping? > 0
int drag_wait; // How long to wait before triggering button down? >= 0
int drag_dist; // How far is the finger allowed to move during wait time? >= 0
int drag_lock_timeout; // How long to wait in 'drag ready' state after
// dragging finger was released?
// < 0 - wait of tap to break drag; 0 - disable; > 0 - time in ms

double sensitivity; // Mouse movement multiplier. >= 0
int scroll_smooth; // Enable high precision (smooth) scrolling. 0 or 1.
};
Expand Down
56 changes: 36 additions & 20 deletions src/gestures.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ static void trigger_button_click(struct Gestures* gs,
#endif
}

static void reset_drag(struct Gestures* gs){
if (gs->drag_state == GS_DRAG_ACTIVE) {
gs->drag_state = GS_NONE;
timerclear(&gs->move_drag_expire);
trigger_button_up(gs, 0);
LOG_DEBUG_GESTURES("reset_drag: drag stopped\n");
}
}

static void trigger_drag_ready(struct Gestures* gs,
const struct MConfig* cfg)
{
Expand Down Expand Up @@ -190,12 +199,15 @@ static int trigger_drag_start(struct Gestures* gs,
return gs->drag_state != GS_DRAG_WAIT;
}

static void trigger_drag_stop(struct Gestures* gs, int force)
static void trigger_drag_stop(struct Gestures* gs, const struct MConfig* cfg)
{
if (gs->drag_state == GS_DRAG_READY && force) {
/* Epoch time will require another tap to break the drag: */
if (!isepochtime(&gs->move_drag_expire)
&& timercmp(&gs->time, &gs->move_drag_expire, >=)) {
int lock_timeout;

lock_timeout = cfg->drag_lock_timeout;

if (gs->drag_state == GS_DRAG_READY) {
/* if timeout < 0 then tap-dragging will require another tap to break the drag */
if (lock_timeout >= 0 && timercmp(&gs->time, &gs->move_drag_expire, >=)) {
LOG_DEBUG_GESTURES("trigger_drag_stop: locked drag expored\n");
trigger_button_up(gs, 0);
}
Expand All @@ -204,13 +216,17 @@ static void trigger_drag_stop(struct Gestures* gs, int force)
LOG_DEBUG_GESTURES("trigger_drag_stop: drag canceled\n");
}
else if (gs->drag_state == GS_DRAG_ACTIVE) {
//gs->drag_state = GS_NONE;
//timerclear(&gs->move_drag_expire);
//trigger_button_up(gs, 0);
//LOG_DEBUG_GESTURES("trigger_drag_stop: drag stopped\n");
gs->drag_state = GS_DRAG_READY;
timeraddms(&gs->time, 500, &gs->move_drag_expire);
LOG_DEBUG_GESTURES("trigger_drag_stop: drag in wait lock\n");
if(lock_timeout == 0){
reset_drag(gs);
}
else{
/* Tap to drag lock timeout implementaion:
* Instead of breaking dragging completely, just take one step back
* to ready state and start timer wainting for future dragging */
gs->drag_state = GS_DRAG_READY;
timeraddms(&gs->time, lock_timeout, &gs->move_drag_expire);
LOG_DEBUG_GESTURES("trigger_drag_stop: drag in wait lock\n");
}
}
}

Expand Down Expand Up @@ -460,7 +476,7 @@ static void tapping_update(struct Gestures* gs,
else{ /* gs->tap_touching is < 0 */
/* That means finges(s) were down, while tap wasn't active and finger was released */
gs->tap_touching = 0;
trigger_drag_stop(gs, 1);
trigger_drag_stop(gs, cfg);
return; /* Pretty common situation; do nothing */
}
LOG_TAP("tapping_update: touch released; gs->tap_touching=%d, gs->tap_released=%d\n", gs->tap_touching, gs->tap_released);
Expand Down Expand Up @@ -619,7 +635,7 @@ static int trigger_swipe_unsafe(struct Gestures* gs,
return 0;
}

trigger_drag_stop(gs, 1);
trigger_drag_stop(gs, cfg);
get_swipe_avg_xy(touches, touches_count, &avg_move_x, &avg_move_y);
// hypot(1/n * (x0 + ... + xn); 1/n * (y0 + ... + yn)) <=> 1/n * hypot(x0 + ... + xn; y0 + ... + yn)
dist = hypot(avg_move_x, avg_move_y);
Expand Down Expand Up @@ -1005,7 +1021,7 @@ static int trigger_scale(struct Gestures* gs, const struct MConfig* cfg,
dir = calc_scale_dir(t0, t1);

struct timeval tv_tmp;
trigger_drag_stop(gs, 1);
trigger_drag_stop(gs, cfg);
if (gs->move_type != GS_SCALE || gs->move_dir != dir)
gs->move_dist = 0;
gs->move_dx = gs->move_dy = 0.0;
Expand Down Expand Up @@ -1034,7 +1050,7 @@ static void trigger_rotate(struct Gestures* gs,
{
if (gs->move_type == GS_ROTATE || !timercmp(&gs->time, &gs->move_wait, <)) {
struct timeval tv_tmp;
trigger_drag_stop(gs, 1);
trigger_drag_stop(gs, cfg);
if (gs->move_type != GS_ROTATE || gs->move_dir != dir)
gs->move_dist = 0;
gs->move_dx = 0.0;
Expand All @@ -1058,7 +1074,7 @@ static void trigger_rotate(struct Gestures* gs,

static void trigger_reset(struct Gestures* gs)
{
trigger_drag_stop(gs, 0);
reset_drag(gs);
gs->move_dx = gs->move_dy = 0.0;
/* Don't reset scroll speed cuz it may break things. */
gs->move_type = GS_NONE;
Expand Down Expand Up @@ -1154,11 +1170,11 @@ static void moving_update(struct Gestures* gs,
}
}

static void dragging_update(struct Gestures* gs)
static void dragging_update(struct Gestures* gs, const struct MConfig* cfg)
{
if (gs->drag_state == GS_DRAG_READY && timercmp(&gs->time, &gs->move_drag_expire, >)) {
LOG_DEBUG_GESTURES("dragging_update: drag expired\n");
trigger_drag_stop(gs, 1);
trigger_drag_stop(gs, cfg);
}
}

Expand Down Expand Up @@ -1196,7 +1212,7 @@ void gestures_extract(struct MTouch* mt)
timersub(&mt->hs.evtime, &mt->gs.time, &mt->gs.dt);
timercp(&mt->gs.time, &mt->hs.evtime);

dragging_update(&mt->gs);
dragging_update(&mt->gs, &mt->cfg);
buttons_update(&mt->gs, &mt->cfg, &mt->hs, &mt->state);
tapping_update(&mt->gs, &mt->cfg, &mt->state);
moving_update(&mt->gs, &mt->cfg, &mt->state);
Expand Down

0 comments on commit da1adc9

Please sign in to comment.