From fd4ef6ec1f76f9e98cc9c8cc81a39640ecf801f8 Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Tue, 11 Jul 2017 00:01:29 +0200 Subject: [PATCH] win: add binding (Alt+Up/Down/Left/Right) to move around panes --- README | 4 + man/terminology.1 | 16 +++ src/bin/config.c | 14 +- src/bin/keyin.c | 48 ++++++- src/bin/term_container.h | 4 + src/bin/win.c | 271 ++++++++++++++++++++++++++++++++++----- src/bin/win.h | 5 + 7 files changed, 327 insertions(+), 35 deletions(-) diff --git a/README b/README index 2c84cb18..36a82aeb 100644 --- a/README +++ b/README @@ -63,6 +63,10 @@ Ctrl+Shift+v = paste current clipboard selection Alt+Home = Enter command mode (enter commands to control terminology itself) Alt+Return = Paste primary selection Alt+w = Copy selection to primary +Alt+Up = Focus the terminal above +Alt+Down = Focus the terminal below +Alt+Left = Focus the terminal on the left +Alt+Right = Focus the terminal on the right Ctrl+Alt+Equal = Font size up 1 Ctrl+Alt+Minus = Font size down 1 Ctrl+Alt+0 = Reset font size diff --git a/man/terminology.1 b/man/terminology.1 index 85506830..ba4eac8d 100644 --- a/man/terminology.1 +++ b/man/terminology.1 @@ -292,6 +292,22 @@ Paste primary selection. Copy selection to primary. . .TP +.B Alt+Up +Focus the terminal above +. +.TP +.B Alt+Down +Focus the terminal down +. +.TP +.B Alt+Left +Focus the terminal on the left +. +.TP +.B Alt+Right +Focus the terminal on the right +. +.TP .B Ctrl+Shift+c Copy current selection to clipboard. . diff --git a/src/bin/config.c b/src/bin/config.c index a80e434d..72e6a7f5 100644 --- a/src/bin/config.c +++ b/src/bin/config.c @@ -7,7 +7,7 @@ #include "col.h" #include "utils.h" -#define CONF_VER 15 +#define CONF_VER 16 #define LIM(v, min, max) {if (v >= max) v = max; else if (v <= min) v = min;} @@ -336,6 +336,10 @@ _add_default_keys(Config *config) ADD_KB("Home", 0, 1, 0, 0, "cmd_box"); ADD_KB("w", 0, 1, 0, 0, "copy_primary"); ADD_KB("Return", 0, 1, 0, 0, "paste_primary"); + ADD_KB("Up", 0, 1, 0, 0, "term_up"); + 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"); /* Ctrl-Shift- */ ADD_KB("Prior", 1, 0, 1, 0, "split_h"); @@ -619,7 +623,13 @@ config_load(const char *key) case 14: config->disable_focus_visuals = EINA_FALSE; /*pass through*/ - case CONF_VER: /* 15 */ + case 15: + _add_key(config, "Up", 0, 1, 0, 0, "term_up"); + _add_key(config, "Down", 0, 1, 0, 0, "term_down"); + _add_key(config, "Left", 0, 1, 0, 0, "term_left"); + _add_key(config, "Right", 0, 1, 0, 0, "term_right"); + /*pass through*/ + case CONF_VER: /* 16 */ config->version = CONF_VER; break; default: diff --git a/src/bin/keyin.c b/src/bin/keyin.c index 15ec8a0e..900d289a 100644 --- a/src/bin/keyin.c +++ b/src/bin/keyin.c @@ -366,6 +366,46 @@ cb_term_next(Evas_Object *termio_obj) return EINA_TRUE; } +static Eina_Bool +cb_term_up(Evas_Object *termio_obj) +{ + Term *term = termio_term_get(termio_obj); + if (!term) + return EINA_FALSE; + term_up(term); + return EINA_TRUE; +} + +static Eina_Bool +cb_term_down(Evas_Object *termio_obj) +{ + Term *term = termio_term_get(termio_obj); + if (!term) + return EINA_FALSE; + term_down(term); + return EINA_TRUE; +} + +static Eina_Bool +cb_term_left(Evas_Object *termio_obj) +{ + Term *term = termio_term_get(termio_obj); + if (!term) + return EINA_FALSE; + term_left(term); + return EINA_TRUE; +} + +static Eina_Bool +cb_term_right(Evas_Object *termio_obj) +{ + Term *term = termio_term_get(termio_obj); + if (!term) + return EINA_FALSE; + term_right(term); + return EINA_TRUE; +} + static Eina_Bool cb_term_new(Evas_Object *termio_obj) { @@ -645,8 +685,12 @@ static Shortcut_Action _actions[] = {"paste_clipboard", gettext_noop("Paste Clipboard buffer (ctrl+c/v)"), cb_paste_clipboard}, {"group", gettext_noop("Splits/Tabs"), NULL}, - {"term_prev", gettext_noop("Focus to the previous terminal"), cb_term_prev}, - {"term_next", gettext_noop("Focus to the next terminal"), cb_term_next}, + {"term_prev", gettext_noop("Focus the previous terminal"), cb_term_prev}, + {"term_next", gettext_noop("Focus the next terminal"), cb_term_next}, + {"term_up", gettext_noop("Focus the terminal above"), cb_term_up}, + {"term_down", gettext_noop("Focus the terminal below"), cb_term_down}, + {"term_left", gettext_noop("Focus the terminal on the left"), cb_term_left}, + {"term_right", gettext_noop("Focus the terminal on the right"), cb_term_right}, {"split_h", gettext_noop("Split horizontally (new below)"), cb_split_h}, {"split_v", gettext_noop("Split vertically (new on right)"), cb_split_v}, {"tab_new", gettext_noop("Create a new \"tab\""), cb_tab_new}, diff --git a/src/bin/term_container.h b/src/bin/term_container.h index 40b70905..1f392e8c 100644 --- a/src/bin/term_container.h +++ b/src/bin/term_container.h @@ -39,6 +39,10 @@ struct _Term_Container { Term *(*term_next)(const Term_Container *tc, const Term_Container *child); Term *(*term_prev)(const Term_Container *tc, const Term_Container *child); + Term *(*term_up)(const Term_Container *tc, const Term_Container *child); + Term *(*term_down)(const Term_Container *tc, const Term_Container *child); + Term *(*term_left)(const Term_Container *tc, const Term_Container *child); + Term *(*term_right)(const Term_Container *tc, const Term_Container *child); Term *(*term_first)(const Term_Container *tc); Term *(*term_last)(const Term_Container *tc); Term *(*focused_term_get)(const Term_Container *tc); diff --git a/src/bin/win.c b/src/bin/win.c index ce048d22..0c8893e2 100644 --- a/src/bin/win.c +++ b/src/bin/win.c @@ -296,6 +296,34 @@ _solo_term_prev(const Term_Container *tc, return tc->parent->term_prev(tc->parent, tc); } +static Term * +_solo_term_up(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_up(tc->parent, tc); +} + +static Term * +_solo_term_down(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_down(tc->parent, tc); +} + +static Term * +_solo_term_left(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_left(tc->parent, tc); +} + +static Term * +_solo_term_right(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_right(tc->parent, tc); +} + static Term * _solo_term_first(const Term_Container *tc) { @@ -449,6 +477,10 @@ _solo_new(Term *term, Win *wn) tc = (Term_Container*)solo; tc->term_next = _solo_term_next; tc->term_prev = _solo_term_prev; + tc->term_up = _solo_term_up; + tc->term_down = _solo_term_down; + tc->term_left = _solo_term_left; + tc->term_right = _solo_term_right; tc->term_first = _solo_term_first; tc->term_last = _solo_term_last; tc->focused_term_get = _solo_focused_term_get; @@ -785,6 +817,34 @@ _win_term_prev(const Term_Container *_tc EINA_UNUSED, return child->term_last(child); } +static Term * +_win_term_up(const Term_Container *_tc EINA_UNUSED, + const Term_Container *child EINA_UNUSED) +{ + return NULL; +} + +static Term * +_win_term_down(const Term_Container *_tc EINA_UNUSED, + const Term_Container *child EINA_UNUSED) +{ + return NULL; +} + +static Term * +_win_term_left(const Term_Container *_tc EINA_UNUSED, + const Term_Container *child EINA_UNUSED) +{ + return NULL; +} + +static Term * +_win_term_right(const Term_Container *_tc EINA_UNUSED, + const Term_Container *child EINA_UNUSED) +{ + return NULL; +} + static Term * _win_term_first(const Term_Container *tc) { @@ -1060,6 +1120,10 @@ win_new(const char *name, const char *role, const char *title, tc = (Term_Container*) wn; tc->term_next = _win_term_next; tc->term_prev = _win_term_prev; + tc->term_up = _win_term_up; + tc->term_down = _win_term_down; + tc->term_left = _win_term_left; + tc->term_right = _win_term_right; tc->term_first = _win_term_first; tc->term_last = _win_term_last; tc->focused_term_get = _win_focused_term_get; @@ -1173,6 +1237,66 @@ _split_term_prev(const Term_Container *tc, const Term_Container *child) return tc->parent->term_prev(tc->parent, tc); } +static Term * +_split_term_up(const Term_Container *tc, + const Term_Container *child) +{ + Split *split; + + assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); + split = (Split*) tc; + + if (child == split->tc2 && split->is_horizontal) + return split->tc1->term_last(split->tc1); + else + return tc->parent->term_up(tc->parent, tc); +} + +static Term * +_split_term_down(const Term_Container *tc, + const Term_Container *child) +{ + Split *split; + + assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); + split = (Split*) tc; + + if (child == split->tc1 && split->is_horizontal) + return split->tc2->term_first(split->tc2); + else + return tc->parent->term_down(tc->parent, tc); +} + +static Term * +_split_term_left(const Term_Container *tc, + const Term_Container *child) +{ + Split *split; + + assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); + split = (Split*) tc; + + if (child == split->tc2 && !split->is_horizontal) + return split->tc1->term_last(split->tc1); + else + return tc->parent->term_left(tc->parent, tc); +} + +static Term * +_split_term_right(const Term_Container *tc, + const Term_Container *child) +{ + Split *split; + + assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); + split = (Split*) tc; + + if (child == split->tc1 && !split->is_horizontal) + return split->tc2->term_first(split->tc2); + else + return tc->parent->term_right(tc->parent, tc); +} + static Term * _split_term_first(const Term_Container *tc) { @@ -1545,6 +1669,10 @@ _split_new(Term_Container *tc1, Term_Container *tc2, tc = (Term_Container*)split; tc->term_next = _split_term_next; tc->term_prev = _split_term_prev; + tc->term_up = _split_term_up; + tc->term_down = _split_term_down; + tc->term_left = _split_term_left; + tc->term_right = _split_term_right; tc->term_first = _split_term_first; tc->term_last = _split_term_last; tc->focused_term_get = _split_focused_term_get; @@ -2330,6 +2458,34 @@ _tabs_term_prev(const Term_Container *tc, const Term_Container *child) } } +static Term * +_tabs_term_up(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_up(tc->parent, tc); +} + +static Term * +_tabs_term_down(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_down(tc->parent, tc); +} + +static Term * +_tabs_term_left(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_left(tc->parent, tc); +} + +static Term * +_tabs_term_right(const Term_Container *tc, + const Term_Container *_child EINA_UNUSED) +{ + return tc->parent->term_right(tc->parent, tc); +} + static Term * _tabs_term_first(const Term_Container *tc) { @@ -2804,6 +2960,10 @@ _tabs_new(Term_Container *child, Term_Container *parent) tc = (Term_Container*)tabs; tc->term_next = _tabs_term_next; tc->term_prev = _tabs_term_prev; + tc->term_up = _tabs_term_up; + tc->term_down = _tabs_term_down; + tc->term_left = _tabs_term_left; + tc->term_right = _tabs_term_right; tc->term_first = _tabs_term_first; tc->term_last = _tabs_term_last; tc->focused_term_get = _tabs_focused_term_get; @@ -2975,32 +3135,100 @@ term_unfocus(Term *term) tc->unfocus(tc, tc); } -Term * -term_prev_get(const Term *term) -{ - Term_Container *tc = term->container; +enum term_to_direction { + TERM_TO_PREV, + TERM_TO_NEXT, + TERM_TO_UP, + TERM_TO_DOWN, + TERM_TO_LEFT, + TERM_TO_RIGHT, +}; - return tc->term_prev(tc, tc); -} - -void term_prev(Term *term) +static void +term_go_to(Term *from, enum term_to_direction dir) { Term *new_term, *focused_term; - Win *wn = term->wn; + Win *wn = from->wn; Term_Container *tc; tc = (Term_Container *) wn; focused_term = tc->focused_term_get(tc); if (!focused_term) - focused_term = term; + focused_term = from; tc = focused_term->container; - new_term = tc->term_prev(tc, tc); + + switch (dir) + { + case TERM_TO_PREV: + new_term = tc->term_prev(tc, tc); + break; + case TERM_TO_NEXT: + new_term = tc->term_next(tc, tc); + break; + case TERM_TO_UP: + new_term = tc->term_up(tc, tc); + break; + case TERM_TO_DOWN: + new_term = tc->term_down(tc, tc); + break; + case TERM_TO_LEFT: + new_term = tc->term_left(tc, tc); + break; + case TERM_TO_RIGHT: + new_term = tc->term_right(tc, tc); + break; + } + if (new_term && new_term != focused_term) _term_focus(new_term); /* TODO: get rid of it? */ - _term_miniview_check(term); + _term_miniview_check(from); +} + +void +term_prev(Term *term) +{ + term_go_to(term, TERM_TO_PREV); +} + +void +term_next(Term *term) +{ + term_go_to(term, TERM_TO_NEXT); +} + +void +term_up(Term *term) +{ + term_go_to(term, TERM_TO_UP); +} + +void +term_down(Term *term) +{ + term_go_to(term, TERM_TO_DOWN); +} + +void +term_left(Term *term) +{ + term_go_to(term, TERM_TO_LEFT); +} + +void +term_right(Term *term) +{ + term_go_to(term, TERM_TO_RIGHT); +} + +Term * +term_prev_get(const Term *term) +{ + Term_Container *tc = term->container; + + return tc->term_prev(tc, tc); } Term * @@ -3011,25 +3239,6 @@ term_next_get(const Term *term) return tc->term_next(tc, tc); } -void term_next(Term *term) -{ - Term *new_term, *focused_term; - Win *wn = term->wn; - Term_Container *tc; - - tc = (Term_Container*) wn; - - focused_term = tc->focused_term_get(tc); - if (!focused_term) - focused_term = term; - tc = focused_term->container; - new_term = tc->term_next(tc, tc); - if (new_term && new_term != focused_term) - _term_focus(new_term); - - /* TODO: get rid of it? */ - _term_miniview_check(term); -} static void _cb_popmedia_del(void *data, diff --git a/src/bin/win.h b/src/bin/win.h index 27ca09ed..5096175a 100644 --- a/src/bin/win.h +++ b/src/bin/win.h @@ -54,6 +54,11 @@ void term_next(Term *term); void term_prev(Term *term); Win * term_win_get(const Term *term); +void term_up(Term *term); +void term_down(Term *term); +void term_left(Term *term); +void term_right(Term *term); + void win_font_size_set(Win *wn, int new_size);