split your terminology man... split it! :)

SVN revision: 83090
This commit is contained in:
Carsten Haitzler 2013-01-22 15:01:53 +00:00
parent 1b69c6c544
commit a0ffffd42d
6 changed files with 802 additions and 69 deletions

2
README
View File

@ -52,6 +52,8 @@ Shift+Keypad-Plus = Font size up 1
Shift+Keypad-Minus = Font size down 1
Shift+Keypad-Multiply = Reset font size to 10
Shift+Keypad-Divide = Copy highlight to Clipboard (same as ctrl+c in gui apps)
Ctrl+PgUp = reserved later for multi-terms
Ctrl+PgDn = reserved later for multi-terms
Alt+Home = Enter command mode (enter commands to control terminology itself)
Command mode commands currently understood:

View File

@ -17,16 +17,6 @@ collections {
image: "pm_fill.png" COMP;
}
parts {
// other signals sent not handled here
// program { name: "focus_in";
// signal: "focus,in";
// source: "terminology";
// }
// program { name: "focus_out";
// signal: "focus,out";
// source: "terminology";
// }
////////////////////////////////////////////////////////////////////
// background handling
part { name: "shadow";
@ -167,6 +157,11 @@ collections {
offset: -1 0;
}
image.normal: "bg_glint.png";
color: 255 255 255 128;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
color: 255 255 255 255;
}
}
part { name: "shine";
@ -179,7 +174,26 @@ collections {
align: 0.5 0.0;
aspect: (255/120) (255/120);
aspect_preference: HORIZONTAL;
color: 255 255 255 128;
}
description { state: "focused" 0.0;
inherit: "default" 0.0;
color: 255 255 255 255;
}
}
program { name: "focus_in";
signal: "focus,in";
source: "terminology";
action: STATE_SET "focused" 0.0;
target: "glint";
target: "shine";
}
program { name: "focus_out";
signal: "focus,out";
source: "terminology";
action: STATE_SET "default" 0.0;
target: "glint";
target: "shine";
}
////////////////////////////////////////////////////////////////////

View File

@ -5,8 +5,10 @@
#include "options.h"
#include "about.h"
#include "termio.h"
#include "main.h"
static Evas_Object *ct_frame = NULL, *ct_box = NULL, *ct_over = NULL;
static Evas_Object *ct_frame = NULL, *ct_boxh = NULL, *ct_box = NULL;
static Evas_Object *ct_box2 = NULL, *ct_over = NULL;
static Eina_Bool ct_out = EINA_FALSE;
static Ecore_Timer *ct_del_timer = NULL;
static Evas_Object *saved_win = NULL;
@ -17,6 +19,11 @@ static Evas_Object *ct_win, *ct_bg, *ct_term;
static Eina_Bool
_cb_ct_del_delay(void *data __UNUSED__)
{
if (ct_over)
{
evas_object_del(ct_over);
ct_over = NULL;
}
evas_object_del(ct_frame);
ct_frame = NULL;
ct_del_timer = NULL;
@ -38,6 +45,24 @@ _cb_ct_paste(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
termio_paste_clipboard(data);
}
static void
_cb_ct_split_v(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
main_split_v(ct_win, ct_term);
}
static void
_cb_ct_split_h(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
main_split_h(ct_win, ct_term);
}
static void
_cb_ct_close(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
main_close(ct_win, ct_term);
}
static void
_cb_ct_options(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
@ -58,13 +83,43 @@ _cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void
controls_toggle(saved_win, saved_bg, data);
}
static void
_cb_saved_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
{
if ((obj == saved_win) || (obj == saved_bg) || (obj == ct_term))
{
if (ct_frame)
{
evas_object_del(ct_frame);
ct_frame = NULL;
}
if (ct_del_timer)
{
ecore_timer_del(ct_del_timer);
ct_del_timer = NULL;
}
if (ct_over)
{
evas_object_del(ct_over);
ct_over = NULL;
}
evas_object_event_callback_del(saved_win, EVAS_CALLBACK_DEL, _cb_saved_del);
evas_object_event_callback_del(saved_bg, EVAS_CALLBACK_DEL, _cb_saved_del);
evas_object_event_callback_del(ct_term, EVAS_CALLBACK_DEL, _cb_saved_del);
saved_win = NULL;
saved_bg = NULL;
ct_win = NULL;
ct_bg = NULL;
ct_term = NULL;
ct_out = EINA_FALSE;
}
}
void
controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
{
Evas_Object *o;
saved_win = win;
saved_bg = bg;
if (!ct_out)
{
if (options_active_get())
@ -80,12 +135,52 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Controls");
ct_box = o = elm_box_add(win);
ct_boxh = o = elm_box_add(win);
elm_box_horizontal_set(o, EINA_TRUE);
elm_object_content_set(ct_frame, o);
evas_object_show(o);
ct_box2 = o = elm_box_add(win);
elm_box_pack_end(ct_boxh, o);
evas_object_show(o);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "|");
elm_box_pack_end(ct_box2, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _cb_ct_split_v, NULL);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "-");
elm_box_pack_end(ct_box2, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _cb_ct_split_h, NULL);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "X");
elm_box_pack_end(ct_box2, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _cb_ct_close, NULL);
o = elm_separator_add(win);
evas_object_size_hint_weight_set(o, 0.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, 0.5, EVAS_HINT_FILL);
elm_separator_horizontal_set(o, EINA_FALSE);
elm_box_pack_end(ct_boxh, o);
evas_object_show(o);
ct_box = o = elm_box_add(win);
elm_box_pack_end(ct_boxh, o);
evas_object_show(o);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Copy");
elm_box_pack_end(ct_box, o);
@ -93,7 +188,7 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
evas_object_smart_callback_add(o, "clicked", _cb_ct_copy, term);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Paste");
elm_box_pack_end(ct_box, o);
@ -108,7 +203,7 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
evas_object_show(o);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Options");
elm_box_pack_end(ct_box, o);
@ -123,18 +218,18 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
evas_object_show(o);
o = elm_button_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "About");
elm_box_pack_end(ct_box, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _cb_ct_about, NULL);
edje_object_part_swallow(bg, "terminology.controls", ct_frame);
evas_object_show(ct_frame);
}
if (!ct_out)
{
edje_object_part_swallow(bg, "terminology.controls", ct_frame);
evas_object_show(ct_frame);
ct_over = o = evas_object_rectangle_add(evas_object_evas_get(win));
evas_object_color_set(o, 0, 0, 0, 0);
edje_object_part_swallow(bg, "terminology.dismiss", o);
@ -155,15 +250,42 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
}
}
else
{
if (ct_over)
{
evas_object_del(ct_over);
ct_over = NULL;
edje_object_signal_emit(bg, "controls,hide", "terminology");
}
edje_object_signal_emit(saved_bg, "controls,hide", "terminology");
ct_out = EINA_FALSE;
elm_object_focus_set(ct_frame, EINA_FALSE);
elm_object_focus_set(term, EINA_TRUE);
elm_object_focus_set(ct_term, EINA_TRUE);
if (ct_del_timer) ecore_timer_del(ct_del_timer);
ct_del_timer = ecore_timer_add(10.0, _cb_ct_del_delay, NULL);
ct_term = NULL;
ct_bg = NULL;
ct_win = NULL;
}
if (saved_win)
{
evas_object_event_callback_del(saved_win, EVAS_CALLBACK_DEL, _cb_saved_del);
evas_object_event_callback_del(saved_bg, EVAS_CALLBACK_DEL, _cb_saved_del);
evas_object_event_callback_del(ct_term, EVAS_CALLBACK_DEL, _cb_saved_del);
}
if (ct_out)
{
saved_win = win;
saved_bg = bg;
evas_object_event_callback_add(saved_win, EVAS_CALLBACK_DEL, _cb_saved_del, NULL);
evas_object_event_callback_add(saved_bg, EVAS_CALLBACK_DEL, _cb_saved_del, NULL);
evas_object_event_callback_add(ct_term, EVAS_CALLBACK_DEL, _cb_saved_del, NULL);
}
else
{
saved_win = NULL;
saved_bg = NULL;
ct_term = NULL;
ct_bg = NULL;
ct_win = NULL;
}
}

View File

@ -14,21 +14,25 @@
typedef struct _Win Win;
typedef struct _Term Term;
typedef struct _Split Split;
struct _Win
{
Evas_Object *win;
Evas_Object *conform;
Evas_Object *backbg;
// Evas_Object *table; // replace with whatever layout widget as needed
Evas_Object *table;
Eina_List *terms;
Split *split;
Config *config;
Eina_Bool focused;
Ecore_Job *size_job;
Eina_Bool focused : 1;
};
struct _Term
{
Win *wn;
Config *config;
Evas_Object *bg;
Evas_Object *term;
Evas_Object *media;
@ -36,9 +40,23 @@ struct _Term
Evas_Object *cmdbox;
Ecore_Timer *cmdbox_focus_timer;
Eina_List *popmedia_queue;
Eina_Bool focused;
Eina_Bool cmdbox_up;
Eina_Bool hold;
int step_x, step_y, min_w, min_h, req_w, req_h;
struct {
int x, y;
} down;
Eina_Bool focused : 1;
Eina_Bool cmdbox_up : 1;
Eina_Bool hold : 1;
};
struct _Split
{
Win *wn; // win this split belongs to
Split *parent; // the parent split or null if toplevel
Split *s1, *s2; // left/right or top/bottom child splits, null if leaf
Term *term; // if leaf node this is not null
Evas_Object *panes;
Eina_Bool horizontal : 1;
};
int _log_domain = -1;
@ -49,6 +67,312 @@ static Ecore_Timer *flush_timer = NULL;
static void _popmedia_queue_process(Term *term);
static void main_win_free(Win *wn);
static void main_term_free(Term *term);
static void main_term_bg_redo(Term *term);
static Term *main_term_new(Win *wn, Config *config, const char *cmd, Eina_Bool login_shell, const char *cd, int size_w, int size_h, Eina_Bool hold);
static void
_split_free(Split *sp)
{
if (sp->s1) _split_free(sp->s1);
if (sp->s2) _split_free(sp->s2);
if (sp->panes) evas_object_del(sp->panes);
free(sp);
}
static Split *
_split_split_find(Split *sp, Evas_Object *term)
{
Split *sp2;
if (sp->term)
{
if (sp->term->term == term) return sp;
}
if (sp->s1)
{
sp2 = _split_split_find(sp->s1, term);
if (sp2) return sp2;
}
if (sp->s2)
{
sp2 = _split_split_find(sp->s2, term);
if (sp2) return sp2;
}
return NULL;
}
static Split *
_split_find(Evas_Object *win, Evas_Object *term)
{
Win *wn;
Eina_List *l;
EINA_LIST_FOREACH(wins, l, wn)
{
if (wn->win == win) return _split_split_find(wn->split, term);
}
return NULL;
}
static void
_split_split(Split *sp, Eina_Bool horizontal)
{
Split *sp2;
Evas_Object *o;
if (!sp->term) return;
o = sp->panes = elm_panes_add(sp->wn->win);
elm_object_style_set(o, "flush");
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
sp->horizontal = horizontal;
elm_panes_horizontal_set(o, sp->horizontal);
sp2 = sp->s1 = calloc(1, sizeof(Split));
sp2->parent = sp;
sp2->wn = sp->wn;
sp2->term = sp->term;
if (!sp->parent) elm_table_unpack(sp->wn->table, sp->term->bg);
main_term_bg_redo(sp->term);
sp2 = sp->s2 = calloc(1, sizeof(Split));
sp2->parent = sp;
sp2->wn = sp->wn;
sp2->term = main_term_new(sp->wn, sp->wn->config,
NULL, EINA_FALSE, NULL,
80, 24, EINA_FALSE);
evas_object_data_set(sp2->term->term, "sizedone", sp2->term->term);
elm_object_part_content_set(sp->panes, "top", sp->s1->term->bg);
elm_object_part_content_set(sp->panes, "bottom", sp->s2->term->bg);
if (!sp->parent)
elm_table_pack(sp->wn->table, sp->panes, 0, 0, 1, 1);
else
{
if (sp == sp->parent->s1)
{
elm_object_part_content_unset(sp->parent->panes, "top");
elm_object_part_content_set(sp->parent->panes, "top", sp->panes);
}
else
{
elm_object_part_content_unset(sp->parent->panes, "bottom");
elm_object_part_content_set(sp->parent->panes, "bottom", sp->panes);
}
}
evas_object_show(sp->panes);
sp->term = NULL;
}
void
main_split_h(Evas_Object *win, Evas_Object *term)
{
Split *sp = _split_find(win, term);
if (!sp) return;
_split_split(sp, EINA_TRUE);
}
void
main_split_v(Evas_Object *win, Evas_Object *term)
{
Split *sp = _split_find(win, term);
if (!sp) return;
_split_split(sp, EINA_FALSE);
}
static void
_split_append(Split *sp, Eina_List **flat)
{
if (sp->term) *flat = eina_list_append(*flat, sp);
else
{
_split_append(sp->s1, flat);
_split_append(sp->s2, flat);
}
}
static Eina_List *
_split_flatten(Split *sp)
{
Eina_List *flat = NULL;
_split_append(sp, &flat);
return flat;
}
static Term *
_term_next_get(Term *termin)
{
Split *sp;
Eina_List *flat, *l;
sp = _split_find(termin->wn->win, termin->term);
if (!sp->parent) return NULL;
flat = _split_flatten(termin->wn->split);
if (!flat) return NULL;
l = eina_list_data_find_list(flat, sp);
if (!l)
{
eina_list_free(flat);
return NULL;
}
if (l->next)
{
sp = l->next->data;
eina_list_free(flat);
return sp->term;
}
sp = flat->data;
eina_list_free(flat);
return sp->term;
}
static Term *
_term_prev_get(Term *termin)
{
Split *sp;
Eina_List *flat, *l;
sp = _split_find(termin->wn->win, termin->term);
if (!sp->parent) return NULL;
flat = _split_flatten(termin->wn->split);
if (!flat) return NULL;
l = eina_list_data_find_list(flat, sp);
if (!l)
{
eina_list_free(flat);
return NULL;
}
if (l->prev)
{
sp = l->prev->data;
eina_list_free(flat);
return sp->term;
}
sp = eina_list_last_data_get(flat);
eina_list_free(flat);
return sp->term;
}
static void
_split_merge(Split *spp, Split *sp, const char *slot)
{
Evas_Object *o = NULL;
if (sp->term)
{
main_term_bg_redo(sp->term);
spp->term = sp->term;
sp->term = NULL;
o = spp->term->bg;
spp->s1 = NULL;
spp->s2 = NULL;
evas_object_del(spp->panes);
spp->panes = NULL;
if (spp->parent)
{
elm_object_part_content_unset(spp->parent->panes, slot);
elm_object_part_content_set(spp->parent->panes, slot, o);
}
else
elm_table_pack(spp->wn->table, o, 0, 0, 1, 1);
}
else
{
spp->s1 = sp->s1;
spp->s2 = sp->s2;
spp->s1->parent = spp;
spp->s2->parent = spp;
spp->horizontal = sp->horizontal;
o = sp->panes;
if (spp->parent)
{
elm_object_part_content_unset(spp->parent->panes, slot);
elm_object_part_content_set(spp->parent->panes, slot, o);
}
else
elm_table_pack(spp->wn->table, o, 0, 0, 1, 1);
evas_object_del(spp->panes);
spp->panes = o;
sp->s1 = NULL;
sp->s2 = NULL;
sp->panes = NULL;
}
_split_free(sp);
}
static void
_term_focus(Term *term)
{
Eina_List *l;
Term *term2;
EINA_LIST_FOREACH(term->wn->terms, l, term2)
{
if (term2 != term)
{
if (term2->focused)
{
term2->focused = EINA_FALSE;
edje_object_signal_emit(term2->bg, "focus,out", "terminology");
elm_object_focus_set(term2->term, EINA_FALSE);
}
}
}
term->focused = EINA_TRUE;
edje_object_signal_emit(term->bg, "focus,in", "terminology");
elm_object_focus_set(term->term, EINA_TRUE);
}
void
main_close(Evas_Object *win, Evas_Object *term)
{
Split *sp = _split_find(win, term);
Split *spp, *spkeep = NULL;
Term *termfoc = NULL;
const char *slot = "top";
if (!sp) return;
if (!sp->term) return;
spp = sp->parent;
if ((sp->term->focused) && (spp)) termfoc = _term_next_get(sp->term);
sp->wn->terms = eina_list_remove(sp->wn->terms, sp->term);
if (spp)
{
if (sp == spp->s2)
{
spkeep = spp->s1;
spp->s2 = NULL;
}
else
{
spkeep = spp->s2;
spp->s1 = NULL;
}
main_term_free(sp->term);
sp->term = NULL;
_split_free(sp);
if ((spp->parent) && (spp->parent->s2 == spp)) slot = "bottom";
_split_merge(spp, spkeep, slot);
if (termfoc) _term_focus(termfoc);
}
else
{
elm_table_unpack(sp->wn->table, sp->term->bg);
main_term_free(sp->term);
sp->term = NULL;
if (!sp->wn->terms) evas_object_del(sp->wn->win);
}
}
static Term *
main_win_focused_term_get(Win *wn)
@ -103,6 +427,161 @@ _cb_focus_out(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
elm_cache_all_flush();
}
static void
_cb_term_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event )
{
Evas_Event_Mouse_Down *ev = event;
Term *term = data;
Term *term2;
term2 = main_win_focused_term_get(term->wn);
if (term == term2) return;
if (ev->button == 1)
{
term->down.x = ev->canvas.x;
term->down.y = ev->canvas.y;
_term_focus(term);
}
}
static void
_cb_term_mouse_up(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
/*
Evas_Event_Mouse_Up *ev = event;
Term *term = data;
Term *term2;
term2 = main_win_focused_term_get(term->wn);
if (term == term2) return;
if (ev->button == 1)
{
int dx, dy, f;
dx = term->down.x - ev->canvas.x;
dy = term->down.y - ev->canvas.y;
f = elm_config_finger_size_get();
if ((f * f) > ((dx * dx) + (dy * dy)))
{
_term_focus(term);
}
}
*/
}
typedef struct _Sizeinfo Sizeinfo;
struct _Sizeinfo
{
int min_w, min_h;
int step_x, step_y;
int req_w, req_h;
int req;
};
static void
_split_size_walk(Split *sp, Sizeinfo *info)
{
Sizeinfo inforet = { 0, 0, 0, 0, 0, 0, 0 };
if (sp->term)
{
info->min_w = sp->term->min_w;
info->min_h = sp->term->min_h;
info->step_x = sp->term->step_x;
info->step_y = sp->term->step_y;
info->req_w = sp->term->req_w;
info->req_h = sp->term->req_h;
if (!evas_object_data_get(sp->term->term, "sizedone"))
{
evas_object_data_set(sp->term->term, "sizedone", sp->term->term);
info->req = 1;
}
}
else
{
Evas_Coord mw = 0, mh = 0;
info->min_w = 0;
info->min_h = 0;
info->req_w = 0;
info->req_h = 0;
evas_object_size_hint_min_get(sp->panes, &mw, &mh);
if (!sp->horizontal)
{
_split_size_walk(sp->s1, &inforet);
info->req |= inforet.req;
mw -= inforet.min_w;
if (info->req)
{
info->req_w += inforet.req_w;
info->req_h = inforet.req_h;
}
_split_size_walk(sp->s2, &inforet);
info->req |= inforet.req;
mw -= inforet.min_w;
if (info->req)
{
info->req_w += inforet.req_w;
info->req_h = inforet.req_h;
}
info->req_w += mw;
if (info->req) info->req_h += mh - inforet.min_h - inforet.step_y;
}
else
{
_split_size_walk(sp->s1, &inforet);
info->req |= inforet.req;
mh -= inforet.min_h;
if (info->req)
{
info->req_h += inforet.req_h;
info->req_w = inforet.req_w;
}
_split_size_walk(sp->s2, &inforet);
info->req |= inforet.req;
mh -= inforet.min_h;
if (info->req)
{
info->req_h += inforet.req_h;
info->req_w = inforet.req_w;
}
info->req_h += mh;
if (info->req) info->req_w += mw - inforet.min_w - inforet.step_x;
}
info->step_x = inforet.step_x;
info->step_y = inforet.step_y;
}
}
static void
_size_job(void *data)
{
Win *wn = data;
Sizeinfo info = { 0, 0, 0, 0, 0, 0, 0 };
Evas_Coord mw = 0, mh = 0;
wn->size_job = NULL;
_split_size_walk(wn->split, &info);
if (wn->split->panes)
evas_object_size_hint_min_get(wn->split->panes, &mw, &mh);
else
evas_object_size_hint_min_get(wn->split->term->bg, &mw, &mh);
elm_win_size_base_set(wn->win, mw - info.step_x, mh - info.step_y);
elm_win_size_step_set(wn->win, info.step_x, info.step_y);
evas_object_size_hint_min_set(wn->backbg, mw, mh);
if (info.req) evas_object_resize(wn->win, info.req_w, info.req_h);
}
static void
main_win_sizing_handle(Win *wn)
{
if (wn->size_job) ecore_job_del(wn->size_job);
_size_job(wn);
}
static void
_cb_size_hint(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
{
@ -114,15 +593,15 @@ _cb_size_hint(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event __UN
edje_object_size_min_calc(term->bg, &w, &h);
evas_object_size_hint_min_set(term->bg, w, h);
// XXX: this is wrong for a container with conform or multiple
// terminals inside a single window
elm_win_size_base_set(term->wn->win, w - mw, h - mh);
elm_win_size_step_set(term->wn->win, mw, mh);
if (!evas_object_data_get(obj, "sizedone"))
{
evas_object_resize(term->wn->win, w - mw + rw, h - mh + rh);
evas_object_data_set(obj, "sizedone", obj);
}
term->step_x = mw;
term->step_y = mh;
term->min_w = w - mw;
term->min_h = h - mh;
term->req_w = w - mw + rw;
term->req_h = w - mw + rh;
if (term->wn->size_job) ecore_job_del(term->wn->size_job);
term->wn->size_job = ecore_job_add(_size_job, term->wn);
}
static void
@ -153,14 +632,7 @@ _cb_exited(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
Term *term = data;
if (!term->hold)
{
Win *wn = term->wn;
wn->terms = eina_list_remove(wn->terms, term);
main_term_free(term);
if (!wn->terms) evas_object_del(wn->win);
}
if (!term->hold) main_close(term->wn->win, term->term);
}
static void
@ -364,6 +836,26 @@ _cb_command(void *data, Evas_Object *obj __UNUSED__, void *event)
}
}
static void
_cb_prev(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
Term *term = data;
Term *term2 = NULL;
if (term->focused) term2 = _term_prev_get(term);
if (term2) _term_focus(term2);
}
static void
_cb_next(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
{
Term *term = data;
Term *term2 = NULL;
if (term->focused) term2 = _term_next_get(term);
if (term2) _term_focus(term2);
}
static Eina_Bool
_cb_cmd_focus(void *data)
{
@ -579,12 +1071,14 @@ main_win_free(Win *wn)
{
main_term_free(term);
}
if (wn->split) _split_free(wn->split);
if (wn->win)
{
evas_object_event_callback_del_full(wn->win, EVAS_CALLBACK_DEL, _cb_del, wn);
evas_object_del(wn->win);
}
if (wn->config) config_del(wn->config);
if (wn->size_job) ecore_job_del(wn->size_job);
free(wn);
}
@ -629,6 +1123,12 @@ main_win_new(const char *name, const char *role,
elm_win_resize_object_add(wn->win, o);
evas_object_show(o);
wn->table = o = elm_table_add(wn->win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_content_set(wn->conform, o);
evas_object_show(o);
evas_object_smart_callback_add(wn->win, "focus,in", _cb_focus_in, wn);
evas_object_smart_callback_add(wn->win, "focus,out", _cb_focus_out, wn);
@ -639,13 +1139,57 @@ main_win_new(const char *name, const char *role,
static void
main_term_free(Term *term)
{
const char *s;
EINA_LIST_FREE(term->popmedia_queue, s)
{
eina_stringshare_del(s);
}
if (term->cmdbox_focus_timer)
{
ecore_timer_del(term->cmdbox_focus_timer);
term->cmdbox_focus_timer = NULL;
}
evas_object_del(term->term);
term->term = NULL;
evas_object_del(term->cmdbox);
term->cmdbox = NULL;
evas_object_del(term->bg);
term->bg = NULL;
if (term->popmedia) evas_object_del(term->popmedia);
term->popmedia = NULL;
if (term->media) evas_object_del(term->media);
term->media = NULL;
free(term);
}
static void
main_term_bg_redo(Term *term)
{
Evas_Object *o;
evas_object_del(term->bg);
term->bg = o = edje_object_add(evas_object_evas_get(term->wn->win));
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
theme_apply(o, term->config, "terminology/background");
theme_auto_reload_enable(o);
evas_object_show(o);
edje_object_signal_callback_add(o, "popmedia,done", "terminology",
_cb_popmedia_done, term);
edje_object_part_swallow(term->bg, "terminology.cmdbox", term->cmdbox);
termio_theme_set(term->term, term->bg);
edje_object_part_swallow(term->bg, "terminology.content", term->term);
if ((term->focused) && (term->wn->focused))
{
edje_object_signal_emit(term->bg, "focus,in", "terminology");
elm_object_focus_set(term->term, EINA_TRUE);
}
}
static Term *
main_term_new(Win *wn, Config *config, const char *cmd,
Eina_Bool login_shell, const char *cd,
@ -659,6 +1203,7 @@ main_term_new(Win *wn, Config *config, const char *cmd,
term->wn = wn;
term->hold = hold;
term->config = config;
term->bg = o = edje_object_add(evas_object_evas_get(wn->win));
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@ -713,8 +1258,15 @@ main_term_new(Win *wn, Config *config, const char *cmd,
evas_object_smart_callback_add(o, "popup", _cb_popup, term);
evas_object_smart_callback_add(o, "cmdbox", _cb_cmdbox, term);
evas_object_smart_callback_add(o, "command", _cb_command, term);
evas_object_smart_callback_add(o, "prev", _cb_prev, term);
evas_object_smart_callback_add(o, "next", _cb_next, term);
evas_object_show(o);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
_cb_term_mouse_down, term);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
_cb_term_mouse_up, term);
if (!wn->terms)
{
term->focused = EINA_TRUE;
@ -731,6 +1283,7 @@ main_ipc_new(Ipc_Instance *inst)
Win *wn;
Term *term;
Config *config;
Split *sp;
int pargc = 0, nargc, i;
char **pargv = NULL, **nargv = NULL, geom[256];
@ -964,9 +1517,14 @@ main_ipc_new(Ipc_Instance *inst)
}
else
{
elm_object_content_set(wn->conform, term->bg);
elm_table_pack(wn->table, term->bg, 0, 0, 1, 1);
_cb_size_hint(term, evas_object_evas_get(wn->win), term->term, NULL);
}
sp = wn->split = calloc(1, sizeof(Split));
sp->wn = wn;
sp->term = term;
main_trans_update(config);
main_media_update(config);
if (inst->pos)
@ -978,6 +1536,7 @@ main_ipc_new(Ipc_Instance *inst)
if (inst->y < 0) inst->y = screen_h + inst->y;
evas_object_move(wn->win, inst->x, inst->y);
}
main_win_sizing_handle(wn);
evas_object_show(wn->win);
if (inst->nowm)
ecore_evas_focus_set
@ -1130,6 +1689,7 @@ elm_main(int argc, char **argv)
Win *wn;
Term *term;
Config *config;
Split *sp;
int args, retval = EXIT_SUCCESS;
int remote_try = 0;
int pos_set = 0, size_set = 0;
@ -1414,8 +1974,8 @@ remote:
}
wn->config = config;
term = main_term_new(wn, config, cmd, login_shell, cd, size_w, size_h,
hold);
term = main_term_new(wn, config, cmd, login_shell, cd,
size_w, size_h, hold);
if (!term)
{
retval = EXIT_FAILURE;
@ -1423,9 +1983,14 @@ remote:
}
else
{
elm_object_content_set(wn->conform, term->bg);
elm_table_pack(wn->table, term->bg, 0, 0, 1, 1);
_cb_size_hint(term, evas_object_evas_get(wn->win), term->term, NULL);
}
sp = wn->split = calloc(1, sizeof(Split));
sp->wn = wn;
sp->term = term;
main_trans_update(config);
main_media_update(config);
if (pos_set)
@ -1437,6 +2002,7 @@ remote:
if (pos_y < 0) pos_y = screen_h + pos_y;
evas_object_move(wn->win, pos_x, pos_y);
}
main_win_sizing_handle(wn);
evas_object_show(wn->win);
if (nowm)
ecore_evas_focus_set

View File

@ -3,6 +3,10 @@
#include "config.h"
void main_split_h(Evas_Object *win, Evas_Object *term);
void main_split_v(Evas_Object *win, Evas_Object *term);
void main_close(Evas_Object *win, Evas_Object *term);
void main_trans_update(const Config *config);
void main_media_update(const Config *config);
void main_media_mute_update(const Config *config);

View File

@ -63,7 +63,7 @@ struct _Termio
Ecore_Timer *delayed_size_timer;
Ecore_Timer *link_do_timer;
Ecore_Job *mouse_move_job;
Evas_Object *win, *theme;
Evas_Object *win, *theme, *glayer;
Config *config;
Ecore_IMF_Context *imf;
Eina_Bool jump_on_change : 1;
@ -1010,6 +1010,21 @@ _smart_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
goto end;
}
}
if ((!evas_key_modifier_is_set(ev->modifiers, "Alt")) &&
(evas_key_modifier_is_set(ev->modifiers, "Control")) &&
(!evas_key_modifier_is_set(ev->modifiers, "Shift")))
{
if (!strcmp(ev->keyname, "Prior"))
{
evas_object_smart_callback_call(data, "prev", NULL);
goto end;
}
else if (!strcmp(ev->keyname, "Next"))
{
evas_object_smart_callback_call(data, "next", NULL);
goto end;
}
}
if (sd->jump_on_keypress)
{
if (!_is_modifier(ev->key))
@ -1797,6 +1812,7 @@ _smart_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__
}
else if (ev->button == 3)
{
elm_object_focus_set(data, EINA_TRUE);
evas_object_smart_callback_call(data, "options", NULL);
}
}
@ -1806,7 +1822,7 @@ _smart_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
{
Evas_Event_Mouse_Up *ev = event;
Termio *sd;
int cx, cy;
int cx, cy, dx, dy, f;
sd = evas_object_smart_data_get(data);
if (!sd) return;
@ -2302,6 +2318,10 @@ _smart_del(Evas_Object *obj)
if (sd->font.name) eina_stringshare_del(sd->font.name);
if (sd->pty) termpty_free(sd->pty);
if (sd->link.string) free(sd->link.string);
if (sd->glayer) evas_object_del(sd->glayer);
if (sd->win)
evas_object_event_callback_del_full(sd->win, EVAS_CALLBACK_DEL,
_win_obj_del, obj);
EINA_LIST_FREE(sd->link.objs, o) evas_object_del(o);
_compose_seq_reset(sd);
sd->cur.obj = NULL;
@ -2314,6 +2334,8 @@ _smart_del(Evas_Object *obj)
sd->font.name = NULL;
sd->pty = NULL;
sd->imf = NULL;
sd->win = NULL;
sd->glayer = NULL;
ecore_imf_shutdown();
termpty_shutdown();
@ -2502,7 +2524,7 @@ termio_add(Evas_Object *parent, Config *config, const char *cmd, Eina_Bool login
_termio_config_set(obj, config);
g = elm_gesture_layer_add(parent);
sd->glayer = g = elm_gesture_layer_add(parent);
elm_gesture_layer_attach(g, sd->event);
elm_gesture_layer_cb_set(g, ELM_GESTURE_N_LONG_TAPS,
@ -2569,8 +2591,7 @@ termio_theme_set(Evas_Object *obj, Evas_Object *theme)
{
Termio *sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (theme)
sd->theme = theme;
if (theme) sd->theme = theme;
}
Evas_Object *
@ -2578,7 +2599,6 @@ termio_theme_get(Evas_Object *obj)
{
Termio *sd = evas_object_smart_data_get(obj);
if (!sd) return NULL;
return sd->theme;
}
@ -2602,6 +2622,8 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y)
cells = termpty_cellrow_get(sd->pty, y, &w);
if (!cells) continue;
if (w > sd->grid.w) w = sd->grid.w;
if (c1x >= w) continue;
if (c2x >= w) c2x = w - 1;
start_x = c1x;
end_x = c2x;
if (c1y != c2y)
@ -2745,11 +2767,14 @@ termio_config_update(Evas_Object *obj)
termpty_backscroll_set(sd->pty, sd->config->scrollback);
sd->scroll = 0;
if (evas_object_focus_get(obj))
{
edje_object_signal_emit(sd->cur.obj, "focus,out", "terminology");
if (sd->config->disable_cursor_blink)
edje_object_signal_emit(sd->cur.obj, "focus,in,noblink", "terminology");
else
edje_object_signal_emit(sd->cur.obj, "focus,in", "terminology");
}
evas_object_scale_set(sd->grid.obj, elm_config_scale_get());
evas_object_textgrid_font_set(sd->grid.obj, sd->font.name, sd->font.size);