From: Kim Shinwoo <kimcinoo.efl@gmail.com>

i have revised the access module and attached. you can find the
following
in the patch.

  - mouse double tap and move gesture for each direction
  - two finger flicking for each direction
  - two finger panning
      


SVN revision: 75945
This commit is contained in:
Kim Shinwoo 2012-09-03 04:06:02 +00:00 committed by Carsten Haitzler
parent 10c27c792b
commit 4d8b3bea44
2 changed files with 245 additions and 25 deletions

View File

@ -36,3 +36,4 @@ q66 <quaker66@gmail.com>
Tom Hacohen (TAsn) <tom@stosb.com> Tom Hacohen (TAsn) <tom@stosb.com>
Maxime Villard <rustyBSD@gmx.fr> Maxime Villard <rustyBSD@gmx.fr>
Jeremy Zurcher <jeremy@asynk.ch> Jeremy Zurcher <jeremy@asynk.ch>
Shinwoo Kim <kimcinoo@gmail.com>

View File

@ -1,18 +1,31 @@
#include "e.h" #include "e.h"
#include "e_mod_main.h" #include "e_mod_main.h"
#define HISTORY_MAX 8
typedef struct typedef struct
{ {
E_Zone *zone; E_Zone *zone;
Ecore_X_Window win; Ecore_X_Window win;
Ecore_Timer *timer; Ecore_Timer *timer;
int x, y, dx, dy; Ecore_Timer *double_down_timer;
int x, y, dx, dy, mx, my;
int mouse_history[HISTORY_MAX];
unsigned int dt; unsigned int dt;
Eina_Inlist *history;
Eina_Bool down : 1; Eina_Bool down : 1;
Eina_Bool two_finger_down : 1;
Eina_Bool mouse_double_down : 1;
} Cover; } Cover;
typedef struct
{
EINA_INLIST;
int device;
} Multi;
static Eina_List *covers = NULL; static Eina_List *covers = NULL;
static Eina_List *handlers = NULL; static Eina_List *handlers = NULL;
static int multi_device[3];
static Ecore_X_Window static Ecore_X_Window
_mouse_win_in_get(Cover *cov, int x, int y) _mouse_win_in_get(Cover *cov, int x, int y)
@ -21,7 +34,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
Ecore_X_Window *skip, inwin; Ecore_X_Window *skip, inwin;
Cover *cov2; Cover *cov2;
int i; int i;
skip = alloca(sizeof(Ecore_X_Window) * eina_list_count(covers)); skip = alloca(sizeof(Ecore_X_Window) * eina_list_count(covers));
i = 0; i = 0;
EINA_LIST_FOREACH(covers, l, cov2) EINA_LIST_FOREACH(covers, l, cov2)
@ -31,6 +44,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
} }
inwin = ecore_x_window_shadow_tree_at_xy_with_skip_get inwin = ecore_x_window_shadow_tree_at_xy_with_skip_get
(cov->zone->container->manager->root, x, y, skip, i); (cov->zone->container->manager->root, x, y, skip, i);
return inwin; return inwin;
} }
@ -39,8 +53,9 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
{ {
Ecore_X_Window inwin; Ecore_X_Window inwin;
int x, y; int x, y;
inwin = _mouse_win_in_get(cov, ev->root.x, ev->root.y); inwin = _mouse_win_in_get(cov, ev->root.x, ev->root.y);
ecore_x_pointer_xy_get(inwin, &x, &y); ecore_x_pointer_xy_get(inwin, &x, &y);
ecore_x_mouse_in_send(inwin, x, y); ecore_x_mouse_in_send(inwin, x, y);
ecore_x_mouse_move_send(inwin, x, y); ecore_x_mouse_move_send(inwin, x, y);
@ -49,20 +64,59 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
ecore_x_mouse_out_send(inwin, x, y); ecore_x_mouse_out_send(inwin, x, y);
} }
static void
_record_mouse_history(Cover *cov, void *event)
{
Ecore_Event_Mouse_Move *ev = event;
int i = 0;
for (i = 0; i < HISTORY_MAX; i++)
{
if (cov->mouse_history[i] == -1)
{
cov->mouse_history[i] = ev->multi.device;
break;
}
}
// if there is not enough space to save device number, shift!
if (i == HISTORY_MAX)
{
for (i = 0; i < (HISTORY_MAX - 1); i++)
cov->mouse_history[i] = cov->mouse_history[i + 1];
cov->mouse_history[HISTORY_MAX - 1] = ev->multi.device;
}
}
static Eina_Bool
_check_mouse_history(Cover *cov)
{
int i = 0;
for (i = 0; i < HISTORY_MAX; i++)
{
if ((cov->mouse_history[i] != multi_device[0]) &&
(cov->mouse_history[i] != -1))
return EINA_FALSE;
}
return EINA_TRUE;
}
static Eina_Bool static Eina_Bool
_mouse_longpress(void *data) _mouse_longpress(void *data)
{ {
Cover *cov = data; Cover *cov = data;
int distance = 40; int distance = 40;
int dx, dy; int dx, dy;
cov->timer = NULL; cov->timer = NULL;
dx = cov->x - cov->dx; dx = cov->x - cov->dx;
dy = cov->y - cov->dy; dy = cov->y - cov->dy;
if (((dx * dx) + (dy * dy)) < (distance * distance)) if (((dx * dx) + (dy * dy)) < (distance * distance))
{ {
E_Border *bd = e_border_focused_get(); E_Border *bd = e_border_focused_get();
cov->down = EINA_FALSE; cov->down = EINA_FALSE;
printf("longpress\n"); printf("longpress\n");
if (bd) if (bd)
@ -71,18 +125,76 @@ _mouse_longpress(void *data)
return EINA_FALSE; return EINA_FALSE;
} }
static Eina_Bool
_mouse_double_down(void *data)
{
Cover *cov = data;
ecore_timer_del(cov->double_down_timer);
cov->double_down_timer = NULL;
return EINA_FALSE;
}
static void
_mouse_double_down_timeout(Cover *cov)
{
double short_time = 0.3;
int distance = 40;
int dx, dy;
dx = cov->x - cov->dx;
dy = cov->y - cov->dy;
if ((cov->double_down_timer) &&
(((dx * dx) + (dy * dy)) < (distance * distance)))
{
// start double tap and move from here
cov->mouse_double_down = EINA_TRUE;
if (cov->timer)
{
ecore_timer_del(cov->timer);
cov->timer = NULL;
}
}
if (cov->double_down_timer)
{
ecore_timer_del(cov->double_down_timer);
cov->double_down_timer = NULL;
return;
}
cov->double_down_timer = ecore_timer_add(short_time, _mouse_double_down,
cov);
}
static void static void
_mouse_down(Cover *cov, Ecore_Event_Mouse_Button *ev) _mouse_down(Cover *cov, Ecore_Event_Mouse_Button *ev)
{ {
int x, y;
E_Border *bd;
double longtime = 0.5; double longtime = 0.5;
cov->dx = ev->x; cov->dx = ev->x;
cov->dy = ev->y; cov->dy = ev->y;
cov->mx = ev->x;
cov->my = ev->y;
cov->x = ev->x; cov->x = ev->x;
cov->y = ev->y; cov->y = ev->y;
cov->dt = ev->timestamp; cov->dt = ev->timestamp;
cov->down = EINA_TRUE; cov->down = EINA_TRUE;
cov->timer = ecore_timer_add(longtime, _mouse_longpress, cov); cov->timer = ecore_timer_add(longtime, _mouse_longpress, cov);
// 2nd finger comes...
_mouse_double_down_timeout(cov);
// mouse in should be here
bd = e_border_focused_get();
if (!bd) return;
ecore_x_pointer_xy_get(bd->client.win, &x, &y);
ecore_x_mouse_in_send(bd->client.win, x, y);
} }
static void static void
@ -91,8 +203,22 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
double timeout = 0.15; double timeout = 0.15;
int distance = 40; int distance = 40;
int dx, dy; int dx, dy;
int x, y;
E_Border *bd = e_border_focused_get(); E_Border *bd = e_border_focused_get();
// for two finger panning
if (cov->two_finger_down)
{
ecore_x_pointer_xy_get(bd->client.win, &x, &y);
ecore_x_mouse_up_send(bd->client.win, x, y, 1);
cov->two_finger_down = EINA_FALSE;
ecore_x_mouse_out_send(bd->client.win, x, y);
}
// reset double down and moving
cov->mouse_double_down = EINA_FALSE;
if (cov->timer) if (cov->timer)
{ {
ecore_timer_del(cov->timer); ecore_timer_del(cov->timer);
@ -115,19 +241,26 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
ecore_x_e_illume_access_action_activate_send(bd->client.win); ecore_x_e_illume_access_action_activate_send(bd->client.win);
} }
} }
else else if (((dx * dx) + (dy * dy)) > (4 * distance * distance)
&& ((ev->timestamp - cov->dt) < (timeout * 1000)))
{ {
if (abs(dx) > abs(dy)) // left or right if (abs(dx) > abs(dy)) // left or right
{ {
if (dx > 0) // right if (dx > 0) // right
{ {
printf("right\n"); if (_check_mouse_history(cov))
printf("single flick right\n");
else
printf("double flick right\n");
if (bd) if (bd)
ecore_x_e_illume_access_action_read_next_send(bd->client.win); ecore_x_e_illume_access_action_read_next_send(bd->client.win);
} }
else // left else // left
{ {
printf("left\n"); if (_check_mouse_history(cov))
printf("single flick left\n");
else
printf("double flick left\n");
if (bd) if (bd)
ecore_x_e_illume_access_action_read_prev_send(bd->client.win); ecore_x_e_illume_access_action_read_prev_send(bd->client.win);
} }
@ -136,13 +269,20 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
{ {
if (dy > 0) // down if (dy > 0) // down
{ {
printf("down\n"); if (_check_mouse_history(cov))
printf("single flick down\n");
else
printf("double flick down\n");
if (bd) if (bd)
ecore_x_e_illume_access_action_next_send(bd->client.win); ecore_x_e_illume_access_action_next_send(bd->client.win);
} }
else // up else // up
{ {
printf("up\n"); if (_check_mouse_history(cov))
printf("single flick up\n");
else
printf("double flick up\n");
if (bd) if (bd)
ecore_x_e_illume_access_action_prev_send(bd->client.win); ecore_x_e_illume_access_action_prev_send(bd->client.win);
} }
@ -154,9 +294,50 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
static void static void
_mouse_move(Cover *cov, Ecore_Event_Mouse_Move *ev) _mouse_move(Cover *cov, Ecore_Event_Mouse_Move *ev)
{ {
if (!cov->down) return; int distance = 5;
int x, y;
int dx, dy;
E_Border *bd;
//FIXME: why here.. after long press you cannot go below..
//if (!cov->down) return;
cov->x = ev->x; cov->x = ev->x;
cov->y = ev->y; cov->y = ev->y;
bd = e_border_focused_get();
if (!bd) return;
_record_mouse_history(cov, ev);
ecore_x_pointer_xy_get(bd->client.win, &x, &y);
ecore_x_mouse_move_send(bd->client.win, x, y);
// for panning, without check two_finger_down, there will be several down_send()
if ((ev->multi.device == multi_device[0]) && (cov->mouse_double_down))
{
dx = ev->x - cov->mx;
dy = ev->y - cov->my;
if (((dx * dx) + (dy * dy)) > (distance * distance))
{
if (abs(dx) > abs(dy)) // left or right
{
if (dx > 0) // right
printf("mouse double down and moving - right\n");
else // left
printf("mouse double down and moving - left\n");
}
else // up or down
{
if (dy > 0) // down
printf("mouse double down and moving - down\n");
else // up
printf("mouse double down and moving - up\n");
}
cov->mx = ev->x;
cov->my = ev->y;
}
}
} }
static void static void
@ -173,13 +354,38 @@ _cb_mouse_down(void *data __UNUSED__,
Ecore_Event_Mouse_Button *ev = event; Ecore_Event_Mouse_Button *ev = event;
Eina_List *l; Eina_List *l;
Cover *cov; Cover *cov;
int i = 0;
E_Border *bd;
int x, y;
for (i = 0; i < 3; i++)
{
if (multi_device[i] == -1)
{
multi_device[i] = ev->multi.device;
break;
}
else if (multi_device[i] == ev->multi.device) break;
}
EINA_LIST_FOREACH(covers, l, cov) EINA_LIST_FOREACH(covers, l, cov)
{ {
if (ev->window == cov->win) if (ev->window == cov->win)
{ {
if ((ev->buttons == 1) && (ev->multi.device == 0)) // XXX change specific number
if (ev->multi.device == multi_device[0])
_mouse_down(cov, ev); _mouse_down(cov, ev);
if ((ev->multi.device == multi_device[1]) &&
(!cov->two_finger_down))
{
bd = e_border_focused_get();
if (!bd) return ECORE_CALLBACK_PASS_ON;
ecore_x_pointer_xy_get(bd->client.win, &x, &y);
ecore_x_mouse_move_send(bd->client.win, x, y);
ecore_x_mouse_down_send(bd->client.win, x, y, 1);
cov->two_finger_down = EINA_TRUE;
}
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
} }
@ -194,12 +400,12 @@ _cb_mouse_up(void *data __UNUSED__,
Ecore_Event_Mouse_Button *ev = event; Ecore_Event_Mouse_Button *ev = event;
Eina_List *l; Eina_List *l;
Cover *cov; Cover *cov;
EINA_LIST_FOREACH(covers, l, cov) EINA_LIST_FOREACH(covers, l, cov)
{ {
if (ev->window == cov->win) if (ev->window == cov->win)
{ {
if ((ev->buttons == 1) && (ev->multi.device == 0)) if (ev->buttons == 1)
_mouse_up(cov, ev); _mouse_up(cov, ev);
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
@ -215,12 +421,12 @@ _cb_mouse_move(void *data __UNUSED__,
Ecore_Event_Mouse_Move *ev = event; Ecore_Event_Mouse_Move *ev = event;
Eina_List *l; Eina_List *l;
Cover *cov; Cover *cov;
EINA_LIST_FOREACH(covers, l, cov) EINA_LIST_FOREACH(covers, l, cov)
{ {
if (ev->window == cov->win) if (ev->window == cov->win)
{ {
if (ev->multi.device == 0) if ((ev->multi.device == multi_device[0]) ||
(ev->multi.device == multi_device[1]))
_mouse_move(cov, ev); _mouse_move(cov, ev);
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
@ -236,7 +442,7 @@ _cb_mouse_wheel(void *data __UNUSED__,
Ecore_Event_Mouse_Wheel *ev = event; Ecore_Event_Mouse_Wheel *ev = event;
Eina_List *l; Eina_List *l;
Cover *cov; Cover *cov;
EINA_LIST_FOREACH(covers, l, cov) EINA_LIST_FOREACH(covers, l, cov)
{ {
if (ev->window == cov->win) if (ev->window == cov->win)
@ -252,7 +458,7 @@ static Cover *
_cover_new(E_Zone *zone) _cover_new(E_Zone *zone)
{ {
Cover *cov; Cover *cov;
cov = E_NEW(Cover, 1); cov = E_NEW(Cover, 1);
if (!cov) return NULL; if (!cov) return NULL;
cov->zone = zone; cov->zone = zone;
@ -260,6 +466,9 @@ _cover_new(E_Zone *zone)
zone->container->x + zone->x, zone->container->x + zone->x,
zone->container->y + zone->y, zone->container->y + zone->y,
zone->w, zone->h); zone->w, zone->h);
ecore_x_input_multi_select(cov->win);
ecore_x_window_ignore_set(cov->win, 1); ecore_x_window_ignore_set(cov->win, 1);
ecore_x_window_configure(cov->win, ecore_x_window_configure(cov->win,
ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
@ -268,6 +477,8 @@ _cover_new(E_Zone *zone)
zone->container->layers[8].win, zone->container->layers[8].win,
ECORE_X_WINDOW_STACK_ABOVE); ECORE_X_WINDOW_STACK_ABOVE);
ecore_x_window_show(cov->win); ecore_x_window_show(cov->win);
ecore_x_window_raise(cov->win);
return cov; return cov;
} }
@ -276,19 +487,23 @@ _covers_init(void)
{ {
Eina_List *l, *l2, *l3; Eina_List *l, *l2, *l3;
E_Manager *man; E_Manager *man;
int i = 0;
EINA_LIST_FOREACH(e_manager_list(), l, man) EINA_LIST_FOREACH(e_manager_list(), l, man)
{ {
E_Container *con; E_Container *con;
EINA_LIST_FOREACH(man->containers, l2, con) EINA_LIST_FOREACH(man->containers, l2, con)
{ {
E_Zone *zone; E_Zone *zone;
EINA_LIST_FOREACH(con->zones, l3, zone) EINA_LIST_FOREACH(con->zones, l3, zone)
{ {
Cover *cov = _cover_new(zone); Cover *cov = _cover_new(zone);
if (cov) covers = eina_list_append(covers, cov); if (cov)
{
covers = eina_list_append(covers, cov);
for (i = 0; i < HISTORY_MAX; i++)
cov->mouse_history[i] = -1;
}
} }
} }
} }
@ -298,7 +513,7 @@ static void
_covers_shutdown(void) _covers_shutdown(void)
{ {
Cover *cov; Cover *cov;
EINA_LIST_FREE(covers, cov) EINA_LIST_FREE(covers, cov)
{ {
ecore_x_window_ignore_set(cov->win, 0); ecore_x_window_ignore_set(cov->win, 0);
@ -345,6 +560,8 @@ _cb_zone_move_resize(void *data __UNUSED__,
static void static void
_events_init(void) _events_init(void)
{ {
int i = 0;
handlers = eina_list_append handlers = eina_list_append
(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, (handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
_cb_mouse_down, NULL)); _cb_mouse_down, NULL));
@ -366,6 +583,8 @@ _events_init(void)
handlers = eina_list_append handlers = eina_list_append
(handlers, ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE, (handlers, ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
_cb_zone_move_resize, NULL)); _cb_zone_move_resize, NULL));
for (i = 0; i < 3; i++) multi_device[i] = -1;
} }
static void static void