early work on multi-input support

This commit is contained in:
Boris Faure 2017-11-13 23:48:05 +01:00
parent 878def120e
commit 39fb41024b
6 changed files with 354 additions and 69 deletions

View File

@ -7,7 +7,7 @@
#include "col.h"
#include "utils.h"
#define CONF_VER 17
#define CONF_VER 18
#define LIM(v, min, max) {if (v >= max) v = max; else if (v <= min) v = min;}
@ -343,6 +343,7 @@ _add_default_keys(Config *config)
ADD_KB("Down", 0, 1, 0, 0, "term_down");
ADD_KB("Left", 0, 1, 0, 0, "term_left");
ADD_KB("Right", 0, 1, 0, 0, "term_right");
ADD_KB("g", 0, 1, 0, 0, "visible_group");
/* Ctrl-Shift- */
ADD_KB("Prior", 1, 0, 1, 0, "split_h");
@ -377,6 +378,9 @@ _add_default_keys(Config *config)
ADD_KB("Right", 0, 0, 1, 0, "term_next");
ADD_KB("Home", 0, 0, 1, 0, "top_backlog");
ADD_KB("End", 0, 0, 1, 0, "reset_scroll");
/* Alt-Shift */
ADD_KB("g", 0, 1, 1, 0, "all_group");
}
void
@ -653,7 +657,12 @@ config_load(const char *key)
config->shine = 255;
EINA_FALLTHROUGH;
/*pass through*/
case CONF_VER: /* 17 */
case 17:
_add_key(config, "g", 0, 1, 0, 0, "visible_group");
_add_key(config, "g", 0, 1, 1, 0, "all_group");
EINA_FALLTHROUGH;
/*pass through*/
case CONF_VER: /* 18 */
config->version = CONF_VER;
break;
default:

View File

@ -343,18 +343,62 @@ keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev)
{
Ecore_IMF_Event_Key_Up imf_ev;
ecore_imf_evas_event_key_up_wrap(ev, &imf_ev);
if (ecore_imf_context_filter_event
(khdl->imf, ECORE_IMF_EVENT_KEY_UP, (Ecore_IMF_Event *)&imf_ev))
return;
ecore_imf_context_filter_event
(khdl->imf, ECORE_IMF_EVENT_KEY_UP, (Ecore_IMF_Event *)&imf_ev);
}
}
/* }}} */
/* {{{ Callbacks */
#define RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED \
Win *wn; \
Term *term = termio_term_get(termio_obj); \
if (!term) \
return EINA_FALSE; \
wn = term_win_get(term); \
if (!wn) \
return EINA_FALSE; \
if (win_is_group_action_handled(wn)) \
return EINA_FALSE; \
#define RETURN_FALSE_ON_GROUP_INPUT \
Win *wn; \
Term *term = termio_term_get(termio_obj); \
if (!term) \
return EINA_FALSE; \
wn = term_win_get(term); \
if (!wn) \
return EINA_FALSE; \
if (win_is_group_input(wn)) \
return EINA_FALSE; \
static Eina_Bool
cb_all_group(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED;
win_toggle_all_group(wn);
ERR("ALL GROUP");
return EINA_TRUE;
}
static Eina_Bool
cb_visible_group(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED;
win_toggle_visible_group(wn);
ERR("VISIBLE GROUP");
return EINA_TRUE;
}
static Eina_Bool
cb_term_prev(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "prev", NULL);
return EINA_TRUE;
}
@ -362,6 +406,8 @@ cb_term_prev(Evas_Object *termio_obj)
static Eina_Bool
cb_term_next(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "next", NULL);
return EINA_TRUE;
}
@ -369,9 +415,8 @@ cb_term_next(Evas_Object *termio_obj)
static Eina_Bool
cb_term_up(Evas_Object *termio_obj)
{
Term *term = termio_term_get(termio_obj);
if (!term)
return EINA_FALSE;
RETURN_FALSE_ON_GROUP_INPUT;
term_up(term);
return EINA_TRUE;
}
@ -379,9 +424,8 @@ cb_term_up(Evas_Object *termio_obj)
static Eina_Bool
cb_term_down(Evas_Object *termio_obj)
{
Term *term = termio_term_get(termio_obj);
if (!term)
return EINA_FALSE;
RETURN_FALSE_ON_GROUP_INPUT;
term_down(term);
return EINA_TRUE;
}
@ -389,9 +433,8 @@ cb_term_down(Evas_Object *termio_obj)
static Eina_Bool
cb_term_left(Evas_Object *termio_obj)
{
Term *term = termio_term_get(termio_obj);
if (!term)
return EINA_FALSE;
RETURN_FALSE_ON_GROUP_INPUT;
term_left(term);
return EINA_TRUE;
}
@ -399,9 +442,8 @@ cb_term_left(Evas_Object *termio_obj)
static Eina_Bool
cb_term_right(Evas_Object *termio_obj)
{
Term *term = termio_term_get(termio_obj);
if (!term)
return EINA_FALSE;
RETURN_FALSE_ON_GROUP_INPUT;
term_right(term);
return EINA_TRUE;
}
@ -409,6 +451,8 @@ cb_term_right(Evas_Object *termio_obj)
static Eina_Bool
cb_term_new(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED;
char path[PATH_MAX], cwd[PATH_MAX], *cmd;
const char *template = "%s -d %s";
int length;
@ -450,10 +494,8 @@ cb_tab_set_title(Evas_Object *termio_obj)
static Eina_Bool \
cb_tab_##N(Evas_Object *termio_obj) \
{ \
RETURN_FALSE_ON_GROUP_INPUT; \
int n = (N == 0) ? 9 : N - 1; \
Term *term = termio_term_get(termio_obj); \
if (!term) \
return EINA_FALSE; \
return term_tab_go(term, n); \
}
@ -472,6 +514,7 @@ CB_TAB(9)
static Eina_Bool
cb_cmd_box(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED;
evas_object_smart_callback_call(termio_obj, "cmdbox", NULL);
return EINA_TRUE;
}
@ -479,6 +522,7 @@ cb_cmd_box(Evas_Object *termio_obj)
static Eina_Bool
cb_split_h(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "split,h", NULL);
return EINA_TRUE;
}
@ -486,6 +530,7 @@ cb_split_h(Evas_Object *termio_obj)
static Eina_Bool
cb_split_v(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "split,v", NULL);
return EINA_TRUE;
}
@ -493,6 +538,7 @@ cb_split_v(Evas_Object *termio_obj)
static Eina_Bool
cb_tab_new(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "new", NULL);
return EINA_TRUE;
}
@ -500,6 +546,7 @@ cb_tab_new(Evas_Object *termio_obj)
static Eina_Bool
cb_close(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "close", NULL);
return EINA_TRUE;
}
@ -507,6 +554,7 @@ cb_close(Evas_Object *termio_obj)
static Eina_Bool
cb_tab_select(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_INPUT;
evas_object_smart_callback_call(termio_obj, "select", NULL);
return EINA_TRUE;
}
@ -557,6 +605,7 @@ cb_miniview(Evas_Object *termio_obj)
static Eina_Bool
cb_win_fullscreen(Evas_Object *termio_obj)
{
RETURN_FALSE_ON_GROUP_ACTION_ALREADY_HANDLED;
Evas_Object *win = termio_win_get(termio_obj);
Eina_Bool fullscreen;
@ -707,6 +756,9 @@ static Shortcut_Action _actions[] =
{"tab_9", gettext_noop("Switch to terminal tab 9"), cb_tab_9},
{"tab_10", gettext_noop("Switch to terminal tab 10"), cb_tab_0},
{"tab_title", gettext_noop("Change title"), cb_tab_set_title},
{"visible_group", gettext_noop("Toggle whether input goes to all visible terminals"), cb_visible_group},
{"all_group", gettext_noop("Toggle whether input goes to all visible terminals"), cb_all_group},
{"group", gettext_noop("Font size"), NULL},
{"increase_font_size", gettext_noop("Font size up 1"), cb_increase_font_size},

View File

@ -101,6 +101,7 @@ struct _Termio
unsigned char bottom_right : 1;
unsigned char top_left : 1;
unsigned char reset_sel : 1;
unsigned char cb_added : 1;
double gesture_zoom_start_size;
};
@ -2029,6 +2030,8 @@ _smart_cb_key_down(void *data,
evas_key_modifier_is_set(ev->modifiers, "AltGr") ||
evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift");
hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper");
ERR("ctrl:%d alt:%d shift:%d win:%d meta:%d hyper:%d",
ctrl, alt, shift, win, meta, hyper);
if (keyin_handle(&sd->khdl, sd->pty, ev, ctrl, alt, shift, win, meta, hyper))
goto end;
@ -3508,13 +3511,10 @@ _imf_cursor_set(Termio *sd)
*/
}
static void
_smart_cb_focus_in(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *_obj EINA_UNUSED,
void *_event EINA_UNUSED)
void
termio_focus_in(Evas_Object *termio)
{
Termio *sd = evas_object_smart_data_get(data);
Termio *sd = evas_object_smart_data_get(termio);
EINA_SAFETY_ON_NULL_RETURN(sd);
if (sd->config->disable_cursor_blink)
@ -3532,13 +3532,10 @@ _smart_cb_focus_in(void *data,
}
}
static void
_smart_cb_focus_out(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *obj,
void *_event EINA_UNUSED)
void
termio_focus_out(Evas_Object *termio)
{
Termio *sd = evas_object_smart_data_get(data);
Termio *sd = evas_object_smart_data_get(termio);
EINA_SAFETY_ON_NULL_RETURN(sd);
if (!sd->config->disable_focus_visuals)
@ -3554,7 +3551,7 @@ _smart_cb_focus_out(void *data,
ecore_imf_context_input_panel_hide(sd->khdl.imf);
}
if (!sd->ctxpopup)
_remove_links(sd, obj);
_remove_links(sd, termio);
term_unfocus(sd->term);
}
@ -5371,15 +5368,6 @@ _smart_add(Evas_Object *obj)
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL,
_smart_cb_mouse_wheel, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
_smart_cb_key_down, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
_smart_cb_key_up, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN,
_smart_cb_focus_in, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT,
_smart_cb_focus_out, obj);
sd->link.suspend = 1;
if (ecore_imf_init())
@ -5432,6 +5420,7 @@ _smart_add(Evas_Object *obj)
imf_done:
if (sd->khdl.imf) DBG("Ecore IMF Setup");
else WRN(_("Ecore IMF failed"));
}
terms = eina_list_append(terms, obj);
}
@ -5470,17 +5459,6 @@ _smart_del(Evas_Object *obj)
evas_object_del(sd->event);
sd->event = NULL;
}
if (sd->self)
{
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_KEY_DOWN,
_smart_cb_key_down);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_KEY_UP,
_smart_cb_key_up);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_FOCUS_IN,
_smart_cb_focus_in);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_FOCUS_OUT,
_smart_cb_focus_out);
}
if (sd->sel.top) evas_object_del(sd->sel.top);
if (sd->sel.bottom) evas_object_del(sd->sel.bottom);
if (sd->sel.theme) evas_object_del(sd->sel.theme);
@ -5682,17 +5660,6 @@ _smart_pty_exited(void *data)
evas_object_del(sd->event);
sd->event = NULL;
}
if (sd->self)
{
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_KEY_DOWN,
_smart_cb_key_down);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_KEY_UP,
_smart_cb_key_up);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_FOCUS_IN,
_smart_cb_focus_in);
evas_object_event_callback_del(sd->self, EVAS_CALLBACK_FOCUS_OUT,
_smart_cb_focus_out);
}
term_close(sd->win, sd->self, EINA_TRUE);
}
@ -6305,3 +6272,15 @@ termio_add(Evas_Object *win, Config *config,
_smart_size(obj, w, h, EINA_FALSE);
return obj;
}
void
termio_key_down(Evas_Object *termio, void *event)
{
_smart_cb_key_down(termio, NULL, NULL, event);
}
void
termio_key_up(Evas_Object *termio, void *event)
{
_smart_cb_key_up(termio, NULL, NULL, event);
}

View File

@ -53,4 +53,9 @@ Termpty *termio_pty_get(const Evas_Object *obj);
Evas_Object * termio_miniview_get(const Evas_Object *obj);
Term* termio_term_get(const Evas_Object *obj);
void termio_key_down(Evas_Object *termio, void *event);
void termio_key_up(Evas_Object *termio, void *event);
void termio_focus_in(Evas_Object *termio);
void termio_focus_out(Evas_Object *termio);
#endif

View File

@ -170,6 +170,9 @@ struct _Win
Ecore_Timer *cmdbox_focus_timer;
unsigned char focused : 1;
unsigned char cmdbox_up : 1;
unsigned char group_input : 1;
unsigned char group_only_visible : 1;
unsigned char group_once_handled : 1;
};
/* }}} */
@ -404,6 +407,7 @@ _solo_unfocus(Term_Container *tc, Term_Container *relative)
return;
tc->is_focused = EINA_FALSE;
termio_focus_out(term->termio);
if (tc->parent != relative)
tc->parent->unfocus(tc->parent, tc);
@ -453,10 +457,11 @@ _solo_focus(Term_Container *tc, Term_Container *relative)
edje_object_signal_emit(term->bg, "focus,in", "terminology");
edje_object_signal_emit(term->base, "focus,in", "terminology");
}
termio_focus_in(term->termio);
if (term->wn->cmdbox)
elm_object_focus_set(term->wn->cmdbox, EINA_FALSE);
elm_object_focus_set(term->termio, EINA_TRUE);
termio_event_feed_mouse_in(term->termio);
//elm_object_focus_set(term->termio, EINA_TRUE);
//termio_event_feed_mouse_in(term->termio);
title = termio_title_get(term->termio);
if (title)
@ -530,7 +535,7 @@ _cb_win_focus_in(void *data,
Term_Container *tc = (Term_Container*) wn;
Term *term;
DBG("tc:%p tc->is_focused:%d",
DBG("FOCUS_IN tc:%p tc->is_focused:%d",
tc, tc->is_focused);
if (!tc->is_focused)
elm_win_urgent_set(wn->win, EINA_FALSE);
@ -577,7 +582,7 @@ _cb_win_focus_out(void *data,
Win *wn = data;
Term_Container *tc = (Term_Container*) wn;
DBG("tc:%p tc->is_focused:%d",
DBG("FOCUS OUT tc:%p tc->is_focused:%d",
tc, tc->is_focused);
tc->unfocus(tc, NULL);
}
@ -1106,6 +1111,154 @@ _win_update(Term_Container *tc)
wn->child->update(wn->child);
}
static void
_cb_win_key_up(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *_obj EINA_UNUSED,
void *event_info)
{
Win *wn = data;
Eina_List *l;
Term *term;
const Evas_Event_Key_Up *ev = event_info;
DBG("GROUP key up (%p) (ctrl:%d)",
wn, evas_key_modifier_is_set(ev->modifiers, "Control"));
if (wn->group_input)
{
wn->group_once_handled = EINA_FALSE;
EINA_LIST_FOREACH(wn->terms, l, term)
{
termio_key_up(term->termio, event_info);
if (!wn->group_input)
return;
}
}
else
{
Term_Container *tc = (Term_Container*) wn;
term = tc->focused_term_get(tc);
if (term)
termio_key_up(term->termio, event_info);
}
}
static void
_cb_win_key_down(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *_obj EINA_UNUSED,
void *event_info)
{
Win *wn = data;
Eina_List *l;
Term *term;
const Evas_Event_Key_Down *ev = event_info;
DBG("GROUP key down (%p) (ctrl:%d)",
wn, evas_key_modifier_is_set(ev->modifiers, "Control"));
int ctrl, alt, shift, win, meta, hyper;
ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
win = evas_key_modifier_is_set(ev->modifiers, "Super");
meta = evas_key_modifier_is_set(ev->modifiers, "Meta") ||
evas_key_modifier_is_set(ev->modifiers, "AltGr") ||
evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift");
hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper");
DBG("ctrl:%d alt:%d shift:%d win:%d meta:%d hyper:%d",
ctrl, alt, shift, win, meta, hyper);
if (wn->group_input)
{
wn->group_once_handled = EINA_FALSE;
EINA_LIST_FOREACH(wn->terms, l, term)
{
termio_key_down(term->termio, event_info);
if (!wn->group_input)
return;
}
}
else
{
Term_Container *tc = (Term_Container*) wn;
term = tc->focused_term_get(tc);
if (term)
termio_key_down(term->termio, event_info);
}
}
static void
_cb_win_mouse_down(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *_obj EINA_UNUSED,
void *event)
{
Win *wn = data;
Evas_Event_Mouse_Down *ev = event;
Term *term, *term_mouse;
Term_Container *tc = (Term_Container*) wn;
Term_Container *tc_child;
DBG("mouse down");
if (wn->group_input)
return;
term_mouse = tc->find_term_at_coords(tc, ev->canvas.x, ev->canvas.y);
term = tc->focused_term_get(tc);
if (term_mouse == term)
return;
if (term)
{
tc_child = term->container;
tc_child->unfocus(tc_child, tc);
}
tc_child = term_mouse->container;
tc_child->focus(tc_child, tc);
}
static void
_cb_win_mouse_move(void *data,
Evas *_e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event)
{
Win *wn = data;
Evas_Event_Mouse_Move *ev = event;
Term *term, *term_mouse;
Term_Container *tc = (Term_Container*) wn;
Term_Container *tc_child;
if (wn->group_input)
return;
if (!wn->config->mouse_over_focus)
return;
term_mouse = tc->find_term_at_coords(tc,
ev->cur.canvas.x, ev->cur.canvas.y);
term = tc->focused_term_get(tc);
if (term_mouse == term)
return;
DBG("mouse move");
if (term)
{
tc_child = term->container;
tc_child->unfocus(tc_child, tc);
}
tc_child = term_mouse->container;
DBG("need to focus");
tc_child->focus(tc_child, tc);
}
Win *
win_new(const char *name, const char *role, const char *title,
const char *icon_name, Config *config,
@ -1187,6 +1340,23 @@ win_new(const char *name, const char *role, const char *title,
evas_object_smart_callback_add(wn->win, "focus,in", _cb_win_focus_in, wn);
evas_object_smart_callback_add(wn->win, "focus,out", _cb_win_focus_out, wn);
evas_object_event_callback_add(wn->win,
EVAS_CALLBACK_KEY_DOWN,
_cb_win_key_down,
wn);
evas_object_event_callback_add(wn->win,
EVAS_CALLBACK_KEY_UP,
_cb_win_key_up,
wn);
evas_object_event_callback_add(wn->win,
EVAS_CALLBACK_MOUSE_DOWN,
_cb_win_mouse_down,
wn);
evas_object_event_callback_add(wn->win,
EVAS_CALLBACK_MOUSE_MOVE,
_cb_win_mouse_move,
wn);
wins = eina_list_append(wins, wn);
return wn;
}
@ -1216,6 +1386,71 @@ term_close(Evas_Object *win, Evas_Object *term, Eina_Bool hold_if_requested)
term_unref(tm);
}
/* Returns True if action is permitted */
Eina_Bool
win_is_group_action_handled(Win *wn)
{
DBG("wn->group_input:%d wn->group_once_handled:%d wn:%p",
wn->group_input, wn->group_once_handled, wn);
if (!wn->group_input)
return EINA_FALSE;
if (wn->group_once_handled)
return EINA_TRUE;
wn->group_once_handled = EINA_TRUE;
return EINA_FALSE;
}
Eina_Bool
win_is_group_input(Win *wn)
{
return wn->group_input;
}
static void
_win_toggle_group(Win *wn)
{
Eina_List *l;
Term *term;
DBG("WIN TOGGLE");
if (!wn->group_input)
{
EINA_LIST_FOREACH(wn->terms, l, term)
{
edje_object_signal_emit(term->bg, "focus,in", "terminology");
}
wn->group_input = EINA_TRUE;
DBG("GROUP INPUT is now TRUE");
}
else
{
wn->group_input = EINA_TRUE;
DBG("GROUP INPUT is now FALSE");
EINA_LIST_FOREACH(wn->terms, l, term)
{
edje_object_signal_emit(term->bg, "focus,out", "terminology");
}
term = wn->child->term_first(wn->child);
wn->child->focus(wn->child, &wn->tc);
}
}
void
win_toggle_all_group(Win *wn)
{
wn->group_only_visible = EINA_FALSE;
_win_toggle_group(wn);
}
void
win_toggle_visible_group(Win *wn)
{
wn->group_only_visible = EINA_TRUE;
_win_toggle_group(wn);
}
/* }}} */
/* {{{ Splits */
@ -4799,7 +5034,7 @@ _cb_options_done(void *data)
return;
}
}
DBG("tc:%p", tc);
DBG("focus tc:%p", tc);
tc->focus(tc, tc);
}

View File

@ -47,6 +47,11 @@ Config *win_config_get(const Win *wn);
void win_term_swallow(Win *wn, Term *term);
void win_add_split(Win *wn, Term *term);
void win_sizing_handle(Win *wn);
void win_toggle_visible_group(Win *wn);
void win_toggle_all_group(Win *wn);
Eina_Bool win_is_group_action_handled(Win *wn);
Eina_Bool win_is_group_input(Win *wn);
void term_ref(Term *term);
void term_unref(Term *term);