Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
#include "e.h"
|
|
|
|
|
|
|
|
#define TEXT_NO_PARAMS _("<None>")
|
|
|
|
|
|
|
|
struct _E_Config_Dialog_Data
|
|
|
|
{
|
|
|
|
Evas *evas;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
Eina_List *swipe;
|
|
|
|
} binding;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
const char *binding, *action;
|
|
|
|
char *params;
|
|
|
|
const char *cur;
|
|
|
|
int button;
|
|
|
|
int cur_act;
|
|
|
|
const char *swipe;
|
|
|
|
const char *source;
|
|
|
|
|
|
|
|
E_Dialog *dia;
|
|
|
|
double degree;
|
|
|
|
double error;
|
|
|
|
double length;
|
|
|
|
unsigned int fingers;
|
|
|
|
} locals;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
Evas_Object *o_add, *o_del, *o_del_all;
|
|
|
|
Evas_Object *o_binding_list, *o_action_list;
|
|
|
|
Evas_Object *o_params, *o_selector;
|
|
|
|
} gui;
|
|
|
|
|
|
|
|
const char *params;
|
|
|
|
|
|
|
|
int fullscreen_flip;
|
|
|
|
int multiscreen_flip;
|
|
|
|
|
|
|
|
E_Config_Dialog *cfd;
|
|
|
|
};
|
|
|
|
|
|
|
|
static E_Config_Binding_Swipe *
|
|
|
|
_swipe_binding_copy(E_Config_Binding_Swipe *bi)
|
|
|
|
{
|
|
|
|
E_Config_Binding_Swipe *bi2;
|
|
|
|
if (!bi) return NULL;
|
|
|
|
|
|
|
|
bi2 = E_NEW(E_Config_Binding_Swipe, 1);
|
|
|
|
bi2->context = bi->context;
|
|
|
|
bi2->direction = bi->direction;
|
|
|
|
bi2->length = bi->length;
|
|
|
|
bi2->fingers = bi->fingers;
|
|
|
|
bi2->error = bi->error;
|
|
|
|
bi2->action = bi->action;
|
|
|
|
bi2->params = bi->params;
|
|
|
|
return bi2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_swipe_binding_free(E_Config_Binding_Swipe *bi)
|
|
|
|
{
|
|
|
|
if (!bi) return;
|
|
|
|
eina_stringshare_del(bi->action);
|
|
|
|
eina_stringshare_del(bi->params);
|
|
|
|
free(bi);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_auto_apply_changes(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
int n, g, a, ok;
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
E_Action_Group *actg;
|
|
|
|
E_Action_Description *actd;
|
|
|
|
|
|
|
|
if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]) ||
|
|
|
|
(!cfdata->locals.action) || (!cfdata->locals.action[0])) return;
|
|
|
|
|
|
|
|
if (sscanf(cfdata->locals.cur, "s%d", &n) != 1)
|
|
|
|
return;
|
|
|
|
if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bi = eina_list_nth(cfdata->binding.swipe, n);
|
|
|
|
if (!bi) return;
|
|
|
|
|
|
|
|
actg = eina_list_nth(e_action_groups_get(), g);
|
|
|
|
if (!actg) return;
|
|
|
|
actd = eina_list_nth(actg->acts, a);
|
|
|
|
if (!actd) return;
|
|
|
|
|
|
|
|
eina_stringshare_del(bi->action);
|
|
|
|
bi->action = NULL;
|
|
|
|
|
|
|
|
if (actd->act_cmd) bi->action = eina_stringshare_add(actd->act_cmd);
|
|
|
|
|
|
|
|
eina_stringshare_del(bi->params);
|
|
|
|
bi->params = NULL;
|
|
|
|
|
|
|
|
if (actd->act_params)
|
|
|
|
bi->params = eina_stringshare_add(actd->act_params);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = 1;
|
|
|
|
if (cfdata->locals.params)
|
|
|
|
{
|
|
|
|
if (!strcmp(cfdata->locals.params, TEXT_NO_PARAMS))
|
|
|
|
ok = 0;
|
|
|
|
|
|
|
|
if ((actd->param_example) && (!strcmp(cfdata->locals.params, actd->param_example)))
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ok = 0;
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
bi->params = eina_stringshare_add(cfdata->locals.params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_fill_data(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
E_Config_Binding_Swipe *bi, *bi2;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
cfdata->locals.params = strdup("");
|
|
|
|
cfdata->locals.action = eina_stringshare_add("");
|
|
|
|
cfdata->locals.binding = eina_stringshare_add("");
|
|
|
|
cfdata->locals.swipe = eina_stringshare_add("");
|
|
|
|
cfdata->locals.source = eina_stringshare_add("");
|
|
|
|
cfdata->locals.cur = NULL;
|
|
|
|
cfdata->locals.dia = NULL;
|
|
|
|
cfdata->binding.swipe = NULL;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e_bindings->swipe_bindings, l, bi)
|
|
|
|
{
|
|
|
|
if (!bi) continue;
|
|
|
|
bi2 = _swipe_binding_copy(bi);
|
|
|
|
cfdata->binding.swipe = eina_list_append(cfdata->binding.swipe, bi2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
_create_data(E_Config_Dialog *cfd)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
cfdata = E_NEW(E_Config_Dialog_Data, 1);
|
|
|
|
cfdata->cfd = cfd;
|
|
|
|
_fill_data(cfdata);
|
|
|
|
|
|
|
|
return cfdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
E_FREE_LIST(cfdata->binding.swipe, _swipe_binding_free);
|
|
|
|
|
|
|
|
eina_stringshare_del(cfdata->locals.cur);
|
|
|
|
eina_stringshare_del(cfdata->params);
|
|
|
|
eina_stringshare_del(cfdata->locals.binding);
|
|
|
|
eina_stringshare_del(cfdata->locals.action);
|
|
|
|
eina_stringshare_del(cfdata->locals.swipe);
|
|
|
|
eina_stringshare_del(cfdata->locals.source);
|
|
|
|
|
|
|
|
if (cfdata->locals.dia) e_object_del(E_OBJECT(cfdata->locals.dia));
|
|
|
|
|
|
|
|
free(cfdata->locals.params);
|
|
|
|
E_FREE(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_update_action_params(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
int g, a, b;
|
|
|
|
E_Action_Group *actg;
|
|
|
|
E_Action_Description *actd;
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
const char *action, *params;
|
|
|
|
|
|
|
|
#define SIGNAL_EXAMPLE_PARAMS \
|
|
|
|
if ((!actd->param_example) || (!actd->param_example[0])) \
|
|
|
|
e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS); \
|
|
|
|
else \
|
|
|
|
e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example)
|
|
|
|
|
|
|
|
if ((!cfdata->locals.action) || (!cfdata->locals.action[0]))
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
actg = eina_list_nth(e_action_groups_get(), g);
|
|
|
|
if (!actg) return;
|
|
|
|
actd = eina_list_nth(actg->acts, a);
|
|
|
|
if (!actd) return;
|
|
|
|
|
|
|
|
if (actd->act_params)
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]))
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!actd->editable)
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
else
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 0);
|
|
|
|
|
|
|
|
if (cfdata->locals.cur[0] == 's')
|
|
|
|
{
|
|
|
|
if (sscanf(cfdata->locals.cur, "s%d", &b) != 1)
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bi = eina_list_nth(cfdata->binding.swipe, b);
|
|
|
|
if (!bi)
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
action = bi->action;
|
|
|
|
params = bi->params;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action)
|
|
|
|
{
|
|
|
|
if (!strcmp(action, actd->act_cmd))
|
|
|
|
{
|
|
|
|
if ((!params) || (!params[0]))
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
else
|
|
|
|
e_widget_entry_text_set(cfdata->gui.o_params, params);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SIGNAL_EXAMPLE_PARAMS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_action_change_cb(void *data)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
cfdata = data;
|
|
|
|
_update_action_params(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_swipe_binding_sort_cb(E_Config_Binding_Swipe *a, E_Config_Binding_Swipe *b)
|
|
|
|
{
|
2021-03-24 08:04:48 -07:00
|
|
|
int finger_diff = a->fingers - b->fingers;
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
if (!finger_diff)
|
|
|
|
{
|
|
|
|
return a->direction - b->direction;
|
|
|
|
}
|
2021-03-24 08:04:48 -07:00
|
|
|
return finger_diff*-1;
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_update_buttons(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
if (e_widget_ilist_count(cfdata->gui.o_binding_list))
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del_all, 0);
|
|
|
|
else
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del_all, 1);
|
|
|
|
|
|
|
|
if (!cfdata->locals.cur)
|
|
|
|
{
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_find_swipe_binding_action(const char *action, const char *params, int *g, int *a, int *n)
|
|
|
|
{
|
|
|
|
Eina_List *l, *l2;
|
|
|
|
int gg = -1, aa = -1, nn = -1, found;
|
|
|
|
E_Action_Group *actg;
|
|
|
|
E_Action_Description *actd;
|
|
|
|
|
|
|
|
if (g) *g = -1;
|
|
|
|
if (a) *a = -1;
|
|
|
|
if (n) *n = -1;
|
|
|
|
|
|
|
|
found = 0;
|
|
|
|
for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++)
|
|
|
|
{
|
|
|
|
actg = l->data;
|
|
|
|
|
|
|
|
for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++)
|
|
|
|
{
|
|
|
|
actd = l2->data;
|
|
|
|
if (!strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd)))
|
|
|
|
{
|
|
|
|
if (!params || !params[0])
|
|
|
|
{
|
|
|
|
if ((!actd->act_params) || (!actd->act_params[0]))
|
|
|
|
{
|
|
|
|
if (g) *g = gg;
|
|
|
|
if (a) *a = aa;
|
|
|
|
if (n) *n = nn;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((!actd->act_params) || (!actd->act_params[0]))
|
|
|
|
{
|
|
|
|
if (g) *g = gg;
|
|
|
|
if (a) *a = aa;
|
|
|
|
if (n) *n = nn;
|
|
|
|
found = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!strcmp(params, actd->act_params))
|
|
|
|
{
|
|
|
|
if (g) *g = gg;
|
|
|
|
if (a) *a = aa;
|
|
|
|
if (n) *n = nn;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nn++;
|
|
|
|
}
|
|
|
|
if (found) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
if (g) *g = -1;
|
|
|
|
if (a) *a = -1;
|
|
|
|
if (n) *n = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_update_action_list(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
int j = -1, i, n;
|
|
|
|
const char *action, *params;
|
|
|
|
|
|
|
|
if (!cfdata->locals.cur) return;
|
|
|
|
|
|
|
|
if (cfdata->locals.cur[0] == 's')
|
|
|
|
{
|
|
|
|
if (sscanf(cfdata->locals.cur, "s%d", &n) != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bi = eina_list_nth(cfdata->binding.swipe, n);
|
|
|
|
if (!bi)
|
|
|
|
{
|
|
|
|
e_widget_ilist_unselect(cfdata->gui.o_action_list);
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
action = bi->action;
|
|
|
|
params = bi->params;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
|
|
|
_find_swipe_binding_action(action, params, NULL, NULL, &j);
|
|
|
|
|
|
|
|
if (j >= 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
|
|
|
|
{
|
|
|
|
if (i > j) break;
|
|
|
|
if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j >= 0)
|
|
|
|
{
|
|
|
|
if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
|
|
|
|
_update_action_params(cfdata);
|
|
|
|
else
|
|
|
|
e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
e_widget_ilist_unselect(cfdata->gui.o_action_list);
|
|
|
|
eina_stringshare_del(cfdata->locals.action);
|
|
|
|
cfdata->locals.action = eina_stringshare_add("");
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_binding_change_cb(void *data)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
cfdata = data;
|
|
|
|
|
|
|
|
_auto_apply_changes(cfdata);
|
|
|
|
if (cfdata->locals.cur) eina_stringshare_del(cfdata->locals.cur);
|
|
|
|
cfdata->locals.cur = NULL;
|
|
|
|
|
|
|
|
if ((!cfdata->locals.binding) || (!cfdata->locals.binding[0])) return;
|
|
|
|
|
|
|
|
cfdata->locals.cur = eina_stringshare_ref(cfdata->locals.binding);
|
|
|
|
|
|
|
|
_update_buttons(cfdata);
|
|
|
|
_update_action_list(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
_basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
E_Config_Binding_Swipe *bi, *bi2;
|
|
|
|
|
|
|
|
_auto_apply_changes(cfdata);
|
|
|
|
E_FREE_LIST(e_bindings->swipe_bindings, _swipe_binding_free);
|
|
|
|
EINA_LIST_FOREACH(cfdata->binding.swipe, l, bi2)
|
|
|
|
{
|
|
|
|
bi = _swipe_binding_copy(bi2);
|
|
|
|
e_bindings->swipe_bindings = eina_list_append(e_bindings->swipe_bindings, bi);
|
|
|
|
}
|
|
|
|
e_bindings_swipe_reset();
|
|
|
|
|
|
|
|
e_config_save_queue();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Object*
|
|
|
|
create_visualisation(Evas *e, double direction, double error)
|
|
|
|
{
|
|
|
|
Evas_Vg_Container *vg = NULL;
|
|
|
|
Evas_Vg_Shape *container, *shape, *viewport = NULL;
|
|
|
|
|
|
|
|
double center_x = 15, center_y = 15;
|
|
|
|
|
|
|
|
vg = evas_object_vg_add(e);
|
|
|
|
evas_object_vg_viewbox_set(vg, EINA_RECT(0, 0, 50, 50));
|
|
|
|
|
|
|
|
container = evas_vg_container_add(vg);
|
|
|
|
|
|
|
|
viewport = evas_vg_shape_add(container);
|
|
|
|
evas_vg_shape_append_rect(viewport, 0, 0, 51, 51, 0, 0);
|
|
|
|
evas_vg_shape_stroke_cap_set(viewport, EVAS_VG_CAP_SQUARE);
|
|
|
|
evas_vg_shape_stroke_color_set(viewport, 0, 0, 0, 0);
|
|
|
|
evas_vg_shape_stroke_width_set(viewport, 1);
|
|
|
|
|
|
|
|
shape = evas_vg_shape_add(container);
|
|
|
|
evas_vg_shape_append_rect(shape, 1, 1, 29, 29, 0, 0);
|
|
|
|
evas_vg_shape_stroke_cap_set(shape, EVAS_VG_CAP_SQUARE);
|
|
|
|
evas_vg_shape_stroke_color_set(shape, 100, 100, 100, 255);
|
|
|
|
evas_vg_shape_stroke_width_set(shape, 1);
|
|
|
|
|
|
|
|
shape = evas_vg_shape_add(container);
|
|
|
|
evas_vg_shape_append_line_to(shape, center_x, center_y);
|
|
|
|
evas_vg_shape_append_line_to(shape, center_x + cos(direction - error)*11, center_y + sin(direction - error)*11);
|
|
|
|
evas_vg_shape_append_arc_to(shape, center_x + cos(direction + error)*11, center_y + sin(direction + error)*11, 11, 11, 0, EINA_FALSE, EINA_TRUE);
|
|
|
|
evas_vg_shape_append_line_to(shape, center_x, center_y);
|
|
|
|
|
|
|
|
evas_vg_shape_stroke_cap_set(shape, EVAS_VG_CAP_ROUND);
|
|
|
|
evas_vg_shape_stroke_color_set(shape, 255, 0, 0, 255);
|
|
|
|
evas_vg_shape_stroke_width_set(shape, 2);
|
|
|
|
|
|
|
|
evas_object_vg_root_node_set(vg, container);
|
|
|
|
|
|
|
|
evas_object_show(vg);
|
|
|
|
|
|
|
|
return vg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_update_swipe_binding_list(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
char b2[64], b3[64];
|
|
|
|
Eina_List *l;
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
unsigned int previous_fingers = 0;
|
|
|
|
|
|
|
|
evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list));
|
|
|
|
edje_freeze();
|
|
|
|
e_widget_ilist_freeze(cfdata->gui.o_binding_list);
|
|
|
|
|
|
|
|
e_widget_ilist_clear(cfdata->gui.o_binding_list);
|
|
|
|
e_widget_ilist_go(cfdata->gui.o_binding_list);
|
|
|
|
|
|
|
|
if (cfdata->binding.swipe)
|
|
|
|
cfdata->binding.swipe = eina_list_sort(cfdata->binding.swipe, 0, (Eina_Compare_Cb)_swipe_binding_sort_cb);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(cfdata->binding.swipe, l, bi)
|
|
|
|
{
|
|
|
|
Evas_Object *vis;
|
|
|
|
|
|
|
|
vis = create_visualisation(evas_object_evas_get(cfdata->gui.o_binding_list), bi->direction, bi->error);
|
|
|
|
if (bi->fingers != previous_fingers)
|
|
|
|
{
|
|
|
|
snprintf(b3, sizeof(b3), "%d Fingers", bi->fingers);
|
|
|
|
previous_fingers = bi->fingers;
|
|
|
|
e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, b3);
|
|
|
|
}
|
|
|
|
snprintf(b2, sizeof(b2), "s%d", i);
|
|
|
|
snprintf(b3, sizeof(b3), "Length: %.2f Error: %.2f", bi->length, bi->error);
|
|
|
|
|
|
|
|
e_widget_ilist_append(cfdata->gui.o_binding_list, vis, b3, _binding_change_cb, cfdata, b2);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
e_widget_ilist_go(cfdata->gui.o_binding_list);
|
|
|
|
|
|
|
|
e_widget_ilist_thaw(cfdata->gui.o_binding_list);
|
|
|
|
edje_thaw();
|
|
|
|
evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list));
|
|
|
|
|
|
|
|
if (eina_list_count(cfdata->binding.swipe))
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del_all, 0);
|
|
|
|
else
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_del_all, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_fill_actions_list(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
Eina_List *l, *l2;
|
|
|
|
E_Action_Group *actg;
|
|
|
|
E_Action_Description *actd;
|
|
|
|
int g, a;
|
|
|
|
|
|
|
|
evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list));
|
|
|
|
edje_freeze();
|
|
|
|
e_widget_ilist_freeze(cfdata->gui.o_action_list);
|
|
|
|
|
|
|
|
e_widget_ilist_clear(cfdata->gui.o_action_list);
|
|
|
|
for (l = e_action_groups_get(), g = 0; l; l = l->next, g++)
|
|
|
|
{
|
|
|
|
actg = l->data;
|
|
|
|
|
|
|
|
if (!actg->acts) continue;
|
|
|
|
|
|
|
|
e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp));
|
|
|
|
|
|
|
|
for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
|
|
|
|
{
|
|
|
|
actd = l2->data;
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%d %d", g, a);
|
|
|
|
e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name),
|
|
|
|
_action_change_cb, cfdata, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e_widget_ilist_go(cfdata->gui.o_action_list);
|
|
|
|
e_widget_ilist_thaw(cfdata->gui.o_action_list);
|
|
|
|
edje_thaw();
|
|
|
|
evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_flush_binding_swipe(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
|
|
|
|
bi = E_NEW(E_Config_Binding_Swipe, 1);
|
|
|
|
bi->context = E_BINDING_CONTEXT_NONE;
|
|
|
|
bi->length = cfdata->locals.length;
|
|
|
|
bi->direction = cfdata->locals.degree;
|
|
|
|
bi->error = cfdata->locals.error;
|
|
|
|
bi->fingers = cfdata->locals.fingers;
|
|
|
|
|
|
|
|
cfdata->binding.swipe = eina_list_append(cfdata->binding.swipe, bi);
|
|
|
|
_update_swipe_binding_list(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_swipe_add_cb_ok(void *data, E_Dialog *dia)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata = data;
|
|
|
|
|
|
|
|
_flush_binding_swipe(cfdata);
|
|
|
|
|
|
|
|
e_object_del(E_OBJECT(dia));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_swipe_add_cb_cancel(void *data EINA_UNUSED, E_Dialog *dia)
|
|
|
|
{
|
|
|
|
e_object_del(E_OBJECT(dia));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_swipe_add_del(void *data)
|
|
|
|
{
|
|
|
|
E_Dialog *dia = data;
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
if (!dia->data) return;
|
|
|
|
cfdata = dia->data;
|
|
|
|
cfdata->locals.dia = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_double_getter(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
double *container = data;
|
|
|
|
double tmp = elm_spinner_value_get(obj);
|
|
|
|
*container = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_int_getter(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
unsigned int *container = data;
|
|
|
|
double tmp = elm_spinner_value_get(obj);
|
|
|
|
*container = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_swipe_add_show(E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
Evas_Object *o, *obg, *ol, *entry;
|
|
|
|
Evas *evas;
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
if (cfdata->locals.dia) return;
|
|
|
|
|
|
|
|
cfdata->locals.dia = e_dialog_new(cfdata->cfd->dia->win, "E", "_swipebind_new_dialog");
|
|
|
|
e_dialog_resizable_set(cfdata->locals.dia, 1);
|
|
|
|
e_dialog_title_set(cfdata->locals.dia, _("Add Swipe Binding"));
|
|
|
|
e_dialog_icon_set(cfdata->locals.dia, "enlightenment/swipes", 48);
|
|
|
|
e_dialog_button_add(cfdata->locals.dia, _("OK"), NULL, _swipe_add_cb_ok, cfdata);
|
|
|
|
e_dialog_button_add(cfdata->locals.dia, _("Cancel"), NULL, _swipe_add_cb_cancel, cfdata);
|
|
|
|
e_object_del_attach_func_set(E_OBJECT(cfdata->locals.dia), _swipe_add_del);
|
|
|
|
cfdata->locals.dia->data = cfdata;
|
|
|
|
elm_win_center(cfdata->locals.dia->win, 1, 1);
|
|
|
|
|
|
|
|
evas = evas_object_evas_get(cfdata->locals.dia->win);
|
|
|
|
obg = e_widget_list_add(evas, 1, 0);
|
|
|
|
|
|
|
|
ol = e_widget_framelist_add(evas, _("Direction:"), 0);
|
|
|
|
entry = o = elm_spinner_add(cfdata->locals.dia->win);
|
|
|
|
evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.degree);
|
|
|
|
elm_spinner_min_max_set(o, 0, 2*M_PI);
|
|
|
|
elm_spinner_label_format_set(o, "%f");
|
|
|
|
elm_spinner_step_set(o, 0.1);
|
|
|
|
elm_spinner_editable_set(o, EINA_TRUE);
|
|
|
|
e_widget_framelist_object_append(ol, o);
|
|
|
|
e_widget_list_object_append(obg, ol, 1, 0, 0.5);
|
|
|
|
|
|
|
|
ol = e_widget_framelist_add(evas, _("Error:"), 0);
|
|
|
|
entry = o = elm_spinner_add(cfdata->locals.dia->win);
|
|
|
|
evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.error);
|
|
|
|
elm_spinner_min_max_set(o, 0, 2*M_PI);
|
|
|
|
elm_spinner_label_format_set(o, "%f");
|
|
|
|
elm_spinner_step_set(o, 0.1);
|
|
|
|
elm_spinner_editable_set(o, EINA_TRUE);
|
|
|
|
e_widget_framelist_object_append(ol, o);
|
|
|
|
e_widget_list_object_append(obg, ol, 1, 0, 0.5);
|
|
|
|
|
|
|
|
ol = e_widget_framelist_add(evas, _("Length:"), 0);
|
|
|
|
entry = o = elm_spinner_add(cfdata->locals.dia->win);
|
|
|
|
evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.length);
|
|
|
|
elm_spinner_min_max_set(o, 0, 200);
|
|
|
|
elm_spinner_step_set(o, 5);
|
|
|
|
elm_spinner_editable_set(o, EINA_TRUE);
|
|
|
|
e_widget_framelist_object_append(ol, o);
|
|
|
|
e_widget_list_object_append(obg, ol, 1, 0, 0.5);
|
|
|
|
|
|
|
|
cfdata->locals.fingers = 3;
|
|
|
|
ol = e_widget_framelist_add(evas, _("Fingers:"), 0);
|
|
|
|
entry = o = elm_spinner_add(cfdata->locals.dia->win);
|
|
|
|
evas_object_smart_callback_add(o, "changed", _int_getter, &cfdata->locals.fingers);
|
|
|
|
elm_spinner_min_max_set(o, 3, 10);
|
|
|
|
elm_spinner_value_set(o, 3.0);
|
|
|
|
elm_spinner_editable_set(o, EINA_TRUE);
|
|
|
|
e_widget_framelist_object_append(ol, o);
|
|
|
|
e_widget_list_object_append(obg, ol, 1, 0, 0.5);
|
|
|
|
|
|
|
|
e_widget_size_min_get(obg, &w, &h);
|
|
|
|
e_dialog_content_set(cfdata->locals.dia, obg, MAX(w, 200), MAX(h, 100));
|
|
|
|
|
|
|
|
e_dialog_show(cfdata->locals.dia);
|
|
|
|
e_widget_focus_set(entry, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_add_swipe_binding_cb(void *data, void *data2 EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata = data;
|
|
|
|
|
|
|
|
_auto_apply_changes(cfdata);
|
|
|
|
_swipe_add_show(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_update_swipe_cb(void *data, Eina_Bool end, double direction, double length, double error, unsigned int fingers)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata = data;
|
|
|
|
|
|
|
|
if (end)
|
|
|
|
{
|
|
|
|
e_object_del(E_OBJECT(cfdata->locals.dia));
|
|
|
|
cfdata->locals.dia = NULL;
|
|
|
|
cfdata->locals.degree = direction;
|
|
|
|
cfdata->locals.length = length;
|
|
|
|
cfdata->locals.error = error;
|
|
|
|
cfdata->locals.fingers = fingers;
|
|
|
|
_flush_binding_swipe(cfdata);
|
|
|
|
e_bindings_swipe_live_update_hook_set(NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char text_buf[1000];
|
|
|
|
Evas_Object *vis;
|
|
|
|
|
|
|
|
vis = create_visualisation(evas_object_evas_get(cfdata->locals.dia->win), direction, error);
|
|
|
|
evas_object_size_hint_align_set(vis, 0.0, 0.5);
|
2020-11-16 10:34:40 -08:00
|
|
|
snprintf(text_buf, sizeof(text_buf), _("Using %d Fingers<br> <b>Direction</b> %f <b>Length</b> %f <b>Error</b> %f"), fingers, direction, length, error);
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
e_dialog_text_set(cfdata->locals.dia, text_buf);
|
|
|
|
elm_object_part_content_set(cfdata->locals.dia->bg_object, "e.swallow.icon", vis);
|
|
|
|
evas_object_size_hint_min_set(vis, 30 * e_scale, 30 * e_scale);
|
|
|
|
elm_layout_signal_emit(cfdata->locals.dia->bg_object, "e,state,icon", "e");
|
|
|
|
elm_layout_signal_emit(cfdata->locals.dia->bg_object, "e,icon,enabled", "e");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_add_swipe_binding_by_sample_cb(void *data, void *data2 EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Config_Dialog_Data *cfdata = data;
|
|
|
|
|
|
|
|
cfdata->locals.dia = e_dialog_new(cfdata->cfd->dia->win, "E", "_swipe_recognition");
|
2021-03-22 06:32:41 -07:00
|
|
|
e_dialog_icon_set(cfdata->locals.dia, "preferences-desktop-swipe-bindings", 48);
|
2020-11-16 10:34:40 -08:00
|
|
|
e_dialog_title_set(cfdata->locals.dia, _("Swipe recognition"));
|
|
|
|
e_dialog_text_set(cfdata->locals.dia, _("Do your swipe gesture.<br><br>Press <hilight>Escape</hilight> to abort"));
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
elm_win_center(cfdata->locals.dia->win, 1, 1);
|
|
|
|
elm_win_borderless_set(cfdata->locals.dia->win, 1);
|
|
|
|
e_dialog_resizable_set(cfdata->locals.dia, 0);
|
|
|
|
e_dialog_show(cfdata->locals.dia);
|
|
|
|
evas_object_layer_set(e_win_client_get(cfdata->locals.dia->win)->frame, E_LAYER_CLIENT_PRIO);
|
|
|
|
|
|
|
|
e_bindings_swipe_live_update_hook_set(_update_swipe_cb, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_delete_swipe_binding_cb(void *data, void *data2 EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Eina_List *l = NULL;
|
|
|
|
int sel, n;
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
cfdata = data;
|
|
|
|
|
|
|
|
sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
|
|
|
|
if (cfdata->locals.binding[0] == 's')
|
|
|
|
{
|
|
|
|
if (sscanf(cfdata->locals.binding, "s%d", &n) != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
l = eina_list_nth_list(cfdata->binding.swipe, n);
|
|
|
|
|
|
|
|
if (l)
|
|
|
|
{
|
|
|
|
_swipe_binding_free(eina_list_data_get(l));
|
|
|
|
cfdata->binding.swipe = eina_list_remove_list(cfdata->binding.swipe, l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_update_swipe_binding_list(cfdata);
|
|
|
|
|
|
|
|
if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list))
|
|
|
|
sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1;
|
|
|
|
|
|
|
|
eina_stringshare_del(cfdata->locals.cur);
|
|
|
|
cfdata->locals.cur = NULL;
|
|
|
|
|
|
|
|
e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
|
|
|
|
if (sel < 0)
|
|
|
|
{
|
|
|
|
e_widget_ilist_unselect(cfdata->gui.o_action_list);
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
_update_buttons(cfdata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_delete_all_swipe_binding_cb(void *data, void *data2 EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Config_Binding_Swipe *bi;
|
|
|
|
E_Config_Dialog_Data *cfdata;
|
|
|
|
|
|
|
|
cfdata = data;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(cfdata->binding.swipe, bi)
|
|
|
|
_swipe_binding_free(bi);
|
|
|
|
|
|
|
|
eina_stringshare_del(cfdata->locals.cur);
|
|
|
|
cfdata->locals.cur = NULL;
|
|
|
|
|
|
|
|
e_widget_ilist_clear(cfdata->gui.o_binding_list);
|
|
|
|
e_widget_ilist_go(cfdata->gui.o_binding_list);
|
|
|
|
e_widget_ilist_unselect(cfdata->gui.o_action_list);
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
|
|
|
|
_update_buttons(cfdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_restore_swipe_binding_defaults_cb(void *data, void *data2 EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Config_Bindings *ecb;
|
|
|
|
Eina_Stringshare *prof;
|
|
|
|
E_Config_Dialog_Data *cfdata = data;
|
|
|
|
|
|
|
|
ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
|
|
|
|
if (!ecb)
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
|
|
|
|
prof = eina_stringshare_ref(e_config_profile_get());
|
|
|
|
switch (e_config->config_type)
|
|
|
|
{
|
|
|
|
case E_CONFIG_PROFILE_TYPE_DESKTOP:
|
|
|
|
type = "standard";
|
|
|
|
break;
|
|
|
|
case E_CONFIG_PROFILE_TYPE_MOBILE:
|
|
|
|
type = "mobile";
|
|
|
|
break;
|
|
|
|
//case E_CONFIG_PROFILE_TYPE_TABLET: FIXME - not used
|
|
|
|
default:
|
|
|
|
type = "default";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
e_config_profile_set(type);
|
|
|
|
ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
|
|
|
|
e_config_profile_set(prof);
|
|
|
|
eina_stringshare_del(prof);
|
|
|
|
}
|
|
|
|
if (!ecb) return;
|
|
|
|
E_FREE_LIST(cfdata->binding.swipe, e_config_binding_swipe_free);
|
|
|
|
cfdata->binding.swipe = ecb->swipe_bindings, ecb->swipe_bindings = NULL;
|
|
|
|
e_config_bindings_free(ecb);
|
|
|
|
|
|
|
|
eina_stringshare_del(cfdata->locals.cur);
|
|
|
|
cfdata->locals.cur = NULL;
|
|
|
|
|
|
|
|
_update_swipe_binding_list(cfdata);
|
|
|
|
_update_buttons(cfdata);
|
|
|
|
|
|
|
|
e_widget_ilist_unselect(cfdata->gui.o_action_list);
|
|
|
|
e_widget_entry_clear(cfdata->gui.o_params);
|
|
|
|
e_widget_disabled_set(cfdata->gui.o_params, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Object *
|
|
|
|
_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
|
|
|
|
{
|
|
|
|
Evas_Object *o, *ol, *ot, *of, *ob;
|
|
|
|
|
|
|
|
cfdata->evas = evas;
|
|
|
|
o = e_widget_list_add(evas, 0, 0);
|
|
|
|
ol = e_widget_list_add(evas, 0, 1);
|
|
|
|
|
|
|
|
of = e_widget_frametable_add(evas, _("Swipe Bindings"), 0);
|
|
|
|
ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding));
|
|
|
|
cfdata->gui.o_binding_list = ob;
|
|
|
|
e_widget_size_min_set(ob, 200, 160);
|
|
|
|
e_widget_frametable_object_append(of, ob, 0, 0, 2, 1, 1, 1, 1, 1);
|
|
|
|
|
|
|
|
ob = e_widget_button_add(evas, _("Add"), "list-add", _add_swipe_binding_by_sample_cb, cfdata, NULL);
|
|
|
|
e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
|
|
|
|
|
|
|
|
ob = e_widget_button_add(evas, _("Add by props"), "list-add", _add_swipe_binding_cb, cfdata, NULL);
|
|
|
|
cfdata->gui.o_add = ob;
|
|
|
|
e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
|
|
|
|
|
|
|
|
ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_swipe_binding_cb, cfdata, NULL);
|
|
|
|
cfdata->gui.o_del = ob;
|
|
|
|
e_widget_disabled_set(ob, 1);
|
|
|
|
e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 0, 1, 0);
|
|
|
|
ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_swipe_binding_cb, cfdata, NULL);
|
|
|
|
cfdata->gui.o_del_all = ob;
|
|
|
|
e_widget_disabled_set(ob, 1);
|
|
|
|
e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 0, 1, 0);
|
|
|
|
ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment", _restore_swipe_binding_defaults_cb, cfdata, NULL);
|
|
|
|
e_widget_frametable_object_append(of, ob, 0, 3, 2, 1, 1, 0, 1, 0);
|
|
|
|
e_widget_list_object_append(ol, of, 1, 1, 0.5);
|
|
|
|
|
|
|
|
ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
|
|
|
|
of = e_widget_framelist_add(evas, _("Action"), 0);
|
|
|
|
ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action));
|
|
|
|
cfdata->gui.o_action_list = ob;
|
|
|
|
e_widget_size_min_set(ob, 200, 240);
|
|
|
|
e_widget_framelist_object_append(of, ob);
|
|
|
|
e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
|
|
|
|
|
|
|
|
of = e_widget_framelist_add(evas, _("Action Params"), 0);
|
|
|
|
ob = e_widget_entry_add(cfd->dia->win, &(cfdata->locals.params), NULL, NULL, NULL);
|
|
|
|
cfdata->gui.o_params = ob;
|
|
|
|
e_widget_disabled_set(ob, 1);
|
|
|
|
e_widget_framelist_object_append(of, ob);
|
|
|
|
e_widget_table_object_append(ot, of, 0, 3, 1, 1, 1, 1, 1, 0);
|
|
|
|
e_widget_list_object_append(ol, ot, 1, 1, 0.5);
|
|
|
|
|
|
|
|
e_widget_list_object_append(o, ol, 1, 1, 0.5);
|
|
|
|
|
|
|
|
_update_swipe_binding_list(cfdata);
|
|
|
|
_fill_actions_list(cfdata);
|
|
|
|
|
|
|
|
e_dialog_resizable_set(cfd->dia, 1);
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
2021-03-24 08:04:48 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_user_part_of_input(void)
|
|
|
|
{
|
|
|
|
uid_t user = getuid();
|
|
|
|
struct passwd *user_pw = getpwuid(user);
|
|
|
|
gid_t *gids = NULL;
|
|
|
|
int number_of_groups = 0;
|
|
|
|
struct group *input_group = getgrnam("input");
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(user_pw, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input_group, EINA_FALSE);
|
|
|
|
|
|
|
|
if (getgrouplist(user_pw->pw_name, getgid(), NULL, &number_of_groups) != -1)
|
|
|
|
{
|
|
|
|
ERR("Failed to enumerate groups of user");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
number_of_groups ++;
|
|
|
|
gids = alloca((number_of_groups) * sizeof(gid_t));
|
|
|
|
if (getgrouplist(user_pw->pw_name, getgid(), gids, &number_of_groups) == -1)
|
|
|
|
{
|
|
|
|
ERR("Failed to get groups of user");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < number_of_groups; ++i)
|
|
|
|
{
|
|
|
|
if (gids[i] == input_group->gr_gid)
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
|
|
|
|
E_Config_Dialog *
|
|
|
|
e_int_config_swipebindings(Evas_Object *parent EINA_UNUSED, const char *params)
|
|
|
|
{
|
|
|
|
E_Config_Dialog *cfd;
|
|
|
|
E_Config_Dialog_View *v;
|
|
|
|
|
|
|
|
if (e_config_dialog_find("E", "keyboard_and_mouse/swipe_bindings")) return NULL;
|
|
|
|
v = E_NEW(E_Config_Dialog_View, 1);
|
|
|
|
|
|
|
|
v->create_cfdata = _create_data;
|
|
|
|
v->free_cfdata = _free_data;
|
|
|
|
v->basic.apply_cfdata = _basic_apply_data;
|
|
|
|
v->basic.create_widgets = _basic_create_widgets;
|
|
|
|
v->override_auto_apply = 1;
|
|
|
|
|
2021-03-24 08:04:48 -07:00
|
|
|
if (!_user_part_of_input())
|
|
|
|
{
|
|
|
|
e_module_dialog_show(NULL, "Gesture Recognition", "Your user is not part of the input group, libinput cannot be used.");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e_bindings_gesture_capable_devices_get() == 0)
|
|
|
|
{
|
|
|
|
e_module_dialog_show(NULL, "Gesture Recognition", "No devices detected that are capable of gesture recognition.");
|
|
|
|
}
|
|
|
|
|
Introduce gesture recognition
This is currently using libinputs gesture recognition. And offers a
config screen to setup new gestures.
1. No default gesture bindings are setup
2. When libinput is not available the module is not going to be loaded,
and nothing is recognited.+
3. Only swipe gestures are recognized yet.
4. For now, you are required to be part of the input group, otherwise we cannot
get the libinput events. (See Todo 1)
5. The visual representation is not really good. In terms of UI, it is
visually showing a value coming from left to right, which is
indicating a direction, which is not always the direction of the
gesture, which is kind of bad. More improvements needed here.
Some things that still can be done:
1. The whole libinput things should be handled by elput, either with the
input group hack, or logind, or simply by root. The ideal idea would
be that e_sys is creating the elput context, which also listens for new
devices etc.. When all this is done, and it recognizes a new device, it
can simply sent a message from e_sys to e, that there is some new
device, with a opened fd. (However, this all needs to be locked up in a
way that e_sys cannot be abused)
2020-07-02 03:18:42 -07:00
|
|
|
cfd = e_config_dialog_new(NULL, _("Swipe Bindings Settings"), "E",
|
|
|
|
"keyboard_and_mouse/swipe_bindings",
|
|
|
|
"enlightenment/swipes", 0, v, NULL);
|
|
|
|
if ((params) && (params[0]))
|
|
|
|
{
|
|
|
|
cfd->cfdata->params = eina_stringshare_add(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfd;
|
|
|
|
}
|