summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2015-03-22 18:17:16 +0100
committerBoris Faure <billiob@gmail.com>2015-04-23 20:07:59 +0200
commit2228945f2ce29c12d98890498c61e493171d5c55 (patch)
treecce58829d900d2671c7150f869c0bab7e8911da3 /src
parentbe62d87f89e5e0ada3d8cbfe3dd091eeb9b45391 (diff)
refactor win.c to use the Term_Container abstraction
Diffstat (limited to 'src')
-rw-r--r--src/bin/controls.c4
-rw-r--r--src/bin/main.c19
-rw-r--r--src/bin/sel.c84
-rw-r--r--src/bin/sel.h5
-rw-r--r--src/bin/term_container.h61
-rw-r--r--src/bin/win.c3315
-rw-r--r--src/bin/win.h4
7 files changed, 2187 insertions, 1305 deletions
diff --git a/src/bin/controls.c b/src/bin/controls.c
index 365cd3a..1640073 100644
--- a/src/bin/controls.c
+++ b/src/bin/controls.c
@@ -76,13 +76,13 @@ _cb_ct_new(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EIN
76static void 76static void
77_cb_ct_split_v(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 77_cb_ct_split_v(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
78{ 78{
79 main_split_v(ct_win, ct_term, NULL); 79 split_vertically(ct_win, ct_term, NULL);
80} 80}
81 81
82static void 82static void
83_cb_ct_split_h(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 83_cb_ct_split_h(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
84{ 84{
85 main_split_h(ct_win, ct_term, NULL); 85 split_horizontally(ct_win, ct_term, NULL);
86} 86}
87 87
88static void 88static void
diff --git a/src/bin/main.c b/src/bin/main.c
index 6eca428..2912d65 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -291,12 +291,9 @@ main_ipc_new(Ipc_Instance *inst)
291 free(nargv); 291 free(nargv);
292 return; 292 return;
293 } 293 }
294 else
295 {
296 win_term_swallow(wn, term);
297 }
298 294
299 win_add_split(wn, term); 295 if (win_term_set(wn, term) < 0)
296 return;
300 297
301 main_trans_update(config); 298 main_trans_update(config);
302 main_media_update(config); 299 main_media_update(config);
@@ -866,13 +863,13 @@ remote:
866 retval = EXIT_FAILURE; 863 retval = EXIT_FAILURE;
867 goto end; 864 goto end;
868 } 865 }
869 else 866
867 if (win_term_set(wn, term) < 0)
870 { 868 {
871 win_term_swallow(wn, term); 869 retval = EXIT_FAILURE;
870 goto end;
872 } 871 }
873 872
874 win_add_split(wn, term);
875
876 main_trans_update(config); 873 main_trans_update(config);
877 main_media_update(config); 874 main_media_update(config);
878 win_sizing_handle(wn); 875 win_sizing_handle(wn);
@@ -890,14 +887,14 @@ remote:
890 if (startup_split[i] == 'v') 887 if (startup_split[i] == 'v')
891 { 888 {
892 pch = eina_list_nth(cmds_list, 1); 889 pch = eina_list_nth(cmds_list, 1);
893 main_split_v(win_evas_object_get(term_win_get(next)), 890 split_vertically(win_evas_object_get(term_win_get(next)),
894 main_term_evas_object_get(next), pch); 891 main_term_evas_object_get(next), pch);
895 cmds_list = eina_list_remove(cmds_list, pch); 892 cmds_list = eina_list_remove(cmds_list, pch);
896 } 893 }
897 else if (startup_split[i] == 'h') 894 else if (startup_split[i] == 'h')
898 { 895 {
899 pch = eina_list_nth(cmds_list, 1); 896 pch = eina_list_nth(cmds_list, 1);
900 main_split_h(win_evas_object_get(term_win_get(next)), 897 split_horizontally(win_evas_object_get(term_win_get(next)),
901 main_term_evas_object_get(next), pch); 898 main_term_evas_object_get(next), pch);
902 cmds_list = eina_list_remove(cmds_list, pch); 899 cmds_list = eina_list_remove(cmds_list, pch);
903 } 900 }
diff --git a/src/bin/sel.c b/src/bin/sel.c
index 9f5244a..0da8e45 100644
--- a/src/bin/sel.c
+++ b/src/bin/sel.c
@@ -6,7 +6,7 @@
6#include "sel.h" 6#include "sel.h"
7#include "config.h" 7#include "config.h"
8#include "utils.h" 8#include "utils.h"
9#include "termio.h" 9#include "term_container.h"
10 10
11typedef struct _Sel Sel; 11typedef struct _Sel Sel;
12typedef struct _Entry Entry; 12typedef struct _Entry Entry;
@@ -41,7 +41,8 @@ struct _Sel
41 41
42struct _Entry 42struct _Entry
43{ 43{
44 Evas_Object *obj, *bg, *termio; 44 Evas_Object *obj, *bg;
45 Term_Container *tc;
45 unsigned char selected : 1; 46 unsigned char selected : 1;
46 unsigned char selected_before : 1; 47 unsigned char selected_before : 1;
47 unsigned char selected_orig : 1; 48 unsigned char selected_orig : 1;
@@ -476,39 +477,40 @@ _label_redo(Entry *en)
476{ 477{
477 const char *s; 478 const char *s;
478 479
479 if (!en->obj) return; 480 if (!en->obj || !en->tc)
480 if (!en->termio) return; 481 return;
481 s = termio_title_get(en->termio); 482 s = en->tc->title;
482 if (!s) s = termio_icon_name_get(en->termio); 483 if (!s)
483 if (s) edje_object_part_text_set(en->bg, "terminology.label", s); 484 s = "Terminology";
485 edje_object_part_text_set(en->bg, "terminology.label", s);
484} 486}
485 487
486static void 488void
487_title_cb(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) 489sel_entry_title_set(void *entry, const char *title)
488{ 490{
489 _label_redo(data); 491 Entry *en = entry;
490}
491 492
492static void 493 edje_object_part_text_set(en->bg, "terminology.label", title);
493_icon_cb(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED)
494{
495 _label_redo(data);
496} 494}
497 495
498static void 496void
499_bell_cb(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) 497sel_entry_close(void *data)
500{ 498{
501 Entry *en = data; 499 Entry *en = data;
502 edje_object_signal_emit(en->bg, "bell", "terminology"); 500
501 en->tc = NULL;
503} 502}
504 503
505static void 504void
506_entry_termio_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) 505sel_entry_update(void *data)
507{ 506{
508 Entry *en = data; 507 Entry *en = data;
509 if (en->termio) evas_object_event_callback_del_full 508
510 (en->termio, EVAS_CALLBACK_DEL, _entry_termio_del_cb, en); 509 en->tc = evas_object_data_get(en->obj, "tc");
511 en->termio = NULL; 510 if (en->tc)
511 {
512 _label_redo(en);
513 }
512} 514}
513 515
514static void 516static void
@@ -518,10 +520,9 @@ _entry_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
518 if (en->obj) evas_object_event_callback_del_full 520 if (en->obj) evas_object_event_callback_del_full
519 (en->obj, EVAS_CALLBACK_DEL, _entry_del_cb, en); 521 (en->obj, EVAS_CALLBACK_DEL, _entry_del_cb, en);
520 en->obj = NULL; 522 en->obj = NULL;
523 /*
521 if (en->termio) 524 if (en->termio)
522 { 525 {
523 evas_object_event_callback_del_full(en->termio, EVAS_CALLBACK_DEL,
524 _entry_termio_del_cb, en);
525 evas_object_smart_callback_del_full(en->termio, "title,change", 526 evas_object_smart_callback_del_full(en->termio, "title,change",
526 _title_cb, en); 527 _title_cb, en);
527 evas_object_smart_callback_del_full(en->termio, "icon,change", 528 evas_object_smart_callback_del_full(en->termio, "icon,change",
@@ -530,6 +531,7 @@ _entry_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
530 _bell_cb, en); 531 _bell_cb, en);
531 en->termio = NULL; 532 en->termio = NULL;
532 } 533 }
534 */
533} 535}
534 536
535static void 537static void
@@ -562,17 +564,6 @@ _smart_del(Evas_Object *obj)
562 if (sd->autozoom_timeout) ecore_timer_del(sd->autozoom_timeout); 564 if (sd->autozoom_timeout) ecore_timer_del(sd->autozoom_timeout);
563 EINA_LIST_FREE(sd->items, en) 565 EINA_LIST_FREE(sd->items, en)
564 { 566 {
565 if (en->termio)
566 {
567 evas_object_event_callback_del_full(en->termio, EVAS_CALLBACK_DEL,
568 _entry_termio_del_cb, en);
569 evas_object_smart_callback_del_full(en->termio, "title,change",
570 _title_cb, en);
571 evas_object_smart_callback_del_full(en->termio, "icon,change",
572 _icon_cb, en);
573 evas_object_smart_callback_del_full(en->termio, "bell",
574 _bell_cb, en);
575 }
576 if (en->obj) evas_object_event_callback_del_full 567 if (en->obj) evas_object_event_callback_del_full
577 (en->obj, EVAS_CALLBACK_DEL, _entry_del_cb, en); 568 (en->obj, EVAS_CALLBACK_DEL, _entry_del_cb, en);
578 if (en->obj) evas_object_del(en->obj); 569 if (en->obj) evas_object_del(en->obj);
@@ -669,12 +660,13 @@ sel_add(Evas_Object *parent)
669 return obj; 660 return obj;
670} 661}
671 662
672void 663void *
673sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Bool bell, Config *config) 664sel_entry_add(Evas_Object *obj, Evas_Object *entry,
665 Eina_Bool selected, Eina_Bool bell, Config *config)
674{ 666{
675 Sel *sd = evas_object_smart_data_get(obj); 667 Sel *sd = evas_object_smart_data_get(obj);
676 Entry *en = calloc(1, sizeof(Entry)); 668 Entry *en = calloc(1, sizeof(Entry));
677 if (!en) return; 669 if (!en) return NULL;
678 sd->items = eina_list_append(sd->items, en); 670 sd->items = eina_list_append(sd->items, en);
679 sd->config = config; 671 sd->config = config;
680 en->obj = entry; 672 en->obj = entry;
@@ -703,21 +695,15 @@ sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Boo
703 edje_object_message_signal_process(en->bg); 695 edje_object_message_signal_process(en->bg);
704 } 696 }
705 sd->interp = 1.0; 697 sd->interp = 1.0;
706 en->termio = evas_object_data_get(en->obj, "termio"); 698 en->tc = evas_object_data_get(en->obj, "tc");
707 if (en->termio) 699 if (en->tc)
708 { 700 {
709 evas_object_smart_callback_add(en->termio, "title,change",
710 _title_cb, en);
711 evas_object_smart_callback_add(en->termio, "icon,change",
712 _icon_cb, en);
713 evas_object_smart_callback_add(en->termio, "bell",
714 _bell_cb, en);
715 _label_redo(en); 701 _label_redo(en);
716 evas_object_event_callback_add(en->termio, EVAS_CALLBACK_DEL,
717 _entry_termio_del_cb, en);
718 } 702 }
719 evas_object_event_callback_add(en->obj, EVAS_CALLBACK_DEL, 703 evas_object_event_callback_add(en->obj, EVAS_CALLBACK_DEL,
720 _entry_del_cb, en); 704 _entry_del_cb, en);
705
706 return en;
721} 707}
722 708
723void 709void
diff --git a/src/bin/sel.h b/src/bin/sel.h
index 724674d..f01f545 100644
--- a/src/bin/sel.h
+++ b/src/bin/sel.h
@@ -4,7 +4,10 @@
4#include "config.h" 4#include "config.h"
5 5
6Evas_Object *sel_add(Evas_Object *parent); 6Evas_Object *sel_add(Evas_Object *parent);
7void sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Bool bell, Config *config); 7void *sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Bool bell, Config *config);
8void sel_entry_title_set(void *entry, const char *title);
9void sel_entry_close(void *entry);
10void sel_entry_update(void *entry);
8void sel_go(Evas_Object *obj); 11void sel_go(Evas_Object *obj);
9void sel_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool keep_before); 12void sel_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool keep_before);
10void sel_zoom(Evas_Object *obj, double zoom); 13void sel_zoom(Evas_Object *obj, double zoom);
diff --git a/src/bin/term_container.h b/src/bin/term_container.h
new file mode 100644
index 0000000..cd4059f
--- /dev/null
+++ b/src/bin/term_container.h
@@ -0,0 +1,61 @@
1#ifndef _TERM_CONTAINER_H__
2#define _TERM_CONTAINER_H__ 1
3
4
5typedef struct _Term_Container Term_Container;
6typedef struct _Term Term;
7typedef struct _Win Win;
8typedef struct _Sizeinfo Sizeinfo;
9
10struct _Sizeinfo
11{
12 int min_w;
13 int min_h;
14 int step_x;
15 int step_y;
16 int req_w;
17 int req_h;
18 int bg_min_w;
19 int bg_min_h;
20 int req;
21};
22
23typedef enum _Term_Container_Type
24{
25 TERM_CONTAINER_TYPE_UNKNOWN,
26 TERM_CONTAINER_TYPE_SOLO,
27 TERM_CONTAINER_TYPE_SPLIT,
28 TERM_CONTAINER_TYPE_TABS,
29 TERM_CONTAINER_TYPE_WIN
30} Term_Container_Type;
31
32struct _Term_Container {
33 Term_Container_Type type;
34 Term_Container *parent;
35 Win *wn;
36 Evas_Object *selector_img;
37 Eina_Bool is_focused;
38 const char *title;
39
40 Term *(*term_next)(Term_Container *tc, Term_Container *child);
41 Term *(*term_prev)(Term_Container *tc, Term_Container *child);
42 Term *(*term_first)(Term_Container *tc);
43 Term *(*term_last)(Term_Container *tc);
44 Term *(*focused_term_get)(Term_Container *tc);
45 Evas_Object* (*get_evas_object)(Term_Container *container);
46 Term *(*find_term_at_coords)(Term_Container *container,
47 Evas_Coord mx, Evas_Coord my);
48 void (*split)(Term_Container *tc, Term_Container *child,
49 const char *cmd, Eina_Bool is_horizontal);
50 void (*size_eval)(Term_Container *container, Sizeinfo *info);
51 void (*swallow)(Term_Container *container, Term_Container *orig,
52 Term_Container *new_child);
53 void (*focus)(Term_Container *tc, Term_Container *relative);
54 void (*unfocus)(Term_Container *tc, Term_Container *relative);
55 void (*set_title)(Term_Container *tc, Term_Container *child, const char *title);
56 void (*bell)(Term_Container *tc, Term_Container *child);
57 void (*close)(Term_Container *container, Term_Container *child);
58 void (*update)(Term_Container *tc);
59};
60
61#endif
diff --git a/src/bin/win.c b/src/bin/win.c
index 0f1840b..5f4425f 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -1,3 +1,4 @@
1#include <assert.h>
1#include <Elementary.h> 2#include <Elementary.h>
2#include "win.h" 3#include "win.h"
3#include "termcmd.h" 4#include "termcmd.h"
@@ -12,6 +13,7 @@
12#include "dbus.h" 13#include "dbus.h"
13#include "sel.h" 14#include "sel.h"
14#include "controls.h" 15#include "controls.h"
16#include "term_container.h"
15 17
16#if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 8) 18#if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 8)
17 #define PANES_TOP "left" 19 #define PANES_TOP "left"
@@ -39,6 +41,7 @@ struct _Term
39 Win *wn; 41 Win *wn;
40 Config *config; 42 Config *config;
41 43
44 Term_Container *container;
42 Evas_Object *bg; 45 Evas_Object *bg;
43 Evas_Object *base; 46 Evas_Object *base;
44 Evas_Object *termio; 47 Evas_Object *termio;
@@ -58,7 +61,6 @@ struct _Term
58 int x, y; 61 int x, y;
59 } down; 62 } down;
60 int refcnt; 63 int refcnt;
61 unsigned char focused : 1;
62 unsigned char hold : 1; 64 unsigned char hold : 1;
63 unsigned char unswallowed : 1; 65 unsigned char unswallowed : 1;
64 unsigned char missed_bell : 1; 66 unsigned char missed_bell : 1;
@@ -66,10 +68,47 @@ struct _Term
66 unsigned char popmedia_deleted : 1; 68 unsigned char popmedia_deleted : 1;
67}; 69};
68 70
71typedef struct _Solo Solo;
72typedef struct _Tabs Tabs;
73
74struct _Solo {
75 Term_Container tc;
76 Term *term;
77};
78
79typedef struct _Tab_Item Tab_Item;
80struct _Tab_Item {
81 Term_Container *tc;
82 Evas_Object *obj;
83 void *selector_entry;
84};
85
86struct _Tabs {
87 Term_Container tc;
88 Evas_Object *selector;
89 Evas_Object *selector_bg;
90 Eina_List *tabs; // Tab_Item
91 Tab_Item *current;
92};
93
94struct _Split
95{
96 Term_Container tc;
97 Term_Container *tc1, *tc2; // left/right or top/bottom child splits, null if leaf
98 Evas_Object *panes;
99 Term_Container *last_focus;
100
101 unsigned char is_horizontal : 1;
102};
103
104
69 105
70 106
71struct _Win 107struct _Win
72{ 108{
109 Term_Container tc;
110
111 Term_Container *child;
73 Evas_Object *win; 112 Evas_Object *win;
74 Evas_Object *conform; 113 Evas_Object *conform;
75 Evas_Object *backbg; 114 Evas_Object *backbg;
@@ -85,130 +124,326 @@ struct _Win
85 unsigned char cmdbox_up : 1; 124 unsigned char cmdbox_up : 1;
86}; 125};
87 126
88struct _Split
89{
90 Win *wn; // win this split belongs to
91 Split *parent; // the parent split or null if toplevel
92 Split *s1, *s2; // left/right or top/bottom child splits, null if leaf
93 Term *term; // if leaf node this is not null - the CURRENT term from terms list
94 Eina_List *terms; // list of terms in the "tabs"
95 Evas_Object *panes; // null if a leaf node
96 Evas_Object *sel; // multi "tab" selector is active
97 Evas_Object *sel_bg; // multi "tab" selector wrapper edje obj for styling
98 unsigned char horizontal : 1;
99};
100
101/* }}} */ 127/* }}} */
102static Eina_List *wins = NULL; 128static Eina_List *wins = NULL;
103 129
104 130static Eina_Bool _win_is_focused(Win *wn);
105static void _term_resize_track_start(Split *sp); 131static Eina_Bool _term_is_focused(Term *term);
106static void _split_tabcount_update(Split *sp, Term *tm); 132static Term_Container *_solo_new(Term *term, Win *wn);
107static Term * win_focused_term_get(Win *wn); 133static Term_Container *_split_new(Term_Container *tc1, Term_Container *tc2, Eina_Bool is_horizontal);
108static Split * _split_find(Evas_Object *win, Evas_Object *term, Term **ptm); 134static Term_Container *_tabs_new(Term_Container *child, Term_Container *parent);
109static void _term_focus(Term *term); 135static void _term_focus(Term *term, Eina_Bool force);
110static void term_free(Term *term); 136static void _term_free(Term *term);
111static void _split_free(Split *sp);
112static void _sel_restore(Split *sp);
113static void _sel_go(Split *sp, Term *term);
114static void _term_resize_track_stop(Split *sp);
115static void _split_merge(Split *spp, Split *sp, const char *slot);
116static void _term_focus_show(Split *sp, Term *term);
117static void _main_term_bg_redo(Term *term);
118static void _term_media_update(Term *term, const Config *config); 137static void _term_media_update(Term *term, const Config *config);
119static void _term_miniview_check(Term *term); 138static void _term_miniview_check(Term *term);
120static void _popmedia_queue_process(Term *term); 139static void _popmedia_queue_process(Term *term);
140static void _cb_size_hint(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED);
141static void _tab_new_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
142static Tab_Item* tab_item_new(Tabs *tabs, Term_Container *child);
143static void _tabs_refresh(Tabs *tabs);
121 144
122void 145
123win_add_split(Win *wn, Term *term) 146/* {{{ Solo */
147
148static Evas_Object *
149_solo_get_evas_object(Term_Container *container)
124{ 150{
125 Split *sp; 151 Solo *solo;
152 assert (container->type == TERM_CONTAINER_TYPE_SOLO);
153 solo = (Solo*)container;
126 154
127 sp = wn->split = calloc(1, sizeof(Split)); 155 return solo->term->bg;
128 sp->wn = wn;
129 sp->term = term;
130 sp->terms = eina_list_append(sp->terms, sp->term);
131 _term_resize_track_start(sp);
132 _split_tabcount_update(sp, sp->term);
133} 156}
134 157
135static Term * 158static Term *
136_find_term_under_mouse(Win *wn) 159_solo_focused_term_get(Term_Container *container)
137{ 160{
138 Evas_Coord mx, my; 161 Solo *solo;
139 Split *sp; 162 assert (container->type == TERM_CONTAINER_TYPE_SOLO);
163 solo = (Solo*)container;
140 164
141 evas_pointer_canvas_xy_get(evas_object_evas_get(wn->win), &mx, &my); 165 return container->is_focused ? solo->term : NULL;
166}
142 167
143 sp = wn->split; 168static Term *
144 while (sp) 169_solo_find_term_at_coords(Term_Container *tc,
170 Evas_Coord mx EINA_UNUSED,
171 Evas_Coord my EINA_UNUSED)
172{
173 Solo *solo;
174 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
175 solo = (Solo*) tc;
176
177 return solo->term;
178}
179
180static void
181_solo_size_eval(Term_Container *container, Sizeinfo *info)
182{
183 Term *term;
184 int mw = 0, mh = 0;
185 Solo *solo;
186 assert (container->type == TERM_CONTAINER_TYPE_SOLO);
187 solo = (Solo*)container;
188
189 term = solo->term;
190
191 info->min_w = term->min_w;
192 info->min_h = term->min_h;
193 info->step_x = term->step_x;
194 info->step_y = term->step_y;
195 info->req_w = term->req_w;
196 info->req_h = term->req_h;
197 if (!evas_object_data_get(term->termio, "sizedone"))
145 { 198 {
146 if (sp->term) 199 evas_object_data_set(term->termio, "sizedone", term->termio);
200 info->req = 1;
201 }
202 evas_object_size_hint_min_get(term->bg, &mw, &mh);
203 info->bg_min_w = mw;
204 info->bg_min_h = mh;
205}
206
207static void
208_solo_close(Term_Container *tc, Term_Container *child EINA_UNUSED)
209{
210 tc->parent->close(tc->parent, tc);
211
212 eina_stringshare_del(tc->title);
213
214 free(tc);
215}
216
217static void
218_solo_tabs_new(Term_Container *tc)
219{
220 if (tc->parent->type != TERM_CONTAINER_TYPE_TABS)
221 _tabs_new(tc, tc->parent);
222 _tab_new_cb(tc->parent, NULL, NULL);
223}
224
225static void
226_solo_split(Term_Container *tc, Term_Container *child EINA_UNUSED,
227 const char *cmd, Eina_Bool is_horizontal)
228{
229 tc->parent->split(tc->parent, tc, cmd, is_horizontal);
230}
231
232static Term *
233_solo_term_next(Term_Container *tc, Term_Container *child EINA_UNUSED)
234{
235 return tc->parent->term_next(tc->parent, tc);
236}
237
238static Term *
239_solo_term_prev(Term_Container *tc, Term_Container *child EINA_UNUSED)
240{
241 return tc->parent->term_prev(tc->parent, tc);
242}
243
244static Term *
245_solo_term_first(Term_Container *tc)
246{
247 Solo *solo;
248 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
249 solo = (Solo*) tc;
250 return solo->term;
251}
252
253static Term *
254_solo_term_last(Term_Container *tc)
255{
256 Solo *solo;
257 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
258 solo = (Solo*) tc;
259 return solo->term;
260}
261
262static void
263_solo_set_title(Term_Container *tc, Term_Container *child EINA_UNUSED,
264 const char *title)
265{
266 eina_stringshare_del(tc->title);
267 tc->title = eina_stringshare_add(title);
268 tc->parent->set_title(tc->parent, tc, title);
269}
270
271static void
272_solo_bell(Term_Container *tc, Term_Container *child EINA_UNUSED)
273{
274 Solo *solo;
275 Term *term;
276
277 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
278 solo = (Solo*) tc;
279 term = solo->term;
280
281 if (tc->is_focused)
282 return;
283 term->missed_bell = EINA_TRUE;
284
285 if (!tc->wn->config->disable_visual_bell)
286 {
287 edje_object_signal_emit(term->bg, "bell", "terminology");
288 edje_object_signal_emit(term->base, "bell", "terminology");
289 if (tc->wn->config->bell_rings)
147 { 290 {
148 return sp->term; 291 edje_object_signal_emit(term->bg, "bell,ring", "terminology");
292 edje_object_signal_emit(term->base, "bell,ring", "terminology");
149 } 293 }
150 else 294 }
151 { 295 tc->parent->bell(tc->parent, tc);
152 Evas_Coord ox, oy, ow, oh; 296}
153 Evas_Object *o1 = sp->s1->panes ? sp->s1->panes : sp->s1->term->base;
154 297
155 evas_object_geometry_get(o1, &ox, &oy, &ow, &oh); 298static void
156 if (ELM_RECTS_INTERSECT(ox, oy, ow, oh, mx, my, 1, 1)) 299_solo_unfocus(Term_Container *tc, Term_Container *relative)
157 { 300{
158 sp = sp->s1; 301 Solo *solo;
159 } 302 Term *term;
160 else 303
161 { 304 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
162 sp = sp->s2; 305 solo = (Solo*) tc;
163 } 306 term = solo->term;
164 } 307
308 if (!tc->is_focused)
309 return;
310
311 if (tc->parent != relative)
312 tc->parent->unfocus(tc->parent, tc);
313
314 edje_object_signal_emit(term->bg, "focus,out", "terminology");
315 edje_object_signal_emit(term->base, "focus,out", "terminology");
316
317 if (!tc->wn->cmdbox_up)
318 elm_object_focus_set(term->termio, EINA_FALSE);
319
320 tc->is_focused = EINA_FALSE;
321}
322
323static void
324_solo_focus(Term_Container *tc, Term_Container *relative)
325{
326 Solo *solo;
327 Term *term;
328 const char *title;
329
330 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
331 solo = (Solo*) tc;
332 term = solo->term;
333
334 if (tc->is_focused)
335 return;
336
337 term->missed_bell = EINA_FALSE;
338
339 if (tc->parent != relative)
340 tc->parent->focus(tc->parent, tc);
341
342 tc->is_focused = EINA_TRUE;
343 edje_object_signal_emit(term->bg, "focus,in", "terminology");
344 edje_object_signal_emit(term->base, "focus,in", "terminology");
345 if (term->wn->cmdbox)
346 elm_object_focus_set(term->wn->cmdbox, EINA_FALSE);
347 elm_object_focus_set(term->termio, EINA_TRUE);
348
349 title = termio_title_get(term->termio);
350 if (title)
351 tc->set_title(tc, tc, title);
352
353 if (term->missed_bell)
354 term->missed_bell = EINA_FALSE;
355}
356
357static void
358_solo_update(Term_Container *tc)
359{
360 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
361}
362
363static Term_Container *
364_solo_new(Term *term, Win *wn)
365{
366 Term_Container *tc = NULL;
367 Solo *solo = NULL;
368 solo = calloc(1, sizeof(Solo));
369 if (!solo)
370 {
371 free(solo);
372 return NULL;
165 } 373 }
166 return NULL; 374
375 tc = (Term_Container*)solo;
376 tc->term_next = _solo_term_next;
377 tc->term_prev = _solo_term_prev;
378 tc->term_first = _solo_term_first;
379 tc->term_last = _solo_term_last;
380 tc->focused_term_get = _solo_focused_term_get;
381 tc->get_evas_object = _solo_get_evas_object;
382 tc->split = _solo_split;
383 tc->find_term_at_coords = _solo_find_term_at_coords;
384 tc->size_eval = _solo_size_eval;
385 tc->swallow = NULL;
386 tc->focus = _solo_focus;
387 tc->unfocus = _solo_unfocus;
388 tc->set_title = _solo_set_title;
389 tc->bell = _solo_bell;
390 tc->close = _solo_close;
391 tc->update = _solo_update;
392 tc->title = eina_stringshare_add("Terminology");
393 tc->type = TERM_CONTAINER_TYPE_SOLO;
394
395 tc->parent = NULL;
396 tc->wn = wn;
397
398 solo->term = term;
399
400 term->container = tc;
401
402 return tc;
167} 403}
168 404
405/* }}} */
406/* {{{ Win */
407
169static void 408static void
170_cb_win_focus_in(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 409_cb_win_focus_in(void *data,
410 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
171{ 411{
172 Win *wn = data; 412 Win *wn = data;
413 Term_Container *tc = (Term_Container*) wn;
173 Term *term; 414 Term *term;
174 Split *sp;
175 415
176 if (!wn->focused) elm_win_urgent_set(wn->win, EINA_FALSE); 416 if (!tc->is_focused) elm_win_urgent_set(wn->win, EINA_FALSE);
177 wn->focused = EINA_TRUE; 417 tc->is_focused = EINA_TRUE;
178 if ((wn->cmdbox_up) && (wn->cmdbox)) 418 if ((wn->cmdbox_up) && (wn->cmdbox))
179 elm_object_focus_set(wn->cmdbox, EINA_TRUE); 419 elm_object_focus_set(wn->cmdbox, EINA_TRUE);
180 420
181 term = win_focused_term_get(wn); 421 term = tc->focused_term_get(tc);
182 422
183 if ( wn->config->mouse_over_focus ) 423 if ( wn->config->mouse_over_focus )
184 { 424 {
185 Term *term_mouse; 425 Term *term_mouse;
426 Evas_Coord mx, my;
186 427
187 term_mouse = _find_term_under_mouse(wn); 428 evas_pointer_canvas_xy_get(evas_object_evas_get(wn->win), &mx, &my);
429 term_mouse = tc->find_term_at_coords(tc, mx, my);
188 if ((term_mouse) && (term_mouse != term)) 430 if ((term_mouse) && (term_mouse != term))
189 { 431 {
190 if (term) 432 if (term)
191 { 433 {
192 edje_object_signal_emit(term->bg, "focus,out", "terminology"); 434 edje_object_signal_emit(term->bg, "focus,out", "terminology");
193 edje_object_signal_emit(term->base, "focus,out", "terminology"); 435 edje_object_signal_emit(term->base, "focus,out", "terminology");
194 if (!wn->cmdbox_up) elm_object_focus_set(term->termio, EINA_FALSE); 436 if (!wn->cmdbox_up)
437 elm_object_focus_set(term->termio, EINA_FALSE);
195 } 438 }
196 term = term_mouse; 439 term = term_mouse;
197 } 440 }
198 } 441 }
199 442
200 if (!term) return; 443 if (term)
201 sp = _split_find(wn->win, term->termio, NULL); 444 _term_focus(term, EINA_TRUE);
202 if (sp->sel)
203 {
204 if (!wn->cmdbox_up) elm_object_focus_set(sp->sel, EINA_TRUE);
205 }
206 else 445 else
207 { 446 tc->focus(tc, tc);
208 edje_object_signal_emit(term->bg, "focus,in", "terminology");
209 edje_object_signal_emit(term->base, "focus,in", "terminology");
210 if (!wn->cmdbox_up) elm_object_focus_set(term->termio, EINA_TRUE);
211 }
212} 447}
213 448
214static void 449static void
@@ -216,54 +451,47 @@ _cb_win_focus_out(void *data, Evas_Object *obj EINA_UNUSED,
216 void *event EINA_UNUSED) 451 void *event EINA_UNUSED)
217{ 452{
218 Win *wn = data; 453 Win *wn = data;
219 Term *term; 454 Term_Container *tc = (Term_Container*) wn;
220 455
221 wn->focused = EINA_FALSE; 456 tc->unfocus(tc, NULL);
222 if ((wn->cmdbox_up) && (wn->cmdbox))
223 elm_object_focus_set(wn->cmdbox, EINA_FALSE);
224 term = win_focused_term_get(wn);
225 if (!term) return;
226 edje_object_signal_emit(term->bg, "focus,out", "terminology");
227 edje_object_signal_emit(term->base, "focus,out", "terminology");
228 if (!wn->cmdbox_up) elm_object_focus_set(term->termio, EINA_FALSE);
229} 457}
230 458
231static void 459static Eina_Bool
232_cb_term_mouse_in(void *data, Evas *e EINA_UNUSED, 460_win_is_focused(Win *wn)
233 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
234{ 461{
235 Term *term = data; 462 Term_Container *tc;
236 Config *config; 463 if (!wn)
464 return EINA_FALSE;
237 465
238 if ((!term) || (!term->termio)) return; 466 tc = (Term_Container*) wn;
239 467
240 config = termio_config_get(term->termio); 468 return tc->is_focused;
469}
241 470
242 if ((!config) || (!config->mouse_over_focus)) return;
243 if ((!term->wn) || (!term->wn->focused)) return;
244 471
245 term->focused = EINA_TRUE; 472int win_term_set(Win *wn, Term *term)
473{
474 Term_Container *tc_win = NULL, *tc_child = NULL;
475 Evas_Object *base = win_base_get(wn);
476 Evas *evas = evas_object_evas_get(base);
246 477
247 _term_focus(term); 478 tc_child = _solo_new(term, wn);
248} 479 if (!tc_child)
480 goto bad;
249 481
250static void 482 tc_win = (Term_Container*) wn;
251_cb_term_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event )
252{
253 Evas_Event_Mouse_Down *ev = event;
254 Term *term = data;
255 Term *term2;
256 483
257 term2 = win_focused_term_get(term->wn); 484 tc_win->swallow(tc_win, NULL, tc_child);
258 if (term == term2) return;
259 term->down.x = ev->canvas.x;
260 term->down.y = ev->canvas.y;
261 _term_focus(term);
262}
263 485
486 _cb_size_hint(term, evas, term->termio, NULL);
264 487
488 return 0;
489
490bad:
491 free(tc_child);
492 return -1;
493}
265 494
266/* {{{ Win */
267 495
268Evas_Object * 496Evas_Object *
269win_base_get(Win *wn) 497win_base_get(Win *wn)
@@ -348,7 +576,8 @@ main_trans_update(const Config *config)
348 576
349 577
350static void 578static void
351_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 579_cb_del(void *data, Evas *e EINA_UNUSED,
580 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
352{ 581{
353 Win *wn = data; 582 Win *wn = data;
354 583
@@ -382,11 +611,6 @@ win_free(Win *wn)
382 evas_object_del(wn->cmdbox); 611 evas_object_del(wn->cmdbox);
383 wn->cmdbox = NULL; 612 wn->cmdbox = NULL;
384 } 613 }
385 if (wn->split)
386 {
387 _split_free(wn->split);
388 wn->split = NULL;
389 }
390 if (wn->win) 614 if (wn->win)
391 { 615 {
392 evas_object_event_callback_del_full(wn->win, EVAS_CALLBACK_DEL, _cb_del, wn); 616 evas_object_event_callback_del_full(wn->win, EVAS_CALLBACK_DEL, _cb_del, wn);
@@ -449,6 +673,231 @@ tg_win_add(const char *name, const char *role, const char *title, const char *ic
449 return win; 673 return win;
450} 674}
451 675
676static Evas_Object *
677_win_get_evas_object(Term_Container *tc)
678{
679 Win *wn;
680 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
681
682 wn = (Win*) tc;
683
684 return wn->win;
685}
686
687static Term *
688_win_term_next(Term_Container *tc EINA_UNUSED, Term_Container *child)
689{
690 return child->term_first(child);
691}
692
693static Term *
694_win_term_prev(Term_Container *tc EINA_UNUSED, Term_Container *child)
695{
696 return child->term_last(child);
697}
698
699static Term *
700_win_term_first(Term_Container *tc)
701{
702 Win *wn;
703 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
704
705 wn = (Win*) tc;
706 return wn->child->term_first(wn->child);
707}
708
709static Term *
710_win_term_last(Term_Container *tc)
711{
712 Win *wn;
713 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
714
715 wn = (Win*) tc;
716 return wn->child->term_last(wn->child);
717}
718
719static Term *
720_win_focused_term_get(Term_Container *tc)
721{
722 Win *wn;
723 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
724
725 wn = (Win*) tc;
726
727 return tc->is_focused ? wn->child->focused_term_get(wn->child) : NULL;
728}
729
730static Term *
731_win_find_term_at_coords(Term_Container *tc,
732 Evas_Coord mx, Evas_Coord my)
733{
734 Win *wn;
735 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
736
737 wn = (Win*) tc;
738
739 return wn->child->find_term_at_coords(wn->child, mx, my);
740}
741
742static void
743_win_size_eval(Term_Container *tc, Sizeinfo *info)
744{
745 Win *wn;
746 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
747
748 wn = (Win*) tc;
749
750 wn->child->size_eval(wn->child, info);
751}
752
753static void
754_win_swallow(Term_Container *tc, Term_Container *orig,
755 Term_Container *new_child)
756{
757 Win *wn;
758 Evas_Object *base;
759 Evas_Object *o;
760 Evas_Coord x, y, w, h;
761
762 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
763
764 wn = (Win*) tc;
765 base = win_base_get(wn);
766
767 if (orig)
768 {
769 o = edje_object_part_swallow_get(base, "terminology.content");
770 edje_object_part_unswallow(base, o);
771 evas_object_hide(o);
772 o = orig->get_evas_object(orig);
773 evas_object_geometry_get(o, &x, &y, &w, &h);
774 }
775 o = new_child->get_evas_object(new_child);
776 edje_object_part_swallow(base, "terminology.content", o);
777 if (orig)
778 evas_object_geometry_set(o, x, y, w, h);
779 evas_object_show(o);
780 new_child->parent = tc;
781 wn->child = new_child;
782 if (tc->is_focused)
783 new_child->focus(new_child, tc);
784}
785
786static void
787_win_close(Term_Container *tc, Term_Container *child EINA_UNUSED)
788{
789 Win *wn;
790 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
791
792 wn = (Win*) tc;
793 eina_stringshare_del(tc->title);
794 win_free(wn);
795}
796
797static void
798_win_focus(Term_Container *tc, Term_Container *child)
799{
800 Win *wn;
801 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
802
803 wn = (Win*) tc;
804 if (child != wn->child)
805 wn->child->focus(wn->child, tc);
806
807 if (!tc->is_focused) elm_win_urgent_set(wn->win, EINA_FALSE);
808 tc->is_focused = EINA_TRUE;
809}
810
811static void
812_win_unfocus(Term_Container *tc, Term_Container *relative)
813{
814 Win *wn;
815 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
816
817 wn = (Win*) tc;
818
819 tc->is_focused = EINA_FALSE;
820 if (relative != wn->child)
821 wn->child->unfocus(wn->child, tc);
822
823 if ((wn->cmdbox_up) && (wn->cmdbox))
824 elm_object_focus_set(wn->cmdbox, EINA_FALSE);
825}
826
827static void
828_win_bell(Term_Container *tc, Term_Container *child EINA_UNUSED)
829{
830 Win *wn;
831 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
832
833 wn = (Win*) tc;
834
835 if (tc->is_focused) return;
836
837 if (wn->config->urg_bell)
838 {
839 elm_win_urgent_set(wn->win, EINA_TRUE);
840 }
841}
842
843static void
844_win_set_title(Term_Container *tc, Term_Container *child EINA_UNUSED,
845 const char *title)
846{
847 Win *wn;
848 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
849
850 wn = (Win*) tc;
851
852 eina_stringshare_del(tc->title);
853 tc->title = eina_stringshare_ref(title);
854
855 elm_win_title_set(wn->win, title);
856}
857
858static void
859_win_split(Term_Container *tc, Term_Container *child, const char *cmd,
860 Eina_Bool is_horizontal)
861{
862 Term *tm_new, *tm;
863 Term_Container *tc_split, *tc_solo_new;
864 Win *wn;
865 Evas_Object *obj_split;
866 char buf[PATH_MAX], *wdir = NULL;
867
868 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
869 wn = (Win*) tc;
870
871 tm = tc->focused_term_get(tc);
872 if (tm && termio_cwd_get(tm->termio, buf, sizeof(buf)))
873 wdir = buf;
874 tm_new = term_new(wn, wn->config,
875 cmd, wn->config->login_shell, wdir,
876 80, 24, EINA_FALSE);
877 tc_solo_new = _solo_new(tm_new, wn);
878 evas_object_data_set(tm_new->termio, "sizedone", tm_new->termio);
879
880 tc_split = _split_new(child, tc_solo_new, is_horizontal);
881
882 obj_split = tc_split->get_evas_object(tc_split);
883
884 tc_split->is_focused = tc->is_focused;
885 tc->swallow(tc, child, tc_split);
886
887 evas_object_show(obj_split);
888}
889
890static void
891_win_update(Term_Container *tc)
892{
893 Win *wn;
894
895 assert (tc->type == TERM_CONTAINER_TYPE_WIN);
896 wn = (Win*) tc;
897
898 wn->child->update(wn->child);
899}
900
452Win * 901Win *
453win_new(const char *name, const char *role, const char *title, 902win_new(const char *name, const char *role, const char *title,
454 const char *icon_name, Config *config, 903 const char *icon_name, Config *config,
@@ -458,6 +907,7 @@ win_new(const char *name, const char *role, const char *title,
458{ 907{
459 Win *wn; 908 Win *wn;
460 Evas_Object *o; 909 Evas_Object *o;
910 Term_Container *tc;
461 911
462 wn = calloc(1, sizeof(Win)); 912 wn = calloc(1, sizeof(Win));
463 if (!wn) return NULL; 913 if (!wn) return NULL;
@@ -469,6 +919,27 @@ win_new(const char *name, const char *role, const char *title,
469 return NULL; 919 return NULL;
470 } 920 }
471 921
922 tc = (Term_Container*) wn;
923 tc->term_next = _win_term_next;
924 tc->term_prev = _win_term_prev;
925 tc->term_first = _win_term_first;
926 tc->term_last = _win_term_last;
927 tc->focused_term_get = _win_focused_term_get;
928 tc->get_evas_object = _win_get_evas_object;
929 tc->split = _win_split;
930 tc->find_term_at_coords = _win_find_term_at_coords;
931 tc->size_eval = _win_size_eval;
932 tc->swallow = _win_swallow;
933 tc->focus = _win_focus;
934 tc->unfocus = _win_unfocus;
935 tc->set_title = _win_set_title;
936 tc->bell = _win_bell;
937 tc->close = _win_close;
938 tc->update = _win_update;
939 tc->title = eina_stringshare_add("Terminology");
940 tc->type = TERM_CONTAINER_TYPE_WIN;
941 tc->wn = wn;
942
472 config_default_font_set(config, evas_object_evas_get(wn->win)); 943 config_default_font_set(config, evas_object_evas_get(wn->win));
473 944
474 wn->config = config_fork(config); 945 wn->config = config_fork(config);
@@ -511,249 +982,454 @@ win_new(const char *name, const char *role, const char *title,
511void 982void
512main_close(Evas_Object *win, Evas_Object *term) 983main_close(Evas_Object *win, Evas_Object *term)
513{ 984{
514 Term *tm = NULL; 985 Term *tm;
515 Split *sp = _split_find(win, term, &tm); 986 Term_Container *tc;
516 Split *spp, *spkeep = NULL; 987 Win *wn = _win_find(win);
517 Eina_List *l; 988
518 const char *slot = PANES_TOP; 989 if (!wn) return;
519 Eina_Bool term_was_focused;
520 990
521 if (!sp) return; 991 tm = evas_object_data_get(term, "term");
522 if (!sp->term) return;
523 if (!tm) return; 992 if (!tm) return;
524 if (sp->sel) _sel_restore(sp);
525 spp = sp->parent;
526 sp->wn->terms = eina_list_remove(sp->wn->terms, tm);
527 993
528 term_was_focused = tm->focused; 994 wn->terms = eina_list_remove(wn->terms, tm);
995 tc = tm->container;
996
997 tc->close(tc, tc);
998
999 term_unref(tm);
1000}
1001
1002/* }}} */
1003/* {{{ Splits */
1004
1005static Term *
1006_split_term_next(Term_Container *tc, Term_Container *child)
1007{
1008 Split *split;
1009
1010 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1011 split = (Split*) tc;
1012
1013 if (child == split->tc1)
1014 return split->tc2->term_first(split->tc2);
1015 else
1016 return tc->parent->term_next(tc->parent, tc);
1017}
1018
1019static Term *
1020_split_term_prev(Term_Container *tc, Term_Container *child)
1021{
1022 Split *split;
529 1023
530 if (spp) 1024 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1025 split = (Split*) tc;
1026
1027 if (child == split->tc2)
1028 return split->tc1->term_last(split->tc1);
1029 else
1030 return tc->parent->term_prev(tc->parent, tc);
1031}
1032
1033static Term *
1034_split_term_first(Term_Container *tc)
1035{
1036 Split *split;
1037
1038 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1039 split = (Split*) tc;
1040
1041 return split->tc1->term_first(split->tc1);
1042}
1043
1044static Term *
1045_split_term_last(Term_Container *tc)
1046{
1047 Split *split;
1048
1049 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1050 split = (Split*) tc;
1051
1052 return split->tc2->term_last(split->tc2);
1053}
1054
1055static Evas_Object *
1056_split_get_evas_object(Term_Container *tc)
1057{
1058 Split *split;
1059
1060 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1061 split = (Split*) tc;
1062
1063 return split->panes;
1064}
1065
1066static void
1067_split_size_eval(Term_Container *tc, Sizeinfo *info)
1068{
1069 Evas_Coord mw = 0, mh = 0;
1070 Term_Container *tc1, *tc2;
1071 Sizeinfo inforet = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1072 Split *split;
1073
1074 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1075 split = (Split*) tc;
1076
1077 tc1 = split->tc1;
1078 tc2 = split->tc2;
1079
1080 info->min_w = 0;
1081 info->min_h = 0;
1082 info->req_w = 0;
1083 info->req_h = 0;
1084
1085 evas_object_size_hint_min_get(split->panes, &mw, &mh);
1086 info->bg_min_w = mw;
1087 info->bg_min_h = mh;
1088
1089 if (split->is_horizontal)
531 { 1090 {
532 if (eina_list_count(sp->terms) <= 1) 1091 tc1->size_eval(tc1, &inforet);
533 { 1092 info->req |= inforet.req;
534 if (sp == spp->s2) 1093 mh -= inforet.min_h;
535 { 1094 if (info->req)
536 spkeep = spp->s1;
537 spp->s2 = NULL;
538 }
539 else
540 {
541 spkeep = spp->s2;
542 spp->s1 = NULL;
543 }
544 }
545 l = eina_list_data_find_list(sp->terms, tm);
546 _term_resize_track_stop(sp);
547 term_unref(tm);
548 if (l)
549 {
550 if (tm == sp->term)
551 {
552 if (l->next) sp->term = l->next->data;
553 else if (l->prev) sp->term = l->prev->data;
554 else sp->term = NULL;
555 }
556 sp->terms = eina_list_remove_list(sp->terms, l);
557 }
558 else
559 { 1095 {
560 sp->term = NULL; 1096 info->req_h += inforet.req_h;
1097 info->req_w = inforet.req_w;
561 } 1098 }
562 if (!sp->term)
563 {
564 _split_free(sp);
565 sp = NULL;
566 if ((spp->parent) && (spp->parent->s2 == spp))
567 slot = PANES_BOTTOM;
568 _split_merge(spp, spkeep, slot);
569 1099
570 if (term_was_focused) 1100 tc2->size_eval(tc2, &inforet);
571 { 1101 info->req |= inforet.req;
572 tm = spp->term; 1102 mh -= inforet.min_h;
573 sp = spp; 1103 if (info->req)
574 while (tm == NULL)
575 {
576 tm = spp->term;
577 sp = spp;
578 spp = spp->s1;
579 }
580 _term_focus(tm);
581 _term_focus_show(sp, tm);
582 _split_tabcount_update(sp, tm);
583 }
584 }
585 else
586 { 1104 {
587 _term_resize_track_start(sp); 1105 info->req_h += inforet.req_h;
588 if ((sp->parent) && (sp->parent->s2 == sp)) slot = PANES_BOTTOM; 1106 info->req_w = inforet.req_w;
589 elm_object_part_content_set(sp->parent->panes, slot,
590 sp->term->bg);
591 evas_object_show(sp->term->bg);
592 if (term_was_focused)
593 {
594 _term_focus(sp->term);
595 _term_focus_show(sp, sp->term);
596 _split_tabcount_update(sp, sp->term);
597 }
598 } 1107 }
599 if (sp) _split_tabcount_update(sp, sp->term); 1108 info->req_h += mh;
1109 if (info->req)
1110 info->req_w += mw - inforet.min_w - inforet.step_x;
600 } 1111 }
601 else 1112 else
602 { 1113 {
603 _term_resize_track_stop(sp); 1114 tc1->size_eval(tc1, &inforet);
604 edje_object_part_unswallow(sp->wn->base, sp->term->bg); 1115 info->req |= inforet.req;
605 l = eina_list_data_find_list(sp->terms, tm); 1116 mw -= inforet.min_w;
606 term_unref(tm); 1117 if (info->req)
607 if (l)
608 { 1118 {
609 if (tm == sp->term) 1119 info->req_w += inforet.req_w;
610 { 1120 info->req_h = inforet.req_h;
611 if (l->next) sp->term = l->next->data;
612 else if (l->prev) sp->term = l->prev->data;
613 else sp->term = NULL;
614 }
615 sp->terms = eina_list_remove_list(sp->terms, l);
616 }
617 else
618 {
619 sp->term = NULL;
620 } 1121 }
621 if (sp->term) 1122
1123 tc2->size_eval(tc2, &inforet);
1124 info->req |= inforet.req;
1125 mw -= inforet.min_w;
1126 if (info->req)
622 { 1127 {
623 _term_resize_track_start(sp); 1128 info->req_w += inforet.req_w;
624 edje_object_part_swallow(sp->wn->base, "terminology.content", 1129 info->req_h = inforet.req_h;
625 sp->term->bg);
626 evas_object_show(sp->term->bg);
627 _term_focus(sp->term);
628 _term_focus_show(sp, sp->term);
629 _split_tabcount_update(sp, sp->term);
630 } 1130 }
631 if (!sp->wn->terms) evas_object_del(sp->wn->win); 1131 info->req_w += mw;
632 else _split_tabcount_update(sp, sp->term); 1132 if (info->req)
1133 info->req_h += mh - inforet.min_h - inforet.step_y;
633 } 1134 }
1135 info->step_x = inforet.step_x;
1136 info->step_y = inforet.step_y;
1137}
1138
1139static void
1140_split_swallow(Term_Container *tc, Term_Container *orig,
1141 Term_Container *new_child)
1142{
1143 Split *split;
1144 Evas_Object *o;
1145 Evas_Coord x, y, w, h;
1146
1147 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1148 split = (Split*) tc;
1149
1150 assert (orig && (orig == split->tc1 || orig == split->tc2));
1151
1152 o = orig->get_evas_object(orig);
1153 evas_object_geometry_get(o, &x, &y, &w, &h);
1154 evas_object_hide(o);
1155
1156 if (orig == split->last_focus)
1157 split->last_focus = new_child;
1158
1159 o = new_child->get_evas_object(new_child);
1160 if (split->tc1 == orig)
1161 {
1162 elm_object_part_content_unset(split->panes, PANES_TOP);
1163 elm_object_part_content_set(split->panes, PANES_TOP, o);
1164 split->tc1 = new_child;
1165 }
1166 else
1167 {
1168 elm_object_part_content_unset(split->panes, PANES_BOTTOM);
1169 elm_object_part_content_set(split->panes, PANES_BOTTOM, o);
1170 split->tc2 = new_child;
1171 }
1172 new_child->parent = tc;
1173 evas_object_geometry_set(o, x, y, w, h);
1174 evas_object_show(o);
1175 evas_object_show(split->panes);
1176
1177 if (tc->is_focused)
1178 new_child->focus(new_child, tc);
634} 1179}
635 1180
636static Term * 1181static Term *
637win_focused_term_get(Win *wn) 1182_split_focused_term_get(Term_Container *tc)
638{ 1183{
639 Term *term; 1184 Split *split;
640 Eina_List *l;
641 1185
642 EINA_LIST_FOREACH(wn->terms, l, term) 1186 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1187 split = (Split*) tc;
1188
1189 return tc->is_focused ?
1190 split->last_focus->focused_term_get(split->last_focus)
1191 : NULL;
1192}
1193
1194static Term *
1195_split_find_term_at_coords(Term_Container *tc,
1196 Evas_Coord mx, Evas_Coord my)
1197{
1198 Split *split;
1199 Evas_Coord ox, oy, ow, oh;
1200 Evas_Object *o;
1201
1202 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1203 split = (Split*) tc;
1204
1205 o = split->tc1->get_evas_object(split->tc1);
1206
1207 evas_object_geometry_get(o, &ox, &oy, &ow, &oh);
1208 if (ELM_RECTS_INTERSECT(ox, oy, ow, oh, mx, my, 1, 1))
643 { 1209 {
644 if (term->focused) return term; 1210 tc = split->tc1;
645 } 1211 }
646 return NULL; 1212 else
1213 {
1214 tc = split->tc2;
1215 }
1216
1217 return tc->find_term_at_coords(tc, mx, my);
647} 1218}
648 1219
1220static void
1221_split_close(Term_Container *tc, Term_Container *child)
1222{
1223 Split *split;
1224 Term_Container *parent, *other_child;
649 1225
650/* }}} */ 1226 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
651/* {{{ Splits */ 1227 split = (Split*) tc;
1228
1229 elm_object_part_content_unset(split->panes, PANES_TOP);
1230 elm_object_part_content_unset(split->panes, PANES_BOTTOM);
1231
1232 parent = tc->parent;
1233 other_child = (child == split->tc1) ? split->tc2 : split->tc1;
1234 parent->swallow(parent, tc, other_child);
1235
1236 evas_object_del(split->panes);
652 1237
653typedef struct _Sizeinfo Sizeinfo; 1238 eina_stringshare_del(tc->title);
1239 free(tc);
1240}
654 1241
655struct _Sizeinfo 1242static void
1243_split_update(Term_Container *tc)
656{ 1244{
657 int min_w, min_h; 1245 Split *split;
658 int step_x, step_y; 1246
659 int req_w, req_h; 1247 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
660 int req; 1248 split = (Split*) tc;
661}; 1249
1250 split->tc1->update(split->tc1);
1251 split->tc2->update(split->tc2);
1252}
662 1253
663static void 1254static void
664_split_size_walk(Split *sp, Sizeinfo *info) 1255_split_focus(Term_Container *tc, Term_Container *relative)
665{ 1256{
666 Sizeinfo inforet = { 0, 0, 0, 0, 0, 0, 0 }; 1257 Split *split;
1258 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1259 split = (Split*) tc;
667 1260
668 if (sp->term) 1261 if (tc->parent == relative)
669 { 1262 {
670 info->min_w = sp->term->min_w; 1263 tc->is_focused = EINA_TRUE;
671 info->min_h = sp->term->min_h; 1264 split->last_focus->focus(split->last_focus, tc);
672 info->step_x = sp->term->step_x;
673 info->step_y = sp->term->step_y;
674 info->req_w = sp->term->req_w;
675 info->req_h = sp->term->req_h;
676 // XXXX sp->terms sizedone too?
677 if (!evas_object_data_get(sp->term->termio, "sizedone"))
678 {
679 evas_object_data_set(sp->term->termio, "sizedone", sp->term->termio);
680 info->req = 1;
681 }
682 } 1265 }
683 else 1266 else
684 { 1267 {
685 Evas_Coord mw = 0, mh = 0; 1268 if (split->last_focus != relative)
1269 split->last_focus->unfocus(split->last_focus, tc);
1270 split->last_focus = relative;
1271 if (!tc->is_focused)
1272 tc->parent->focus(tc->parent, tc);
1273 tc->is_focused = EINA_TRUE;
1274 }
1275}
686 1276
687 info->min_w = 0; 1277static void
688 info->min_h = 0; 1278_split_unfocus(Term_Container *tc, Term_Container *relative)
689 info->req_w = 0; 1279{
690 info->req_h = 0; 1280 Split *split;
691 evas_object_size_hint_min_get(sp->panes, &mw, &mh); 1281 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
692 if (!sp->horizontal) 1282 split = (Split*) tc;
693 {
694 _split_size_walk(sp->s1, &inforet);
695 info->req |= inforet.req;
696 mw -= inforet.min_w;
697 if (info->req)
698 {
699 info->req_w += inforet.req_w;
700 info->req_h = inforet.req_h;
701 }
702 1283
703 _split_size_walk(sp->s2, &inforet); 1284 if (!tc->is_focused)
704 info->req |= inforet.req; 1285 return;
705 mw -= inforet.min_w;
706 if (info->req)
707 {
708 info->req_w += inforet.req_w;
709 info->req_h = inforet.req_h;
710 }
711 info->req_w += mw;
712 if (info->req) info->req_h += mh - inforet.min_h - inforet.step_y;
713 }
714 else
715 {
716 _split_size_walk(sp->s1, &inforet);
717 info->req |= inforet.req;
718 mh -= inforet.min_h;
719 if (info->req)
720 {
721 info->req_h += inforet.req_h;
722 info->req_w = inforet.req_w;
723 }
724 1286
725 _split_size_walk(sp->s2, &inforet); 1287 tc->is_focused = EINA_FALSE;
726 info->req |= inforet.req; 1288 if (tc->parent == relative)
727 mh -= inforet.min_h; 1289 split->last_focus->unfocus(split->last_focus, tc);
728 if (info->req) 1290 else
729 { 1291 tc->parent->unfocus(tc->parent, tc);
730 info->req_h += inforet.req_h; 1292}
731 info->req_w = inforet.req_w; 1293
732 } 1294static void
733 info->req_h += mh; 1295_split_set_title(Term_Container *tc, Term_Container *child,
734 if (info->req) info->req_w += mw - inforet.min_w - inforet.step_x; 1296 const char *title)
735 } 1297{
736 info->step_x = inforet.step_x; 1298 Split *split;
737 info->step_y = inforet.step_y; 1299
1300 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1301 split = (Split*) tc;
1302
1303 if (child == split->last_focus)
1304 {
1305 eina_stringshare_del(tc->title);
1306 tc->title = eina_stringshare_ref(title);
1307 tc->parent->set_title(tc->parent, tc, title);
738 } 1308 }
739} 1309}
740 1310
741static void 1311static void
1312_split_bell(Term_Container *tc, Term_Container *child EINA_UNUSED)
1313{
1314 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1315
1316 if (tc->is_focused)
1317 return;
1318
1319 tc->parent->bell(tc->parent, tc);
1320}
1321
1322static void
1323_split_split(Term_Container *tc, Term_Container *child,
1324 const char *cmd, Eina_Bool is_horizontal)
1325{
1326 Term *tm_new, *tm;
1327 Term_Container *tc_split, *tc_solo_new;
1328 Win *wn;
1329 Evas_Object *obj_split;
1330 char buf[PATH_MAX], *wdir = NULL;
1331
1332 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
1333 wn = tc->wn;
1334
1335 tm = child->focused_term_get(child);
1336 if (tm && termio_cwd_get(tm->termio, buf, sizeof(buf)))
1337 wdir = buf;
1338 tm_new = term_new(wn, wn->config,
1339 cmd, wn->config->login_shell, wdir,
1340 80, 24, EINA_FALSE);
1341 tc_solo_new = _solo_new(tm_new, wn);
1342 evas_object_data_set(tm_new->termio, "sizedone", tm_new->termio);
1343
1344 tc_split = _split_new(child, tc_solo_new, is_horizontal);
1345
1346 obj_split = tc_split->get_evas_object(tc_split);
1347
1348 tc_split->is_focused = tc->is_focused;
1349 tc->swallow(tc, child, tc_split);
1350
1351 evas_object_show(obj_split);
1352}
1353
1354static Term_Container *
1355_split_new(Term_Container *tc1, Term_Container *tc2, Eina_Bool is_horizontal)
1356{
1357 Evas_Object *o;
1358 Term_Container *tc = NULL;
1359 Split *split = NULL;
1360 split = calloc(1, sizeof(Split));
1361 if (!split)
1362 {
1363 free(split);
1364 return NULL;
1365 }
1366
1367 tc = (Term_Container*)split;
1368 tc->term_next = _split_term_next;
1369 tc->term_prev = _split_term_prev;
1370 tc->term_first = _split_term_first;
1371 tc->term_last = _split_term_last;
1372 tc->focused_term_get = _split_focused_term_get;
1373 tc->get_evas_object = _split_get_evas_object;
1374 tc->split = _split_split;
1375 tc->find_term_at_coords = _split_find_term_at_coords;
1376 tc->size_eval = _split_size_eval;
1377 tc->swallow = _split_swallow;
1378 tc->focus = _split_focus;
1379 tc->unfocus = _split_unfocus;
1380 tc->set_title = _split_set_title;
1381 tc->bell = _split_bell;
1382 tc->close = _split_close;
1383 tc->update = _split_update;
1384 tc->title = eina_stringshare_add("Terminology");
1385 tc->type = TERM_CONTAINER_TYPE_SPLIT;
1386
1387
1388 tc->parent = NULL;
1389 tc->wn = tc1->wn;
1390
1391 tc1->parent = tc2->parent = tc;
1392
1393 split->tc1 = tc1;
1394 split->tc2 = tc2;
1395 if (tc1->is_focused)
1396 tc1->unfocus(tc1, tc);
1397 tc2->focus(tc2, tc);
1398 split->last_focus = tc2;
1399
1400 o = split->panes = elm_panes_add(tc1->wn->win);
1401 elm_object_style_set(o, "flush");
1402 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1403 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
1404
1405 split->is_horizontal = is_horizontal;
1406 elm_panes_horizontal_set(o, split->is_horizontal);
1407
1408 elm_object_part_content_set(o, PANES_TOP,
1409 tc1->get_evas_object(tc1));
1410 elm_object_part_content_set(o, PANES_BOTTOM,
1411 tc2->get_evas_object(tc2));
1412
1413 return tc;
1414}
1415
1416static void
742_size_job(void *data) 1417_size_job(void *data)
743{ 1418{
744 Win *wn = data; 1419 Win *wn = data;
745 Sizeinfo info = { 0, 0, 0, 0, 0, 0, 0 }; 1420 Sizeinfo info = {0, 0, 0, 0, 0, 0, 0, 0, 0};
746 Evas_Coord mw = 0, mh = 0; 1421 Term_Container *tc = (Term_Container*) wn;
747 1422
748 wn->size_job = NULL; 1423 wn->size_job = NULL;
749 _split_size_walk(wn->split, &info); 1424 tc->size_eval(tc, &info);
750 if (wn->split->panes) 1425
751 evas_object_size_hint_min_get(wn->split->panes, &mw, &mh); 1426 elm_win_size_base_set(wn->win,
752 else 1427 info.bg_min_w - info.step_x,
753 evas_object_size_hint_min_get(wn->split->term->bg, &mw, &mh); 1428 info.bg_min_h - info.step_y);
754 elm_win_size_base_set(wn->win, mw - info.step_x, mh - info.step_y);
755 elm_win_size_step_set(wn->win, info.step_x, info.step_y); 1429 elm_win_size_step_set(wn->win, info.step_x, info.step_y);
756 evas_object_size_hint_min_set(wn->backbg, mw, mh); 1430 evas_object_size_hint_min_set(wn->backbg,
1431 info.bg_min_w,
1432 info.bg_min_h);
757 if (info.req) evas_object_resize(wn->win, info.req_w, info.req_h); 1433 if (info.req) evas_object_resize(wn->win, info.req_w, info.req_h);
758} 1434}
759 1435
@@ -765,7 +1441,8 @@ win_sizing_handle(Win *wn)
765} 1441}
766 1442
767static void 1443static void
768_cb_size_hint(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED) 1444_cb_size_hint(void *data,
1445 Evas *e EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
769{ 1446{
770 Term *term = data; 1447 Term *term = data;
771 Evas_Coord mw, mh, rw, rh, w = 0, h = 0; 1448 Evas_Coord mw, mh, rw, rh, w = 0, h = 0;
@@ -787,64 +1464,37 @@ _cb_size_hint(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event EIN
787 term->wn->size_job = ecore_job_add(_size_job, term->wn); 1464 term->wn->size_job = ecore_job_add(_size_job, term->wn);
788} 1465}
789 1466
790static Split * 1467void
791_split_split_find(Split *sp, Evas_Object *termio, Term **ptm) 1468split_horizontally(Evas_Object *win EINA_UNUSED, Evas_Object *term,
1469 const char *cmd)
792{ 1470{
793 Split *sp2;
794 Eina_List *l;
795 Term *tm; 1471 Term *tm;
1472 Term_Container *tc;
796 1473
797 if (sp->term) 1474 tm = evas_object_data_get(term, "term");
798 { 1475 if (!tm) return;
799 if (sp->term->termio == termio) 1476
800 { 1477 tc = tm->container;
801 if (ptm) *ptm = sp->term; 1478 tc->split(tc, tc, cmd, EINA_TRUE);
802 return sp;
803 }
804 EINA_LIST_FOREACH(sp->terms, l, tm)
805 {
806 if (tm->termio == termio)
807 {
808 if (ptm) *ptm = tm;
809 return sp;
810 }
811 }
812 }
813 if (sp->s1)
814 {
815 sp2 = _split_split_find(sp->s1, termio, ptm);
816 if (sp2) return sp2;
817 }
818 if (sp->s2)
819 {
820 sp2 = _split_split_find(sp->s2, termio, ptm);
821 if (sp2) return sp2;
822 }
823 return NULL;
824} 1479}
825 1480
826static Split * 1481void
827_split_find(Evas_Object *win, Evas_Object *term, Term **ptm) 1482split_vertically(Evas_Object *win EINA_UNUSED, Evas_Object *term,
1483 const char *cmd)
828{ 1484{
829 Win *wn; 1485 Term *tm;
830 Eina_List *l; 1486 Term_Container *tc;
831 1487
832 EINA_LIST_FOREACH(wins, l, wn) 1488 tm = evas_object_data_get(term, "term");
833 { 1489 if (!tm) return;
834 if (wn->win == win) return _split_split_find(wn->split, term, ptm);
835 }
836 return NULL;
837}
838 1490
839static void 1491 tc = tm->container;
840_split_free(Split *sp) 1492 tc->split(tc, tc, cmd, EINA_FALSE);
841{
842 if (sp->s1) _split_free(sp->s1);
843 if (sp->s2) _split_free(sp->s2);
844 if (sp->panes) evas_object_del(sp->panes);
845 free(sp);
846} 1493}
847 1494
1495/* }}} */
1496/* {{{ Tabs */
1497
848static void 1498static void
849_tabbar_clear(Term *tm) 1499_tabbar_clear(Term *tm)
850{ 1500{
@@ -865,38 +1515,44 @@ _tabbar_clear(Term *tm)
865} 1515}
866 1516
867static void 1517static void
868_cb_tab_activate(void *data, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) 1518_cb_tab_activate(void *data, Evas_Object *obj EINA_UNUSED,
1519 const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
869{ 1520{
870 Split *sp = data; 1521 Tab_Item *tab_item = data;
871 Term *term = evas_object_data_get(obj, "term"); 1522 Solo *solo;
872 if (term) 1523 Term *term;
873 { 1524
874 _term_focus(term); 1525 assert (tab_item->tc->type == TERM_CONTAINER_TYPE_SOLO);
875 if (sp) 1526 solo = (Solo*)tab_item->tc;
876 { 1527 term = solo->term;
877 _term_focus_show(sp, term); 1528 _term_focus(term, EINA_TRUE);
878 _split_tabcount_update(sp, term);
879 }
880 }
881} 1529}
882 1530
883static void 1531static void
884_split_tabbar_fill(Split *sp, Term *tm) 1532_tabbar_fill(Tabs *tabs)
885{ 1533{
886 Eina_List *l; 1534 Eina_List *l;
887 Term *term; 1535 Term *term;
1536 Solo *solo;
888 Evas_Object *o; 1537 Evas_Object *o;
889 int n = eina_list_count(sp->terms); 1538 int n = eina_list_count(tabs->tabs);
890 int i = 0, j = 0; 1539 int i = 0, j = 0;
1540 Tab_Item *tab_item;
891 1541
892 EINA_LIST_FOREACH(sp->terms, l, term) 1542 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
893 { 1543 {
894 if (term == tm) break; 1544 if (tab_item == tabs->current) break;
895 i++; 1545 i++;
896 } 1546 }
1547
1548 tab_item = tabs->current;
1549 assert (tab_item->tc->type == TERM_CONTAINER_TYPE_SOLO);
1550 solo = (Solo*)tab_item->tc;
1551 term = solo->term;
1552
897 if (i > 0) 1553 if (i > 0)
898 { 1554 {
899 tm->tabbar.l.box = o = elm_box_add(sp->wn->win); 1555 term->tabbar.l.box = o = elm_box_add(tabs->tc.wn->win);
900 elm_box_horizontal_set(o, EINA_TRUE); 1556 elm_box_horizontal_set(o, EINA_TRUE);
901 elm_box_homogeneous_set(o, EINA_TRUE); 1557 elm_box_homogeneous_set(o, EINA_TRUE);
902 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 1558 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -906,7 +1562,7 @@ _split_tabbar_fill(Split *sp, Term *tm)
906 } 1562 }
907 if (i < (n - 1)) 1563 if (i < (n - 1))
908 { 1564 {
909 tm->tabbar.r.box = o = elm_box_add(sp->wn->win); 1565 term->tabbar.r.box = o = elm_box_add(tabs->tc.wn->win);
910 elm_box_horizontal_set(o, EINA_TRUE); 1566 elm_box_horizontal_set(o, EINA_TRUE);
911 elm_box_homogeneous_set(o, EINA_TRUE); 1567 elm_box_homogeneous_set(o, EINA_TRUE);
912 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 1568 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -914,476 +1570,1027 @@ _split_tabbar_fill(Split *sp, Term *tm)
914 edje_object_part_swallow(term->bg, "terminology.tabr.content", o); 1570 edje_object_part_swallow(term->bg, "terminology.tabr.content", o);
915 evas_object_show(o); 1571 evas_object_show(o);
916 } 1572 }
917 EINA_LIST_FOREACH(sp->terms, l, term) 1573 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
918 { 1574 {
919 if (term != tm) 1575 if (tab_item != tabs->current)
920 { 1576 {
921 Evas_Coord w, h; 1577 Evas_Coord w, h;
922 1578
923 o = edje_object_add(evas_object_evas_get(sp->wn->win)); 1579 o = edje_object_add(evas_object_evas_get(tabs->tc.wn->win));
924 theme_apply(o, term->config, "terminology/tabbar_back"); 1580 theme_apply(o, term->config, "terminology/tabbar_back");
925 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 1581 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
926 evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); 1582 evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
927 edje_object_part_text_set(o, "terminology.title", termio_title_get(term->termio)); 1583 edje_object_part_text_set(o, "terminology.title",
1584 tab_item->tc->title);
928 edje_object_size_min_calc(o, &w, &h); 1585 edje_object_size_min_calc(o, &w, &h);
929 evas_object_size_hint_min_set(o, w, h); 1586 evas_object_size_hint_min_set(o, w, h);
930 if (j < i) 1587 if (j < i)
931 { 1588 {
932 tm->tabbar.l.tabs = eina_list_append(tm->tabbar.l.tabs, o); 1589 term->tabbar.l.tabs = eina_list_append(term->tabbar.l.tabs, o);
933 elm_box_pack_end(tm->tabbar.l.box, o); 1590 elm_box_pack_end(term->tabbar.l.box, o);
934 } 1591 }
935 else if (j > i) 1592 else if (j > i)
936 { 1593 {
937 tm->tabbar.r.tabs = eina_list_append(tm->tabbar.r.tabs, o); 1594 term->tabbar.r.tabs = eina_list_append(term->tabbar.r.tabs, o);
938 elm_box_pack_end(tm->tabbar.r.box, o); 1595 elm_box_pack_end(term->tabbar.r.box, o);
939 } 1596 }
940 evas_object_data_set(o, "term", term); 1597 evas_object_data_set(o, "term", term);
941 evas_object_show(o); 1598 evas_object_show(o);
942 edje_object_signal_callback_add(o, "tab,activate", "terminology", 1599 edje_object_signal_callback_add(o, "tab,activate", "terminology",
943 _cb_tab_activate, sp); 1600 _cb_tab_activate, tab_item);
944 } 1601 }
945 j++; 1602 j++;
946 } 1603 }
947} 1604}
948 1605
949static void 1606static void
950_split_tabcount_update(Split *sp, Term *tm) 1607_tab_go(Term *term, int tnum)
951{ 1608{
952 char buf[32], bufm[32]; 1609 Term_Container *tc = term->container,
953 int n = eina_list_count(sp->terms); 1610 *child = tc;
954 int missed = 0;
955 int cnt = 0, term_cnt = 0;
956 int i = 0;
957 Eina_List *l;
958 Term *term;
959
960 EINA_LIST_FOREACH(sp->terms, l, term)
961 {
962 if (term->missed_bell) missed++;
963 1611
964 cnt++; 1612 while (tc)
965 if (tm == term) term_cnt = cnt;
966 }
967 snprintf(buf, sizeof(buf), "%i/%i", term_cnt, n);
968 if (missed > 0) snprintf(bufm, sizeof(bufm), "%i", missed);
969 else bufm[0] = 0;
970 EINA_LIST_FOREACH(sp->terms, l, term)
971 { 1613 {
972 Evas_Coord w = 0, h = 0; 1614 Tabs *tabs;
1615 Tab_Item *tab_item;
973 1616
974 if (!term->tabcount_spacer) 1617 if (tc->type != TERM_CONTAINER_TYPE_TABS)
975 { 1618 {
976 term->tabcount_spacer = evas_object_rectangle_add(evas_object_evas_get(term->bg)); 1619 child = tc;
977 evas_object_color_set(term->tabcount_spacer, 0, 0, 0, 0); 1620 tc = tc->parent;
1621 continue;
978 } 1622 }
979 elm_coords_finger_size_adjust(1, &w, 1, &h); 1623 tabs = (Tabs*) tc;
980 evas_object_size_hint_min_set(term->tabcount_spacer, w, h); 1624 tab_item = eina_list_nth(tabs->tabs, tnum);
981 edje_object_part_swallow(term->bg, "terminology.tabcount.control", term->tabcount_spacer); 1625 if (!tab_item)
982 if (n > 1)
983 { 1626 {
984 edje_object_part_text_set(term->bg, "terminology.tabcount.label", buf); 1627 child = tc;
985 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufm); 1628 tc = tc->parent;
986 edje_object_signal_emit(term->bg, "tabcount,on", "terminology"); 1629 continue;
987 // this is all below just for tab bar at the top
988 if (!term->config->notabs)
989 {
990 double v1, v2;
991
992 v1 = (double)i / (double)n;
993 v2 = (double)(i + 1) / (double)n;
994 if (!term->tab_spacer)
995 {
996 term->tab_spacer = evas_object_rectangle_add(evas_object_evas_get(term->bg));
997 evas_object_color_set(term->tab_spacer, 0, 0, 0, 0);
998 elm_coords_finger_size_adjust(1, &w, 1, &h);
999 evas_object_size_hint_min_set(term->tab_spacer, w, h);
1000 edje_object_part_swallow(term->bg, "terminology.tab", term->tab_spacer);
1001 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
1002 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
1003 edje_object_part_text_set(term->bg, "terminology.tab.title", termio_title_get(term->termio));
1004 edje_object_signal_emit(term->bg, "tabbar,on", "terminology");
1005 edje_object_message_signal_process(term->bg);
1006 }
1007 else
1008 {
1009 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
1010 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
1011 edje_object_message_signal_process(term->bg);
1012 }
1013 _tabbar_clear(term);
1014 if (sp->term == term) _split_tabbar_fill(sp, term);
1015 }
1016 else
1017 {
1018 _tabbar_clear(term);
1019 if (term->tab_spacer)
1020 {
1021 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
1022 evas_object_del(term->tab_spacer);
1023 term->tab_spacer = NULL;
1024 edje_object_message_signal_process(term->bg);
1025 }
1026 }
1027 } 1630 }
1028 else 1631 if (tab_item == tabs->current)
1029 { 1632 return;
1030 _tabbar_clear(term); 1633 tab_item->tc->focus(tab_item->tc, child);
1031 edje_object_signal_emit(term->bg, "tabcount,off", "terminology"); 1634 return;
1032 if (term->tab_spacer)
1033 {
1034 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
1035 evas_object_del(term->tab_spacer);
1036 term->tab_spacer = NULL;
1037 edje_object_message_signal_process(term->bg);
1038 }
1039 }
1040 if (missed > 0)
1041 edje_object_signal_emit(term->bg, "tabmissed,on", "terminology");
1042 else
1043 edje_object_signal_emit(term->bg, "tabmissed,off", "terminology");
1044 i++;
1045 } 1635 }
1046} 1636}
1047 1637
1638#define CB_TAB(TAB) \
1639static void \
1640_cb_tab_##TAB(void *data, Evas_Object *obj EINA_UNUSED, \
1641 void *event EINA_UNUSED) \
1642{ \
1643 _tab_go(data, TAB - 1); \
1644}
1645
1646CB_TAB(1)
1647CB_TAB(2)
1648CB_TAB(3)
1649CB_TAB(4)
1650CB_TAB(5)
1651CB_TAB(6)
1652CB_TAB(7)
1653CB_TAB(8)
1654CB_TAB(9)
1655CB_TAB(10)
1656#undef CB_TAB
1657
1658static void
1659_tabs_selector_cb_selected(void *data,
1660 Evas_Object *obj EINA_UNUSED,
1661 void *info);
1662static void
1663_tabs_selector_cb_exit(void *data,
1664 Evas_Object *obj EINA_UNUSED,
1665 void *info EINA_UNUSED);
1666
1048static void 1667static void
1049_cb_size_track(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED) 1668_tabs_restore(Tabs *tabs)
1050{ 1669{
1051 Split *sp = data;
1052 Eina_List *l; 1670 Eina_List *l;
1671 Tab_Item *tab_item;
1672 Term_Container *tc = (Term_Container*)tabs;
1053 Term *term; 1673 Term *term;
1054 Evas_Coord w = 0, h = 0; 1674 Solo *solo;
1055 1675
1056 evas_object_geometry_get(obj, NULL, NULL, &w, &h); 1676 if (!tabs->selector)
1057 EINA_LIST_FOREACH(sp->terms, l, term) 1677 return;
1678
1679 EINA_LIST_FOREACH(tc->wn->terms, l, term)
1680 {
1681 if (term->unswallowed)
1682 {
1683#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
1684 evas_object_image_source_visible_set(term->sel, EINA_TRUE);
1685#endif
1686 edje_object_part_swallow(term->bg, "terminology.content", term->base);
1687 term->unswallowed = EINA_FALSE;
1688 evas_object_show(term->base);
1689 }
1690 }
1691
1692 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
1693 {
1694 tab_item->selector_entry = NULL;
1695 }
1696
1697 evas_object_smart_callback_del_full(tabs->selector, "selected",
1698 _tabs_selector_cb_selected, tabs);
1699 evas_object_smart_callback_del_full(tabs->selector, "exit",
1700 _tabs_selector_cb_exit, tabs);
1701 evas_object_del(tabs->selector);
1702 evas_object_del(tabs->selector_bg);
1703 tabs->selector = NULL;
1704 tabs->selector_bg = NULL;
1705
1706 /* XXX: reswallow in parent */
1707 tc->parent->swallow(tc->parent, tc, tc);
1708 solo = (Solo*)tabs->current->tc;
1709 term = solo->term;
1710 _tabbar_clear(term);
1711 if (!term->config->notabs)
1058 { 1712 {
1059 if (term->bg != obj) evas_object_resize(term->bg, w, h); 1713 _tabbar_fill(tabs);
1060 } 1714 }
1715
1716 _tabs_refresh(tabs);
1717 tabs->current->tc->focus(tabs->current->tc, tabs->current->tc);
1061} 1718}
1062 1719
1063static void 1720static void
1064_term_resize_track_start(Split *sp) 1721_tabs_selector_cb_selected(void *data,
1722 Evas_Object *obj EINA_UNUSED,
1723 void *info)
1065{ 1724{
1066 if ((!sp) || (!sp->term) || (!sp->term->bg)) return; 1725 Tabs *tabs = data;
1067 evas_object_event_callback_del_full(sp->term->bg, EVAS_CALLBACK_RESIZE, 1726 Eina_List *l;
1068 _cb_size_track, sp); 1727 Tab_Item *tab_item;
1069 evas_object_event_callback_add(sp->term->bg, EVAS_CALLBACK_RESIZE, 1728
1070 _cb_size_track, sp); 1729 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
1730 {
1731 if (tab_item->tc->selector_img == info)
1732 {
1733 tabs->current = tab_item;
1734 _tabs_restore(tabs);
1735 return;
1736 }
1737 }
1738
1739 ERR("Can't find selected tab item");
1071} 1740}
1072 1741
1073static void 1742static void
1074_term_resize_track_stop(Split *sp) 1743_tabs_selector_cb_exit(void *data,
1744 Evas_Object *obj EINA_UNUSED,
1745 void *info EINA_UNUSED)
1075{ 1746{
1076 if ((!sp) || (!sp->term) || (!sp->term->bg)) return; 1747 Tabs *tabs = data;
1077 evas_object_event_callback_del_full(sp->term->bg, EVAS_CALLBACK_RESIZE, 1748
1078 _cb_size_track, sp); 1749 _tabs_restore(tabs);
1079} 1750}
1080 1751
1081static void 1752static void
1082_split_split(Split *sp, Eina_Bool horizontal, char *cmd) 1753_cb_tab_selector_show(Tabs *tabs)
1083{ 1754{
1084 Split *sp2, *sp1; 1755 Term_Container *tc = (Term_Container *)tabs;
1756 Eina_List *l;
1757 int count;
1758 double z;
1759 Edje_Message_Int msg;
1760 Win *wn = tc->wn;
1761 Tab_Item *tab_item;
1085 Evas_Object *o; 1762 Evas_Object *o;
1086 Config *config; 1763 Evas_Coord x, y, w, h;
1087 char buf[PATH_MAX], *wdir = NULL;
1088 1764
1089 if (!sp->term) return; 1765 if (tabs->selector_bg)
1766 return;
1090 1767
1091 o = sp->panes = elm_panes_add(sp->wn->win); 1768 o = tc->get_evas_object(tc);
1092 elm_object_style_set(o, "flush"); 1769 evas_object_geometry_get(o, &x, &y, &w, &h);
1093 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 1770
1094 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); 1771 tabs->selector_bg = edje_object_add(evas_object_evas_get(tc->wn->win));
1095 sp->horizontal = horizontal; 1772 theme_apply(tabs->selector_bg, wn->config, "terminology/sel/base");
1096 elm_panes_horizontal_set(o, sp->horizontal); 1773
1097 1774 evas_object_geometry_set(tabs->selector_bg, x, y, w, h);
1098 _term_resize_track_stop(sp); 1775 evas_object_hide(o);
1099 sp1 = sp->s1 = calloc(1, sizeof(Split)); 1776
1100 sp1->parent = sp; 1777 if (wn->config->translucent)
1101 sp1->wn = sp->wn; 1778 msg.val = wn->config->opacity;
1102 sp1->term = sp->term;
1103 sp1->terms = sp->terms;
1104 _term_resize_track_start(sp1);
1105
1106 sp->terms = NULL;
1107
1108 if (!sp->parent) edje_object_part_unswallow(sp->wn->base, sp->term->bg);
1109 _main_term_bg_redo(sp1->term);
1110 _split_tabcount_update(sp1, sp1->term);
1111
1112 sp2 = sp->s2 = calloc(1, sizeof(Split));
1113 sp2->parent = sp;
1114 sp2->wn = sp->wn;
1115 config = config_fork(sp->term->config);
1116 if (termio_cwd_get(sp->term->termio, buf, sizeof(buf))) wdir = buf;
1117 sp2->term = term_new(sp->wn, config,
1118 cmd, config->login_shell, wdir,
1119 80, 24, EINA_FALSE);
1120 sp2->terms = eina_list_append(sp2->terms, sp2->term);
1121 _term_resize_track_start(sp2);
1122 _term_focus(sp2->term);
1123 _term_media_update(sp2->term, config);
1124 _split_tabcount_update(sp2, sp2->term);
1125 evas_object_data_set(sp2->term->termio, "sizedone", sp2->term->termio);
1126 elm_object_part_content_set(sp->panes, PANES_TOP, sp1->term->bg);
1127 elm_object_part_content_set(sp->panes, PANES_BOTTOM, sp2->term->bg);
1128
1129 if (!sp->parent)
1130 edje_object_part_swallow(sp->wn->base, "terminology.content", sp->panes);
1131 else 1779 else
1780 msg.val = 100;
1781
1782 edje_object_message_send(tabs->selector_bg, EDJE_MESSAGE_INT, 1, &msg);
1783 edje_object_signal_emit(tabs->selector_bg, "begin", "terminology");
1784
1785 tab_item = tabs->current;
1786
1787 tabs->selector = sel_add(wn->win);
1788 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
1132 { 1789 {
1133 if (sp == sp->parent->s1) 1790 Evas_Object *img;
1791 Eina_Bool is_selected, missed_bell;
1792 Solo *solo;
1793 Term *term;
1794
1795 solo = (Solo*)tab_item->tc;
1796 term = solo->term;
1797 _tabbar_clear(term);
1798
1799 edje_object_part_unswallow(term->bg, term->base);
1800 term->unswallowed = EINA_TRUE;
1801 img = evas_object_image_filled_add(evas_object_evas_get(wn->win));
1802 o = term->base;
1803 evas_object_lower(o);
1804 evas_object_move(o, -9999, -9999);
1805 evas_object_show(o);
1806 evas_object_clip_unset(o);
1807 evas_object_image_source_set(img, o);
1808 evas_object_geometry_get(o, NULL, NULL, &w, &h);
1809 evas_object_resize(img, w, h);
1810 evas_object_data_set(img, "tc", tab_item->tc);
1811 tab_item->tc->selector_img = img;
1812
1813 is_selected = (tab_item == tabs->current);
1814 missed_bell = term->missed_bell;
1815 tab_item->selector_entry = sel_entry_add(tabs->selector, img,
1816 is_selected,
1817 missed_bell, wn->config);
1818 }
1819 edje_object_part_swallow(tabs->selector_bg, "terminology.content",
1820 tabs->selector);
1821
1822 evas_object_show(tabs->selector);
1823
1824 /* XXX: refresh */
1825 tc->parent->swallow(tc->parent, tc, tc);
1826
1827 evas_object_smart_callback_add(tabs->selector, "selected",
1828 _tabs_selector_cb_selected, tabs);
1829 evas_object_smart_callback_add(tabs->selector, "exit",
1830 _tabs_selector_cb_exit, tabs);
1831 z = 1.0;
1832 sel_go(tabs->selector);
1833 count = eina_list_count(tabs->tabs);
1834 if (count >= 1)
1835 z = 1.0 / (sqrt(count) * 0.8);
1836 if (z > 1.0) z = 1.0;
1837 sel_orig_zoom_set(tabs->selector, z);
1838 sel_zoom(tabs->selector, z);
1839 elm_object_focus_set(tabs->selector, EINA_TRUE);
1840}
1841
1842static void
1843_cb_select(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1844{
1845 Term *term = data;
1846 Term_Container *tc = term->container;
1847
1848 while (tc)
1849 {
1850 Tabs *tabs;
1851
1852 if (tc->type != TERM_CONTAINER_TYPE_TABS)
1134 { 1853 {
1135 elm_object_part_content_unset(sp->parent->panes, PANES_TOP); 1854 tc = tc->parent;
1136 elm_object_part_content_set(sp->parent->panes, PANES_TOP, sp->panes); 1855 continue;
1137 } 1856 }
1138 else 1857 tabs = (Tabs*) tc;
1858 if (eina_list_count(tabs->tabs) < 2)
1139 { 1859 {
1140 elm_object_part_content_unset(sp->parent->panes, PANES_BOTTOM); 1860 tc = tc->parent;
1141 elm_object_part_content_set(sp->parent->panes, PANES_BOTTOM, sp->panes); 1861 continue;
1142 } 1862 }
1863
1864 _cb_tab_selector_show(tabs);
1865 return;
1143 } 1866 }
1144 evas_object_show(sp->panes); 1867}
1145 sp->term = NULL; 1868
1869
1870
1871static Evas_Object *
1872_tabs_get_evas_object(Term_Container *container)
1873{
1874 Tabs *tabs;
1875 Term_Container *tc;
1876
1877 assert (container->type == TERM_CONTAINER_TYPE_TABS);
1878 tabs = (Tabs*)container;
1879
1880 if (tabs->selector_bg)
1881 return tabs->selector_bg;
1882
1883 assert(tabs->current != NULL);
1884 tc = tabs->current->tc;
1885 return tc->get_evas_object(tc);
1886}
1887
1888static Term *
1889_tabs_focused_term_get(Term_Container *tc)
1890{
1891 Tabs *tabs;
1892
1893 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1894 tabs = (Tabs*)tc;
1895
1896
1897 return tc->is_focused ?
1898 tabs->current->tc->focused_term_get(tabs->current->tc)
1899 : NULL;
1900}
1901
1902static Term *
1903_tabs_find_term_at_coords(Term_Container *container,
1904 Evas_Coord mx,
1905 Evas_Coord my)
1906{
1907 Tabs *tabs;
1908 Term_Container *tc;
1909
1910 assert (container->type == TERM_CONTAINER_TYPE_TABS);
1911 tabs = (Tabs*)container;
1912
1913 tc = tabs->current->tc;
1914
1915 return tc->find_term_at_coords(tc, mx, my);
1146} 1916}
1147 1917
1148static void 1918static void
1149_term_focus_show(Split *sp, Term *term) 1919_tabs_size_eval(Term_Container *container, Sizeinfo *info)
1920{
1921 Tabs *tabs;
1922 Term_Container *tc;
1923
1924 assert (container->type == TERM_CONTAINER_TYPE_TABS);
1925 tabs = (Tabs*)container;
1926
1927 tc = tabs->current->tc;
1928 tc->size_eval(tc, info);
1929}
1930
1931static Eina_List *
1932_tab_item_find(Tabs *tabs, Term_Container *child)
1150{ 1933{
1151 if (term != sp->term) 1934 Eina_List *l;
1935 Tab_Item *tab_item;
1936
1937 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
1152 { 1938 {
1153 _term_resize_track_stop(sp); 1939 if (tab_item->tc == child)
1154 evas_object_hide(sp->term->bg); 1940 return l;
1155 sp->term = term; 1941 }
1156 _term_resize_track_start(sp); 1942 return NULL;
1943}
1944
1945static void
1946_tabs_close(Term_Container *tc, Term_Container *child)
1947{
1948 int count;
1949 Tabs *tabs;
1950 Eina_List *l;
1951 Tab_Item *item, *next_item;
1952 Eina_List *next;
1953 Term_Container *next_child, *tc_parent;
1954 Term *term;
1955 Solo *solo;
1956
1957 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1958 tabs = (Tabs*)tc;
1959
1960 tc_parent = tc->parent;
1961
1962 l = _tab_item_find(tabs, child);
1963 item = l->data;
1964
1965 next = eina_list_next(l);
1966 if (!next)
1967 next = tabs->tabs;
1968 next_item = next->data;
1969 next_child = next_item->tc;
1970 tabs->tabs = eina_list_remove_list(tabs->tabs, l);
1971
1972 assert (child->type == TERM_CONTAINER_TYPE_SOLO);
1973 solo = (Solo*)child;
1974 term = solo->term;
1975 _tabbar_clear(term);
1976
1977 edje_object_signal_emit(term->bg, "tabcount,off", "terminology");
1978 if (term->tab_spacer)
1979 {
1980 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
1981 evas_object_del(term->tab_spacer);
1982 term->tab_spacer = NULL;
1983 edje_object_message_signal_process(term->bg);
1984 }
1985
1986
1987 count = eina_list_count(tabs->tabs);
1988 if (count == 1)
1989 {
1990 assert (next_child->type == TERM_CONTAINER_TYPE_SOLO);
1991 solo = (Solo*)next_child;
1992 term = solo->term;
1993 _tabbar_clear(term);
1994
1995 edje_object_signal_emit(term->bg, "tabcount,off", "terminology");
1996 if (term->tab_spacer)
1997 {
1998 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
1999 evas_object_del(term->tab_spacer);
2000 term->tab_spacer = NULL;
2001 edje_object_message_signal_process(term->bg);
2002 }
2003 if (tabs->selector)
2004 _tabs_restore(tabs);
2005 eina_stringshare_del(tc->title);
2006 tc_parent->swallow(tc_parent, tc, next_child);
2007 if (tc->is_focused)
2008 next_child->focus(next_child, tc_parent);
2009
2010 free(next_item);
2011 free(tc);
2012 free(item);
1157 } 2013 }
1158 if (!sp->parent)
1159 edje_object_part_swallow(sp->wn->base, "terminology.content",
1160 sp->term->bg);
1161 else 2014 else
1162 { 2015 {
1163 if (sp == sp->parent->s1) 2016 if (item == tabs->current)
1164 { 2017 {
1165 elm_object_part_content_unset(sp->parent->panes, PANES_TOP); 2018 tabs->current = next_item;
1166 elm_object_part_content_set(sp->parent->panes, PANES_TOP, 2019 /* XXX: refresh */
1167 sp->term->bg); 2020 tc_parent->swallow(tc_parent, tc, tc);
2021 if (tc->is_focused)
2022 next_child->focus(next_child, tc);
1168 } 2023 }
1169 else 2024
2025 if (item->tc->selector_img)
1170 { 2026 {
1171 elm_object_part_content_unset(sp->parent->panes, PANES_BOTTOM); 2027 Evas_Object *o;
1172 elm_object_part_content_set(sp->parent->panes, PANES_BOTTOM, 2028 o = item->tc->selector_img;
1173 sp->term->bg); 2029 item->tc->selector_img = NULL;
2030 evas_object_del(o);
1174 } 2031 }
2032
2033
2034 free(item);
2035 count--;
2036 _tabs_refresh(tabs);
1175 } 2037 }
1176 evas_object_show(sp->term->bg);
1177} 2038}
1178 2039
1179void 2040static void
1180main_new_with_dir(Evas_Object *win, Evas_Object *term, const char *wdir) 2041_tabs_update(Term_Container *tc)
1181{ 2042{
1182 Split *sp = _split_find(win, term, NULL); 2043 Tabs *tabs;
1183 Config *config; 2044 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1184 int w, h; 2045 tabs = (Tabs*)tc;
1185 2046
1186 if (!sp) return; 2047 _tabs_refresh(tabs);
1187 _term_resize_track_stop(sp);
1188 evas_object_hide(sp->term->bg);
1189 config = config_fork(sp->term->config);
1190 termio_size_get(sp->term->termio, &w, &h);
1191 sp->term = term_new(sp->wn, config,
1192 NULL, config->login_shell, wdir,
1193 w, h, EINA_FALSE);
1194 sp->terms = eina_list_append(sp->terms, sp->term);
1195 _term_resize_track_start(sp);
1196 _term_focus(sp->term);
1197 _term_media_update(sp->term, config);
1198 evas_object_data_set(sp->term->termio, "sizedone", sp->term->termio);
1199 _term_focus_show(sp, sp->term);
1200 _split_tabcount_update(sp, sp->term);
1201} 2048}
1202 2049
1203void 2050static Term *
1204main_new(Evas_Object *win, Evas_Object *term) 2051_tabs_term_next(Term_Container *tc, Term_Container *child)
1205{ 2052{
1206 Split *sp = _split_find(win, term, NULL); 2053 Tabs *tabs;
1207 char buf[PATH_MAX], *wdir = NULL; 2054 Tab_Item *tab_item;
2055 Eina_List *l;
1208 2056
1209 if (termio_cwd_get(sp->term->termio, buf, sizeof(buf))) wdir = buf; 2057 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1210 main_new_with_dir(win, term, wdir); 2058 tabs = (Tabs*)tc;
2059 l = _tab_item_find(tabs, child);
2060 l = eina_list_next(l);
2061 if (l)
2062 {
2063 tab_item = l->data;
2064 tc = tab_item->tc;
2065 return tc->term_first(tc);
2066 }
2067 else
2068 {
2069 return tc->parent->term_next(tc->parent, tc);
2070 }
1211} 2071}
1212 2072
1213void 2073static Term *
1214main_split_h(Evas_Object *win, Evas_Object *term, char *cmd) 2074_tabs_term_prev(Term_Container *tc, Term_Container *child)
1215{ 2075{
1216 Split *sp = _split_find(win, term, NULL); 2076 Tabs *tabs;
2077 Tab_Item *tab_item;
2078 Eina_List *l;
1217 2079
1218 if (!sp) return; 2080 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1219 _split_split(sp, EINA_TRUE, cmd); 2081 tabs = (Tabs*)tc;
2082 l = _tab_item_find(tabs, child);
2083 l = eina_list_prev(l);
2084 if (l)
2085 {
2086 tab_item = l->data;
2087 tc = tab_item->tc;
2088 return tc->term_last(tc);
2089 }
2090 else
2091 {
2092 return tc->parent->term_prev(tc->parent, tc);
2093 }
1220} 2094}
1221 2095
1222void 2096static Term *
1223main_split_v(Evas_Object *win, Evas_Object *term, char *cmd) 2097_tabs_term_first(Term_Container *tc)
1224{ 2098{
1225 Split *sp = _split_find(win, term, NULL); 2099 Tabs *tabs;
2100 Tab_Item *tab_item;
1226 2101
1227 if (!sp) return; 2102 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
1228 _split_split(sp, EINA_FALSE, cmd); 2103 tabs = (Tabs*)tc;
2104
2105 tab_item = tabs->tabs->data;
2106 tc = tab_item->tc;
2107
2108 return tc->term_first(tc);
2109}
2110
2111static Term *
2112_tabs_term_last(Term_Container *tc)
2113{
2114 Tabs *tabs;
2115 Tab_Item *tab_item;
2116 Eina_List *l;
2117
2118 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2119 tabs = (Tabs*)tc;
2120
2121 l = eina_list_last(tabs->tabs);
2122 tab_item = l->data;
2123 tc = tab_item->tc;
2124
2125 return tc->term_last(tc);
1229} 2126}
1230 2127
1231static void 2128static void
1232_split_append(Split *sp, Eina_List **flat) 2129_tabs_swallow(Term_Container *tc, Term_Container *orig,
2130 Term_Container *new_child)
1233{ 2131{
1234 if (sp->term) 2132 Tabs *tabs;
1235 *flat = eina_list_append(*flat, sp); 2133 Tab_Item *tab_item;
1236 else 2134 Eina_List *l;
2135 Evas_Object *o;
2136 Evas_Coord x, y, w, h;
2137
2138 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2139 tabs = (Tabs*) tc;
2140
2141 l = _tab_item_find(tabs, new_child);
2142 tab_item = l->data;
2143
2144 if (tabs->selector)
2145 {
2146 Evas_Object *img = tab_item->tc->selector_img;
2147 evas_object_image_source_set(img,
2148 new_child->get_evas_object(new_child));
2149 evas_object_data_set(img, "tc", new_child);
2150 sel_entry_update(tab_item->selector_entry);
2151 }
2152 else if (tab_item != tabs->current)
1237 { 2153 {
1238 _split_append(sp->s1, flat); 2154 Term_Container *tc_parent = tc->parent;
1239 _split_append(sp->s2, flat); 2155 if (tc->is_focused)
2156 tabs->current->tc->unfocus(tabs->current->tc, tc);
2157 tabs->current = tab_item;
2158
2159 o = orig->get_evas_object(orig);
2160 evas_object_geometry_get(o, &x, &y, &w, &h);
2161 evas_object_hide(o);
2162
2163 o = new_child->get_evas_object(new_child);
2164 evas_object_geometry_set(o, x, y, w, h);
2165 evas_object_show(o);
2166
2167 /* XXX: need to refresh */
2168 tc_parent->swallow(tc_parent, tc, tc);
2169 /* TODO: redo title */
1240 } 2170 }
2171
2172 _tabs_refresh(tabs);
1241} 2173}
1242 2174
1243static Eina_List * 2175
1244_split_flatten(Split *sp) 2176static void
2177_tab_new_cb(void *data,
2178 Evas_Object *obj EINA_UNUSED,
2179 void *event_info EINA_UNUSED)
1245{ 2180{
1246 Eina_List *flat = NULL; 2181 Tabs *tabs = data;
2182 Tab_Item *tab_item;
2183 Evas_Object *o;
2184 Evas_Coord x, y, w, h;
2185 Term_Container *tc = (Term_Container*) tabs,
2186 *tc_new, *tc_parent, *tc_old;
2187 Term *tm_new;
2188 Win *wn = tc->wn;
2189
2190 tm_new = term_new(wn, wn->config,
2191 NULL, wn->config->login_shell, NULL,
2192 80, 24, EINA_FALSE);
2193 tc_new = _solo_new(tm_new, wn);
2194 evas_object_data_set(tm_new->termio, "sizedone", tm_new->termio);
2195
2196 tc_new->parent = tc;
2197
2198 tab_item = tab_item_new(tabs, tc_new);
2199 tc_parent = tc->parent;
2200 tc_old = tabs->current->tc;
2201 tc_old->unfocus(tc_old, tc);
2202 o = tc_old->get_evas_object(tc_old);
2203 evas_object_geometry_get(o, &x, &y, &w, &h);
2204 evas_object_hide(o);
2205 o = tc_new->get_evas_object(tc_new);
2206 evas_object_geometry_set(o, x, y, w, h);
2207 evas_object_show(o);
2208 tabs->current = tab_item;
2209 /* XXX: need to refresh */
2210 tc_parent->swallow(tc_parent, tc, tc);
2211
2212 if (tc->is_focused)
2213 tc_new->focus(tc_new, tc);
1247 2214
1248 _split_append(sp, &flat); 2215 _tabs_refresh(tabs);
1249 return flat;
1250} 2216}
1251 2217
1252Term * 2218static void
1253term_next_get(Term *termin) 2219_cb_new(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1254{ 2220{
1255 Split *sp; 2221 Term *term = data;
1256 Eina_List *flat, *l; 2222 Term_Container *tc = term->container;
2223
2224 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
1257 2225
1258 sp = _split_find(termin->wn->win, termin->termio, NULL); 2226 _solo_tabs_new(tc);
1259 l = eina_list_data_find_list(sp->terms, termin); 2227}
1260 if ((l) && (l->next)) return l->next->data; 2228
1261 if (!sp->parent) return sp->terms->data; 2229void
1262 flat = _split_flatten(termin->wn->split); 2230main_new(Evas_Object *win EINA_UNUSED, Evas_Object *term)
1263 if (!flat) return NULL; 2231{
1264 l = eina_list_data_find_list(flat, sp); 2232 Term *tm;
1265 if (!l) 2233
2234 tm = evas_object_data_get(term, "term");
2235 if (!tm) return;
2236
2237 _cb_new(tm, term, NULL);
2238}
2239
2240static void
2241_tabs_focus(Term_Container *tc, Term_Container *relative)
2242{
2243 Tabs *tabs;
2244
2245 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2246 tabs = (Tabs*) tc;
2247
2248 if (tc->parent == relative)
1266 { 2249 {
1267 eina_list_free(flat); 2250 if (!tc->is_focused)
1268 return NULL; 2251 tabs->current->tc->focus(tabs->current->tc, tc);
1269 } 2252 }
1270 if (l->next) 2253 else
1271 { 2254 {
1272 sp = l->next->data; 2255 Eina_List *l;
1273 eina_list_free(flat); 2256 Tab_Item *tab_item;
1274 if (sp->terms) return sp->terms->data; 2257
1275 return sp->term; 2258 l = _tab_item_find(tabs, relative);
2259 assert(l);
2260
2261 tc->is_focused = EINA_TRUE;
2262
2263 tab_item = l->data;
2264 if (tab_item != tabs->current)
2265 {
2266 tabs->current->tc->unfocus(tabs->current->tc, tc);
2267 tc->swallow(tc, tabs->current->tc, relative);
2268 }
2269 tc->parent->focus(tc->parent, tc);
1276 } 2270 }
1277 sp = flat->data; 2271 tc->is_focused = EINA_TRUE;
1278 eina_list_free(flat);
1279 if (sp->terms) return sp->terms->data;
1280 return sp->term;
1281} 2272}
1282 2273
1283Term * 2274static void
1284term_prev_get(Term *termin) 2275_tabs_unfocus(Term_Container *tc, Term_Container *relative)
1285{ 2276{
1286 Split *sp; 2277 Tabs *tabs;
1287 Eina_List *flat, *l; 2278
2279 if (!tc->is_focused)
2280 return;
2281
2282 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2283 tabs = (Tabs*) tc;
2284
2285 if (tc->parent == relative)
2286 tabs->current->tc->unfocus(tabs->current->tc, tc);
2287 else
2288 tc->parent->unfocus(tc->parent, tc);
2289 tc->is_focused = EINA_FALSE;
2290}
2291
2292static void
2293_tabs_bell(Term_Container *tc, Term_Container *child EINA_UNUSED)
2294{
2295 Tabs *tabs;
2296
2297 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2298 tabs = (Tabs*) tc;
2299
2300 _tabs_refresh(tabs);
2301
2302 if (tc->is_focused)
2303 return;
2304
2305 tc->parent->bell(tc->parent, tc);
2306}
2307
2308static void
2309_tabs_set_title(Term_Container *tc, Term_Container *child,
2310 const char *title)
2311{
2312 Tabs *tabs;
2313 Tab_Item *tab_item;
2314 Eina_List *l;
2315
2316 assert (tc->type == TERM_CONTAINER_TYPE_TABS);
2317 tabs = (Tabs*) tc;
2318
2319 l = _tab_item_find(tabs, child);
2320 assert(l);
2321 tab_item = l->data;
1288 2322
1289 sp = _split_find(termin->wn->win, termin->termio, NULL); 2323 if (tabs->selector)
1290 l = eina_list_data_find_list(sp->terms, termin);
1291 if ((l) && (l->prev)) return l->prev->data;
1292 if (!sp->parent) return eina_list_data_get(eina_list_last(sp->terms));
1293 flat = _split_flatten(termin->wn->split);
1294 if (!flat) return NULL;
1295 l = eina_list_data_find_list(flat, sp);
1296 if (!l)
1297 { 2324 {
1298 eina_list_free(flat); 2325 sel_entry_title_set(tab_item->selector_entry, title);
1299 return NULL;
1300 } 2326 }
1301 if (l->prev) 2327
2328 if (tab_item == tabs->current)
1302 { 2329 {
1303 sp = l->prev->data; 2330 Solo *solo;
1304 eina_list_free(flat); 2331 Term *term;
1305 l = eina_list_last(sp->terms); 2332
1306 if (l) return l->data; 2333 eina_stringshare_del(tc->title);
1307 return sp->term; 2334 tc->title = eina_stringshare_ref(title);
2335 tc->parent->set_title(tc->parent, tc, title);
2336
2337 assert (tab_item->tc->type == TERM_CONTAINER_TYPE_SOLO);
2338 solo = (Solo*)tab_item->tc;
2339 term = solo->term;
2340
2341 if (!term->config->notabs)
2342 {
2343 edje_object_part_text_set(term->bg, "terminology.tab.title",
2344 title);
2345 }
2346 }
2347 else
2348 {
2349 _tabs_refresh(tabs);
1308 } 2350 }
1309#if (EINA_VERSION_MAJOR > 1) || (EINA_VERSION_MINOR >= 8)
1310 sp = eina_list_last_data_get(flat);
1311#else
1312 sp = eina_list_data_get(eina_list_last(flat));
1313#endif
1314 eina_list_free(flat);
1315 l = eina_list_last(sp->terms);
1316 if (l) return l->data;
1317 return sp->term;
1318} 2351}
1319 2352
1320static void 2353static void
1321_split_merge(Split *spp, Split *sp, const char *slot) 2354_tabs_refresh(Tabs *tabs)
1322{ 2355{
1323 Evas_Object *o = NULL; 2356 Eina_List *l;
1324 if (!sp) return; 2357 Solo *solo;
2358 Term *term;
2359 char buf[32], bufmissed[32];
2360 Tab_Item *tab_item;
2361 Evas_Coord w = 0, h = 0;
2362 int missed = 0;
2363 int i = 1;
2364 int n = eina_list_count(tabs->tabs);
2365
2366 buf[0] = '\0';
2367 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
2368 {
2369 assert (tab_item->tc->type == TERM_CONTAINER_TYPE_SOLO);
2370 solo = (Solo*) tab_item->tc;
2371 term = solo->term;
2372
2373 if (term->missed_bell)
2374 missed++;
2375 }
2376 EINA_LIST_FOREACH(tabs->tabs, l, tab_item)
2377 {
2378 if (tabs->current == tab_item)
2379 {
2380 snprintf(buf, sizeof(buf), "%i/%i", i, n);
2381 break;
2382 }
2383 i++;
2384 }
2385 if (missed > 0) snprintf(bufmissed, sizeof(bufmissed), "%i", missed);
2386 else bufmissed[0] = '\0';
2387
2388 tab_item = tabs->current;
2389 assert (tab_item->tc->type == TERM_CONTAINER_TYPE_SOLO);
2390 solo = (Solo*)tab_item->tc;
2391 term = solo->term;
1325 2392
1326 if (sp->term) 2393 if (!term->tabcount_spacer)
2394 {
2395 term->tabcount_spacer = evas_object_rectangle_add(evas_object_evas_get(term->bg));
2396 evas_object_color_set(term->tabcount_spacer, 0, 0, 0, 0);
2397 }
2398 elm_coords_finger_size_adjust(1, &w, 1, &h);
2399 evas_object_size_hint_min_set(term->tabcount_spacer, w, h);
2400 edje_object_part_swallow(term->bg, "terminology.tabcount.control",
2401 term->tabcount_spacer);
2402 edje_object_part_text_set(term->bg, "terminology.tabcount.label", buf);
2403 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufmissed);
2404 edje_object_signal_emit(term->bg, "tabcount,on", "terminology");
2405 // this is all below just for tab bar at the top
2406 if (!term->config->notabs)
1327 { 2407 {
1328 _main_term_bg_redo(sp->term); 2408 double v1, v2;
1329 _term_resize_track_stop(sp); 2409
1330 spp->term = sp->term; 2410 v1 = (double)(i-1) / (double)n;
1331 spp->terms = sp->terms; 2411 v2 = (double)i / (double)n;
1332 sp->term = NULL; 2412 if (!term->tab_spacer)
1333 sp->terms = NULL;
1334 _term_resize_track_start(spp);
1335 o = spp->term->bg;
1336 spp->s1 = NULL;
1337 spp->s2 = NULL;
1338 evas_object_del(spp->panes);
1339 spp->panes = NULL;
1340 if (spp->parent)
1341 { 2413 {
1342 elm_object_part_content_unset(spp->parent->panes, slot); 2414 term->tab_spacer = evas_object_rectangle_add(
1343 elm_object_part_content_set(spp->parent->panes, slot, o); 2415 evas_object_evas_get(term->bg));
2416 evas_object_color_set(term->tab_spacer, 0, 0, 0, 0);
2417 elm_coords_finger_size_adjust(1, &w, 1, &h);
2418 evas_object_size_hint_min_set(term->tab_spacer, w, h);
2419 edje_object_part_swallow(term->bg, "terminology.tab", term->tab_spacer);
2420 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
2421 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
2422 edje_object_part_text_set(term->bg, "terminology.tab.title",
2423 solo->tc.title);
2424 edje_object_signal_emit(term->bg, "tabbar,on", "terminology");
2425 edje_object_message_signal_process(term->bg);
1344 } 2426 }
1345 else 2427 else
1346 edje_object_part_swallow(spp->wn->base, "terminology.content", o); 2428 {
1347 _split_tabcount_update(sp, sp->term); 2429 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
2430 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
2431 edje_object_message_signal_process(term->bg);
2432 }
2433 _tabbar_clear(term);
2434 _tabbar_fill(tabs);
1348 } 2435 }
1349 else 2436 else
1350 { 2437 {
1351 spp->s1 = sp->s1; 2438 _tabbar_clear(term);
1352 spp->s2 = sp->s2; 2439 if (term->tab_spacer)
1353 spp->s1->parent = spp;
1354 spp->s2->parent = spp;
1355 spp->horizontal = sp->horizontal;
1356 o = sp->panes;
1357 elm_object_part_content_unset(sp->parent->panes, slot);
1358 elm_object_part_content_unset(sp->parent->panes,
1359 (!strcmp(slot, PANES_TOP)) ?
1360 PANES_BOTTOM : PANES_TOP);
1361 if (spp->parent)
1362 { 2440 {
1363 elm_object_part_content_unset(spp->parent->panes, slot); 2441 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
1364 elm_object_part_content_set(spp->parent->panes, slot, o); 2442 evas_object_del(term->tab_spacer);
2443 term->tab_spacer = NULL;
2444 edje_object_message_signal_process(term->bg);
1365 } 2445 }
1366 else
1367 edje_object_part_swallow(spp->wn->base, "terminology.content", o);
1368 evas_object_del(spp->panes);
1369 spp->panes = o;
1370 sp->s1 = NULL;
1371 sp->s2 = NULL;
1372 sp->panes = NULL;
1373 } 2446 }
1374 _split_free(sp); 2447 if (missed > 0)
2448 edje_object_signal_emit(term->bg, "tabmissed,on", "terminology");
2449 else
2450 edje_object_signal_emit(term->bg, "tabmissed,off", "terminology");
2451}
2452
2453static Tab_Item*
2454tab_item_new(Tabs *tabs, Term_Container *child)
2455{
2456 Tab_Item *tab_item;
2457
2458 tab_item = calloc(1, sizeof(Tab_Item));
2459 tab_item->tc = child;
2460 assert(child != NULL);
2461 assert(child->type == TERM_CONTAINER_TYPE_SOLO);
2462
2463 tabs->tabs = eina_list_append(tabs->tabs, tab_item);
2464
2465 return tab_item;
2466}
2467
2468static void
2469_tabs_split(Term_Container *tc, Term_Container *child EINA_UNUSED,
2470 const char *cmd, Eina_Bool is_horizontal)
2471{
2472 tc->parent->split(tc->parent, tc, cmd, is_horizontal);
2473}
2474
2475static Term_Container *
2476_tabs_new(Term_Container *child, Term_Container *parent)
2477{
2478 Win *wn;
2479 Term_Container *tc;
2480 Tabs *tabs;
2481 Tab_Item *tab_item;
2482
2483 tabs = calloc(1, sizeof(Tabs));
2484 if (!tabs)
2485 {
2486 free(tabs);
2487 return NULL;
2488 }
2489
2490 wn = child->wn;
2491
2492 tc = (Term_Container*)tabs;
2493 tc->term_next = _tabs_term_next;
2494 tc->term_prev = _tabs_term_prev;
2495 tc->term_first = _tabs_term_first;
2496 tc->term_last = _tabs_term_last;
2497 tc->focused_term_get = _tabs_focused_term_get;
2498 tc->get_evas_object = _tabs_get_evas_object;
2499 tc->split = _tabs_split;
2500 tc->find_term_at_coords = _tabs_find_term_at_coords;
2501 tc->size_eval = _tabs_size_eval;
2502 tc->swallow = _tabs_swallow;
2503 tc->focus = _tabs_focus;
2504 tc->unfocus = _tabs_unfocus;
2505 tc->set_title = _tabs_set_title;
2506 tc->bell = _tabs_bell;
2507 tc->close = _tabs_close;
2508 tc->update = _tabs_update;
2509 tc->title = eina_stringshare_add("Terminology");
2510 tc->type = TERM_CONTAINER_TYPE_TABS;
2511
2512 tc->parent = parent;
2513 tc->wn = wn;
2514
2515 child->parent = tc;
2516 tab_item = tab_item_new(tabs, child);
2517 tabs->current = tab_item;
2518
2519 /* XXX: need to refresh */
2520 parent->swallow(parent, child, tc);
2521
2522 tc->is_focused = child->is_focused;
2523
2524 return tc;
1375} 2525}
1376 2526
2527
1377/* }}} */ 2528/* }}} */
1378/* {{{ Term */ 2529/* {{{ Term */
1379 2530
1380void win_term_swallow(Win *wn, Term *term) 2531Eina_Bool
2532term_has_popmedia(const Term *term)
1381{ 2533{
1382 Evas_Object *base = win_base_get(wn); 2534 return !!term->popmedia;
1383 Evas *evas = evas_object_evas_get(base); 2535}
1384 2536
1385 edje_object_part_swallow(base, "terminology.content", term->bg); 2537void
1386 _cb_size_hint(term, evas, term->termio, NULL); 2538term_popmedia_close(Term *term)
2539{
2540 if (term->popmedia)
2541 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
2542}
2543
2544
2545static void
2546_cb_term_mouse_in(void *data, Evas *e EINA_UNUSED,
2547 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2548{
2549 Term *term = data;
2550 Config *config;
2551
2552 if ((!term) || (!term->termio))
2553 return;
2554
2555 config = termio_config_get(term->termio);
2556 if ((!config) || (!config->mouse_over_focus))
2557 return;
2558 if (!_win_is_focused(term->wn))
2559 return;
2560
2561 _term_focus(term, EINA_TRUE);
2562}
2563
2564static void
2565_cb_term_mouse_down(void *data, Evas *e EINA_UNUSED,
2566 Evas_Object *obj EINA_UNUSED, void *event)
2567{
2568 Evas_Event_Mouse_Down *ev = event;
2569 Term *term = data;
2570 Term *term2;
2571 Term_Container *tc;
2572
2573 tc = (Term_Container*) term->wn;
2574 term2 = tc->focused_term_get(tc);
2575 if (term == term2) return;
2576 term->down.x = ev->canvas.x;
2577 term->down.y = ev->canvas.y;
2578 _term_focus(term, EINA_TRUE);
2579}
2580
2581static Eina_Bool
2582_term_is_focused(Term *term)
2583{
2584 Term_Container *tc;
2585
2586 if (!term)
2587 return EINA_FALSE;
2588
2589 tc = term->container;
2590 if (!tc)
2591 return EINA_FALSE;
2592
2593 return tc->is_focused;
1387} 2594}
1388 2595
1389void change_theme(Evas_Object *win, Config *config) 2596void change_theme(Evas_Object *win, Config *config)
@@ -1412,120 +2619,87 @@ void change_theme(Evas_Object *win, Config *config)
1412} 2619}
1413 2620
1414static void 2621static void
1415_term_focus(Term *term) 2622_term_focus(Term *term, Eina_Bool force)
1416{ 2623{
1417 Eina_List *l; 2624 Term_Container *tc;
1418 Term *term2;
1419 Split *sp = NULL;
1420 2625
1421 EINA_LIST_FOREACH(term->wn->terms, l, term2) 2626 if (!force && (_term_is_focused(term) || !_win_is_focused(term->wn)))
1422 { 2627 return;
1423 if (term2 != term)
1424 {
1425 if (term2->focused)
1426 {
1427 term2->focused = EINA_FALSE;
1428 edje_object_signal_emit(term2->bg, "focus,out", "terminology");
1429 edje_object_signal_emit(term2->base, "focus,out", "terminology");
1430 elm_object_focus_set(term2->termio, EINA_FALSE);
1431 }
1432 }
1433 }
1434 term->focused = EINA_TRUE;
1435 edje_object_signal_emit(term->bg, "focus,in", "terminology");
1436 edje_object_signal_emit(term->base, "focus,in", "terminology");
1437 if (term->wn->cmdbox) elm_object_focus_set(term->wn->cmdbox, EINA_FALSE);
1438 elm_object_focus_set(term->termio, EINA_TRUE);
1439 elm_win_title_set(term->wn->win, termio_title_get(term->termio));
1440 if (term->missed_bell)
1441 term->missed_bell = EINA_FALSE;
1442 2628
1443 sp = _split_find(term->wn->win, term->termio, NULL); 2629 tc = term->container;
1444 if (sp) _split_tabcount_update(sp, term); 2630 tc->focus(tc, tc);
1445} 2631}
1446 2632
1447void 2633Term *
1448term_prev(Term *term) 2634term_prev_get(Term *term)
1449{ 2635{
1450 Term *term2 = NULL; 2636 Term_Container *tc = term->container;
1451 Config *config = termio_config_get(term->termio);
1452 2637
1453 if (term->focused) term2 = term_prev_get(term); 2638 return tc->term_prev(tc, tc);
1454 if ((term2 != NULL) && (term2 != term)) 2639}
1455 {
1456 Split *sp, *sp0;
1457 2640
1458 sp0 = _split_find(term->wn->win, term->termio, NULL); 2641void term_prev(Term *term)
1459 sp = _split_find(term2->wn->win, term2->termio, NULL); 2642{
1460 if ((sp == sp0) && (config->tab_zoom >= 0.01) && (config->notabs)) 2643 Term *new_term, *focused_term;
1461 _sel_go(sp, term2); 2644 Win *wn = term->wn;
1462 else 2645 Term_Container *tc;
1463 { 2646
1464 _term_focus(term2); 2647 tc = (Term_Container *) wn;
1465 if (sp) 2648
1466 { 2649 focused_term = tc->focused_term_get(tc);
1467 _term_focus_show(sp, term2); 2650 if (!focused_term)
1468 _split_tabcount_update(sp, term2); 2651 focused_term = term;
1469 } 2652 tc = focused_term->container;
1470 } 2653 new_term = tc->term_prev(tc, tc);
1471 } 2654 if (new_term && new_term != focused_term)
2655 _term_focus(new_term, EINA_FALSE);
2656
2657 /* TODO: get rid of it? */
1472 _term_miniview_check(term); 2658 _term_miniview_check(term);
1473} 2659}
1474 2660
1475void 2661Term *
1476term_next(Term *term) 2662term_next_get(Term *term)
1477{ 2663{
1478 Term *term2 = NULL; 2664 Term_Container *tc = term->container;
1479 Config *config = termio_config_get(term->termio);
1480 2665
1481 if (term->focused) term2 = term_next_get(term); 2666 return tc->term_next(tc, tc);
1482 if ((term2 != NULL) && (term2 != term)) 2667}
1483 {
1484 Split *sp, *sp0;
1485 2668
1486 sp0 = _split_find(term->wn->win, term->termio, NULL); 2669void term_next(Term *term)
1487 sp = _split_find(term2->wn->win, term2->termio, NULL); 2670{
1488 if ((sp == sp0) && (config->tab_zoom >= 0.01) && (config->notabs)) 2671 Term *new_term, *focused_term;
1489 _sel_go(sp, term2); 2672 Win *wn = term->wn;
1490 else 2673 Term_Container *tc;
1491 { 2674
1492 _term_focus(term2); 2675 tc = (Term_Container*) wn;
1493 if (sp) 2676
1494 { 2677 focused_term = tc->focused_term_get(tc);
1495 _term_focus_show(sp, term2); 2678 if (!focused_term)
1496 _split_tabcount_update(sp, term2); 2679 focused_term = term;
1497 } 2680 tc = focused_term->container;
1498 } 2681 new_term = tc->term_next(tc, tc);
1499 } 2682 if (new_term && new_term != focused_term)
2683 _term_focus(new_term, EINA_FALSE);
2684
2685 /* TODO: get rid of it? */
1500 _term_miniview_check(term); 2686 _term_miniview_check(term);
1501} 2687}
1502 2688
1503static void 2689static void
1504_cb_popmedia_del(void *data, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED) 2690_cb_popmedia_del(void *data, Evas *e EINA_UNUSED,
2691 Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED)
1505{ 2692{
1506 Term *term = data; 2693 Term *term = data;
1507 2694
1508 term->popmedia = NULL; 2695 term->popmedia = NULL;
1509 term->popmedia_deleted = EINA_TRUE; 2696 term->popmedia_deleted = EINA_TRUE;
1510 edje_object_signal_emit(term->bg, "popmedia,off", "terminology"); 2697 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
1511} 2698}
1512 2699
1513Eina_Bool
1514term_has_popmedia(const Term *term)
1515{
1516 return !!term->popmedia;
1517}
1518
1519void
1520term_popmedia_close(Term *term)
1521{
1522 if (term->popmedia)
1523 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
1524}
1525
1526
1527static void 2700static void
1528_cb_popmedia_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) 2701_cb_popmedia_done(void *data, Evas_Object *obj EINA_UNUSED,
2702 const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
1529{ 2703{
1530 Term *term = data; 2704 Term *term = data;
1531 2705
@@ -1545,10 +2719,11 @@ _cb_popmedia_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA
1545} 2719}
1546 2720
1547static void 2721static void
1548_cb_media_loop(void *data, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) 2722_cb_media_loop(void *data,
2723 Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED)
1549{ 2724{
1550 Term *term = data; 2725 Term *term = data;
1551 2726
1552 if (term->popmedia_queue) 2727 if (term->popmedia_queue)
1553 { 2728 {
1554 if (term->popmedia) media_play_set(term->popmedia, EINA_FALSE); 2729 if (term->popmedia) media_play_set(term->popmedia, EINA_FALSE);
@@ -1749,7 +2924,6 @@ error:
1749 } 2924 }
1750} 2925}
1751 2926
1752
1753static void 2927static void
1754_term_miniview_check(Term *term) 2928_term_miniview_check(Term *term)
1755{ 2929{
@@ -1762,15 +2936,11 @@ _term_miniview_check(Term *term)
1762 2936
1763 EINA_LIST_FOREACH(wn_list, l, term) 2937 EINA_LIST_FOREACH(wn_list, l, term)
1764 { 2938 {
1765 Split *sp = _split_find(term->wn->win, term->termio, NULL);
1766 if (term->miniview_shown) 2939 if (term->miniview_shown)
1767 { 2940 {
1768 if (term->focused) 2941 if (_term_is_focused(term))
1769 edje_object_signal_emit(term->bg, "miniview,on", "terminology"); 2942 edje_object_signal_emit(term->bg, "miniview,on", "terminology");
1770 else if (sp->term != term)
1771 edje_object_signal_emit(term->bg, "miniview,off", "terminology");
1772 } 2943 }
1773 sp = NULL;
1774 } 2944 }
1775} 2945}
1776 2946
@@ -1809,10 +2979,10 @@ static void
1809_popmedia_queue_process(Term *term) 2979_popmedia_queue_process(Term *term)
1810{ 2980{
1811 const char *src; 2981 const char *src;
1812 2982
1813 if (!term->popmedia_queue) return; 2983 if (!term->popmedia_queue) return;
1814 src = term->popmedia_queue->data; 2984 src = term->popmedia_queue->data;
1815 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue, 2985 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
1816 term->popmedia_queue); 2986 term->popmedia_queue);
1817 if (!src) return; 2987 if (!src) return;
1818 _popmedia(term, src); 2988 _popmedia(term, src);
@@ -1832,6 +3002,7 @@ _cb_popup(void *data, Evas_Object *obj EINA_UNUSED, void *event)
1832{ 3002{
1833 Term *term = data; 3003 Term *term = data;
1834 const char *src = event; 3004 const char *src = event;
3005
1835 if (!src) src = termio_link_get(term->termio); 3006 if (!src) src = termio_link_get(term->termio);
1836 if (!src) return; 3007 if (!src) return;
1837 _popmedia(term, src); 3008 _popmedia(term, src);
@@ -1940,13 +3111,10 @@ _cb_command(void *data, Evas_Object *obj EINA_UNUSED, void *event)
1940} 3111}
1941 3112
1942static void 3113static void
1943_cb_tabcount_go(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) 3114_cb_tabcount_go(void *data, Evas_Object *obj EINA_UNUSED,
3115 const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
1944{ 3116{
1945 Term *term = data; 3117 _cb_select(data, NULL, NULL);
1946 Split *sp;
1947
1948 sp = _split_find(term->wn->win, term->termio, NULL);
1949 _sel_go(sp, term);
1950} 3118}
1951 3119
1952static void 3120static void
@@ -1966,133 +3134,54 @@ _cb_next(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1966} 3134}
1967 3135
1968static void 3136static void
1969_cb_new(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1970{
1971 Term *term = data;
1972
1973 main_new(term->wn->win, term->termio);
1974 _term_miniview_check(term);
1975}
1976
1977void
1978main_term_focus(Term *term EINA_UNUSED)
1979{
1980 Split *sp;
1981
1982 sp = _split_find(term->wn->win, term->termio, NULL);
1983 if (sp->terms->next != NULL)
1984 _sel_go(sp, term);
1985}
1986
1987static void
1988_cb_select(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1989{
1990 Term *term = data;
1991 main_term_focus(term);
1992}
1993
1994static void
1995_cb_split_h(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3137_cb_split_h(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
1996{ 3138{
1997 Term *term = data; 3139 Term *term = data;
3140 Term_Container *tc = term->container;
1998 3141
1999 main_split_h(term->wn->win, term->termio, NULL); 3142 assert(tc->type == TERM_CONTAINER_TYPE_SOLO);
3143 tc->split(tc, tc, NULL, EINA_TRUE);
2000} 3144}
2001 3145
2002static void 3146static void
2003_cb_split_v(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3147_cb_split_v(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2004{ 3148{
2005 Term *term = data; 3149 Term *term = data;
2006 3150 Term_Container *tc = term->container;
2007 main_split_v(term->wn->win, term->termio, NULL); 3151
3152 assert(tc->type == TERM_CONTAINER_TYPE_SOLO);
3153 tc->split(tc, tc, NULL, EINA_FALSE);
2008} 3154}
2009 3155
2010static void 3156static void
2011_cb_title(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3157_cb_title(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2012{ 3158{
2013 Term *term = data; 3159 Term *term = data;
2014 if (term->focused) 3160 Term_Container *tc = term->container;
2015 elm_win_title_set(term->wn->win, termio_title_get(term->termio)); 3161 const char *title = termio_title_get(term->termio);
2016 edje_object_part_text_set(term->bg, "terminology.tab.title",
2017 termio_title_get(term->termio));
2018 if (term->config->notabs)
2019 {
2020 Split *sp = _split_find(term->wn->win, term->termio, NULL);
2021 if (sp)
2022 {
2023 Eina_List *l, *ll;
2024 Evas_Object *o;
2025 Term *term2;
2026 3162
2027 EINA_LIST_FOREACH(sp->terms, l, term) 3163 if (title)
2028 { 3164 tc->set_title(tc, tc, title);
2029 EINA_LIST_FOREACH(term->tabbar.l.tabs, ll, o)
2030 {
2031 term2 = evas_object_data_get(o, "term");
2032 if (term2)
2033 edje_object_part_text_set(o, "terminology.title",
2034 termio_title_get(term2->termio));
2035 }
2036 EINA_LIST_FOREACH(term->tabbar.r.tabs, ll, o)
2037 {
2038 term2 = evas_object_data_get(o, "term");
2039 if (term2)
2040 edje_object_part_text_set(o, "terminology.title",
2041 termio_title_get(term2->termio));
2042 }
2043 }
2044 }
2045 }
2046} 3165}
2047 3166
2048static void 3167static void
2049_cb_icon(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3168_cb_icon(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2050{ 3169{
2051 Term *term = data; 3170 Term *term = data;
2052 if (term->focused) 3171 if (_term_is_focused(term))
2053 elm_win_icon_name_set(term->wn->win, termio_icon_name_get(term->termio)); 3172 elm_win_icon_name_set(term->wn->win, termio_icon_name_get(term->termio));
2054} 3173}
2055 3174
2056static void
2057_tab_go(Term *term, int tnum)
2058{
2059 Term *term2;
2060 Split *sp = _split_find(term->wn->win, term->termio, NULL);
2061 if (!sp) return;
2062
2063 term2 = eina_list_nth(sp->terms, tnum);
2064 if ((!term2) || (term2 == term)) return;
2065 _sel_go(sp, term2);
2066}
2067
2068#define CB_TAB(TAB) \
2069static void \
2070_cb_tab_##TAB(void *data, Evas_Object *obj EINA_UNUSED, \
2071 void *event EINA_UNUSED) \
2072{ \
2073 _tab_go(data, TAB - 1); \
2074}
2075
2076CB_TAB(1)
2077CB_TAB(2)
2078CB_TAB(3)
2079CB_TAB(4)
2080CB_TAB(5)
2081CB_TAB(6)
2082CB_TAB(7)
2083CB_TAB(8)
2084CB_TAB(9)
2085CB_TAB(10)
2086#undef CB_TAB
2087
2088static Eina_Bool 3175static Eina_Bool
2089_cb_cmd_focus(void *data) 3176_cb_cmd_focus(void *data)
2090{ 3177{
2091 Win *wn = data; 3178 Win *wn = data;
2092 Term *term; 3179 Term *term;
2093 3180 Term_Container *tc;
3181
2094 wn->cmdbox_focus_timer = NULL; 3182 wn->cmdbox_focus_timer = NULL;
2095 term = win_focused_term_get(wn); 3183 tc = (Term_Container*) wn;
3184 term = tc->focused_term_get(tc);
2096 if (term) 3185 if (term)
2097 { 3186 {
2098 elm_object_focus_set(term->termio, EINA_FALSE); 3187 elm_object_focus_set(term->termio, EINA_FALSE);
@@ -2105,7 +3194,7 @@ static Eina_Bool
2105_cb_cmd_del(void *data) 3194_cb_cmd_del(void *data)
2106{ 3195{
2107 Win *wn = data; 3196 Win *wn = data;
2108 3197
2109 wn->cmdbox_del_timer = NULL; 3198 wn->cmdbox_del_timer = NULL;
2110 if (wn->cmdbox) 3199 if (wn->cmdbox)
2111 { 3200 {
@@ -2121,10 +3210,12 @@ _cb_cmd_activated(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNU
2121 Win *wn = data; 3210 Win *wn = data;
2122 char *cmd = NULL; 3211 char *cmd = NULL;
2123 Term *term; 3212 Term *term;
2124 3213 Term_Container *tc;
3214
2125 if (wn->cmdbox) elm_object_focus_set(wn->cmdbox, EINA_FALSE); 3215 if (wn->cmdbox) elm_object_focus_set(wn->cmdbox, EINA_FALSE);
2126 edje_object_signal_emit(wn->base, "cmdbox,hide", "terminology"); 3216 edje_object_signal_emit(wn->base, "cmdbox,hide", "terminology");
2127 term = win_focused_term_get(wn); 3217 tc = (Term_Container *) wn;
3218 term = tc->focused_term_get(tc);
2128 if (term) elm_object_focus_set(term->termio, EINA_TRUE); 3219 if (term) elm_object_focus_set(term->termio, EINA_TRUE);
2129 if (wn->cmdbox) cmd = (char *)elm_entry_entry_get(wn->cmdbox); 3220 if (wn->cmdbox) cmd = (char *)elm_entry_entry_get(wn->cmdbox);
2130 if (cmd) 3221 if (cmd)
@@ -2147,14 +3238,17 @@ _cb_cmd_activated(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNU
2147} 3238}
2148 3239
2149static void 3240static void
2150_cb_cmd_aborted(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3241_cb_cmd_aborted(void *data,
3242 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2151{ 3243{
2152 Win *wn = data; 3244 Win *wn = data;
2153 Term *term; 3245 Term *term;
2154 3246 Term_Container *tc;
3247
2155 if (wn->cmdbox) elm_object_focus_set(wn->cmdbox, EINA_FALSE); 3248 if (wn->cmdbox) elm_object_focus_set(wn->cmdbox, EINA_FALSE);
2156 edje_object_signal_emit(wn->base, "cmdbox,hide", "terminology"); 3249 edje_object_signal_emit(wn->base, "cmdbox,hide", "terminology");
2157 term = win_focused_term_get(wn); 3250 tc = (Term_Container*) wn;
3251 term = tc->focused_term_get(tc);
2158 if (term) elm_object_focus_set(term->termio, EINA_TRUE); 3252 if (term) elm_object_focus_set(term->termio, EINA_TRUE);
2159 if (wn->cmdbox_focus_timer) 3253 if (wn->cmdbox_focus_timer)
2160 { 3254 {
@@ -2167,13 +3261,16 @@ _cb_cmd_aborted(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSE
2167} 3261}
2168 3262
2169static void 3263static void
2170_cb_cmd_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3264_cb_cmd_changed(void *data,
3265 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2171{ 3266{
2172 Win *wn = data; 3267 Win *wn = data;
2173 char *cmd = NULL; 3268 char *cmd = NULL;
2174 Term *term; 3269 Term *term;
2175 3270 Term_Container *tc;
2176 term = win_focused_term_get(wn); 3271
3272 tc = (Term_Container *) wn;
3273 term = tc->focused_term_get(tc);
2177 if (!term) return; 3274 if (!term) return;
2178 if (wn->cmdbox) cmd = (char *)elm_entry_entry_get(wn->cmdbox); 3275 if (wn->cmdbox) cmd = (char *)elm_entry_entry_get(wn->cmdbox);
2179 if (cmd) 3276 if (cmd)
@@ -2188,10 +3285,11 @@ _cb_cmd_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSE
2188} 3285}
2189 3286
2190static void 3287static void
2191_cb_cmd_hints_changed(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 3288_cb_cmd_hints_changed(void *data, Evas *e EINA_UNUSED,
3289 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2192{ 3290{
2193 Win *wn = data; 3291 Win *wn = data;
2194 3292
2195 if (wn->cmdbox) 3293 if (wn->cmdbox)
2196 { 3294 {
2197 evas_object_show(wn->cmdbox); 3295 evas_object_show(wn->cmdbox);
@@ -2200,16 +3298,17 @@ _cb_cmd_hints_changed(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNU
2200} 3298}
2201 3299
2202static void 3300static void
2203_cb_cmdbox(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) 3301_cb_cmdbox(void *data,
3302 Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2204{ 3303{
2205 Term *term = data; 3304 Term *term = data;
2206 3305
2207 term->wn->cmdbox_up = EINA_TRUE; 3306 term->wn->cmdbox_up = EINA_TRUE;
2208 if (!term->wn->cmdbox) 3307 if (!term->wn->cmdbox)
2209 { 3308 {
2210 Evas_Object *o; 3309 Evas_Object *o;
2211 Win *wn = term->wn; 3310 Win *wn = term->wn;
2212 3311
2213 wn->cmdbox = o = elm_entry_add(wn->win); 3312 wn->cmdbox = o = elm_entry_add(wn->win);
2214 elm_entry_single_line_set(o, EINA_TRUE); 3313 elm_entry_single_line_set(o, EINA_TRUE);
2215 elm_entry_scrollable_set(o, EINA_FALSE); 3314 elm_entry_scrollable_set(o, EINA_FALSE);
@@ -2245,12 +3344,14 @@ _cb_cmdbox(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
2245 3344
2246 3345
2247static void 3346static void
2248_cb_media_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 3347_cb_media_del(void *data, Evas *e EINA_UNUSED,
3348 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2249{ 3349{
2250 Term *term = data; 3350 Term *term = data;
2251 Config *config = NULL; 3351 Config *config = NULL;
2252 3352
2253 if (term->termio) config = termio_config_get(term->termio); 3353 if (term->termio)
3354 config = termio_config_get(term->termio);
2254 term->media = NULL; 3355 term->media = NULL;
2255 if (term->bg) 3356 if (term->bg)
2256 { 3357 {
@@ -2413,77 +3514,60 @@ main_config_sync(const Config *config)
2413} 3514}
2414 3515
2415static void 3516static void
2416term_free(Term *term) 3517_term_free(Term *term)
2417{ 3518{
2418 const char *s; 3519 const char *s;
2419 3520
2420 EINA_LIST_FREE(term->popmedia_queue, s) 3521 EINA_LIST_FREE(term->popmedia_queue, s)
2421 {