2018-09-29 09:06:41 -07:00
# include "private.h"
2015-03-22 10:17:16 -07:00
# include <assert.h>
2012-06-12 03:10:01 -07:00
# include <Elementary.h>
2018-02-04 15:07:47 -08:00
# include <Ecore_Input.h>
# include <Ecore_IMF.h>
# include <Ecore_IMF_Evas.h>
2012-06-12 03:10:01 -07:00
# include "win.h"
2014-10-26 13:00:14 -07:00
# include "termcmd.h"
2012-06-12 03:10:01 -07:00
# include "config.h"
2013-09-06 11:39:37 -07:00
# include "main.h"
2014-10-26 13:00:14 -07:00
# include "miniview.h"
# include "gravatar.h"
# include "media.h"
# include "termio.h"
2020-06-23 03:48:27 -07:00
# include "theme.h"
2014-10-26 13:00:14 -07:00
# include "sel.h"
# include "controls.h"
2018-02-04 15:07:47 -08:00
# include "keyin.h"
2015-03-22 10:17:16 -07:00
# include "term_container.h"
2014-10-26 13:00:14 -07:00
2015-07-22 14:16:23 -07:00
/**
* Design :
* A terminal widget is Term . It hosts various Evas_Object , like a ` termio `
* handling the textgrid .
* It is hosted in a Term_Container of type Solo .
* On Term_Container :
* It is a generic structure with a set of function pointers . It is a simple
* way to objectify and have genericity between a Window , a Split or Tabs .
* Solo , Win , Split , Tabs have a Term_Container as their first field and thus
* can be casted to Term_Container to have access to those APIs .
*
* Solo is the simplest container , hosting just a Term .
* Win is a window and has only one container child .
* Split is a widget to separate an area of the screen in 2 and thus has 2
* children that can be either Solo or Tabs .
* Tabs is a Term_Container containing many containers ( at the moment , only
* Solo ones ) and have a system of tabs .
*
* All the windows are in the ` wins ` list .
*/
2016-10-17 13:19:23 -07:00
/* specific log domain to help debug code in that file */
2015-06-02 14:11:16 -07:00
int _win_log_dom = - 1 ;
# undef CRITICAL
# undef ERR
# undef WRN
# undef INF
# undef DBG
# define CRITICAL(...) EINA_LOG_DOM_CRIT(_win_log_dom, __VA_ARGS__)
# define ERR(...) EINA_LOG_DOM_ERR(_win_log_dom, __VA_ARGS__)
# define WRN(...) EINA_LOG_DOM_WARN(_win_log_dom, __VA_ARGS__)
# define INF(...) EINA_LOG_DOM_INFO(_win_log_dom, __VA_ARGS__)
# define DBG(...) EINA_LOG_DOM_DBG(_win_log_dom, __VA_ARGS__)
2018-03-13 10:58:41 -07:00
# define PANES_TOP "top"
# define PANES_BOTTOM "bottom"
2014-10-26 13:00:14 -07:00
2020-02-07 11:09:27 -08:00
# define DRAG_TIMEOUT 0.4
2014-10-26 13:00:14 -07:00
/* {{{ Structs */
typedef struct _Split Split ;
2014-12-09 05:32:47 -08:00
typedef struct _Tabbar Tabbar ;
2020-01-19 07:51:17 -08:00
typedef struct _Solo Solo ;
typedef struct _Tabs Tabs ;
typedef struct _Tab_Item Tab_Item ;
2020-02-08 15:30:40 -08:00
typedef struct _Tab_Drag Tab_Drag ;
2020-02-07 11:09:27 -08:00
2020-02-25 14:43:16 -08:00
2020-02-08 15:30:40 -08:00
struct _Tab_Drag
2020-02-07 11:09:27 -08:00
{
Evas_Coord mdx ; /* Mouse-down x */
Evas_Coord mdy ; /* Mouse-down y */
2020-02-29 07:18:07 -08:00
Split_Direction split_direction ;
2020-02-25 14:43:16 -08:00
Term * term_over ;
2020-02-29 07:18:07 -08:00
Term * term ;
2020-02-08 15:30:40 -08:00
Evas_Object * icon ;
2020-03-22 02:53:30 -07:00
Evas_Object * img ;
2020-02-07 11:09:27 -08:00
Evas * e ;
Ecore_Timer * timer ;
2020-03-07 05:58:12 -08:00
/* To be able to restore */
Term_Container_Type parent_type ;
union {
struct {
2020-03-14 08:09:02 -07:00
int previous_position ;
2020-03-07 05:58:12 -08:00
Term_Container * tabs_child ;
} ;
struct {
Term_Container * other ;
2020-04-14 14:40:08 -07:00
double left_size ;
2020-03-07 05:58:12 -08:00
Eina_Bool is_horizontal ;
Eina_Bool is_first_child ;
2020-03-14 08:09:02 -07:00
} ; } ;
2020-02-07 11:09:27 -08:00
} ;
2014-12-09 05:32:47 -08:00
struct _Tabbar
{
struct {
Evas_Object * box ;
} l , r ;
} ;
2014-10-26 13:00:14 -07:00
struct _Term
{
Win * wn ;
Config * config ;
2015-03-22 07:11:10 -07:00
2015-03-22 10:17:16 -07:00
Term_Container * container ;
2014-10-26 13:00:14 -07:00
Evas_Object * bg ;
2019-12-26 12:33:33 -08:00
Evas_Object * bg_edj ;
2019-12-26 04:17:52 -08:00
Evas_Object * core ;
2015-03-22 07:11:10 -07:00
Evas_Object * termio ;
2014-10-26 13:00:14 -07:00
Evas_Object * media ;
Evas_Object * popmedia ;
Evas_Object * miniview ;
2014-12-02 15:42:53 -08:00
Evas_Object * sel ;
2017-12-17 06:36:51 -08:00
Evas_Object * sendfile_request ;
Evas_Object * sendfile_progress ;
Evas_Object * sendfile_progress_bar ;
2014-12-09 05:32:47 -08:00
Evas_Object * tab_spacer ;
Evas_Object * tab_region_base ;
Evas_Object * tab_region_bg ;
2020-01-19 07:51:17 -08:00
Evas_Object * tab_inactive ;
Tab_Item * tab_item ;
2014-10-26 13:00:14 -07:00
Eina_List * popmedia_queue ;
2017-12-17 06:36:51 -08:00
Ecore_Timer * sendfile_request_hide_timer ;
Ecore_Timer * sendfile_progress_hide_timer ;
const char * sendfile_dir ;
2014-10-26 13:00:14 -07:00
Media_Type poptype , mediatype ;
2014-12-09 05:32:47 -08:00
Tabbar tabbar ;
2014-10-26 13:00:14 -07:00
int step_x , step_y , min_w , min_h , req_w , req_h ;
struct {
int x , y ;
} down ;
2015-02-15 11:32:16 -08:00
int refcnt ;
2014-10-26 13:00:14 -07:00
unsigned char hold : 1 ;
unsigned char unswallowed : 1 ;
unsigned char missed_bell : 1 ;
unsigned char miniview_shown : 1 ;
unsigned char popmedia_deleted : 1 ;
2020-04-16 08:44:58 -07:00
unsigned char has_bg_cursor : 1 ;
2020-07-29 13:43:25 -07:00
unsigned char core_cursor_set : 1 ;
2017-12-17 06:36:51 -08:00
Eina_Bool sendfile_request_enabled : 1 ;
Eina_Bool sendfile_progress_enabled : 1 ;
2014-10-26 13:00:14 -07:00
} ;
2015-03-22 10:17:16 -07:00
struct _Solo {
Term_Container tc ;
Term * term ;
} ;
struct _Tab_Item {
Term_Container * tc ;
Evas_Object * obj ;
void * selector_entry ;
} ;
struct _Tabs {
Term_Container tc ;
Evas_Object * selector ;
Evas_Object * selector_bg ;
Eina_List * tabs ; // Tab_Item
Tab_Item * current ;
2020-01-19 07:51:17 -08:00
double v1_orig ;
double v2_orig ;
2015-03-22 10:17:16 -07:00
} ;
struct _Split
{
Term_Container tc ;
Term_Container * tc1 , * tc2 ; // left/right or top/bottom child splits, null if leaf
Evas_Object * panes ;
Term_Container * last_focus ;
unsigned char is_horizontal : 1 ;
} ;
2014-10-26 13:00:14 -07:00
2014-12-02 15:42:51 -08:00
2014-10-26 13:00:14 -07:00
struct _Win
{
2018-02-04 15:07:47 -08:00
Term_Container tc ; /* has to be first field */
2015-03-22 10:17:16 -07:00
2018-02-04 15:07:47 -08:00
Keys_Handler khdl ;
const char * preedit_str ;
2015-03-22 10:17:16 -07:00
Term_Container * child ;
2014-10-26 13:00:14 -07:00
Evas_Object * win ;
Evas_Object * conform ;
Evas_Object * backbg ;
Evas_Object * base ;
Config * config ;
Eina_List * terms ;
2014-12-02 15:42:55 -08:00
Split * split ;
2014-10-26 13:00:14 -07:00
Ecore_Job * size_job ;
Evas_Object * cmdbox ;
Ecore_Timer * cmdbox_del_timer ;
2019-06-30 07:20:40 -07:00
Ecore_Timer * hide_cursor_timer ;
2014-12-02 15:42:36 -08:00
unsigned char focused : 1 ;
2014-10-26 13:00:14 -07:00
unsigned char cmdbox_up : 1 ;
2017-11-13 14:48:05 -08:00
unsigned char group_input : 1 ;
unsigned char group_only_visible : 1 ;
unsigned char group_once_handled : 1 ;
2020-04-06 12:58:21 -07:00
unsigned char translucent : 1 ;
2018-03-10 10:40:13 -08:00
unsigned int on_popover ;
2014-10-26 13:00:14 -07:00
} ;
/* }}} */
2019-12-26 12:39:39 -08:00
/* {{{ static */
2014-10-26 13:00:14 -07:00
static Eina_List * wins = NULL ;
2020-02-17 14:17:06 -08:00
static Tab_Drag * _tab_drag = NULL ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Eina_Bool _win_is_focused ( Win * wn ) ;
static Term_Container * _solo_new ( Term * term , Win * wn ) ;
2020-04-14 14:40:08 -07:00
static Term_Container * _split_new ( Term_Container * tc1 , Term_Container * tc2 ,
double left_size , Eina_Bool is_horizontal ) ;
2015-03-22 10:17:16 -07:00
static Term_Container * _tabs_new ( Term_Container * child , Term_Container * parent ) ;
static void _term_free ( Term * term ) ;
2014-10-26 13:00:14 -07:00
static void _term_media_update ( Term * term , const Config * config ) ;
static void _term_miniview_check ( Term * term ) ;
static void _popmedia_queue_process ( Term * term ) ;
2016-10-05 13:00:22 -07:00
static void _cb_size_hint ( void * data , Evas * _e EINA_UNUSED , Evas_Object * obj , void * _event EINA_UNUSED ) ;
static void _tab_new_cb ( void * data , Evas_Object * _obj EINA_UNUSED , void * _event_info EINA_UNUSED ) ;
2015-03-22 10:17:16 -07:00
static Tab_Item * tab_item_new ( Tabs * tabs , Term_Container * child ) ;
2020-01-19 07:51:17 -08:00
static void _tabs_recreate ( Tabs * tabs ) ;
2020-03-14 08:09:02 -07:00
static void _tab_drag_free ( void ) ;
2016-08-08 03:51:27 -07:00
static void _term_tabregion_free ( Term * term ) ;
2018-02-04 15:07:47 -08:00
static void _imf_event_commit_cb ( void * data , Ecore_IMF_Context * _ctx EINA_UNUSED , void * event ) ;
2014-10-26 13:00:14 -07:00
2020-03-16 15:50:04 -07:00
/* }}} */
/* {{{ Utils */
# ifndef NDEBUG
static void
_focus_validator ( void )
{
Win * wn ;
Term * term ;
Eina_List * l , * ll ;
EINA_LIST_FOREACH ( wins , l , wn )
{
2020-03-30 13:12:45 -07:00
Term_Container * focused_found = NULL ;
2020-03-16 15:50:04 -07:00
if ( wn - > group_input )
continue ;
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
Term_Container * tc = term - > container ;
if ( focused_found )
{
assert ( ! tc - > is_focused ) ;
}
else
{
if ( tc - > is_focused )
{
Term * term_focused ;
2020-03-29 04:33:44 -07:00
Term_Container * tc_parent = tc ;
2020-03-16 15:50:04 -07:00
2020-03-30 13:12:45 -07:00
focused_found = tc ;
2020-03-16 15:50:04 -07:00
do
{
2020-03-29 04:33:44 -07:00
assert ( tc_parent - > is_focused ) ;
tc_parent = tc_parent - > parent ;
2020-05-16 10:07:28 -07:00
if ( tc_parent - > type = = TERM_CONTAINER_TYPE_TABS )
{
Tabs * tabs = ( Tabs * ) tc_parent ;
if ( tabs - > selector_bg )
return ;
}
2020-03-16 15:50:04 -07:00
}
2020-03-29 04:33:44 -07:00
while ( tc_parent - > type ! = TERM_CONTAINER_TYPE_WIN ) ;
assert ( tc_parent - > is_focused ) ;
term_focused = tc_parent - > focused_term_get ( tc_parent ) ;
2020-03-16 15:50:04 -07:00
assert ( term_focused = = term ) ;
}
}
}
}
}
# else
static void
_focus_validator ( void )
{ }
# endif
2020-04-14 13:51:14 -07:00
# define GROUPED_INPUT_TERM_FOREACH(_wn, _list, _term) \
EINA_LIST_FOREACH ( _wn - > terms , _list , _term ) \
if ( ! _wn - > group_only_visible | | term_is_visible ( _term ) )
2019-12-26 12:39:39 -08:00
/* }}} */
/* {{{ Scale */
2019-09-08 10:28:52 -07:00
static void
_scale_round ( void * data EINA_UNUSED ,
Evas_Object * obj ,
void * event_info EINA_UNUSED )
{
double val = elm_slider_value_get ( obj ) ;
double v ;
v = ( ( double ) ( ( int ) ( val * 10.0 ) ) ) / 10.0 ;
if ( v ! = val ) elm_slider_value_set ( obj , v ) ;
}
static void
_scale_change ( void * data EINA_UNUSED ,
Evas_Object * obj ,
void * event_info EINA_UNUSED )
{
double scale = elm_config_scale_get ( ) ;
double val = elm_slider_value_get ( obj ) ;
if ( scale = = val )
return ;
elm_config_scale_set ( val ) ;
elm_config_all_flush ( ) ;
}
typedef struct _Scale_Ctx
{
Evas_Object * hv ;
Term * term ;
} Scale_Ctx ;
static void
_scale_done ( void * data ,
Evas_Object * obj EINA_UNUSED ,
void * event_info EINA_UNUSED )
{
Scale_Ctx * ctx = data ;
evas_object_smart_callback_del_full ( ctx - > hv , " dismissed " ,
_scale_done , ctx ) ;
evas_object_del ( ctx - > hv ) ;
ctx - > term - > wn - > on_popover - - ;
term_unref ( ctx - > term ) ;
elm_config_save ( ) ;
2019-09-08 10:41:16 -07:00
config_save ( ctx - > term - > config ) ;
2019-09-08 10:28:52 -07:00
free ( ctx ) ;
}
void
win_scale_wizard ( Evas_Object * win , Term * term )
{
Evas_Object * bx , * lbl , * sl , * fr , * bt ;
const char * txt ;
Scale_Ctx * ctx ;
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
ctx = calloc ( 1 , sizeof ( * ctx ) ) ;
if ( ! ctx )
return ;
ctx - > term = term ;
term - > wn - > on_popover + + ;
term_ref ( term ) ;
ctx - > hv = elm_hover_add ( win ) ;
evas_object_size_hint_weight_set ( ctx - > hv , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( ctx - > hv , EVAS_HINT_FILL , 0.5 ) ;
elm_hover_parent_set ( ctx - > hv , win ) ;
elm_hover_target_set ( ctx - > hv , win ) ;
evas_object_smart_callback_add ( ctx - > hv , " dismissed " , _scale_done , ctx ) ;
fr = elm_frame_add ( win ) ;
evas_object_size_hint_weight_set ( fr , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( fr , EVAS_HINT_FILL , 0.5 ) ;
elm_object_text_set ( fr , _ ( " Scale " ) ) ;
elm_object_part_content_set ( ctx - > hv , " middle " , fr ) ;
evas_object_show ( fr ) ;
bx = elm_box_add ( win ) ;
evas_object_size_hint_weight_set ( bx , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( bx , EVAS_HINT_FILL , 0.5 ) ;
elm_object_content_set ( fr , bx ) ;
evas_object_show ( bx ) ;
fr = elm_frame_add ( win ) ;
evas_object_size_hint_weight_set ( fr , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( fr , EVAS_HINT_FILL , 0.5 ) ;
elm_object_style_set ( fr , " pad_medium " ) ;
elm_box_pack_end ( bx , fr ) ;
evas_object_show ( fr ) ;
lbl = elm_label_add ( win ) ;
evas_object_size_hint_weight_set ( lbl , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( lbl , EVAS_HINT_FILL , 0.5 ) ;
txt = eina_stringshare_printf ( " <hilight>%s</> " , _ ( " Scale " ) ) ;
elm_object_text_set ( lbl , txt ) ;
eina_stringshare_del ( txt ) ;
elm_object_content_set ( fr , lbl ) ;
elm_box_pack_end ( bx , lbl ) ;
evas_object_show ( lbl ) ;
sl = elm_slider_add ( win ) ;
evas_object_size_hint_weight_set ( sl , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( sl , EVAS_HINT_FILL , 0.5 ) ;
elm_slider_span_size_set ( sl , 120 ) ;
elm_slider_unit_format_set ( sl , " %1.2f " ) ;
elm_slider_indicator_format_set ( sl , " %1.2f " ) ;
elm_slider_min_max_set ( sl , 0.25 , 5.0 ) ;
elm_slider_value_set ( sl , elm_config_scale_get ( ) ) ;
elm_box_pack_end ( bx , sl ) ;
evas_object_show ( sl ) ;
evas_object_smart_callback_add ( sl , " changed " , _scale_round , NULL ) ;
evas_object_smart_callback_add ( sl , " delay,changed " , _scale_change , NULL ) ;
2020-05-19 14:41:39 -07:00
bt = elm_button_add ( win ) ;
elm_object_text_set ( bt , _ ( " Done " ) ) ;
elm_box_pack_end ( bx , bt ) ;
evas_object_smart_callback_add ( bt , " clicked " , _scale_done , ctx ) ;
evas_object_show ( bt ) ;
2019-09-08 10:28:52 -07:00
lbl = elm_label_add ( win ) ;
evas_object_size_hint_weight_set ( lbl , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( lbl , EVAS_HINT_FILL , 0.5 ) ;
2020-09-15 10:40:37 -07:00
elm_object_text_set ( lbl , _ ( " Select preferred size so that this text is readable " ) ) ;
2020-05-19 14:41:39 -07:00
elm_label_line_wrap_set ( lbl , ELM_WRAP_WORD ) ;
2019-09-08 10:28:52 -07:00
elm_box_pack_end ( bx , lbl ) ;
evas_object_show ( lbl ) ;
lbl = elm_label_add ( win ) ;
evas_object_size_hint_weight_set ( lbl , EVAS_HINT_EXPAND , 0.0 ) ;
evas_object_size_hint_align_set ( lbl , EVAS_HINT_FILL , 0.5 ) ;
2020-09-15 10:40:37 -07:00
elm_object_text_set ( lbl , _ ( " The scale configuration can be changed in the Settings (right click on the terminal) → Toolkit, or by starting the command <keyword>elementary_config</keyword> " ) ) ;
2020-05-19 14:41:39 -07:00
elm_label_line_wrap_set ( lbl , ELM_WRAP_WORD ) ;
2019-09-08 10:28:52 -07:00
elm_box_pack_end ( bx , lbl ) ;
evas_object_show ( lbl ) ;
evas_object_show ( ctx - > hv ) ;
elm_object_focus_set ( ctx - > hv , EINA_TRUE ) ;
2020-05-19 14:41:39 -07:00
elm_object_focus_set ( bt , EINA_TRUE ) ;
2019-09-08 10:28:52 -07:00
}
2015-03-22 10:17:16 -07:00
2019-12-26 12:39:39 -08:00
/* }}} */
2015-03-22 10:17:16 -07:00
/* {{{ Solo */
static Evas_Object *
2017-07-06 11:55:02 -07:00
_solo_get_evas_object ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Solo * solo ;
2015-06-11 14:55:35 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
2015-03-22 10:17:16 -07:00
return solo - > term - > bg ;
}
static Term *
2020-03-16 15:50:04 -07:00
_solo_focused_term_get ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Solo * solo ;
2020-03-16 15:50:04 -07:00
Term * term = NULL ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
2015-03-22 10:17:16 -07:00
2020-03-16 15:50:04 -07:00
if ( tc - > is_focused )
term = solo - > term ;
return term ;
2015-03-22 10:17:16 -07:00
}
static Term *
2017-07-06 11:55:02 -07:00
_solo_find_term_at_coords ( const Term_Container * tc ,
2016-10-05 13:00:22 -07:00
Evas_Coord _mx EINA_UNUSED ,
Evas_Coord _my EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
Solo * solo ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
return solo - > term ;
}
static void
_solo_size_eval ( Term_Container * container , Sizeinfo * info )
{
Term * term ;
int mw = 0 , mh = 0 ;
Solo * solo ;
assert ( container - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) container ;
term = solo - > term ;
info - > min_w = term - > min_w ;
info - > min_h = term - > min_h ;
info - > step_x = term - > step_x ;
info - > step_y = term - > step_y ;
info - > req_w = term - > req_w ;
info - > req_h = term - > req_h ;
if ( ! evas_object_data_get ( term - > termio , " sizedone " ) )
{
evas_object_data_set ( term - > termio , " sizedone " , term - > termio ) ;
info - > req = 1 ;
}
evas_object_size_hint_min_get ( term - > bg , & mw , & mh ) ;
info - > bg_min_w = mw ;
info - > bg_min_h = mh ;
}
static void
2016-10-05 13:00:22 -07:00
_solo_close ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
2016-07-31 07:50:13 -07:00
Solo * solo ;
Term * term ;
2016-03-03 04:01:19 -08:00
DBG ( " close " ) ;
2016-07-31 07:50:13 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
2015-03-22 10:17:16 -07:00
tc - > parent - > close ( tc - > parent , tc ) ;
eina_stringshare_del ( tc - > title ) ;
2016-07-31 07:50:13 -07:00
term = solo - > term ;
term - > container = NULL ;
2015-03-22 10:17:16 -07:00
free ( tc ) ;
}
static void
_solo_tabs_new ( Term_Container * tc )
{
if ( tc - > parent - > type ! = TERM_CONTAINER_TYPE_TABS )
_tabs_new ( tc , tc - > parent ) ;
_tab_new_cb ( tc - > parent , NULL , NULL ) ;
}
static void
2016-10-05 13:00:22 -07:00
_solo_split ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED ,
2015-09-19 05:49:40 -07:00
Term * from ,
2016-10-05 13:00:22 -07:00
const char * cmd ,
Eina_Bool is_horizontal )
2015-03-22 10:17:16 -07:00
{
2015-09-19 05:49:40 -07:00
tc - > parent - > split ( tc - > parent , tc , from , cmd , is_horizontal ) ;
2015-03-22 10:17:16 -07:00
}
2020-02-29 07:18:07 -08:00
static int
_solo_split_direction ( Term_Container * tc ,
Term_Container * child_orig EINA_UNUSED ,
Term_Container * child_new ,
Split_Direction direction )
{
return tc - > parent - > split_direction ( tc - > parent , tc , child_new , direction ) ;
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_solo_term_next ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
return tc - > parent - > term_next ( tc - > parent , tc ) ;
}
static Term *
2017-07-06 11:55:02 -07:00
_solo_term_prev ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
2014-12-02 15:42:55 -08:00
{
2015-03-22 10:17:16 -07:00
return tc - > parent - > term_prev ( tc - > parent , tc ) ;
}
2014-12-02 15:42:55 -08:00
2017-07-10 15:01:29 -07:00
static Term *
_solo_term_up ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_up ( tc - > parent , tc ) ;
}
static Term *
_solo_term_down ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_down ( tc - > parent , tc ) ;
}
static Term *
_solo_term_left ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_left ( tc - > parent , tc ) ;
}
static Term *
_solo_term_right ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_right ( tc - > parent , tc ) ;
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_solo_term_first ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Solo * solo ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
return solo - > term ;
2014-12-02 15:42:55 -08:00
}
2014-12-02 15:42:27 -08:00
static Term *
2017-07-06 11:55:02 -07:00
_solo_term_last ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Solo * solo ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
return solo - > term ;
}
static void
2016-10-05 13:00:22 -07:00
_solo_set_title ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED ,
2015-03-22 10:17:16 -07:00
const char * title )
{
2019-09-26 13:49:11 -07:00
Solo * solo ;
Term * term ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
2015-03-22 10:17:16 -07:00
eina_stringshare_del ( tc - > title ) ;
tc - > title = eina_stringshare_add ( title ) ;
2019-09-29 14:03:12 -07:00
if ( term - > config - > show_tabs )
2019-09-26 13:49:11 -07:00
{
2019-12-26 12:33:33 -08:00
elm_layout_text_set ( term - > bg , " terminology.tab.title " , title ) ;
2019-09-26 13:49:11 -07:00
}
2020-02-17 14:17:06 -08:00
if ( _tab_drag & & _tab_drag - > term = = term & & _tab_drag - > icon )
2020-02-07 11:09:27 -08:00
{
2020-02-17 14:17:06 -08:00
elm_layout_text_set ( _tab_drag - > icon ,
2020-02-07 11:09:27 -08:00
" terminology.title " , title ) ;
}
2015-03-22 10:17:16 -07:00
tc - > parent - > set_title ( tc - > parent , tc , title ) ;
}
static void
2016-10-05 13:00:22 -07:00
_solo_bell ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Solo * solo ;
Term * term ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
2014-12-02 15:42:27 -08:00
2019-10-06 14:36:28 -07:00
if ( ! tc - > is_focused )
term - > missed_bell = EINA_TRUE ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
if ( ! tc - > wn - > config - > disable_visual_bell )
2014-12-02 15:42:27 -08:00
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " bell " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " bell " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
if ( tc - > wn - > config - > bell_rings )
2014-12-02 15:42:27 -08:00
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " bell,ring " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " bell,ring " , " terminology " ) ;
2014-12-02 15:42:27 -08:00
}
2020-03-22 02:53:30 -07:00
if ( ( _tab_drag ! = NULL ) & & ( _tab_drag - > term = = term ) )
{
elm_layout_signal_emit ( _tab_drag - > icon , " bell " , " terminology " ) ;
}
2015-03-22 10:17:16 -07:00
}
2019-10-06 14:36:28 -07:00
if ( ( term - > missed_bell ) & & ( term - > config - > show_tabs )
& & ( tc - > parent - > type = = TERM_CONTAINER_TYPE_SPLIT ) )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " tab,bell,on " , " terminology " ) ;
2019-10-06 14:36:28 -07:00
}
2019-12-26 12:33:33 -08:00
edje_object_message_signal_process ( term - > bg_edj ) ;
2015-03-22 10:17:16 -07:00
tc - > parent - > bell ( tc - > parent , tc ) ;
}
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
static void
_solo_unfocus ( Term_Container * tc , Term_Container * relative )
{
Solo * solo ;
Term * term ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
2020-03-30 13:12:45 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d term:%p " ,
tc , tc - > is_focused , tc - > parent = = relative , term ) ;
2015-03-22 10:17:16 -07:00
if ( ! tc - > is_focused )
return ;
2015-09-20 06:51:57 -07:00
tc - > is_focused = EINA_FALSE ;
2017-11-13 14:48:05 -08:00
termio_focus_out ( term - > termio ) ;
2015-09-20 06:51:57 -07:00
2015-03-22 10:17:16 -07:00
if ( tc - > parent ! = relative )
tc - > parent - > unfocus ( tc - > parent , tc ) ;
2017-03-13 09:02:52 -07:00
if ( ! term - > config - > disable_focus_visuals )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focus,out " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focus,out " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
2015-03-22 10:17:16 -07:00
}
static void
_solo_focus ( Term_Container * tc , Term_Container * relative )
{
Solo * solo ;
Term * term ;
const char * title ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
2015-07-15 14:17:24 -07:00
if ( ! tc - > parent )
return ;
2020-03-30 13:12:45 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d term:%p " ,
tc , tc - > is_focused , tc - > parent = = relative , term ) ;
2015-03-22 10:17:16 -07:00
if ( tc - > is_focused )
return ;
term - > missed_bell = EINA_FALSE ;
2019-10-06 14:36:28 -07:00
if ( ( term - > config - > show_tabs )
& & ( tc - > parent - > type = = TERM_CONTAINER_TYPE_SPLIT ) )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " tab,bell,off " , " terminology " ) ;
2019-10-06 14:36:28 -07:00
}
2015-03-22 10:17:16 -07:00
2017-03-13 09:02:52 -07:00
if ( term - > config - > disable_focus_visuals )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focused,set " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focused,set " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
else
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focus,in " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focus,in " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
2018-02-08 13:38:55 -08:00
termio_event_feed_mouse_in ( term - > termio ) ;
2018-02-09 13:02:19 -08:00
termio_focus_in ( term - > termio ) ;
2018-02-08 13:38:55 -08:00
2015-03-22 10:17:16 -07:00
title = termio_title_get ( term - > termio ) ;
if ( title )
tc - > set_title ( tc , tc , title ) ;
if ( term - > missed_bell )
term - > missed_bell = EINA_FALSE ;
2019-12-26 12:33:33 -08:00
edje_object_message_signal_process ( term - > bg_edj ) ;
2020-03-30 13:29:21 -07:00
if ( ! tc - > is_focused & & relative ! = tc - > parent )
{
tc - > is_focused = EINA_TRUE ;
tc - > parent - > focus ( tc - > parent , tc ) ;
}
tc - > is_focused = EINA_TRUE ;
2020-03-29 04:33:44 -07:00
_focus_validator ( ) ;
2015-03-22 10:17:16 -07:00
}
2018-02-11 02:48:06 -08:00
static Eina_Bool
2020-04-11 01:01:13 -07:00
_solo_is_visible ( const Term_Container * tc , const Term_Container * _child EINA_UNUSED )
2018-02-11 02:48:06 -08:00
{
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
return tc - > parent - > is_visible ( tc - > parent , tc ) ;
}
2019-09-26 13:49:11 -07:00
static void
2020-03-16 15:50:04 -07:00
_solo_tab_show ( Term_Container * tc )
2019-09-26 13:49:11 -07:00
{
Solo * solo ;
Term * term ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
2020-03-16 15:50:04 -07:00
DBG ( " tab show tc:%p " , tc ) ;
2019-09-26 13:49:11 -07:00
if ( ! term - > tab_spacer )
{
Evas_Coord w = 0 , h = 0 ;
term - > tab_spacer = evas_object_rectangle_add (
evas_object_evas_get ( term - > bg ) ) ;
evas_object_color_set ( term - > tab_spacer , 0 , 0 , 0 , 0 ) ;
elm_coords_finger_size_adjust ( 1 , & w , 1 , & h ) ;
evas_object_size_hint_min_set ( term - > tab_spacer , w , h ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.tab " , term - > tab_spacer ) ;
edje_object_part_drag_value_set ( term - > bg_edj ,
" terminology.tabl " , 0.0 , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj ,
" terminology.tabr " , 1.0 , 0.0 ) ;
elm_layout_text_set ( term - > bg , " terminology.tab.title " ,
solo - > tc . title ) ;
elm_layout_signal_emit ( term - > bg , " tabbar,on " , " terminology " ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
2019-09-26 13:49:11 -07:00
}
else
{
2019-12-26 12:33:33 -08:00
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabl " , 0.0 , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabr " , 1.0 , 0.0 ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
2019-09-26 13:49:11 -07:00
}
}
static void
2020-03-16 15:50:04 -07:00
_solo_tab_hide ( Term_Container * tc )
2019-09-26 13:49:11 -07:00
{
Solo * solo ;
Term * term ;
2020-03-16 15:50:04 -07:00
DBG ( " title hide tc:%p " , tc ) ;
2019-09-26 13:49:11 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
if ( term - > tab_spacer )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " tabbar,off " , " terminology " ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
elm_layout_content_unset ( term - > bg , " terminology.tab " ) ;
2019-09-26 13:49:11 -07:00
evas_object_del ( term - > tab_spacer ) ;
term - > tab_spacer = NULL ;
}
}
2019-09-30 12:54:53 -07:00
static void
_solo_update ( Term_Container * tc )
{
Solo * solo ;
Term * term ;
Term_Container * tc_parent = tc - > parent ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tc ;
term = solo - > term ;
if ( tc_parent - > type = = TERM_CONTAINER_TYPE_SPLIT )
{
if ( term - > config - > show_tabs )
2020-03-16 15:50:04 -07:00
_solo_tab_show ( tc ) ;
2019-09-30 12:54:53 -07:00
else
2020-03-16 15:50:04 -07:00
_solo_tab_hide ( tc ) ;
2019-09-30 12:54:53 -07:00
}
}
static Term_Container *
_solo_new ( Term * term , Win * wn )
{
Term_Container * tc = NULL ;
Solo * solo = NULL ;
solo = calloc ( 1 , sizeof ( Solo ) ) ;
if ( ! solo )
{
free ( solo ) ;
return NULL ;
}
tc = ( Term_Container * ) solo ;
tc - > term_next = _solo_term_next ;
tc - > term_prev = _solo_term_prev ;
tc - > term_up = _solo_term_up ;
tc - > term_down = _solo_term_down ;
tc - > term_left = _solo_term_left ;
tc - > term_right = _solo_term_right ;
tc - > term_first = _solo_term_first ;
tc - > term_last = _solo_term_last ;
tc - > focused_term_get = _solo_focused_term_get ;
tc - > get_evas_object = _solo_get_evas_object ;
tc - > split = _solo_split ;
2020-02-29 07:18:07 -08:00
tc - > split_direction = _solo_split_direction ;
2019-09-30 12:54:53 -07:00
tc - > find_term_at_coords = _solo_find_term_at_coords ;
tc - > size_eval = _solo_size_eval ;
tc - > swallow = NULL ;
tc - > focus = _solo_focus ;
tc - > unfocus = _solo_unfocus ;
tc - > set_title = _solo_set_title ;
tc - > bell = _solo_bell ;
tc - > close = _solo_close ;
tc - > update = _solo_update ;
tc - > title = eina_stringshare_add ( " Terminology " ) ;
tc - > is_visible = _solo_is_visible ;
2020-02-15 07:47:47 -08:00
tc - > detach = NULL ;
2019-09-30 12:54:53 -07:00
tc - > type = TERM_CONTAINER_TYPE_SOLO ;
tc - > parent = NULL ;
tc - > wn = wn ;
solo - > term = term ;
term - > container = tc ;
return tc ;
}
2015-03-22 10:17:16 -07:00
/* }}} */
/* {{{ Win */
2014-12-02 15:42:27 -08:00
static void
2015-03-22 10:17:16 -07:00
_cb_win_focus_in ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-12-02 15:42:27 -08:00
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc = ( Term_Container * ) wn ;
2014-12-02 15:42:27 -08:00
Term * term ;
2017-11-13 14:48:05 -08:00
DBG ( " FOCUS_IN tc:%p tc->is_focused:%d " ,
2015-06-02 14:11:16 -07:00
tc , tc - > is_focused ) ;
2015-05-06 12:30:18 -07:00
if ( ! tc - > is_focused )
elm_win_urgent_set ( wn - > win , EINA_FALSE ) ;
2015-03-22 10:17:16 -07:00
tc - > is_focused = EINA_TRUE ;
2018-03-10 10:40:13 -08:00
if ( wn - > on_popover )
2018-03-10 08:22:52 -08:00
return ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
term = tc - > focused_term_get ( tc ) ;
2014-12-02 15:42:27 -08:00
2020-04-14 13:51:14 -07:00
if ( wn - > group_input )
{
Eina_List * l ;
Term * t ;
GROUPED_INPUT_TERM_FOREACH ( wn , l , t )
{
elm_layout_signal_emit ( t - > bg , " focus,in " , " terminology " ) ;
termio_event_feed_mouse_in ( t - > termio ) ;
termio_focus_in ( t - > termio ) ;
}
}
else if ( wn - > config - > mouse_over_focus )
2014-12-02 15:42:27 -08:00
{
Term * term_mouse ;
2015-03-22 10:17:16 -07:00
Evas_Coord mx , my ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
evas_pointer_canvas_xy_get ( evas_object_evas_get ( wn - > win ) , & mx , & my ) ;
term_mouse = tc - > find_term_at_coords ( tc , mx , my ) ;
2014-12-02 15:42:27 -08:00
if ( ( term_mouse ) & & ( term_mouse ! = term ) )
{
if ( term )
{
2017-03-13 09:02:52 -07:00
if ( ! term - > config - > disable_focus_visuals )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focus,out " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focus,out " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
2014-12-02 15:42:27 -08:00
}
term = term_mouse ;
}
}
2015-03-22 10:17:16 -07:00
if ( term )
2018-03-13 10:15:57 -07:00
{
2018-03-19 14:11:53 -07:00
term_focus ( term ) ;
2018-03-13 10:15:57 -07:00
}
2014-12-02 15:42:43 -08:00
else
2018-03-13 10:15:57 -07:00
{
DBG ( " focus tc:%p " , tc ) ;
tc - > focus ( tc , tc ) ;
}
2014-12-02 15:42:27 -08:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_win_focus_out ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-12-02 15:42:27 -08:00
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc = ( Term_Container * ) wn ;
2014-12-02 15:42:27 -08:00
2017-11-13 14:48:05 -08:00
DBG ( " FOCUS OUT tc:%p tc->is_focused:%d " ,
2015-06-02 14:11:16 -07:00
tc , tc - > is_focused ) ;
2015-03-22 10:17:16 -07:00
tc - > unfocus ( tc , NULL ) ;
2020-04-14 13:51:14 -07:00
if ( wn - > group_input )
{
Eina_List * l ;
Term * term ;
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
{
elm_layout_signal_emit ( term - > bg , " focus,out " , " terminology " ) ;
termio_focus_out ( term - > termio ) ;
}
}
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
static Eina_Bool
_win_is_focused ( Win * wn )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Term_Container * tc ;
2015-05-31 08:38:02 -07:00
2015-03-22 10:17:16 -07:00
if ( ! wn )
return EINA_FALSE ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tc = ( Term_Container * ) wn ;
2014-12-02 15:42:47 -08:00
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d " ,
tc , tc - > is_focused ) ;
2015-03-22 10:17:16 -07:00
return tc - > is_focused ;
}
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
int win_term_set ( Win * wn , Term * term )
{
Term_Container * tc_win = NULL , * tc_child = NULL ;
2014-12-02 15:42:36 -08:00
2015-03-22 10:17:16 -07:00
tc_child = _solo_new ( term , wn ) ;
if ( ! tc_child )
goto bad ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tc_win = ( Term_Container * ) wn ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tc_win - > swallow ( tc_win , NULL , tc_child ) ;
2014-12-02 15:42:27 -08:00
2019-05-22 14:03:03 -07:00
_cb_size_hint ( term , NULL , term - > termio , NULL ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
return 0 ;
bad :
free ( tc_child ) ;
return - 1 ;
}
2014-10-26 13:00:14 -07:00
2017-07-06 11:55:02 -07:00
Config *
win_config_get ( const Win * wn )
2014-10-26 13:00:14 -07:00
{
return wn - > config ;
}
2017-07-06 11:55:02 -07:00
Eina_List *
win_terms_get ( const Win * wn )
2014-10-26 13:00:14 -07:00
{
return wn - > terms ;
}
2012-06-12 03:10:01 -07:00
Evas_Object *
2017-07-06 11:55:02 -07:00
win_evas_object_get ( const Win * wn )
2014-10-26 13:00:14 -07:00
{
return wn - > win ;
}
static void
2020-04-06 12:58:21 -07:00
_term_trans ( Term * term )
2014-10-26 13:00:14 -07:00
{
Edje_Message_Int msg ;
2019-12-26 04:17:52 -08:00
Evas_Object * edje = elm_layout_edje_get ( term - > core ) ;
2020-04-06 12:58:21 -07:00
Win * wn = term - > wn ;
2014-10-26 13:00:14 -07:00
if ( term - > config - > translucent )
msg . val = term - > config - > opacity ;
else
msg . val = 100 ;
2020-04-05 15:53:34 -07:00
edje_object_message_send ( term - > bg_edj , EDJE_MESSAGE_INT , 1 , & msg ) ;
2019-05-22 14:03:03 -07:00
edje_object_message_send ( edje , EDJE_MESSAGE_INT , 1 , & msg ) ;
2014-10-26 13:00:14 -07:00
2020-04-06 12:58:21 -07:00
if ( term - > config - > translucent ! = wn - > translucent )
2014-10-26 13:00:14 -07:00
{
2020-04-06 12:58:21 -07:00
if ( term - > config - > translucent )
{
elm_win_alpha_set ( wn - > win , EINA_TRUE ) ;
evas_object_hide ( wn - > backbg ) ;
wn - > translucent = EINA_TRUE ;
}
else
{
elm_win_alpha_set ( wn - > win , EINA_FALSE ) ;
evas_object_show ( wn - > backbg ) ;
wn - > translucent = EINA_FALSE ;
}
2014-10-26 13:00:14 -07:00
}
}
void
2020-04-05 13:59:46 -07:00
main_trans_update ( void )
2014-10-26 13:00:14 -07:00
{
Win * wn ;
2020-04-05 13:59:46 -07:00
Term * term ;
2014-10-26 13:00:14 -07:00
Eina_List * l , * ll ;
EINA_LIST_FOREACH ( wins , l , wn )
{
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
2020-04-06 12:58:21 -07:00
_term_trans ( term ) ;
2014-10-26 13:00:14 -07:00
}
}
}
static void
2016-10-05 13:00:22 -07:00
_cb_del ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Win * wn = data ;
// already obj here is deleted - dont do it again
wn - > win = NULL ;
win_free ( wn ) ;
}
void
win_free ( Win * wn )
{
Term * term ;
wins = eina_list_remove ( wins , wn ) ;
EINA_LIST_FREE ( wn - > terms , term )
{
2015-02-15 11:32:16 -08:00
term_unref ( term ) ;
2014-10-26 13:00:14 -07:00
}
if ( wn - > cmdbox_del_timer )
{
ecore_timer_del ( wn - > cmdbox_del_timer ) ;
wn - > cmdbox_del_timer = NULL ;
}
if ( wn - > cmdbox )
{
evas_object_del ( wn - > cmdbox ) ;
wn - > cmdbox = NULL ;
}
if ( wn - > win )
{
2015-09-02 12:39:01 -07:00
evas_object_smart_callback_del_full ( wn - > win , " focus,in " , _cb_win_focus_in , wn ) ;
evas_object_smart_callback_del_full ( wn - > win , " focus,out " , _cb_win_focus_out , wn ) ;
2014-10-26 13:00:14 -07:00
evas_object_event_callback_del_full ( wn - > win , EVAS_CALLBACK_DEL , _cb_del , wn ) ;
evas_object_del ( wn - > win ) ;
}
2018-02-04 15:07:47 -08:00
if ( wn - > size_job )
ecore_job_del ( wn - > size_job ) ;
2019-11-29 10:59:57 -08:00
config_del ( wn - > config ) ;
eina_stringshare_del ( wn - > preedit_str ) ;
2018-02-04 15:07:47 -08:00
keyin_compose_seq_reset ( & wn - > khdl ) ;
if ( wn - > khdl . imf )
{
ecore_imf_context_event_callback_del
( wn - > khdl . imf , ECORE_IMF_CALLBACK_COMMIT , _imf_event_commit_cb ) ;
ecore_imf_context_del ( wn - > khdl . imf ) ;
}
2019-10-14 12:54:47 -07:00
if ( wn - > hide_cursor_timer )
{
ecore_timer_del ( wn - > hide_cursor_timer ) ;
}
2018-02-04 15:07:47 -08:00
ecore_imf_shutdown ( ) ;
2014-10-26 13:00:14 -07:00
free ( wn ) ;
}
2020-04-11 00:50:38 -07:00
Win *
win_evas_object_to_win ( const Evas_Object * win )
2014-10-26 13:00:14 -07:00
{
Win * wn ;
Eina_List * l ;
EINA_LIST_FOREACH ( wins , l , wn )
{
if ( wn - > win = = win ) return wn ;
}
return NULL ;
}
Eina_List *
terms_from_win_object ( Evas_Object * win )
{
Win * wn ;
2020-04-11 00:50:38 -07:00
wn = win_evas_object_to_win ( win ) ;
2014-10-26 13:00:14 -07:00
if ( ! wn ) return NULL ;
return wn - > terms ;
}
static Evas_Object *
2016-02-09 11:59:32 -08:00
win_add ( const char * name , const char * role ,
const char * title , const char * icon_name )
2012-06-12 03:10:01 -07:00
{
2016-07-19 09:56:54 -07:00
Evas_Object * win ;
2012-06-12 17:26:00 -07:00
2012-07-05 03:04:39 -07:00
if ( ! name ) name = " main " ;
if ( ! title ) title = " Terminology " ;
2016-07-19 09:56:54 -07:00
if ( ! icon_name ) icon_name = " terminology " ;
2014-10-26 13:00:14 -07:00
2012-07-05 03:04:39 -07:00
win = elm_win_add ( NULL , name , ELM_WIN_BASIC ) ;
elm_win_title_set ( win , title ) ;
elm_win_icon_name_set ( win , icon_name ) ;
if ( role ) elm_win_role_set ( win , role ) ;
2014-10-26 13:00:14 -07:00
2012-06-12 03:10:01 -07:00
elm_win_autodel_set ( win , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
2012-06-12 03:10:01 -07:00
return win ;
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Evas_Object *
2017-07-06 11:55:02 -07:00
_win_get_evas_object ( const Term_Container * tc )
2014-10-26 13:00:14 -07:00
{
Win * wn ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
wn = ( Win * ) tc ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
return wn - > win ;
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_term_next ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child )
2015-03-22 10:17:16 -07:00
{
return child - > term_first ( child ) ;
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_term_prev ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child )
2015-03-22 10:17:16 -07:00
{
return child - > term_last ( child ) ;
}
2014-10-26 13:00:14 -07:00
2017-07-10 15:01:29 -07:00
static Term *
_win_term_up ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child EINA_UNUSED )
{
return NULL ;
}
static Term *
_win_term_down ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child EINA_UNUSED )
{
return NULL ;
}
static Term *
_win_term_left ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child EINA_UNUSED )
{
return NULL ;
}
static Term *
_win_term_right ( const Term_Container * _tc EINA_UNUSED ,
const Term_Container * child EINA_UNUSED )
{
return NULL ;
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_term_first ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
wn = ( Win * ) tc ;
return wn - > child - > term_first ( wn - > child ) ;
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_term_last ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
wn = ( Win * ) tc ;
return wn - > child - > term_last ( wn - > child ) ;
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_focused_term_get ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
2020-03-16 15:50:04 -07:00
Term * term = NULL ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
wn = ( Win * ) tc ;
2020-04-29 13:53:02 -07:00
if ( tc - > is_focused & & wn - > child )
2020-03-16 15:50:04 -07:00
term = wn - > child - > focused_term_get ( wn - > child ) ;
return term ;
2014-10-26 13:00:14 -07:00
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_win_find_term_at_coords ( const Term_Container * tc ,
2015-03-22 10:17:16 -07:00
Evas_Coord mx , Evas_Coord my )
2014-10-26 13:00:14 -07:00
{
2015-03-22 10:17:16 -07:00
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
2014-12-02 15:42:53 -08:00
2015-03-22 10:17:16 -07:00
wn = ( Win * ) tc ;
2014-12-02 15:42:27 -08:00
2020-04-29 13:53:02 -07:00
if ( ! wn - > child )
return NULL ;
2015-03-22 10:17:16 -07:00
return wn - > child - > find_term_at_coords ( wn - > child , mx , my ) ;
}
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
static void
_win_size_eval ( Term_Container * tc , Sizeinfo * info )
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2020-04-29 13:53:02 -07:00
assert ( wn - > child ) ;
2015-03-22 10:17:16 -07:00
wn - > child - > size_eval ( wn - > child , info ) ;
}
static void
_win_swallow ( Term_Container * tc , Term_Container * orig ,
Term_Container * new_child )
{
Win * wn ;
Evas_Object * o ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2016-03-03 04:01:19 -08:00
DBG ( " orig:%p " , orig ) ;
2015-03-22 10:17:16 -07:00
if ( orig )
{
2019-05-22 14:03:03 -07:00
elm_layout_content_unset ( wn - > base , " terminology.content " ) ;
2015-03-22 10:17:16 -07:00
}
2015-06-11 14:55:35 -07:00
2015-03-22 10:17:16 -07:00
o = new_child - > get_evas_object ( new_child ) ;
2019-05-22 14:03:03 -07:00
elm_layout_content_set ( wn - > base , " terminology.content " , o ) ;
2015-06-11 14:55:35 -07:00
2020-03-07 05:58:12 -08:00
if ( ( new_child - > type = = TERM_CONTAINER_TYPE_SOLO )
& & ( wn - > config - > show_tabs ) )
2019-09-26 13:49:11 -07:00
{
2020-04-16 10:35:19 -07:00
if ( _tab_drag & & _tab_drag - > term & & ( _tab_drag - > term - > wn = = wn ) & &
_tab_drag - > icon )
2020-03-16 15:50:04 -07:00
_solo_tab_show ( new_child ) ;
else
_solo_tab_hide ( new_child ) ;
2019-09-26 13:49:11 -07:00
}
2015-03-22 10:17:16 -07:00
evas_object_show ( o ) ;
new_child - > parent = tc ;
wn - > child = new_child ;
2020-03-14 15:32:02 -07:00
if ( _tab_drag & & _tab_drag - > icon )
{
evas_object_raise ( _tab_drag - > icon ) ;
}
2015-03-22 10:17:16 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_win_close ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2020-03-15 01:28:31 -07:00
DBG ( " win close " ) ;
if ( _tab_drag & & _tab_drag - > term & & ( _tab_drag - > term - > wn = = wn ) )
{
_tab_drag - > parent_type = TERM_CONTAINER_TYPE_WIN ;
_tab_drag_free ( ) ;
return ;
}
2015-03-22 10:17:16 -07:00
eina_stringshare_del ( tc - > title ) ;
win_free ( wn ) ;
}
static void
2015-06-02 14:11:16 -07:00
_win_focus ( Term_Container * tc , Term_Container * relative )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_child:%d " ,
tc , tc - > is_focused , wn - > child = = relative ) ;
2020-03-30 13:29:21 -07:00
if ( ! tc - > is_focused )
elm_win_urgent_set ( wn - > win , EINA_FALSE ) ;
tc - > is_focused = EINA_TRUE ;
2019-04-15 09:19:33 -07:00
if ( ( relative ! = wn - > child ) | | ( ! wn - > focused ) )
2018-02-04 15:07:47 -08:00
{
2018-05-13 13:44:37 -07:00
DBG ( " focus tc:%p " , tc ) ;
2018-02-04 15:07:47 -08:00
wn - > child - > focus ( wn - > child , tc ) ;
elm_win_keyboard_mode_set ( wn - > win , ELM_WIN_KEYBOARD_TERMINAL ) ;
if ( wn - > khdl . imf )
{
Term * focused ;
2015-03-22 10:17:16 -07:00
2018-02-04 15:07:47 -08:00
ecore_imf_context_input_panel_show ( wn - > khdl . imf ) ;
ecore_imf_context_reset ( wn - > khdl . imf ) ;
ecore_imf_context_focus_in ( wn - > khdl . imf ) ;
focused = tc - > focused_term_get ( tc ) ;
if ( focused )
termio_imf_cursor_set ( focused - > termio , wn - > khdl . imf ) ;
}
}
2015-03-22 10:17:16 -07:00
}
static void
_win_unfocus ( Term_Container * tc , Term_Container * relative )
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_child:%d " ,
tc , tc - > is_focused , wn - > child = = relative ) ;
2018-02-04 15:07:47 -08:00
elm_win_keyboard_mode_set ( wn - > win , ELM_WIN_KEYBOARD_OFF ) ;
2016-03-06 04:20:36 -08:00
if ( relative ! = wn - > child & & wn - > child )
2015-06-01 12:19:14 -07:00
{
2018-02-04 15:07:47 -08:00
if ( wn - > khdl . imf )
{
Term * focused ;
ecore_imf_context_reset ( wn - > khdl . imf ) ;
focused = tc - > focused_term_get ( tc ) ;
if ( focused )
termio_imf_cursor_set ( focused - > termio , wn - > khdl . imf ) ;
ecore_imf_context_focus_out ( wn - > khdl . imf ) ;
ecore_imf_context_input_panel_hide ( wn - > khdl . imf ) ;
}
2015-06-01 12:19:14 -07:00
tc - > is_focused = EINA_FALSE ;
wn - > child - > unfocus ( wn - > child , tc ) ;
}
2015-03-22 10:17:16 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_win_bell ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
if ( tc - > is_focused ) return ;
if ( wn - > config - > urg_bell )
{
elm_win_urgent_set ( wn - > win , EINA_TRUE ) ;
}
}
static void
2016-10-05 13:00:22 -07:00
_win_set_title ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED ,
2015-03-22 10:17:16 -07:00
const char * title )
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
eina_stringshare_del ( tc - > title ) ;
tc - > title = eina_stringshare_ref ( title ) ;
elm_win_title_set ( wn - > win , title ) ;
}
2015-08-05 02:40:54 -07:00
Eina_Bool
2015-08-06 12:50:58 -07:00
_term_container_is_splittable ( Term_Container * tc , Eina_Bool is_horizontal )
2015-08-05 02:40:54 -07:00
{
2015-08-06 12:50:58 -07:00
int w = 0 , h = 0 , c_w = 0 , c_h = 0 ;
Term * tm ;
2015-09-26 03:01:42 -07:00
if ( terminology_starting_up )
return EINA_TRUE ;
2015-08-06 12:50:58 -07:00
tm = tc - > term_first ( tc ) ;
2015-08-08 03:05:04 -07:00
evas_object_geometry_get ( tm - > bg , NULL , NULL , & w , & h ) ;
2015-08-05 02:40:54 -07:00
evas_object_textgrid_cell_size_get ( termio_textgrid_get ( tm - > termio ) ,
& c_w , & c_h ) ;
if ( is_horizontal )
{
2015-08-06 12:50:58 -07:00
if ( c_h * 2 > h )
2015-08-05 02:40:54 -07:00
return EINA_FALSE ;
}
else
{
2015-08-06 12:50:58 -07:00
if ( c_w * 2 > w )
2015-08-05 02:40:54 -07:00
return EINA_FALSE ;
}
return EINA_TRUE ;
}
2015-03-22 10:17:16 -07:00
static void
2015-09-19 05:49:40 -07:00
_win_split ( Term_Container * tc , Term_Container * child ,
Term * from , const char * cmd , Eina_Bool is_horizontal )
2015-03-22 10:17:16 -07:00
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2015-08-06 12:50:58 -07:00
if ( _term_container_is_splittable ( tc , is_horizontal ) )
2015-08-05 02:40:54 -07:00
{
2015-08-06 12:50:58 -07:00
Term * tm_new , * tm ;
Term_Container * tc_split , * tc_solo_new ;
2015-12-26 02:59:08 -08:00
char * wdir = NULL ;
2016-01-07 13:56:53 -08:00
char buf [ PATH_MAX ] ;
2015-08-06 12:50:58 -07:00
2015-12-26 02:59:08 -08:00
// copy the current path to wdir if we should change the directory,
// passing wdir NULL otherwise:
if ( wn - > config - > changedir_to_current )
{
if ( from )
tm = from ;
else
tm = tc - > focused_term_get ( tc ) ;
if ( tm & & termio_cwd_get ( tm - > termio , buf , sizeof ( buf ) ) )
wdir = buf ;
}
2015-08-05 02:40:54 -07:00
tm_new = term_new ( wn , wn - > config ,
cmd , wn - > config - > login_shell , wdir ,
2017-08-28 12:36:48 -07:00
80 , 24 , EINA_FALSE , NULL ) ;
2015-08-05 02:40:54 -07:00
tc_solo_new = _solo_new ( tm_new , wn ) ;
evas_object_data_set ( tm_new - > termio , " sizedone " , tm_new - > termio ) ;
2019-05-22 14:03:03 -07:00
elm_layout_content_unset ( wn - > base , " terminology.content " ) ;
2015-03-22 10:17:16 -07:00
2020-04-14 14:40:08 -07:00
tc_split = _split_new ( child , tc_solo_new , 0.5 , is_horizontal ) ;
2019-09-29 14:03:12 -07:00
if ( wn - > config - > show_tabs )
2019-09-26 13:49:11 -07:00
{
if ( child - > type = = TERM_CONTAINER_TYPE_SOLO )
{
2020-03-16 15:50:04 -07:00
_solo_tab_show ( child ) ;
2019-09-26 13:49:11 -07:00
}
2020-03-16 15:50:04 -07:00
_solo_tab_show ( tc_solo_new ) ;
2019-09-26 13:49:11 -07:00
}
2015-03-22 10:17:16 -07:00
2020-03-07 05:58:12 -08:00
child - > unfocus ( child , tc_split ) ;
2015-08-05 02:40:54 -07:00
tc - > swallow ( tc , NULL , tc_split ) ;
2020-03-07 05:58:12 -08:00
tc_split - > is_focused = EINA_TRUE ;
tc_split - > focus ( tc_split , tc_solo_new ) ;
2020-06-23 13:38:28 -07:00
tc_solo_new - > focus ( tc_solo_new , tc_split ) ;
2015-08-05 02:40:54 -07:00
}
2015-09-26 03:01:42 -07:00
else
{
2020-02-29 07:18:07 -08:00
ERR ( " term is not splittable " ) ;
}
}
static int
_win_split_direction ( Term_Container * tc ,
Term_Container * child_orig ,
Term_Container * child_new ,
Split_Direction direction )
{
Term_Container * child1 , * child2 , * tc_split ;
Win * wn ;
Eina_Bool is_horizontal =
( direction = = SPLIT_DIRECTION_LEFT ) | | ( direction = = SPLIT_DIRECTION_RIGHT ) ?
EINA_FALSE : EINA_TRUE ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
if ( ! _term_container_is_splittable ( tc , is_horizontal ) )
{
ERR ( " term is not splittable " ) ;
return - 1 ;
}
if ( ( direction = = SPLIT_DIRECTION_TOP ) | |
( direction = = SPLIT_DIRECTION_LEFT ) )
{
child1 = child_new ;
child2 = child_orig ;
}
else
{
child1 = child_orig ;
child2 = child_new ;
}
2020-03-30 13:29:21 -07:00
wn - > tc . unfocus ( & wn - > tc , NULL ) ; /* unfocus from top */
2020-04-14 14:40:08 -07:00
tc_split = _split_new ( child1 , child2 , 0.5 , is_horizontal ) ;
2020-02-29 07:18:07 -08:00
if ( wn - > config - > show_tabs )
{
if ( child_orig - > type = = TERM_CONTAINER_TYPE_SOLO )
{
2020-03-16 15:50:04 -07:00
_solo_tab_show ( child_orig ) ;
2020-02-29 07:18:07 -08:00
}
2020-03-16 15:50:04 -07:00
_solo_tab_show ( child_new ) ;
2015-09-26 03:01:42 -07:00
}
2020-02-29 07:18:07 -08:00
tc_split - > is_focused = tc - > is_focused ;
tc - > swallow ( tc , NULL , tc_split ) ;
2020-03-30 13:29:21 -07:00
child_new - > focus ( child_new , NULL ) ; /* refocus from bottom */
2020-02-29 07:18:07 -08:00
return 0 ;
2015-03-22 10:17:16 -07:00
}
2020-07-29 13:43:25 -07:00
static Eina_Bool
_set_cursor ( Term * term , void * data )
{
const char * cursor = data ;
assert ( term - > core ) ;
if ( cursor )
{
elm_object_cursor_set ( term - > core , cursor ) ;
term - > core_cursor_set = 1 ;
}
else
{
if ( term - > core_cursor_set )
elm_object_cursor_unset ( term - > core ) ;
term - > core_cursor_set = 0 ;
}
return ECORE_CALLBACK_PASS_ON ;
}
2015-03-22 10:17:16 -07:00
static void
_win_update ( Term_Container * tc )
{
Win * wn ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
wn = ( Win * ) tc ;
2020-07-29 13:43:25 -07:00
if ( wn - > config - > hide_cursor > = CONFIG_CURSOR_IDLE_TIMEOUT_MAX )
{
ecore_timer_del ( wn - > hide_cursor_timer ) ;
wn - > hide_cursor_timer = NULL ;
for_each_term_do ( wn , & _set_cursor , NULL ) ;
}
2015-03-22 10:17:16 -07:00
wn - > child - > update ( wn - > child ) ;
}
2020-04-11 00:55:52 -07:00
Eina_Bool
win_has_single_child ( const Win * wn )
{
const Term_Container * child = wn - > child ;
return ( child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
}
2017-11-13 14:48:05 -08:00
static void
_cb_win_key_up ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
2018-02-04 15:07:47 -08:00
void * event )
2017-11-13 14:48:05 -08:00
{
Win * wn = data ;
2018-02-04 15:07:47 -08:00
Evas_Event_Key_Up * ev = event ;
2018-01-30 14:31:26 -08:00
2017-11-13 14:48:05 -08:00
DBG ( " GROUP key up (%p) (ctrl:%d) " ,
wn , evas_key_modifier_is_set ( ev - > modifiers , " Control " ) ) ;
2018-02-04 15:07:47 -08:00
keyin_handle_up ( & wn - > khdl , ev ) ;
}
2018-02-08 09:40:06 -08:00
const char *
2018-02-04 15:07:47 -08:00
term_preedit_str_get ( Term * term )
{
Win * wn = term - > wn ;
Term_Container * tc = ( Term_Container * ) wn ;
2018-03-10 10:40:13 -08:00
if ( wn - > on_popover )
2018-02-04 15:07:47 -08:00
return NULL ;
tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
if ( term )
{
return wn - > preedit_str ;
}
return NULL ;
}
2018-02-09 14:18:03 -08:00
Ecore_IMF_Context *
term_imf_context_get ( Term * term )
{
Win * wn = term - > wn ;
Term_Container * tc = ( Term_Container * ) wn ;
Term * focused ;
tc = ( Term_Container * ) wn ;
focused = tc - > focused_term_get ( tc ) ;
if ( term = = focused )
return wn - > khdl . imf ;
return NULL ;
}
2018-02-04 15:07:47 -08:00
static void
_imf_event_commit_cb ( void * data ,
Ecore_IMF_Context * _ctx EINA_UNUSED ,
void * event )
{
Eina_List * l ;
Term * term ;
Win * wn = data ;
Termpty * ty ;
char * str = event ;
int len ;
DBG ( " IMF committed '%s' " , str ) ;
if ( ! str )
return ;
len = strlen ( str ) ;
2017-11-13 14:48:05 -08:00
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2017-11-13 14:48:05 -08:00
{
2018-02-04 15:07:47 -08:00
ty = termio_pty_get ( term - > termio ) ;
if ( ty )
termpty_write ( ty , str , len ) ;
2017-11-13 14:48:05 -08:00
}
}
else
{
Term_Container * tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
if ( term )
2018-02-04 15:07:47 -08:00
{
ty = termio_pty_get ( term - > termio ) ;
if ( ty )
termpty_write ( ty , str , len ) ;
}
}
2019-11-29 10:59:57 -08:00
eina_stringshare_del ( wn - > preedit_str ) ;
wn - > preedit_str = NULL ;
2017-11-13 14:48:05 -08:00
}
2018-02-04 15:07:47 -08:00
static void
_imf_event_delete_surrounding_cb ( void * data ,
Ecore_IMF_Context * _ctx EINA_UNUSED ,
void * event )
{
Win * wn = data ;
Ecore_IMF_Event_Delete_Surrounding * ev = event ;
DBG ( " IMF del surrounding %p %i %i " , wn , ev - > offset , ev - > n_chars ) ;
}
static void
_imf_event_preedit_changed_cb ( void * data ,
Ecore_IMF_Context * ctx ,
void * _event EINA_UNUSED )
{
Win * wn = data ;
char * preedit_string ;
int cursor_pos ;
ecore_imf_context_preedit_string_get ( ctx , & preedit_string , & cursor_pos ) ;
if ( ! preedit_string )
return ;
DBG ( " IMF preedit str '%s' " , preedit_string ) ;
2019-11-29 10:59:57 -08:00
eina_stringshare_del ( wn - > preedit_str ) ;
2018-02-04 15:07:47 -08:00
wn - > preedit_str = eina_stringshare_add ( preedit_string ) ;
free ( preedit_string ) ;
}
2017-11-13 14:48:05 -08:00
static void
_cb_win_key_down ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * event_info )
{
Win * wn = data ;
2018-02-04 15:07:47 -08:00
Eina_List * l = NULL ;
Term * term = NULL ;
Termpty * ty = NULL ;
Evas_Event_Key_Down * ev = event_info ;
Eina_Bool done = EINA_FALSE ;
int ctrl , alt , shift , win , meta , hyper ;
2017-11-13 14:48:05 -08:00
DBG ( " GROUP key down (%p) (ctrl:%d) " ,
wn , evas_key_modifier_is_set ( ev - > modifiers , " Control " ) ) ;
2020-03-16 15:50:04 -07:00
_focus_validator ( ) ;
2019-12-06 01:14:40 -08:00
if ( ( wn - > on_popover ) | | ( wn - > cmdbox_up ) ) return ;
2018-01-30 14:31:26 -08:00
2017-11-13 14:48:05 -08:00
ctrl = evas_key_modifier_is_set ( ev - > modifiers , " Control " ) ;
alt = evas_key_modifier_is_set ( ev - > modifiers , " Alt " ) ;
shift = evas_key_modifier_is_set ( ev - > modifiers , " Shift " ) ;
win = evas_key_modifier_is_set ( ev - > modifiers , " Super " ) ;
meta = evas_key_modifier_is_set ( ev - > modifiers , " Meta " ) | |
evas_key_modifier_is_set ( ev - > modifiers , " AltGr " ) | |
evas_key_modifier_is_set ( ev - > modifiers , " ISO_Level3_Shift " ) ;
hyper = evas_key_modifier_is_set ( ev - > modifiers , " Hyper " ) ;
2019-07-07 07:26:32 -07:00
/* 1st/ Tab selector */
{
Term_Container * tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
if ( term )
{
Term_Container * tc_parent = tc - > parent ;
2019-07-07 08:28:05 -07:00
tc = term - > container ;
tc_parent = tc - > parent ;
2019-07-07 07:26:32 -07:00
if ( tc_parent - > type = = TERM_CONTAINER_TYPE_TABS )
{
Tabs * tabs = ( Tabs * ) tc_parent ;
if ( tabs - > selector ! = NULL )
{
sel_key_down ( tabs - > selector , ev ) ;
return ;
}
}
}
}
/* 2nd/ Miniview */
2018-02-04 15:07:47 -08:00
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2018-02-04 15:07:47 -08:00
{
done = miniview_handle_key ( term_miniview_get ( term ) , ev ) ;
if ( ! wn - > group_input )
return ;
}
}
else
{
Term_Container * tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
if ( ! term )
2020-03-16 15:50:04 -07:00
{
DBG ( " no focused term " ) ;
return ;
}
2018-02-04 15:07:47 -08:00
done = miniview_handle_key ( term_miniview_get ( term ) , ev ) ;
}
if ( done )
{
keyin_compose_seq_reset ( & wn - > khdl ) ;
goto end ;
}
2019-07-07 07:26:32 -07:00
/* 3rd/ PopMedia */
2018-02-04 15:07:47 -08:00
done = EINA_FALSE ;
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2018-02-04 15:07:47 -08:00
{
if ( term_has_popmedia ( term ) & & ! strcmp ( ev - > key , " Escape " ) )
{
term_popmedia_close ( term ) ;
done = EINA_TRUE ;
}
}
}
else
{
Term_Container * tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
if ( ! term )
2020-03-16 15:50:04 -07:00
{
DBG ( " no focused term " ) ;
return ;
}
2018-02-04 15:07:47 -08:00
if ( term_has_popmedia ( term ) & & ! strcmp ( ev - > key , " Escape " ) )
{
term_popmedia_close ( term ) ;
done = EINA_TRUE ;
}
}
if ( done )
{
keyin_compose_seq_reset ( & wn - > khdl ) ;
goto end ;
}
2017-11-13 14:48:05 -08:00
2019-07-07 07:26:32 -07:00
/* 4th/ Handle key bindings */
2018-02-04 15:07:47 -08:00
done = EINA_FALSE ;
2017-11-13 14:48:05 -08:00
if ( wn - > group_input )
{
wn - > group_once_handled = EINA_FALSE ;
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2017-11-13 14:48:05 -08:00
{
2018-02-04 15:07:47 -08:00
done = keyin_handle_key_binding ( term - > termio , ev , ctrl , alt ,
shift , win , meta , hyper ) ;
2017-11-13 14:48:05 -08:00
if ( ! wn - > group_input )
return ;
}
}
else
{
Term_Container * tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
2018-02-04 15:07:47 -08:00
if ( ! term )
return ;
done = keyin_handle_key_binding ( term - > termio , ev , ctrl , alt ,
shift , win , meta , hyper ) ;
}
if ( done )
{
keyin_compose_seq_reset ( & wn - > khdl ) ;
goto end ;
}
done = EINA_FALSE ;
2019-07-07 07:26:32 -07:00
/* 5th/ Composing */
2018-03-26 02:16:58 -07:00
if ( wn - > khdl . imf )
2018-02-04 15:07:47 -08:00
{
// EXCEPTION. Don't filter modifiers alt+shift -> breaks emacs
// and jed (alt+shift+5 for search/replace for example)
// Don't filter modifiers alt, is used by shells
if ( ( ! alt ) & & ( ! ctrl ) )
{
Ecore_IMF_Event_Key_Down imf_ev ;
ecore_imf_evas_event_key_down_wrap ( ev , & imf_ev ) ;
if ( ! wn - > khdl . composing )
{
if ( ecore_imf_context_filter_event ( wn - > khdl . imf ,
ECORE_IMF_EVENT_KEY_DOWN ,
( Ecore_IMF_Event * ) & imf_ev ) )
goto end ;
}
}
}
if ( ! wn - > khdl . composing )
{
Ecore_Compose_State state ;
char * compres = NULL ;
keyin_compose_seq_reset ( & wn - > khdl ) ;
wn - > khdl . seq = eina_list_append ( wn - > khdl . seq ,
eina_stringshare_add ( ev - > key ) ) ;
state = ecore_compose_get ( wn - > khdl . seq , & compres ) ;
if ( state = = ECORE_COMPOSE_MIDDLE )
wn - > khdl . composing = EINA_TRUE ;
else
wn - > khdl . composing = EINA_FALSE ;
if ( ! wn - > khdl . composing )
keyin_compose_seq_reset ( & wn - > khdl ) ;
else
goto end ;
}
else
{
Ecore_Compose_State state ;
char * compres = NULL ;
if ( key_is_modifier ( ev - > key ) )
goto end ;
wn - > khdl . seq = eina_list_append ( wn - > khdl . seq ,
eina_stringshare_add ( ev - > key ) ) ;
state = ecore_compose_get ( wn - > khdl . seq , & compres ) ;
if ( state = = ECORE_COMPOSE_NONE )
keyin_compose_seq_reset ( & wn - > khdl ) ;
else if ( state = = ECORE_COMPOSE_DONE )
{
keyin_compose_seq_reset ( & wn - > khdl ) ;
if ( compres )
{
int len = strlen ( compres ) ;
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2018-02-04 15:07:47 -08:00
{
ty = termio_pty_get ( term - > termio ) ;
if ( ty & & termpty_can_handle_key ( ty , & wn - > khdl , ev ) )
termpty_write ( ty , compres , len ) ;
}
}
else
{
ty = termio_pty_get ( term - > termio ) ;
if ( ty & & termpty_can_handle_key ( ty , & wn - > khdl , ev ) )
termpty_write ( ty , compres , len ) ;
}
free ( compres ) ;
compres = NULL ;
}
goto end ;
}
else
goto end ;
}
2019-07-07 07:26:32 -07:00
/* 6th/ send key to pty */
2018-02-04 15:07:47 -08:00
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2018-02-04 15:07:47 -08:00
{
ty = termio_pty_get ( term - > termio ) ;
if ( ty & & termpty_can_handle_key ( ty , & wn - > khdl , ev ) )
keyin_handle_key_to_pty ( ty , ev , alt , shift , ctrl ) ;
}
}
else
{
ty = termio_pty_get ( term - > termio ) ;
2020-03-16 15:50:04 -07:00
DBG ( " ty:%p " , ty ) ;
2018-02-04 15:07:47 -08:00
if ( ty & & termpty_can_handle_key ( ty , & wn - > khdl , ev ) )
keyin_handle_key_to_pty ( ty , ev , alt , shift , ctrl ) ;
}
2019-07-07 07:26:32 -07:00
/* 7th: specifics: jump on keypress / flicker on key */
2018-02-04 15:07:47 -08:00
end :
if ( wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2018-02-04 15:07:47 -08:00
{
if ( term )
2018-02-12 13:03:02 -08:00
termio_key_down ( term - > termio , ev , done ) ;
2018-02-04 15:07:47 -08:00
}
}
else
{
2017-11-13 14:48:05 -08:00
if ( term )
2018-02-12 13:03:02 -08:00
termio_key_down ( term - > termio , ev , done ) ;
2017-11-13 14:48:05 -08:00
}
}
static void
_cb_win_mouse_down ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * event )
{
Win * wn = data ;
Evas_Event_Mouse_Down * ev = event ;
Term * term , * term_mouse ;
Term_Container * tc = ( Term_Container * ) wn ;
Term_Container * tc_child ;
2018-03-10 10:40:13 -08:00
if ( wn - > on_popover | | wn - > group_input )
2017-11-13 14:48:05 -08:00
return ;
2018-05-13 13:44:37 -07:00
/* Focus In event will handle that */
if ( ! tc - > is_focused )
return ;
2017-11-13 14:48:05 -08:00
term_mouse = tc - > find_term_at_coords ( tc , ev - > canvas . x , ev - > canvas . y ) ;
term = tc - > focused_term_get ( tc ) ;
if ( term_mouse = = term )
return ;
if ( term )
{
tc_child = term - > container ;
tc_child - > unfocus ( tc_child , tc ) ;
}
tc_child = term_mouse - > container ;
2018-05-13 13:44:37 -07:00
DBG ( " focus tc_child:%p " , tc_child ) ;
2017-11-13 14:48:05 -08:00
tc_child - > focus ( tc_child , tc ) ;
}
2019-06-30 07:20:40 -07:00
static Eina_Bool
_hide_cursor ( void * data )
{
Win * wn = data ;
wn - > hide_cursor_timer = NULL ;
for_each_term_do ( wn , & _set_cursor , ( void * ) " blank " ) ;
return ECORE_CALLBACK_CANCEL ;
}
2017-11-13 14:48:05 -08:00
static void
_cb_win_mouse_move ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * obj EINA_UNUSED ,
void * event )
{
Win * wn = data ;
Evas_Event_Mouse_Move * ev = event ;
Term * term , * term_mouse ;
Term_Container * tc = ( Term_Container * ) wn ;
2017-12-17 13:57:00 -08:00
Term_Container * tc_child = NULL ;
2017-11-13 14:48:05 -08:00
2019-06-30 07:20:40 -07:00
if ( wn - > on_popover )
2017-11-13 14:48:05 -08:00
return ;
2019-09-02 14:27:42 -07:00
if ( wn - > config - > hide_cursor < CONFIG_CURSOR_IDLE_TIMEOUT_MAX )
2019-06-30 07:20:40 -07:00
{
if ( wn - > hide_cursor_timer )
{
ecore_timer_interval_set ( wn - > hide_cursor_timer ,
wn - > config - > hide_cursor ) ;
}
else
{
for_each_term_do ( wn , & _set_cursor , NULL ) ;
wn - > hide_cursor_timer = ecore_timer_add (
wn - > config - > hide_cursor , _hide_cursor , wn ) ;
}
}
if ( wn - > group_input | | ! tc - > is_focused | | ! wn - > config - > mouse_over_focus )
2017-11-13 14:48:05 -08:00
return ;
term_mouse = tc - > find_term_at_coords ( tc ,
ev - > cur . canvas . x , ev - > cur . canvas . y ) ;
term = tc - > focused_term_get ( tc ) ;
if ( term_mouse = = term )
return ;
DBG ( " mouse move " ) ;
if ( term )
{
tc_child = term - > container ;
tc_child - > unfocus ( tc_child , tc ) ;
}
tc_child = term_mouse - > container ;
DBG ( " need to focus " ) ;
tc_child - > focus ( tc_child , tc ) ;
}
2018-02-11 02:48:06 -08:00
static Eina_Bool
2020-04-11 01:01:13 -07:00
_win_is_visible ( const Term_Container * tc , const Term_Container * _child EINA_UNUSED )
2018-02-11 02:48:06 -08:00
{
assert ( tc - > type = = TERM_CONTAINER_TYPE_WIN ) ;
return EINA_TRUE ;
}
2017-11-13 14:48:05 -08:00
2015-03-22 10:17:16 -07:00
Win *
win_new ( const char * name , const char * role , const char * title ,
const char * icon_name , Config * config ,
Eina_Bool fullscreen , Eina_Bool iconic ,
Eina_Bool borderless , Eina_Bool override ,
Eina_Bool maximized )
{
Win * wn ;
Evas_Object * o ;
Term_Container * tc ;
wn = calloc ( 1 , sizeof ( Win ) ) ;
if ( ! wn ) return NULL ;
2016-02-09 11:59:32 -08:00
wn - > win = win_add ( name , role , title , icon_name ) ;
2015-03-22 10:17:16 -07:00
if ( ! wn - > win )
{
free ( wn ) ;
return NULL ;
}
2019-01-14 14:44:31 -08:00
if ( _win_log_dom < 0 )
{
_win_log_dom = eina_log_domain_register ( " win " , NULL ) ;
if ( _win_log_dom < 0 )
2020-09-15 10:40:37 -07:00
EINA_LOG_CRIT ( " Could not create logging domain '%s' " , " win " ) ;
2019-01-14 14:44:31 -08:00
}
2015-03-22 10:17:16 -07:00
tc = ( Term_Container * ) wn ;
tc - > term_next = _win_term_next ;
tc - > term_prev = _win_term_prev ;
2017-07-10 15:01:29 -07:00
tc - > term_up = _win_term_up ;
tc - > term_down = _win_term_down ;
tc - > term_left = _win_term_left ;
tc - > term_right = _win_term_right ;
2015-03-22 10:17:16 -07:00
tc - > term_first = _win_term_first ;
tc - > term_last = _win_term_last ;
tc - > focused_term_get = _win_focused_term_get ;
tc - > get_evas_object = _win_get_evas_object ;
tc - > split = _win_split ;
2020-02-29 07:18:07 -08:00
tc - > split_direction = _win_split_direction ;
2015-03-22 10:17:16 -07:00
tc - > find_term_at_coords = _win_find_term_at_coords ;
tc - > size_eval = _win_size_eval ;
tc - > swallow = _win_swallow ;
tc - > focus = _win_focus ;
tc - > unfocus = _win_unfocus ;
tc - > set_title = _win_set_title ;
tc - > bell = _win_bell ;
tc - > close = _win_close ;
tc - > update = _win_update ;
2018-02-11 02:48:06 -08:00
tc - > is_visible = _win_is_visible ;
2020-02-15 07:47:47 -08:00
tc - > detach = NULL ;
2017-08-26 10:27:39 -07:00
tc - > title = eina_stringshare_add ( title ? title : " Terminology " ) ;
2015-03-22 10:17:16 -07:00
tc - > type = TERM_CONTAINER_TYPE_WIN ;
tc - > wn = wn ;
config_default_font_set ( config , evas_object_evas_get ( wn - > win ) ) ;
wn - > config = config_fork ( config ) ;
evas_object_event_callback_add ( wn - > win , EVAS_CALLBACK_DEL , _cb_del , wn ) ;
if ( fullscreen ) elm_win_fullscreen_set ( wn - > win , EINA_TRUE ) ;
if ( iconic ) elm_win_iconified_set ( wn - > win , EINA_TRUE ) ;
if ( borderless ) elm_win_borderless_set ( wn - > win , EINA_TRUE ) ;
if ( override ) elm_win_override_set ( wn - > win , EINA_TRUE ) ;
if ( maximized ) elm_win_maximized_set ( wn - > win , EINA_TRUE ) ;
wn - > backbg = o = evas_object_rectangle_add ( evas_object_evas_get ( wn - > win ) ) ;
evas_object_color_set ( o , 0 , 0 , 0 , 255 ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
elm_win_resize_object_add ( wn - > win , o ) ;
evas_object_show ( o ) ;
wn - > conform = o = elm_conformant_add ( wn - > win ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
elm_win_resize_object_add ( wn - > win , o ) ;
evas_object_show ( o ) ;
2019-05-22 14:03:03 -07:00
wn - > base = o = elm_layout_add ( wn - > win ) ;
2019-06-18 13:06:44 -07:00
elm_object_focus_allow_set ( o , EINA_TRUE ) ;
evas_object_propagate_events_set ( o , EINA_FALSE ) ;
2019-05-22 14:03:03 -07:00
theme_apply_elm ( o , config , " terminology/base " ) ;
2015-03-22 10:17:16 -07:00
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
elm_object_content_set ( wn - > conform , o ) ;
evas_object_show ( o ) ;
evas_object_smart_callback_add ( wn - > win , " focus,in " , _cb_win_focus_in , wn ) ;
evas_object_smart_callback_add ( wn - > win , " focus,out " , _cb_win_focus_out , wn ) ;
2018-02-12 13:23:05 -08:00
evas_object_event_callback_add ( wn - > base ,
2017-11-13 14:48:05 -08:00
EVAS_CALLBACK_KEY_DOWN ,
_cb_win_key_down ,
wn ) ;
2018-02-12 13:23:05 -08:00
evas_object_event_callback_add ( wn - > base ,
2017-11-13 14:48:05 -08:00
EVAS_CALLBACK_KEY_UP ,
_cb_win_key_up ,
wn ) ;
2018-02-12 13:23:05 -08:00
evas_object_event_callback_add ( wn - > base ,
2017-11-13 14:48:05 -08:00
EVAS_CALLBACK_MOUSE_DOWN ,
_cb_win_mouse_down ,
wn ) ;
2018-02-12 13:23:05 -08:00
evas_object_event_callback_add ( wn - > base ,
2017-11-13 14:48:05 -08:00
EVAS_CALLBACK_MOUSE_MOVE ,
_cb_win_mouse_move ,
wn ) ;
2019-06-17 12:22:17 -07:00
elm_object_focus_set ( wn - > base , EINA_TRUE ) ;
2017-11-13 14:48:05 -08:00
2018-02-04 15:07:47 -08:00
if ( ecore_imf_init ( ) )
{
const char * imf_id = ecore_imf_context_default_id_get ( ) ;
Evas * e ;
if ( ! imf_id )
wn - > khdl . imf = NULL ;
else
{
const Ecore_IMF_Context_Info * imf_info ;
imf_info = ecore_imf_context_info_by_id_get ( imf_id ) ;
if ( ( ! imf_info - > canvas_type ) | |
( strcmp ( imf_info - > canvas_type , " evas " ) = = 0 ) )
wn - > khdl . imf = ecore_imf_context_add ( imf_id ) ;
else
{
imf_id = ecore_imf_context_default_id_by_canvas_type_get ( " evas " ) ;
if ( imf_id )
wn - > khdl . imf = ecore_imf_context_add ( imf_id ) ;
}
}
if ( ! wn - > khdl . imf )
goto imf_done ;
e = evas_object_evas_get ( o ) ;
ecore_imf_context_client_window_set
( wn - > khdl . imf , ( void * ) ecore_evas_window_get ( ecore_evas_ecore_evas_get ( e ) ) ) ;
ecore_imf_context_client_canvas_set ( wn - > khdl . imf , e ) ;
ecore_imf_context_event_callback_add
( wn - > khdl . imf , ECORE_IMF_CALLBACK_COMMIT , _imf_event_commit_cb , wn ) ;
ecore_imf_context_event_callback_add
( wn - > khdl . imf , ECORE_IMF_CALLBACK_DELETE_SURROUNDING , _imf_event_delete_surrounding_cb , wn ) ;
ecore_imf_context_event_callback_add
( wn - > khdl . imf , ECORE_IMF_CALLBACK_PREEDIT_CHANGED , _imf_event_preedit_changed_cb , wn ) ;
/* make IMF usable by a terminal - no preedit, prediction... */
ecore_imf_context_prediction_allow_set
( wn - > khdl . imf , EINA_FALSE ) ;
ecore_imf_context_autocapital_type_set
( wn - > khdl . imf , ECORE_IMF_AUTOCAPITAL_TYPE_NONE ) ;
ecore_imf_context_input_panel_layout_set
( wn - > khdl . imf , ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL ) ;
ecore_imf_context_input_mode_set
( wn - > khdl . imf , ECORE_IMF_INPUT_MODE_FULL ) ;
ecore_imf_context_input_panel_language_set
( wn - > khdl . imf , ECORE_IMF_INPUT_PANEL_LANG_ALPHABET ) ;
ecore_imf_context_input_panel_return_key_type_set
( wn - > khdl . imf , ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT ) ;
imf_done :
if ( wn - > khdl . imf )
DBG ( " Ecore IMF Setup " ) ;
else
WRN ( _ ( " Ecore IMF failed " ) ) ;
}
2019-09-02 14:27:42 -07:00
if ( wn - > config - > hide_cursor < CONFIG_CURSOR_IDLE_TIMEOUT_MAX )
2019-07-05 14:12:32 -07:00
{
wn - > hide_cursor_timer = ecore_timer_add (
wn - > config - > hide_cursor , _hide_cursor , wn ) ;
}
2015-03-22 10:17:16 -07:00
wins = eina_list_append ( wins , wn ) ;
2020-04-29 13:54:50 -07:00
wn - > tc . is_focused = EINA_TRUE ;
2015-03-22 10:17:16 -07:00
return wn ;
}
void
2016-02-02 14:15:50 -08:00
term_close ( Evas_Object * win , Evas_Object * term , Eina_Bool hold_if_requested )
2015-03-22 10:17:16 -07:00
{
Term * tm ;
Term_Container * tc ;
2020-04-11 00:50:38 -07:00
Win * wn = win_evas_object_to_win ( win ) ;
2015-03-22 10:17:16 -07:00
2016-02-02 14:15:50 -08:00
if ( ! wn )
return ;
2015-03-22 10:17:16 -07:00
tm = evas_object_data_get ( term , " term " ) ;
2016-02-02 14:15:50 -08:00
if ( ! tm )
return ;
if ( tm - > hold & & hold_if_requested )
return ;
2015-03-22 10:17:16 -07:00
wn - > terms = eina_list_remove ( wn - > terms , tm ) ;
tc = tm - > container ;
tc - > close ( tc , tc ) ;
term_unref ( tm ) ;
}
2017-11-13 14:48:05 -08:00
/* Returns True if action is permitted */
Eina_Bool
win_is_group_action_handled ( Win * wn )
{
DBG ( " wn->group_input:%d wn->group_once_handled:%d wn:%p " ,
wn - > group_input , wn - > group_once_handled , wn ) ;
if ( ! wn - > group_input )
return EINA_FALSE ;
if ( wn - > group_once_handled )
return EINA_TRUE ;
wn - > group_once_handled = EINA_TRUE ;
return EINA_FALSE ;
}
Eina_Bool
2020-04-11 01:01:13 -07:00
win_is_group_input ( const Win * wn )
2017-11-13 14:48:05 -08:00
{
return wn - > group_input ;
}
static void
_win_toggle_group ( Win * wn )
{
Eina_List * l ;
Term * term ;
DBG ( " WIN TOGGLE " ) ;
if ( ! wn - > group_input )
{
2018-02-11 02:48:06 -08:00
GROUPED_INPUT_TERM_FOREACH ( wn , l , term )
2017-11-13 14:48:05 -08:00
{
2020-04-14 13:06:53 -07:00
elm_layout_signal_emit ( term - > bg , " focus,in " , " terminology " ) ;
elm_layout_signal_emit ( term - > bg , " grouped,on " , " terminology " ) ;
if ( term - > tab_inactive )
edje_object_signal_emit ( term - > tab_inactive ,
" grouped,on " , " terminology " ) ;
2018-02-08 13:38:55 -08:00
termio_event_feed_mouse_in ( term - > termio ) ;
2018-02-09 13:02:19 -08:00
termio_focus_in ( term - > termio ) ;
2017-11-13 14:48:05 -08:00
}
wn - > group_input = EINA_TRUE ;
DBG ( " GROUP INPUT is now TRUE " ) ;
}
else
{
2018-02-08 09:40:27 -08:00
wn - > group_input = EINA_FALSE ;
2017-11-13 14:48:05 -08:00
DBG ( " GROUP INPUT is now FALSE " ) ;
2020-04-14 13:06:53 -07:00
/* Better disable it for all of them in case of change of policy
* between only visible or all .
* Using the GROUPED_INPUT_TERM_FOREACH macro would miss some terms */
EINA_LIST_FOREACH ( wn - > terms , l , term )
2017-11-13 14:48:05 -08:00
{
2020-04-14 13:06:53 -07:00
elm_layout_signal_emit ( term - > bg , " focus,out " , " terminology " ) ;
elm_layout_signal_emit ( term - > bg , " grouped,off " , " terminology " ) ;
if ( term - > tab_inactive )
edje_object_signal_emit ( term - > tab_inactive ,
" grouped,off " , " terminology " ) ;
2018-02-09 13:02:19 -08:00
termio_focus_out ( term - > termio ) ;
2017-11-13 14:48:05 -08:00
}
term = wn - > child - > term_first ( wn - > child ) ;
wn - > child - > focus ( wn - > child , & wn - > tc ) ;
}
}
void
win_toggle_all_group ( Win * wn )
{
wn - > group_only_visible = EINA_FALSE ;
_win_toggle_group ( wn ) ;
}
void
win_toggle_visible_group ( Win * wn )
{
wn - > group_only_visible = EINA_TRUE ;
_win_toggle_group ( wn ) ;
}
2015-03-22 10:17:16 -07:00
/* }}} */
/* {{{ Splits */
static Term *
2017-07-06 11:55:02 -07:00
_split_term_next ( const Term_Container * tc , const Term_Container * child )
2015-03-22 10:17:16 -07:00
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc1 )
return split - > tc2 - > term_first ( split - > tc2 ) ;
else
return tc - > parent - > term_next ( tc - > parent , tc ) ;
}
static Term *
2017-07-06 11:55:02 -07:00
_split_term_prev ( const Term_Container * tc , const Term_Container * child )
2015-03-22 10:17:16 -07:00
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc2 )
return split - > tc1 - > term_last ( split - > tc1 ) ;
else
return tc - > parent - > term_prev ( tc - > parent , tc ) ;
}
2017-07-10 15:01:29 -07:00
static Term *
_split_term_up ( const Term_Container * tc ,
const Term_Container * child )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc2 & & split - > is_horizontal )
return split - > tc1 - > term_last ( split - > tc1 ) ;
else
return tc - > parent - > term_up ( tc - > parent , tc ) ;
}
static Term *
_split_term_down ( const Term_Container * tc ,
const Term_Container * child )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc1 & & split - > is_horizontal )
return split - > tc2 - > term_first ( split - > tc2 ) ;
else
return tc - > parent - > term_down ( tc - > parent , tc ) ;
}
static Term *
_split_term_left ( const Term_Container * tc ,
const Term_Container * child )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc2 & & ! split - > is_horizontal )
return split - > tc1 - > term_last ( split - > tc1 ) ;
else
return tc - > parent - > term_left ( tc - > parent , tc ) ;
}
static Term *
_split_term_right ( const Term_Container * tc ,
const Term_Container * child )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > tc1 & & ! split - > is_horizontal )
return split - > tc2 - > term_first ( split - > tc2 ) ;
else
return tc - > parent - > term_right ( tc - > parent , tc ) ;
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_split_term_first ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
return split - > tc1 - > term_first ( split - > tc1 ) ;
}
static Term *
2017-07-06 11:55:02 -07:00
_split_term_last ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
return split - > tc2 - > term_last ( split - > tc2 ) ;
}
static Evas_Object *
2017-07-06 11:55:02 -07:00
_split_get_evas_object ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
return split - > panes ;
}
static void
_split_size_eval ( Term_Container * tc , Sizeinfo * info )
{
Evas_Coord mw = 0 , mh = 0 ;
Term_Container * tc1 , * tc2 ;
Sizeinfo inforet = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
tc1 = split - > tc1 ;
tc2 = split - > tc2 ;
info - > min_w = 0 ;
info - > min_h = 0 ;
info - > req_w = 0 ;
info - > req_h = 0 ;
evas_object_size_hint_min_get ( split - > panes , & mw , & mh ) ;
info - > bg_min_w = mw ;
info - > bg_min_h = mh ;
if ( split - > is_horizontal )
{
tc1 - > size_eval ( tc1 , & inforet ) ;
info - > req | = inforet . req ;
mh - = inforet . min_h ;
if ( info - > req )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
info - > req_h + = inforet . req_h ;
info - > req_w = inforet . req_w ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
tc2 - > size_eval ( tc2 , & inforet ) ;
info - > req | = inforet . req ;
mh - = inforet . min_h ;
if ( info - > req )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
info - > req_h + = inforet . req_h ;
info - > req_w = inforet . req_w ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
info - > req_h + = mh ;
if ( info - > req )
info - > req_w + = mw - inforet . min_w - inforet . step_x ;
2014-12-02 15:42:27 -08:00
}
else
{
2015-03-22 10:17:16 -07:00
tc1 - > size_eval ( tc1 , & inforet ) ;
info - > req | = inforet . req ;
mw - = inforet . min_w ;
if ( info - > req )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
info - > req_w + = inforet . req_w ;
info - > req_h = inforet . req_h ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
tc2 - > size_eval ( tc2 , & inforet ) ;
info - > req | = inforet . req ;
mw - = inforet . min_w ;
if ( info - > req )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
info - > req_w + = inforet . req_w ;
info - > req_h = inforet . req_h ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
info - > req_w + = mw ;
if ( info - > req )
info - > req_h + = mh - inforet . min_h - inforet . step_y ;
}
info - > step_x = inforet . step_x ;
info - > step_y = inforet . step_y ;
}
static void
_split_swallow ( Term_Container * tc , Term_Container * orig ,
Term_Container * new_child )
{
Split * split ;
Evas_Object * o ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
assert ( orig & & ( orig = = split - > tc1 | | orig = = split - > tc2 ) ) ;
2020-03-07 05:58:12 -08:00
if ( ( _tab_drag ) & & ( _tab_drag - > parent_type = = TERM_CONTAINER_TYPE_SPLIT ) & &
( _tab_drag - > other = = orig ) )
{
_tab_drag - > other = new_child ;
}
2016-03-06 06:34:36 -08:00
if ( split - > last_focus = = orig )
split - > last_focus = new_child ;
2015-03-22 10:17:16 -07:00
o = orig - > get_evas_object ( orig ) ;
evas_object_hide ( o ) ;
o = new_child - > get_evas_object ( new_child ) ;
if ( split - > tc1 = = orig )
{
elm_object_part_content_unset ( split - > panes , PANES_TOP ) ;
elm_object_part_content_set ( split - > panes , PANES_TOP , o ) ;
split - > tc1 = new_child ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
else
{
elm_object_part_content_unset ( split - > panes , PANES_BOTTOM ) ;
elm_object_part_content_set ( split - > panes , PANES_BOTTOM , o ) ;
split - > tc2 = new_child ;
}
new_child - > parent = tc ;
evas_object_show ( o ) ;
evas_object_show ( split - > panes ) ;
2014-10-26 13:00:14 -07:00
}
static Term *
2017-07-06 11:55:02 -07:00
_split_focused_term_get ( const Term_Container * tc )
2014-10-26 13:00:14 -07:00
{
2015-03-22 10:17:16 -07:00
Split * split ;
2020-03-16 15:50:04 -07:00
Term * term = NULL ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
2020-03-16 15:50:04 -07:00
if ( tc - > is_focused )
term = split - > last_focus - > focused_term_get ( split - > last_focus ) ;
return term ;
2015-03-22 10:17:16 -07:00
}
static Term *
2017-07-06 11:55:02 -07:00
_split_find_term_at_coords ( const Term_Container * tc ,
2015-03-22 10:17:16 -07:00
Evas_Coord mx , Evas_Coord my )
{
Split * split ;
Evas_Coord ox , oy , ow , oh ;
Evas_Object * o ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
o = split - > tc1 - > get_evas_object ( split - > tc1 ) ;
evas_object_geometry_get ( o , & ox , & oy , & ow , & oh ) ;
if ( ELM_RECTS_INTERSECT ( ox , oy , ow , oh , mx , my , 1 , 1 ) )
2014-10-26 13:00:14 -07:00
{
2015-03-22 10:17:16 -07:00
tc = split - > tc1 ;
2014-10-26 13:00:14 -07:00
}
2015-03-22 10:17:16 -07:00
else
{
tc = split - > tc2 ;
}
return tc - > find_term_at_coords ( tc , mx , my ) ;
2014-10-26 13:00:14 -07:00
}
2015-03-22 10:17:16 -07:00
static void
_split_close ( Term_Container * tc , Term_Container * child )
{
Split * split ;
Term_Container * parent , * other_child ;
2015-06-11 14:55:35 -07:00
Evas_Object * top , * bottom ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
2020-03-07 05:58:12 -08:00
assert ( ( child = = split - > tc1 ) | | ( child = = split - > tc2 ) ) ;
2015-03-22 10:17:16 -07:00
2016-03-03 04:01:19 -08:00
DBG ( " close " ) ;
2020-03-07 05:58:12 -08:00
if ( ( _tab_drag ) & & ( _tab_drag - > parent_type = = TERM_CONTAINER_TYPE_SPLIT ) & &
( _tab_drag - > other = = child ) )
{
_tab_drag - > other = tc - > parent ;
}
2015-06-11 14:55:35 -07:00
top = elm_object_part_content_unset ( split - > panes , PANES_TOP ) ;
bottom = elm_object_part_content_unset ( split - > panes , PANES_BOTTOM ) ;
evas_object_hide ( top ) ;
evas_object_hide ( bottom ) ;
2015-03-22 10:17:16 -07:00
parent = tc - > parent ;
other_child = ( child = = split - > tc1 ) ? split - > tc2 : split - > tc1 ;
parent - > swallow ( parent , tc , other_child ) ;
2014-10-26 13:00:14 -07:00
2016-03-03 04:01:19 -08:00
if ( tc - > is_focused )
{
2020-04-16 08:16:18 -07:00
child - > unfocus ( child , tc ) ;
2016-03-03 04:01:19 -08:00
other_child - > focus ( other_child , parent ) ;
}
2015-03-22 10:17:16 -07:00
evas_object_del ( split - > panes ) ;
eina_stringshare_del ( tc - > title ) ;
free ( tc ) ;
}
2014-12-02 15:42:53 -08:00
2015-03-22 10:17:16 -07:00
static void
_split_update ( Term_Container * tc )
2014-12-02 15:42:53 -08:00
{
2015-03-22 10:17:16 -07:00
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
split - > tc1 - > update ( split - > tc1 ) ;
split - > tc2 - > update ( split - > tc2 ) ;
}
2014-12-02 15:42:53 -08:00
2014-12-02 15:42:27 -08:00
static void
2015-03-22 10:17:16 -07:00
_split_focus ( Term_Container * tc , Term_Container * relative )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
2014-12-02 15:42:27 -08:00
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d " ,
tc , tc - > is_focused , tc - > parent = = relative ) ;
2015-07-15 14:17:24 -07:00
if ( ! tc - > parent )
return ;
2015-03-22 10:17:16 -07:00
if ( tc - > parent = = relative )
2014-12-02 15:42:27 -08:00
{
2020-10-17 08:03:56 -07:00
/* top to bottom */
2020-04-16 08:16:18 -07:00
if ( ! tc - > is_focused )
{
Term_Container * last_focus = split - > last_focus ;
Term_Container * other = ( split - > tc1 = = last_focus ) ?
split - > tc2 : split - > tc1 ;
tc - > is_focused = EINA_TRUE ;
other - > unfocus ( other , tc ) ;
last_focus - > focus ( last_focus , tc ) ;
}
2014-12-02 15:42:27 -08:00
}
else
{
2020-10-17 08:03:56 -07:00
/* bottom to top */
2015-03-22 10:17:16 -07:00
if ( split - > last_focus ! = relative )
split - > last_focus - > unfocus ( split - > last_focus , tc ) ;
split - > last_focus = relative ;
if ( ! tc - > is_focused )
2020-03-30 13:29:21 -07:00
{
2020-10-17 08:03:56 -07:00
/* was not focused, bring focus up */
2020-03-30 13:29:21 -07:00
tc - > is_focused = EINA_TRUE ;
tc - > parent - > focus ( tc - > parent , tc ) ;
}
2015-03-22 10:17:16 -07:00
}
}
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
static void
_split_unfocus ( Term_Container * tc , Term_Container * relative )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
2014-12-02 15:42:27 -08:00
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d " ,
tc , tc - > is_focused , tc - > parent = = relative ) ;
2015-03-22 10:17:16 -07:00
if ( ! tc - > is_focused )
return ;
tc - > is_focused = EINA_FALSE ;
if ( tc - > parent = = relative )
split - > last_focus - > unfocus ( split - > last_focus , tc ) ;
else
tc - > parent - > unfocus ( tc - > parent , tc ) ;
}
static void
_split_set_title ( Term_Container * tc , Term_Container * child ,
const char * title )
{
Split * split ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
if ( child = = split - > last_focus )
{
eina_stringshare_del ( tc - > title ) ;
tc - > title = eina_stringshare_ref ( title ) ;
tc - > parent - > set_title ( tc - > parent , tc , title ) ;
}
}
static void
2016-10-05 13:00:22 -07:00
_split_bell ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
if ( tc - > is_focused )
return ;
tc - > parent - > bell ( tc - > parent , tc ) ;
}
static void
_split_split ( Term_Container * tc , Term_Container * child ,
2015-09-19 05:49:40 -07:00
Term * from ,
2015-03-22 10:17:16 -07:00
const char * cmd , Eina_Bool is_horizontal )
{
2015-06-11 14:55:35 -07:00
Split * split ;
2015-03-22 10:17:16 -07:00
Win * wn ;
2017-12-17 13:57:00 -08:00
Term * tm_new , * tm ;
char * wdir = NULL ;
char buf [ PATH_MAX ] ;
Term_Container * tc_split , * tc_solo_new ;
Evas_Object * obj_split ;
2020-06-21 14:46:22 -07:00
Eina_Bool child_is_focused ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
2015-06-11 14:55:35 -07:00
split = ( Split * ) tc ;
2015-03-22 10:17:16 -07:00
wn = tc - > wn ;
2017-12-17 13:57:00 -08:00
if ( ! _term_container_is_splittable ( tc , is_horizontal ) )
return ;
2015-03-22 10:17:16 -07:00
2017-12-17 13:57:00 -08:00
// copy the current path to wdir if we should change the directory,
// passing wdir NULL otherwise:
if ( wn - > config - > changedir_to_current )
{
if ( from )
tm = from ;
2015-08-05 02:40:54 -07:00
else
2017-12-17 13:57:00 -08:00
tm = child - > focused_term_get ( child ) ;
if ( tm & & termio_cwd_get ( tm - > termio , buf , sizeof ( buf ) ) )
wdir = buf ;
}
tm_new = term_new ( wn , wn - > config ,
cmd , wn - > config - > login_shell , wdir ,
80 , 24 , EINA_FALSE , NULL ) ;
tc_solo_new = _solo_new ( tm_new , wn ) ;
evas_object_data_set ( tm_new - > termio , " sizedone " , tm_new - > termio ) ;
2015-06-11 14:55:35 -07:00
2017-12-17 13:57:00 -08:00
if ( child = = split - > tc1 )
elm_object_part_content_unset ( split - > panes , PANES_TOP ) ;
else
elm_object_part_content_unset ( split - > panes , PANES_BOTTOM ) ;
2015-03-22 10:17:16 -07:00
2020-06-21 14:46:22 -07:00
child_is_focused = child - > is_focused ;
/* force unfocus animation */
tc_solo_new - > is_focused = EINA_TRUE ;
tc_solo_new - > unfocus ( tc_solo_new , NULL ) ;
2020-04-14 14:40:08 -07:00
tc_split = _split_new ( child , tc_solo_new , 0.5 , is_horizontal ) ;
2015-03-22 10:17:16 -07:00
2017-12-17 13:57:00 -08:00
obj_split = tc_split - > get_evas_object ( tc_split ) ;
2015-03-22 10:17:16 -07:00
2020-06-21 14:46:22 -07:00
tc_split - > is_focused = child_is_focused ;
2017-12-17 13:57:00 -08:00
tc - > swallow ( tc , child , tc_split ) ;
2019-09-29 14:03:12 -07:00
if ( wn - > config - > show_tabs )
2019-09-26 13:49:11 -07:00
{
2020-03-16 15:50:04 -07:00
_solo_tab_show ( tc_solo_new ) ;
2019-09-26 13:49:11 -07:00
}
2020-10-17 08:03:56 -07:00
child - > unfocus ( child , tc_split ) ;
2020-09-07 12:18:03 -07:00
tc_split - > focus ( tc_split , tc_solo_new ) ;
tc_solo_new - > focus ( tc_solo_new , tc_split ) ;
2017-12-17 13:57:00 -08:00
evas_object_show ( obj_split ) ;
2020-03-16 15:50:04 -07:00
_focus_validator ( ) ;
2015-03-22 10:17:16 -07:00
}
2020-02-29 07:18:07 -08:00
static int
_split_split_direction ( Term_Container * tc ,
Term_Container * child_orig ,
Term_Container * child_new ,
Split_Direction direction )
{
Split * split ;
Win * wn ;
Term_Container * child1 , * child2 , * tc_split ;
Eina_Bool is_horizontal =
( direction = = SPLIT_DIRECTION_LEFT ) | | ( direction = = SPLIT_DIRECTION_RIGHT ) ?
EINA_FALSE : EINA_TRUE ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
split = ( Split * ) tc ;
wn = tc - > wn ;
if ( ! _term_container_is_splittable ( tc , is_horizontal ) )
{
ERR ( " term is not splittable " ) ;
return - 1 ;
}
if ( ( direction = = SPLIT_DIRECTION_TOP ) | |
( direction = = SPLIT_DIRECTION_LEFT ) )
{
child1 = child_new ;
child2 = child_orig ;
}
else
{
child1 = child_orig ;
child2 = child_new ;
}
if ( child_orig = = split - > tc1 )
elm_object_part_content_unset ( split - > panes , PANES_TOP ) ;
else
elm_object_part_content_unset ( split - > panes , PANES_BOTTOM ) ;
2020-03-30 13:29:21 -07:00
wn - > tc . unfocus ( & wn - > tc , NULL ) ; /* unfocus from top */
2020-04-14 14:40:08 -07:00
tc_split = _split_new ( child1 , child2 , 0.5 , is_horizontal ) ;
2020-02-29 07:18:07 -08:00
if ( wn - > config - > show_tabs )
{
if ( child_orig - > type = = TERM_CONTAINER_TYPE_SOLO )
{
2020-03-16 15:50:04 -07:00
_solo_tab_show ( child_orig ) ;
2020-02-29 07:18:07 -08:00
}
2020-03-16 15:50:04 -07:00
_solo_tab_show ( child_new ) ;
2020-02-29 07:18:07 -08:00
}
tc_split - > is_focused = tc - > is_focused ;
tc - > swallow ( tc , child_orig , tc_split ) ;
2020-03-30 13:29:21 -07:00
child_new - > focus ( child_new , NULL ) ; /* refocus from bottom */
2020-02-29 07:18:07 -08:00
return 0 ;
}
2018-02-11 02:48:06 -08:00
static Eina_Bool
2020-04-11 01:01:13 -07:00
_split_is_visible ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
2018-02-11 02:48:06 -08:00
{
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
/* Could return True with the current design because splits are at a higher
* level than tabs */
return tc - > parent - > is_visible ( tc - > parent , tc ) ;
}
2020-02-15 07:47:47 -08:00
static void
_split_detach ( Term_Container * tc , Term_Container * solo_child )
{
2020-03-16 15:50:04 -07:00
Evas_Object * o ;
2020-02-15 07:47:47 -08:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SPLIT ) ;
assert ( solo_child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
_split_close ( tc , solo_child ) ;
2020-03-07 05:58:12 -08:00
solo_child - > is_focused = EINA_FALSE ;
2020-03-16 15:50:04 -07:00
o = solo_child - > get_evas_object ( solo_child ) ;
evas_object_hide ( o ) ;
2020-03-22 02:53:30 -07:00
solo_child - > parent = ( Term_Container * ) solo_child - > wn ;
2020-02-15 07:47:47 -08:00
}
2015-03-22 10:17:16 -07:00
static Term_Container *
2015-07-15 14:17:24 -07:00
_split_new ( Term_Container * tc1 , Term_Container * tc2 ,
2020-04-14 14:40:08 -07:00
double left_size ,
2015-07-15 14:17:24 -07:00
Eina_Bool is_horizontal )
2015-03-22 10:17:16 -07:00
{
Evas_Object * o ;
Term_Container * tc = NULL ;
Split * split = NULL ;
split = calloc ( 1 , sizeof ( Split ) ) ;
if ( ! split )
{
free ( split ) ;
return NULL ;
}
2020-10-17 08:03:56 -07:00
DBG ( " split new %p 1:%p 2:%p (1 is %sfocused) (2 is %sfocused) " , split , tc1 , tc2 ,
tc1 - > is_focused ? " " : " not " ,
tc2 - > is_focused ? " " : " not " ) ;
2020-03-16 15:50:04 -07:00
2015-03-22 10:17:16 -07:00
tc = ( Term_Container * ) split ;
tc - > term_next = _split_term_next ;
tc - > term_prev = _split_term_prev ;
2017-07-10 15:01:29 -07:00
tc - > term_up = _split_term_up ;
tc - > term_down = _split_term_down ;
tc - > term_left = _split_term_left ;
tc - > term_right = _split_term_right ;
2015-03-22 10:17:16 -07:00
tc - > term_first = _split_term_first ;
tc - > term_last = _split_term_last ;
tc - > focused_term_get = _split_focused_term_get ;
tc - > get_evas_object = _split_get_evas_object ;
tc - > split = _split_split ;
2020-02-29 07:18:07 -08:00
tc - > split_direction = _split_split_direction ;
2015-03-22 10:17:16 -07:00
tc - > find_term_at_coords = _split_find_term_at_coords ;
tc - > size_eval = _split_size_eval ;
tc - > swallow = _split_swallow ;
tc - > focus = _split_focus ;
tc - > unfocus = _split_unfocus ;
tc - > set_title = _split_set_title ;
tc - > bell = _split_bell ;
tc - > close = _split_close ;
tc - > update = _split_update ;
2018-02-11 02:48:06 -08:00
tc - > is_visible = _split_is_visible ;
2020-02-15 07:47:47 -08:00
tc - > detach = _split_detach ;
2015-03-22 10:17:16 -07:00
tc - > title = eina_stringshare_add ( " Terminology " ) ;
tc - > type = TERM_CONTAINER_TYPE_SPLIT ;
tc - > parent = NULL ;
tc - > wn = tc1 - > wn ;
tc1 - > parent = tc2 - > parent = tc ;
split - > tc1 = tc1 ;
split - > tc2 = tc2 ;
2020-03-16 15:50:04 -07:00
split - > last_focus = tc2 ;
2020-06-21 14:46:22 -07:00
if ( tc1 - > is_focused )
split - > last_focus = tc1 ;
2015-03-22 10:17:16 -07:00
o = split - > panes = elm_panes_add ( tc1 - > wn - > win ) ;
elm_object_style_set ( o , " flush " ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_align_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
split - > is_horizontal = is_horizontal ;
elm_panes_horizontal_set ( o , split - > is_horizontal ) ;
elm_object_part_content_set ( o , PANES_TOP ,
tc1 - > get_evas_object ( tc1 ) ) ;
elm_object_part_content_set ( o , PANES_BOTTOM ,
tc2 - > get_evas_object ( tc2 ) ) ;
2020-04-14 14:40:08 -07:00
elm_panes_content_left_size_set ( o , left_size ) ;
2015-03-22 10:17:16 -07:00
2020-03-07 05:58:12 -08:00
tc - > is_focused = tc1 - > is_focused | tc2 - > is_focused ;
2020-04-16 08:16:18 -07:00
assert ( ! ( tc1 - > is_focused & & tc2 - > is_focused ) ) ;
2015-03-22 10:17:16 -07:00
return tc ;
2014-12-02 15:42:27 -08:00
}
2014-10-26 13:00:14 -07:00
static void
_size_job ( void * data )
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
Sizeinfo info = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
Term_Container * tc = ( Term_Container * ) wn ;
2014-10-26 13:00:14 -07:00
wn - > size_job = NULL ;
2015-03-22 10:17:16 -07:00
tc - > size_eval ( tc , & info ) ;
2014-10-26 13:00:14 -07:00
elm_win_size_step_set ( wn - > win , info . step_x , info . step_y ) ;
2020-04-10 15:31:04 -07:00
if ( info . bg_min_w > 0 & & info . bg_min_h > 0 )
{
elm_win_size_base_set ( wn - > win ,
info . min_w , info . min_h ) ;
evas_object_size_hint_min_set ( wn - > backbg ,
info . bg_min_w ,
info . bg_min_h ) ;
if ( info . req )
evas_object_resize ( wn - > win , info . req_w , info . req_h ) ;
}
2014-10-26 13:00:14 -07:00
}
void
win_sizing_handle ( Win * wn )
{
2020-01-19 07:51:17 -08:00
if ( wn - > size_job )
ecore_job_del ( wn - > size_job ) ;
2014-10-26 13:00:14 -07:00
_size_job ( wn ) ;
}
static void
2015-03-22 10:17:16 -07:00
_cb_size_hint ( void * data ,
2016-10-05 13:00:22 -07:00
Evas * _e EINA_UNUSED ,
Evas_Object * obj ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
Evas_Coord mw , mh , rw , rh , w = 0 , h = 0 ;
2019-12-26 04:17:52 -08:00
Evas_Object * edje_base = elm_layout_edje_get ( term - > core ) ;
2014-10-26 13:00:14 -07:00
evas_object_size_hint_min_get ( obj , & mw , & mh ) ;
evas_object_size_hint_request_get ( obj , & rw , & rh ) ;
2019-05-22 14:03:03 -07:00
edje_object_size_min_calc ( edje_base , & w , & h ) ;
2019-12-26 04:17:52 -08:00
evas_object_size_hint_min_set ( term - > core , w , h ) ;
2020-02-03 12:00:09 -08:00
edje_object_size_min_calc ( term - > bg_edj , & w , & h ) ;
2014-10-26 13:00:14 -07:00
evas_object_size_hint_min_set ( term - > bg , w , h ) ;
term - > step_x = mw ;
term - > step_y = mh ;
term - > min_w = w - mw ;
term - > min_h = h - mh ;
term - > req_w = w - mw + rw ;
term - > req_h = h - mh + rh ;
2020-01-19 07:51:17 -08:00
if ( term - > wn - > size_job )
ecore_job_del ( term - > wn - > size_job ) ;
2014-12-02 15:42:27 -08:00
term - > wn - > size_job = ecore_job_add ( _size_job , term - > wn ) ;
}
2015-03-22 10:17:16 -07:00
void
2020-04-06 14:11:10 -07:00
split_horizontally ( Evas_Object * term ,
2015-03-22 10:17:16 -07:00
const char * cmd )
2014-12-02 15:42:27 -08:00
{
Term * tm ;
2015-03-22 10:17:16 -07:00
Term_Container * tc ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tm = evas_object_data_get ( term , " term " ) ;
if ( ! tm ) return ;
tc = tm - > container ;
2015-09-19 05:49:40 -07:00
tc - > split ( tc , tc , tm , cmd , EINA_TRUE ) ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
void
2020-04-06 14:11:10 -07:00
split_vertically ( Evas_Object * term ,
2015-03-22 10:17:16 -07:00
const char * cmd )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Term * tm ;
Term_Container * tc ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tm = evas_object_data_get ( term , " term " ) ;
if ( ! tm ) return ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
tc = tm - > container ;
2015-09-19 05:49:40 -07:00
tc - > split ( tc , tc , tm , cmd , EINA_FALSE ) ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
/* }}} */
/* {{{ Tabs */
2020-01-19 07:51:17 -08:00
static Term *
_tab_item_to_term ( const Tab_Item * tab_item )
2014-12-09 05:32:47 -08:00
{
2020-01-19 07:51:17 -08:00
Solo * solo ;
2014-12-09 05:32:47 -08:00
2020-01-19 07:51:17 -08:00
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
assert ( solo - > term ) ;
assert ( solo - > term - > tab_item = = tab_item ) ;
return solo - > term ;
}
2020-03-14 15:32:02 -07:00
static void
_cb_tab_activate ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
{
Tab_Item * tab_item = data ;
Term * term = _tab_item_to_term ( tab_item ) ;
term_focus ( term ) ;
}
2020-01-19 07:51:17 -08:00
static void
_tabbar_clear ( Term * term )
{
if ( term - > tabbar . l . box )
2014-12-09 05:32:47 -08:00
{
2020-01-19 07:51:17 -08:00
elm_box_unpack_all ( term - > tabbar . l . box ) ;
evas_object_del ( term - > tabbar . l . box ) ;
term - > tabbar . l . box = NULL ;
2014-12-09 05:32:47 -08:00
}
2020-01-19 07:51:17 -08:00
if ( term - > tabbar . r . box )
2014-12-09 05:32:47 -08:00
{
2020-01-19 07:51:17 -08:00
elm_box_unpack_all ( term - > tabbar . r . box ) ;
evas_object_del ( term - > tabbar . r . box ) ;
term - > tabbar . r . box = NULL ;
2014-12-09 05:32:47 -08:00
}
2020-01-19 07:51:17 -08:00
if ( term - > tab_spacer )
2016-01-31 06:24:15 -08:00
{
2020-01-19 07:51:17 -08:00
elm_layout_signal_emit ( term - > bg , " tabbar,off " , " terminology " ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
elm_layout_content_unset ( term - > bg , " terminology.tab " ) ;
evas_object_del ( term - > tab_spacer ) ;
term - > tab_spacer = NULL ;
2016-01-31 06:24:15 -08:00
}
2020-01-19 09:02:18 -08:00
if ( term - > tab_inactive )
2020-03-14 15:32:02 -07:00
{
evas_object_hide ( term - > tab_inactive ) ;
edje_object_signal_callback_del ( term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
}
2014-12-09 05:32:47 -08:00
}
2020-01-19 07:51:17 -08:00
static void
_tab_item_free ( Tab_Item * tab_item )
{
Term * term ;
2020-03-14 15:32:02 -07:00
2020-01-19 07:51:17 -08:00
if ( ! tab_item )
return ;
term = _tab_item_to_term ( tab_item ) ;
term - > tab_item = NULL ;
if ( term - > tab_inactive )
edje_object_signal_callback_del ( term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
2020-03-14 15:32:02 -07:00
free ( tab_item ) ;
2020-01-19 07:51:17 -08:00
}
2015-10-10 10:39:16 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_tab_close ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2015-10-10 10:39:16 -07:00
{
Term * term = data ;
Win * wn = term - > wn ;
Evas_Object * win = win_evas_object_get ( wn ) ;
2016-02-02 14:15:50 -08:00
term_close ( win , term - > termio , EINA_FALSE ) ;
2015-10-10 10:39:16 -07:00
}
2017-02-17 12:47:10 -08:00
static void
_cb_tab_title ( void * data ,
2020-01-19 07:51:17 -08:00
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2017-02-17 12:47:10 -08:00
{
Term * term = data ;
term_set_title ( term ) ;
}
2020-01-19 07:51:17 -08:00
2014-12-09 05:32:47 -08:00
static void
2020-01-19 07:51:17 -08:00
_tabs_recompute_drag ( Tabs * tabs )
2014-12-09 05:32:47 -08:00
{
2020-01-19 09:51:27 -08:00
Term * term = NULL ;
2015-03-22 10:17:16 -07:00
int n = eina_list_count ( tabs - > tabs ) ;
2020-01-19 07:51:17 -08:00
int idx = - 1 ;
2015-03-22 10:17:16 -07:00
Tab_Item * tab_item ;
2020-01-19 07:51:17 -08:00
Eina_List * l ;
double v1 = 0.0 , v2 = 1.0 ;
2014-12-09 05:32:47 -08:00
2015-03-22 10:17:16 -07:00
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
2014-12-09 05:32:47 -08:00
{
2020-01-19 07:51:17 -08:00
idx + + ;
if ( tab_item = = tabs - > current )
{
term = _tab_item_to_term ( tab_item ) ;
break ;
}
}
2020-03-14 15:32:02 -07:00
assert ( term ! = NULL ) ;
2020-01-19 07:51:17 -08:00
if ( n > 1 )
{
v1 = ( double ) ( idx ) / ( double ) n ;
v2 = ( double ) ( idx + 1 ) / ( double ) n ;
2014-12-09 05:32:47 -08:00
}
2020-01-19 07:51:17 -08:00
tabs - > v1_orig = v1 ;
tabs - > v2_orig = v2 ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabl " , v1 , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabr " , v2 , 0.0 ) ;
}
2020-02-07 11:09:27 -08:00
static Eina_Bool
_term_hdrag_on ( Term * term , void * data EINA_UNUSED )
{
elm_layout_signal_emit ( term - > bg , " hdrag,on " , " terminology " ) ;
return ECORE_CALLBACK_PASS_ON ;
}
static Eina_Bool
_term_hdrag_off ( Term * term , void * data EINA_UNUSED )
{
elm_layout_signal_emit ( term - > bg , " hdrag,off " , " terminology " ) ;
return ECORE_CALLBACK_PASS_ON ;
}
2020-01-19 07:51:17 -08:00
2020-02-25 14:43:16 -08:00
static void
_tab_drag_disable_anim_over ( void )
{
if ( ( ! _tab_drag ) | | ( ! _tab_drag - > term_over ) | |
2020-02-29 07:18:07 -08:00
( _tab_drag - > split_direction = = SPLIT_DIRECTION_NONE ) )
2020-02-25 14:43:16 -08:00
return ;
2020-02-29 07:18:07 -08:00
switch ( _tab_drag - > split_direction )
2020-02-25 14:43:16 -08:00
{
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_LEFT :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" drag_left,off " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_RIGHT :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" drag_right,off " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_TOP :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" drag_top,off " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_BOTTOM :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" drag_bottom,off " , " terminology " ) ;
break ;
2020-03-25 14:13:43 -07:00
case SPLIT_DIRECTION_TABS :
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" drag_over_tabs,off " , " terminology " ) ;
break ;
2020-02-25 14:43:16 -08:00
default :
break ;
}
elm_layout_signal_emit ( _tab_drag - > term_over - > bg ,
" hdrag,off " , " terminology " ) ;
}
2020-03-07 05:58:12 -08:00
static void
_tab_drag_rollback_split ( void )
{
Eina_Bool is_horizontal = _tab_drag - > is_horizontal ;
Term_Container * tc_split = NULL ;
Term_Container * child1 = NULL , * child2 = NULL ;
Term_Container * other = _tab_drag - > other ;
Term_Container * parent = NULL ;
Win * wn = _tab_drag - > term - > wn ;
Term_Container * tc_win = ( Term_Container * ) wn ;
Term_Container * tc = _tab_drag - > term - > container ;
if ( ! _tab_drag - > other )
{
other = wn - > child ;
}
parent = other - > parent ;
if ( _tab_drag - > is_first_child )
{
child1 = tc ;
child2 = other ;
}
else
{
child1 = other ;
child2 = tc ;
}
2020-04-16 08:16:18 -07:00
assert ( ! tc - > is_focused ) ;
2020-04-14 14:40:08 -07:00
tc_split = _split_new ( child1 , child2 , _tab_drag - > left_size , is_horizontal ) ;
2020-03-07 05:58:12 -08:00
parent - > swallow ( parent , other , tc_split ) ;
2020-04-16 08:16:18 -07:00
/* Ensure the other child is unfocused */
other - > unfocus ( other , tc_split ) ;
/* Unfocus from the window down to a single term */
2020-03-07 05:58:12 -08:00
tc_win - > unfocus ( tc_win , NULL ) ;
2020-04-16 08:16:18 -07:00
/* Focus the dragged term, up to the window */
2020-03-07 05:58:12 -08:00
tc - > focus ( tc , NULL ) ;
}
static void
2020-03-14 08:09:02 -07:00
_tabs_attach ( Term_Container * tc , Term_Container * tc_new )
2020-03-07 05:58:12 -08:00
{
2020-03-14 08:09:02 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
Evas_Object * o ;
Evas_Coord x , y , w , h ;
Term_Container * tc_old , * tc_parent ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
assert ( tc_new - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
tabs = ( Tabs * ) tc ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
tc_new - > parent = tc ;
tab_item = tab_item_new ( tabs , tc_new ) ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
tc_parent = tc - > parent ;
tc_old = tabs - > current - > tc ;
tc_old - > unfocus ( tc_old , tc ) ;
o = tc_old - > get_evas_object ( tc_old ) ;
evas_object_geometry_get ( o , & x , & y , & w , & h ) ;
evas_object_hide ( o ) ;
o = tc_new - > get_evas_object ( tc_new ) ;
evas_object_geometry_set ( o , x , y , w , h ) ;
evas_object_show ( o ) ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
tc - > swallow ( tc , tc_old , tc_new ) ;
tabs - > current = tab_item ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
/* XXX: need to refresh parent */
tc_parent - > swallow ( tc_parent , tc , tc ) ;
2020-03-07 05:58:12 -08:00
2020-03-14 08:09:02 -07:00
if ( tc - > is_focused )
tc_new - > focus ( tc_new , tc ) ;
else
tc_new - > unfocus ( tc_new , tc ) ;
2020-03-07 05:58:12 -08:00
}
2020-02-25 14:43:16 -08:00
2020-03-14 08:09:02 -07:00
2020-01-19 07:51:17 -08:00
static void
2020-03-14 08:09:02 -07:00
_solo_attach ( Term_Container * tc , Term_Container * tc_to_add )
2020-01-19 07:51:17 -08:00
{
2020-03-14 08:09:02 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
assert ( tc_to_add - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2020-02-07 11:09:27 -08:00
2020-03-14 08:09:02 -07:00
if ( tc - > parent - > type ! = TERM_CONTAINER_TYPE_TABS )
_tabs_new ( tc , tc - > parent ) ;
2020-02-07 11:09:27 -08:00
2020-03-14 08:09:02 -07:00
_tabs_attach ( tc - > parent , tc_to_add ) ;
2020-03-14 15:32:02 -07:00
assert ( eina_list_count ( ( ( Tabs * ) ( tc - > parent ) ) - > tabs ) > 1 ) ;
2020-03-14 08:09:02 -07:00
}
2020-02-07 11:09:27 -08:00
2020-03-14 08:09:02 -07:00
static void
_tab_drag_reparented ( void )
{
assert ( _tab_drag ) ;
_tab_drag - > parent_type = TERM_CONTAINER_TYPE_UNKNOWN ;
2020-01-19 07:51:17 -08:00
}
static void
2020-02-09 04:09:05 -08:00
_term_on_horizontal_drag ( void * data ,
Evas_Object * o EINA_UNUSED ,
const char * emission EINA_UNUSED ,
const char * source EINA_UNUSED )
2020-01-19 07:51:17 -08:00
{
Eina_List * l , * next , * prev ;
int tab_active_idx ;
int n ;
Tabs * tabs ;
Tab_Item * tab_item ;
Tab_Item * item_moved ;
Term * term = data ;
2020-02-09 04:09:05 -08:00
Term_Container * tc = term - > container ;
Term_Container * tc_parent = tc - > parent ;
2020-01-19 07:51:17 -08:00
Term * term_moved ;
2020-03-18 15:31:06 -07:00
double v1 , v2 , m ;
2015-03-22 10:17:16 -07:00
2020-02-09 04:09:05 -08:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
if ( tc - > parent - > type ! = TERM_CONTAINER_TYPE_TABS )
{
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabl " ,
0.0 , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabr " ,
1.0 , 0.0 ) ;
return ;
}
tabs = ( Tabs * ) tc_parent ;
2020-01-19 07:51:17 -08:00
n = eina_list_count ( tabs - > tabs ) ;
2020-03-19 01:27:57 -07:00
if ( n < = 1 )
return ;
2020-01-19 07:51:17 -08:00
2020-02-07 11:09:27 -08:00
tab_item = tabs - > current ;
2020-02-17 14:17:06 -08:00
_tab_drag_free ( ) ;
2020-02-07 11:09:27 -08:00
2020-01-19 07:51:17 -08:00
tab_active_idx = - 1 ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
tab_active_idx + + ;
if ( tab_item = = tabs - > current )
break ;
}
2015-03-22 10:17:16 -07:00
tab_item = tabs - > current ;
2020-01-19 07:51:17 -08:00
edje_object_part_drag_value_get ( term - > bg_edj , " terminology.tabl " ,
2020-01-19 09:02:18 -08:00
& v1 , NULL ) ;
edje_object_part_drag_value_get ( term - > bg_edj , " terminology.tabr " ,
& v2 , NULL ) ;
2020-03-18 15:31:06 -07:00
m = 1.2 / ( ( double ) ( 2 * n ) ) ; /* 1.2, to have some sense of hysteresis */
2020-01-19 07:51:17 -08:00
while ( ( tab_active_idx < n - 1 ) & &
2020-03-18 15:31:06 -07:00
( ( v2 > ( tabs - > v2_orig + m ) ) | |
2020-02-15 13:33:51 -08:00
( ( v1 = = v2 ) & & ( v2 > tabs - > v2_orig ) ) ) )
2020-01-19 07:51:17 -08:00
{
/* To the right */
l = eina_list_nth_list ( tabs - > tabs , tab_active_idx ) ;
next = eina_list_next ( l ) ;
item_moved = next - > data ;
term_moved = _tab_item_to_term ( item_moved ) ;
elm_box_unpack ( term - > tabbar . r . box , term_moved - > tab_inactive ) ;
2020-01-19 09:02:18 -08:00
elm_box_pack_end ( term - > tabbar . l . box , term_moved - > tab_inactive ) ;
2020-01-19 07:51:17 -08:00
tabs - > tabs = eina_list_remove_list ( tabs - > tabs , l ) ;
tabs - > tabs = eina_list_append_relative_list ( tabs - > tabs ,
eina_list_data_get ( l ) ,
next ) ;
_tabs_recompute_drag ( tabs ) ;
2020-02-07 11:09:27 -08:00
tab_active_idx + + ;
if ( v2 < = tabs - > v2_orig )
return ;
2020-01-19 07:51:17 -08:00
}
while ( ( tab_active_idx > 0 ) & &
2020-03-18 15:31:06 -07:00
( ( v1 < tabs - > v1_orig - m ) | |
2020-02-15 13:33:51 -08:00
( ( v1 = = v2 ) & & v1 < tabs - > v1_orig ) ) )
2020-01-19 07:51:17 -08:00
{
/* To the left */
l = eina_list_nth_list ( tabs - > tabs , tab_active_idx ) ;
prev = eina_list_prev ( l ) ;
item_moved = prev - > data ;
term_moved = _tab_item_to_term ( item_moved ) ;
elm_box_unpack ( term - > tabbar . l . box , term_moved - > tab_inactive ) ;
2020-01-19 09:02:18 -08:00
elm_box_pack_start ( term - > tabbar . r . box , term_moved - > tab_inactive ) ;
2020-01-19 07:51:17 -08:00
tabs - > tabs = eina_list_remove_list ( tabs - > tabs , prev ) ;
tabs - > tabs = eina_list_append_relative_list ( tabs - > tabs ,
eina_list_data_get ( prev ) ,
l ) ;
_tabs_recompute_drag ( tabs ) ;
2020-02-07 11:09:27 -08:00
tab_active_idx - - ;
}
}
2020-03-07 05:58:12 -08:00
static void
2020-03-14 08:09:02 -07:00
_tabs_set_main_tab ( Term * term ,
Tab_Item * tab_item )
2020-02-07 11:09:27 -08:00
{
2020-03-14 08:09:02 -07:00
if ( ! term - > tab_spacer )
{
Evas_Coord w = 0 , h = 0 ;
Evas * canvas = evas_object_evas_get ( term - > bg ) ;
2020-02-07 11:09:27 -08:00
2020-03-14 08:09:02 -07:00
term - > tab_spacer = evas_object_rectangle_add ( canvas ) ;
evas_object_color_set ( term - > tab_spacer , 0 , 0 , 0 , 0 ) ;
elm_coords_finger_size_adjust ( 1 , & w , 1 , & h ) ;
evas_object_size_hint_min_set ( term - > tab_spacer , w , h ) ;
elm_layout_content_set ( term - > bg , " terminology.tab " , term - > tab_spacer ) ;
}
evas_object_show ( term - > tab_spacer ) ;
elm_layout_text_set ( term - > bg , " terminology.tab.title " , tab_item - > tc - > title ) ;
elm_layout_signal_emit ( term - > bg , " tabbar,on " , " terminology " ) ;
elm_layout_signal_emit ( term - > bg , " tab_btn,on " , " terminology " ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
2020-02-07 11:09:27 -08:00
}
2020-03-14 08:09:02 -07:00
static Evas_Object *
_tab_inactive_get_or_create ( Evas * canvas ,
Term * term ,
Tab_Item * tab_item )
2020-02-15 07:47:47 -08:00
{
Evas_Object * o ;
2020-03-14 08:09:02 -07:00
Evas_Coord w , h ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
if ( term - > tab_inactive )
{
o = term - > tab_inactive ;
goto created ;
}
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
term - > tab_inactive = o = edje_object_add ( canvas ) ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
theme_apply ( o , term - > config , " terminology/tabbar_back " ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
edje_object_size_min_calc ( o , & w , & h ) ;
evas_object_size_hint_min_set ( o , w , h ) ;
evas_object_data_set ( o , " term " , term ) ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
created :
edje_object_signal_callback_add ( o , " tab,activate " , " terminology " ,
_cb_tab_activate , tab_item ) ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
if ( term - > missed_bell )
edje_object_signal_emit ( o , " bell " , " terminology " ) ;
2020-02-15 07:47:47 -08:00
else
2020-03-14 08:09:02 -07:00
edje_object_signal_emit ( o , " bell,off " , " terminology " ) ;
edje_object_part_text_set ( o , " terminology.title " ,
tab_item - > tc - > title ) ;
return o ;
2020-02-15 07:47:47 -08:00
}
2020-03-14 08:09:02 -07:00
2020-02-15 07:47:47 -08:00
static void
2020-03-14 08:09:02 -07:00
_tabbar_fill ( Tabs * tabs )
2020-02-15 07:47:47 -08:00
{
2020-03-14 08:09:02 -07:00
Eina_List * l ;
Eina_Bool after_current = EINA_FALSE ;
Tab_Item * tab_item ;
Term * main_term = _tab_item_to_term ( tabs - > current ) ;
Evas * canvas = evas_object_evas_get ( main_term - > bg ) ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
Term * term = _tab_item_to_term ( tab_item ) ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
if ( tab_item = = tabs - > current )
{
_tabs_set_main_tab ( term , tab_item ) ;
assert ( main_term = = term ) ;
evas_object_hide ( term - > tab_inactive ) ;
2020-03-14 15:32:02 -07:00
edje_object_signal_callback_del ( term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
2020-03-14 08:09:02 -07:00
after_current = EINA_TRUE ;
}
else
{
Evas_Object * o ;
_tabbar_clear ( term ) ;
o = _tab_inactive_get_or_create ( canvas , term , tab_item ) ;
evas_object_show ( o ) ;
if ( after_current )
elm_box_pack_end ( main_term - > tabbar . r . box , o ) ;
else
elm_box_pack_end ( main_term - > tabbar . l . box , o ) ;
}
}
_tabs_recompute_drag ( tabs ) ;
2020-02-15 07:47:47 -08:00
}
static void
2020-03-14 08:09:02 -07:00
_tabs_get_or_create_boxes ( Term * term , Term * src )
2020-02-15 07:47:47 -08:00
{
2020-03-14 08:09:02 -07:00
Evas_Object * o ;
2020-02-15 07:47:47 -08:00
2020-03-14 08:09:02 -07:00
assert ( term - > tabbar . l . box = = NULL ) ;
assert ( term - > tabbar . r . box = = NULL ) ;
/* Left */
if ( src & & src - > tabbar . l . box )
{
term - > tabbar . l . box = o = src - > tabbar . l . box ;
elm_box_unpack_all ( term - > tabbar . l . box ) ;
src - > tabbar . l . box = NULL ;
}
else
{
term - > tabbar . l . box = o = elm_box_add ( term - > bg ) ;
elm_box_horizontal_set ( o , EINA_TRUE ) ;
elm_box_homogeneous_set ( o , EINA_TRUE ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
}
elm_layout_content_set ( term - > bg , " terminology.tabl.content " , o ) ;
evas_object_show ( o ) ;
/* Right */
if ( src & & src - > tabbar . r . box )
{
term - > tabbar . r . box = o = src - > tabbar . r . box ;
elm_box_unpack_all ( term - > tabbar . r . box ) ;
src - > tabbar . r . box = NULL ;
}
else
{
term - > tabbar . r . box = o = elm_box_add ( term - > bg ) ;
elm_box_horizontal_set ( o , EINA_TRUE ) ;
elm_box_homogeneous_set ( o , EINA_TRUE ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
}
elm_layout_content_set ( term - > bg , " terminology.tabr.content " , o ) ;
evas_object_show ( o ) ;
}
2020-03-15 01:28:31 -07:00
static void
_tab_drag_rollback_win ( void )
{
Term * term = _tab_drag - > term ;
Win * wn = term - > wn ;
Term_Container * tc_win = ( Term_Container * ) wn ;
Term_Container * tc = term - > container ;
2020-04-16 10:30:27 -07:00
if ( term - > unswallowed )
elm_layout_content_set ( term - > bg , " terminology.content " , term - > core ) ;
term - > unswallowed = EINA_FALSE ;
2020-03-15 01:28:31 -07:00
tc_win - > swallow ( tc_win , NULL , tc ) ;
tc_win - > unfocus ( tc_win , NULL ) ;
tc - > focus ( tc , NULL ) ;
_tab_drag_reparented ( ) ;
}
2020-03-14 08:09:02 -07:00
static void
_tab_drag_rollback_tabs ( void )
{
Term * term = _tab_drag - > term ;
Win * wn = term - > wn ;
Term_Container * tc_win = ( Term_Container * ) wn ;
Term_Container * tc = term - > container ;
Term_Container * tc_tabs = _tab_drag - > tabs_child ;
2020-03-14 15:32:02 -07:00
int n ;
Tabs * tabs ;
2020-03-14 08:09:02 -07:00
if ( tc_tabs - > type = = TERM_CONTAINER_TYPE_TABS )
{
2020-03-14 15:32:02 -07:00
tabs = ( Tabs * ) tc_tabs ;
2020-03-14 08:09:02 -07:00
/* reinsert at correct place */
_solo_attach ( tabs - > current - > tc , tc ) ;
2020-03-14 15:32:02 -07:00
}
else
{
assert ( tc_tabs - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
/* Create tabs with solo */
assert ( term - > tab_item = = NULL ) ;
_solo_attach ( _tab_drag - > tabs_child , term - > container ) ;
tabs = ( Tabs * ) term - > container - > parent ;
}
n = eina_list_count ( tabs - > tabs ) ;
assert ( n > = 2 ) ;
2020-03-14 08:09:02 -07:00
2020-03-14 15:32:02 -07:00
/* move tab_item to expected place */
if ( _tab_drag - > previous_position < n )
{
Tab_Item * tab_item = term - > tab_item ;
2020-03-14 08:09:02 -07:00
2020-03-14 15:32:02 -07:00
tabs - > tabs = eina_list_remove ( tabs - > tabs , tab_item ) ;
if ( _tab_drag - > previous_position = = n - 1 )
{
tabs - > tabs = eina_list_append ( tabs - > tabs , term - > tab_item ) ;
}
else
2020-03-14 08:09:02 -07:00
{
int i = 0 ;
Eina_List * l ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
if ( i = = _tab_drag - > previous_position )
{
tabs - > tabs = eina_list_prepend_relative_list ( tabs - > tabs ,
2020-03-14 15:32:02 -07:00
term - > tab_item ,
l ) ;
2020-03-14 08:09:02 -07:00
break ;
}
i + + ;
}
}
2020-03-14 15:32:02 -07:00
}
2020-03-14 08:09:02 -07:00
2020-03-14 15:32:02 -07:00
tc_win - > unfocus ( tc_win , NULL ) ;
tc - > focus ( tc , NULL ) ;
2020-03-14 08:09:02 -07:00
2020-03-14 15:32:02 -07:00
/* Repack in correct boxes */
elm_box_unpack_all ( term - > tabbar . l . box ) ;
elm_box_unpack_all ( term - > tabbar . r . box ) ;
_tabbar_fill ( tabs ) ;
2020-03-14 08:09:02 -07:00
2020-03-14 15:32:02 -07:00
_tab_drag_reparented ( ) ;
2020-03-14 08:09:02 -07:00
}
static void
_tab_drag_rollback ( void )
{
2020-04-16 08:16:18 -07:00
_focus_validator ( ) ;
2020-03-14 08:09:02 -07:00
switch ( _tab_drag - > parent_type )
{
case TERM_CONTAINER_TYPE_TABS :
_tab_drag_rollback_tabs ( ) ;
break ;
case TERM_CONTAINER_TYPE_SPLIT :
_tab_drag_rollback_split ( ) ;
break ;
case TERM_CONTAINER_TYPE_WIN :
2020-03-15 01:28:31 -07:00
_tab_drag_rollback_win ( ) ;
2020-03-14 08:09:02 -07:00
break ;
default :
ERR ( " invalid parent type:%d " , _tab_drag - > parent_type ) ;
abort ( ) ;
}
2020-04-16 08:16:18 -07:00
_focus_validator ( ) ;
2020-03-14 08:09:02 -07:00
}
static void
_tab_drag_save_state ( Term_Container * tc )
{
assert ( _tab_drag ) ;
_tab_drag - > parent_type = tc - > parent - > type ;
switch ( _tab_drag - > parent_type )
{
case TERM_CONTAINER_TYPE_TABS :
{
int position = 0 ;
Tabs * tabs ;
Eina_List * l ;
Tab_Item * tab_item ;
tabs = ( Tabs * ) tc - > parent ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
if ( tab_item - > tc = = tc )
break ;
position + + ;
}
_tab_drag - > previous_position = position ;
_tab_drag - > tabs_child = tc - > parent ;
}
break ;
case TERM_CONTAINER_TYPE_SPLIT :
{
Split * split ;
split = ( Split * ) tc - > parent ;
_tab_drag - > is_horizontal = split - > is_horizontal ;
if ( ( _tab_drag - > is_first_child = ( split - > tc1 = = tc ) ) )
_tab_drag - > other = split - > tc2 ;
else
_tab_drag - > other = split - > tc1 ;
2020-04-14 14:40:08 -07:00
_tab_drag - > left_size = elm_panes_content_left_size_get (
split - > panes ) ;
2020-03-14 08:09:02 -07:00
}
break ;
default :
ERR ( " invalid parent type:%d " , tc - > parent - > type ) ;
abort ( ) ;
}
}
static void
_tab_drag_free ( void )
{
if ( ! _tab_drag )
return ;
2020-04-16 08:44:58 -07:00
if ( _tab_drag - > term_over & & _tab_drag - > term_over - > has_bg_cursor )
{
elm_object_cursor_unset ( _tab_drag - > term_over - > bg ) ;
_tab_drag - > term_over - > has_bg_cursor = EINA_FALSE ;
}
if ( _tab_drag - > term - > has_bg_cursor )
{
elm_object_cursor_unset ( _tab_drag - > term - > bg ) ;
_tab_drag - > term - > has_bg_cursor = EINA_FALSE ;
}
2020-03-14 08:09:02 -07:00
2020-04-16 10:35:19 -07:00
/* free _tab_drag->icon to mark we're freeing _tab_drag */
evas_object_del ( _tab_drag - > icon ) ;
_tab_drag - > icon = NULL ;
2020-03-14 08:09:02 -07:00
if ( _tab_drag - > parent_type ! = TERM_CONTAINER_TYPE_UNKNOWN )
_tab_drag_rollback ( ) ;
_tab_drag_disable_anim_over ( ) ;
for_each_term_do ( _tab_drag - > term - > wn , & _term_hdrag_on , NULL ) ;
ecore_timer_del ( _tab_drag - > timer ) ;
_tab_drag - > timer = NULL ;
2020-03-22 02:53:30 -07:00
evas_object_del ( _tab_drag - > img ) ;
_tab_drag - > img = NULL ;
2020-03-14 08:09:02 -07:00
term_unref ( _tab_drag - > term ) ;
free ( _tab_drag ) ;
_tab_drag = NULL ;
}
static void
_tab_drag_reinsert ( Term * term , double mid )
{
Term_Container * tc = term - > container ;
Term_Container * tc_parent = tc - > parent ;
Tabs * tabs ;
tc = term - > container ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
if ( tc_parent - > type ! = TERM_CONTAINER_TYPE_TABS )
return ;
tabs = ( Tabs * ) tc_parent ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabl " , mid , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabr " , mid , 0.0 ) ;
_term_on_horizontal_drag ( term , NULL , NULL , NULL ) ;
/* In case there is no drag, need to recompute to something valid */
_tabs_recompute_drag ( tabs ) ;
}
static void
2020-03-25 14:13:43 -07:00
_tab_reorg ( Term * term , Term * to_term , Evas_Coord mx )
2020-03-14 08:09:02 -07:00
{
Term_Container * tc_orig = term - > container ;
Term_Container * to_tc = to_term - > container ;
assert ( tc_orig - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
assert ( to_tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2020-02-15 07:47:47 -08:00
2020-03-25 14:13:43 -07:00
if ( _tab_drag - > split_direction = = SPLIT_DIRECTION_TABS )
2020-02-29 07:18:07 -08:00
{
2020-03-25 14:13:43 -07:00
Evas_Coord x = 0 , w = 0 ;
2020-02-29 07:18:07 -08:00
double mid ;
2020-03-25 14:13:43 -07:00
edje_object_part_geometry_get ( term - > bg_edj , " terminology.tabregion " ,
2020-02-29 07:18:07 -08:00
& x , NULL , & w , NULL ) ;
mid = ( double ) ( mx - x ) / ( double ) w ;
2020-02-15 07:47:47 -08:00
2020-02-29 07:18:07 -08:00
_solo_attach ( to_tc , tc_orig ) ;
/* reinsert at correct place */
2020-03-07 05:58:12 -08:00
_tab_drag_reparented ( ) ;
2020-03-14 15:32:02 -07:00
_tab_drag_reinsert ( term , mid ) ;
2020-02-29 07:18:07 -08:00
return ;
}
to_tc - > split_direction ( to_tc , to_tc , tc_orig , _tab_drag - > split_direction ) ;
2020-03-07 05:58:12 -08:00
_tab_drag_reparented ( ) ;
2020-02-15 07:47:47 -08:00
}
2020-02-07 11:09:27 -08:00
static void
2020-02-29 07:18:07 -08:00
_tab_drag_stop ( void )
2020-02-07 11:09:27 -08:00
{
Evas_Coord mx = 0 , my = 0 ;
2020-02-29 07:18:07 -08:00
Win * wn ;
Term_Container * tc_wn ;
Term * term ;
2020-02-07 11:09:27 -08:00
Term * term_at_coords ;
2020-02-17 14:17:06 -08:00
assert ( _tab_drag ) ;
2020-02-07 11:09:27 -08:00
2020-02-29 07:18:07 -08:00
term = _tab_drag - > term ;
wn = term - > wn ;
tc_wn = ( Term_Container * ) wn ;
2020-02-17 14:17:06 -08:00
evas_pointer_canvas_xy_get ( _tab_drag - > e , & mx , & my ) ;
2020-02-09 04:09:05 -08:00
term_at_coords = tc_wn - > find_term_at_coords ( tc_wn , mx , my ) ;
2020-02-07 11:09:27 -08:00
if ( ! term_at_coords )
goto end ;
2020-03-22 02:53:30 -07:00
evas_object_image_source_visible_set ( _tab_drag - > img , EINA_TRUE ) ;
2020-04-16 08:44:58 -07:00
if ( term - > has_bg_cursor )
{
elm_object_cursor_unset ( term - > bg ) ;
term - > has_bg_cursor = EINA_FALSE ;
}
2020-03-22 02:53:30 -07:00
elm_layout_content_unset ( _tab_drag - > icon , " terminology.content " ) ;
elm_layout_content_set ( term - > bg , " terminology.content " , term - > core ) ;
term - > unswallowed = EINA_FALSE ;
evas_object_show ( term - > core ) ;
2020-04-16 08:44:58 -07:00
evas_object_show ( term - > bg ) ;
2020-03-22 02:53:30 -07:00
2020-02-07 11:09:27 -08:00
if ( term_at_coords = = term )
{
2020-02-29 07:18:07 -08:00
Evas_Coord x = 0 , y = 0 , w = 0 , h = 0 , off_x = 0 , off_y = 0 ;
double mid ;
2020-02-09 04:09:05 -08:00
/* Reinsert in same set of Tabs or same "tab" (could be a split) */
2020-02-29 07:18:07 -08:00
evas_object_geometry_get ( term - > bg_edj , & off_x , & off_y , NULL , NULL ) ;
2020-03-25 14:13:43 -07:00
edje_object_part_geometry_get ( term - > bg_edj , " terminology.tabregion " ,
& x , & y , & w , & h ) ;
2020-02-29 07:18:07 -08:00
if ( ! ELM_RECTS_INTERSECT ( x , y , w , h , mx , my , 1 , 1 ) )
goto end ;
mid = ( double ) ( mx - x ) / ( double ) w ;
2020-03-07 05:58:12 -08:00
_tab_drag_reparented ( ) ;
2020-03-14 15:32:02 -07:00
_tab_drag_reinsert ( term , mid ) ;
2020-02-07 11:09:27 -08:00
}
2020-03-25 14:13:43 -07:00
else if ( _tab_drag - > split_direction ! = SPLIT_DIRECTION_NONE )
2020-02-07 11:09:27 -08:00
{
/* Move to different set of Tabs */
2020-03-25 14:13:43 -07:00
_tab_reorg ( term , term_at_coords , mx ) ;
2020-02-07 11:09:27 -08:00
}
end :
2020-02-17 14:17:06 -08:00
_tab_drag_free ( ) ;
2020-02-07 11:09:27 -08:00
}
static void
2020-02-09 04:09:05 -08:00
_term_on_drag_stop ( void * data ,
2020-02-07 11:09:27 -08:00
Evas_Object * o EINA_UNUSED ,
const char * emission EINA_UNUSED ,
const char * source EINA_UNUSED )
{
Term * term = data ;
2020-02-09 04:09:05 -08:00
Term_Container * tc ;
2020-02-07 11:09:27 -08:00
2020-02-29 07:18:07 -08:00
if ( _tab_drag & & _tab_drag - > icon )
2020-02-07 11:09:27 -08:00
{
2020-02-29 07:18:07 -08:00
_tab_drag_stop ( ) ;
2020-01-19 07:51:17 -08:00
return ;
}
2020-02-17 14:17:06 -08:00
_tab_drag_free ( ) ;
2020-02-07 11:09:27 -08:00
2020-02-09 04:09:05 -08:00
tc = term - > container ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
if ( tc - > parent - > type = = TERM_CONTAINER_TYPE_TABS )
{
Term_Container * tc_parent = tc - > parent ;
Tabs * tabs = ( Tabs * ) tc_parent ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabl " ,
tabs - > v1_orig , 0.0 ) ;
edje_object_part_drag_value_set ( term - > bg_edj , " terminology.tabr " ,
tabs - > v2_orig , 0.0 ) ;
}
2020-03-29 04:33:44 -07:00
_focus_validator ( ) ;
2020-02-07 11:09:27 -08:00
}
static void
_tabs_drag_mouse_move (
2020-02-17 14:17:06 -08:00
void * data EINA_UNUSED ,
2020-02-07 11:09:27 -08:00
Evas_Object * obj EINA_UNUSED ,
const char * emission EINA_UNUSED ,
const char * source EINA_UNUSED )
{
2020-02-25 14:43:16 -08:00
Evas_Coord x , y , w , h , off_x , off_y , mx , my ;
Win * wn ;
Term_Container * tc_wn ;
Term * term_at_coords ;
2020-02-29 07:18:07 -08:00
Split_Direction split_direction = SPLIT_DIRECTION_NONE ;
2020-02-07 11:09:27 -08:00
2020-02-17 14:17:06 -08:00
if ( ! _tab_drag | | ! _tab_drag - > icon )
2020-02-07 11:09:27 -08:00
return ;
2020-02-25 14:43:16 -08:00
wn = _tab_drag - > term - > wn ;
tc_wn = ( Term_Container * ) wn ;
2020-02-17 14:17:06 -08:00
evas_object_geometry_get ( _tab_drag - > icon , NULL , NULL , & w , & h ) ;
2020-02-25 14:43:16 -08:00
evas_pointer_canvas_xy_get ( _tab_drag - > e , & mx , & my ) ;
x = ( mx - ( w / 2 ) ) ;
y = ( my - ( h / 2 ) ) ;
2020-02-17 14:17:06 -08:00
evas_object_move ( _tab_drag - > icon , x , y ) ;
2020-02-25 14:43:16 -08:00
term_at_coords = tc_wn - > find_term_at_coords ( tc_wn , mx , my ) ;
if ( ! term_at_coords )
return ;
evas_object_geometry_get ( term_at_coords - > bg_edj , & off_x , & off_y , NULL , NULL ) ;
2020-03-25 14:13:43 -07:00
edje_object_part_geometry_get ( term_at_coords - > bg_edj , " terminology.tabregion " ,
& x , & y , & w , & h ) ;
if ( ELM_RECTS_INTERSECT ( x + off_x , y + off_y , w , h , mx , my , 1 , 1 ) )
{
split_direction = SPLIT_DIRECTION_TABS ;
goto found ;
}
2020-02-25 14:43:16 -08:00
edje_object_part_geometry_get ( term_at_coords - > bg_edj , " drag_left_outline " ,
& x , & y , & w , & h ) ;
if ( ELM_RECTS_INTERSECT ( x + off_x , y + off_y , w , h , mx , my , 1 , 1 ) )
{
2020-02-29 07:18:07 -08:00
split_direction = SPLIT_DIRECTION_LEFT ;
2020-02-25 14:43:16 -08:00
goto found ;
}
2020-03-25 14:13:43 -07:00
2020-02-25 14:43:16 -08:00
edje_object_part_geometry_get ( term_at_coords - > bg_edj , " drag_right_outline " ,
& x , & y , & w , & h ) ;
if ( ELM_RECTS_INTERSECT ( x + off_x , y + off_y , w , h , mx , my , 1 , 1 ) )
{
2020-02-29 07:18:07 -08:00
split_direction = SPLIT_DIRECTION_RIGHT ;
2020-02-25 14:43:16 -08:00
goto found ;
}
2020-03-25 14:13:43 -07:00
2020-02-25 14:43:16 -08:00
edje_object_part_geometry_get ( term_at_coords - > bg_edj , " drag_top_outline " ,
& x , & y , & w , & h ) ;
if ( ELM_RECTS_INTERSECT ( x + off_x , y + off_y , w , h , mx , my , 1 , 1 ) )
{
2020-02-29 07:18:07 -08:00
split_direction = SPLIT_DIRECTION_TOP ;
2020-02-25 14:43:16 -08:00
goto found ;
}
2020-03-25 14:13:43 -07:00
2020-02-25 14:43:16 -08:00
edje_object_part_geometry_get ( term_at_coords - > bg_edj , " drag_bottom_outline " ,
& x , & y , & w , & h ) ;
if ( ELM_RECTS_INTERSECT ( x + off_x , y + off_y , w , h , mx , my , 1 , 1 ) )
{
2020-02-29 07:18:07 -08:00
split_direction = SPLIT_DIRECTION_BOTTOM ;
2020-02-25 14:43:16 -08:00
goto found ;
}
2020-03-25 14:13:43 -07:00
found :
2020-02-25 14:43:16 -08:00
if ( ( _tab_drag - > term_over ! = NULL ) & &
( ( _tab_drag - > term_over ! = term_at_coords ) | |
2020-02-29 07:18:07 -08:00
( _tab_drag - > split_direction ! = split_direction ) ) )
2020-02-25 14:43:16 -08:00
{
_tab_drag_disable_anim_over ( ) ;
}
2020-02-29 07:18:07 -08:00
if ( ( split_direction ! = SPLIT_DIRECTION_NONE ) & &
2020-02-25 14:43:16 -08:00
( ( _tab_drag - > term_over ! = term_at_coords ) | |
2020-02-29 07:18:07 -08:00
( _tab_drag - > split_direction ! = split_direction ) ) )
2020-02-25 14:43:16 -08:00
{
2020-02-29 07:18:07 -08:00
switch ( split_direction )
2020-02-25 14:43:16 -08:00
{
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_LEFT :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( term_at_coords - > bg ,
" drag_left,on " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_RIGHT :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( term_at_coords - > bg ,
" drag_right,on " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_TOP :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( term_at_coords - > bg ,
" drag_top,on " , " terminology " ) ;
break ;
2020-02-29 07:18:07 -08:00
case SPLIT_DIRECTION_BOTTOM :
2020-02-25 14:43:16 -08:00
elm_layout_signal_emit ( term_at_coords - > bg ,
" drag_bottom,on " , " terminology " ) ;
break ;
2020-03-25 14:13:43 -07:00
case SPLIT_DIRECTION_TABS :
elm_layout_signal_emit ( term_at_coords - > bg ,
" drag_over_tabs,on " , " terminology " ) ;
2020-02-25 14:43:16 -08:00
default :
break ;
}
}
_tab_drag - > term_over = term_at_coords ;
2020-02-29 07:18:07 -08:00
_tab_drag - > split_direction = split_direction ;
2020-01-19 07:51:17 -08:00
}
2020-02-07 11:09:27 -08:00
static Eina_Bool
2020-02-17 14:17:06 -08:00
_tab_drag_start ( void * data EINA_UNUSED )
2020-02-07 11:09:27 -08:00
{
/* Start icons animation before actually drag-starts */
2020-04-15 13:52:31 -07:00
Evas_Coord mx , my , w , h , ch_w , ch_h , core_w , core_h ;
2020-02-17 14:17:06 -08:00
Term * term = _tab_drag - > term ;
2020-02-07 11:09:27 -08:00
Evas_Object * o = elm_layout_add ( term - > bg ) ;
2020-03-22 02:53:30 -07:00
Evas_Object * img ;
2020-03-07 05:58:12 -08:00
Term_Container * tc = term - > container ;
2020-03-22 02:53:30 -07:00
float ratio ;
2020-02-07 11:09:27 -08:00
2020-02-25 11:54:24 -08:00
if ( ! term - > container )
{
_tab_drag_free ( ) ;
return ECORE_CALLBACK_CANCEL ;
}
2020-03-22 02:53:30 -07:00
for_each_term_do ( _tab_drag - > term - > wn , & _term_hdrag_off , NULL ) ;
_tab_drag - > icon = o ;
theme_apply_elm ( o , term - > config , " terminology/tab_drag_thumb " ) ;
2020-02-07 11:09:27 -08:00
elm_layout_text_set ( o , " terminology.title " ,
term - > container - > title ) ;
2020-03-22 02:53:30 -07:00
elm_layout_content_unset ( term - > bg , " terminology.content " ) ;
term - > unswallowed = EINA_TRUE ;
img = evas_object_image_filled_add ( evas_object_evas_get ( term - > core ) ) ;
evas_object_lower ( term - > core ) ;
evas_object_move ( term - > core , - 9999 , - 9999 ) ;
evas_object_show ( term - > core ) ;
evas_object_clip_unset ( term - > core ) ;
evas_object_image_source_set ( img , term - > core ) ;
evas_object_geometry_get ( term - > core , NULL , NULL , & core_w , & core_h ) ;
evas_object_resize ( img , core_w , core_h ) ;
_tab_drag - > img = img ;
elm_layout_content_set ( o , " terminology.content " , img ) ;
evas_object_size_hint_min_get ( term - > core , & ch_w , & ch_h ) ;
2020-02-07 11:09:27 -08:00
evas_object_size_hint_align_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
2020-03-22 02:53:30 -07:00
w = ch_w * 10 ;
h = ch_h * 5 ;
ratio = ( float ) core_w / ( float ) core_h ;
if ( h * ratio > w )
h = w / ratio ;
else
w = h * ratio ;
2020-02-07 11:09:27 -08:00
evas_object_resize ( o , w , h ) ;
2020-04-15 13:52:31 -07:00
evas_pointer_canvas_xy_get ( _tab_drag - > e , & mx , & my ) ;
evas_object_move ( _tab_drag - > icon , mx - w / 2 , my - h / 2 ) ;
2020-03-14 15:32:02 -07:00
evas_object_raise ( o ) ;
2020-03-22 13:55:27 -07:00
elm_object_cursor_set ( term - > bg , " hand2 " ) ;
2020-04-16 08:44:58 -07:00
term - > has_bg_cursor = EINA_TRUE ;
2020-02-07 11:09:27 -08:00
evas_object_show ( o ) ;
2020-03-07 05:58:12 -08:00
_tab_drag_save_state ( tc ) ;
2020-04-16 08:16:18 -07:00
DBG ( " detaching %p from %p " , tc , tc - > parent ) ;
2020-03-07 05:58:12 -08:00
tc - > parent - > detach ( tc - > parent , tc ) ;
2020-03-14 15:32:02 -07:00
assert ( term - > tab_item = = NULL ) ;
2020-04-15 13:52:31 -07:00
_focus_validator ( ) ;
2020-04-16 08:16:18 -07:00
assert ( ! tc - > is_focused ) ;
2020-03-07 05:58:12 -08:00
2020-02-17 14:17:06 -08:00
_tab_drag - > timer = NULL ;
2020-02-07 11:09:27 -08:00
return ECORE_CALLBACK_CANCEL ;
}
static void
_tabs_mouse_down (
void * data ,
Evas_Object * obj EINA_UNUSED ,
const char * emission EINA_UNUSED ,
const char * source EINA_UNUSED )
{
/* Launch a timer to start drag animation */
Term * term = data ;
Evas_Coord mx = 0 , my = 0 ;
2020-02-25 11:54:24 -08:00
assert ( term - > container ! = NULL ) ;
assert ( _tab_drag = = NULL ) ;
_tab_drag = calloc ( 1 , sizeof ( * _tab_drag ) ) ;
2020-02-17 14:17:06 -08:00
if ( ! _tab_drag )
2020-02-15 14:09:32 -08:00
return ;
2020-02-17 14:17:06 -08:00
_tab_drag - > e = evas_object_evas_get ( term - > bg ) ;
evas_pointer_canvas_xy_get ( _tab_drag - > e , & mx , & my ) ;
2020-02-07 11:09:27 -08:00
term_ref ( term ) ;
2020-02-17 14:17:06 -08:00
_tab_drag - > mdx = mx ;
_tab_drag - > mdy = my ;
_tab_drag - > term = term ;
_tab_drag - > timer = ecore_timer_add ( DRAG_TIMEOUT ,
2020-02-25 11:54:24 -08:00
_tab_drag_start , NULL ) ;
2020-02-07 11:09:27 -08:00
}
2015-09-14 14:01:32 -07:00
Eina_Bool
term_tab_go ( Term * term , int tnum )
2015-03-22 10:17:16 -07:00
{
Term_Container * tc = term - > container ,
* child = tc ;
while ( tc )
{
Tabs * tabs ;
Tab_Item * tab_item ;
if ( tc - > type ! = TERM_CONTAINER_TYPE_TABS )
{
child = tc ;
tc = tc - > parent ;
continue ;
}
tabs = ( Tabs * ) tc ;
tab_item = eina_list_nth ( tabs - > tabs , tnum ) ;
if ( ! tab_item )
{
child = tc ;
tc = tc - > parent ;
continue ;
}
2015-09-14 14:01:32 -07:00
if ( tab_item ! = tabs - > current )
tab_item - > tc - > focus ( tab_item - > tc , child ) ;
return EINA_TRUE ;
2015-03-22 10:17:16 -07:00
}
2015-09-14 14:01:32 -07:00
return EINA_FALSE ;
2015-03-22 10:17:16 -07:00
}
static void
_tabs_selector_cb_selected ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
2015-03-22 10:17:16 -07:00
void * info ) ;
static void
_tabs_selector_cb_exit ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _info EINA_UNUSED ) ;
2015-03-22 10:17:16 -07:00
2015-04-30 12:06:06 -07:00
static void
_tabs_selector_cb_ending ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _info EINA_UNUSED ) ;
2015-04-30 12:06:06 -07:00
2015-03-22 10:17:16 -07:00
static void
_tabs_restore ( Tabs * tabs )
2014-12-02 15:42:27 -08:00
{
Eina_List * l ;
2015-03-22 10:17:16 -07:00
Tab_Item * tab_item ;
Term_Container * tc = ( Term_Container * ) tabs ;
2014-12-02 15:42:27 -08:00
Term * term ;
2015-03-22 10:17:16 -07:00
Solo * solo ;
2018-08-09 23:03:52 -07:00
Win * wn = tc - > wn ;
2019-07-07 07:26:32 -07:00
Evas_Object * selector = tabs - > selector ;
Evas_Object * selector_bg = tabs - > selector_bg ;
2015-03-22 10:17:16 -07:00
if ( ! tabs - > selector )
return ;
2018-08-09 23:03:52 -07:00
EINA_LIST_FOREACH ( wn - > terms , l , term )
2015-03-22 10:17:16 -07:00
{
if ( term - > unswallowed )
{
evas_object_image_source_visible_set ( term - > sel , EINA_TRUE ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.content " , term - > core ) ;
2015-03-22 10:17:16 -07:00
term - > unswallowed = EINA_FALSE ;
2019-12-26 04:17:52 -08:00
evas_object_show ( term - > core ) ;
2015-03-22 10:17:16 -07:00
}
}
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
tab_item - > selector_entry = NULL ;
2018-03-13 10:15:57 -07:00
if ( tab_item - > tc - > is_focused )
tab_item - > tc - > unfocus ( tab_item - > tc , tc ) ;
2015-03-22 10:17:16 -07:00
}
2019-07-07 07:26:32 -07:00
evas_object_smart_callback_del_full ( selector , " selected " ,
2015-03-22 10:17:16 -07:00
_tabs_selector_cb_selected , tabs ) ;
2019-07-07 07:26:32 -07:00
evas_object_smart_callback_del_full ( selector , " exit " ,
2015-03-22 10:17:16 -07:00
_tabs_selector_cb_exit , tabs ) ;
2019-07-07 07:26:32 -07:00
evas_object_smart_callback_del_full ( selector , " ending " ,
2015-04-30 12:06:06 -07:00
_tabs_selector_cb_ending , tabs ) ;
2019-07-07 07:26:32 -07:00
2015-03-22 10:17:16 -07:00
tabs - > selector = NULL ;
tabs - > selector_bg = NULL ;
/* XXX: reswallow in parent */
tc - > parent - > swallow ( tc - > parent , tc , tc ) ;
solo = ( Solo * ) tabs - > current - > tc ;
term = solo - > term ;
_tabbar_clear ( term ) ;
2020-01-19 07:51:17 -08:00
/* Restore -> recreate the whole tabbar */
_tabs_recreate ( tabs ) ;
2018-03-13 10:15:57 -07:00
tabs - > current - > tc - > unfocus ( tabs - > current - > tc , tabs - > current - > tc ) ;
2015-03-22 10:17:16 -07:00
tabs - > current - > tc - > focus ( tabs - > current - > tc , tabs - > current - > tc ) ;
2019-07-07 07:26:32 -07:00
elm_object_focus_set ( selector , EINA_FALSE ) ;
evas_object_del ( selector ) ;
evas_object_del ( selector_bg ) ;
2015-03-22 10:17:16 -07:00
}
2015-04-30 12:06:06 -07:00
static void
_tabs_selector_cb_ending ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _info EINA_UNUSED )
2015-04-30 12:06:06 -07:00
{
Tabs * tabs = data ;
2018-03-13 10:15:57 -07:00
2015-04-30 12:06:06 -07:00
edje_object_signal_emit ( tabs - > selector_bg , " end " , " terminology " ) ;
}
2015-03-22 10:17:16 -07:00
static void
_tabs_selector_cb_selected ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
2015-03-22 10:17:16 -07:00
void * info )
{
Tabs * tabs = data ;
Eina_List * l ;
Tab_Item * tab_item ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
if ( tab_item - > tc - > selector_img = = info )
{
tabs - > current = tab_item ;
_tabs_restore ( tabs ) ;
return ;
}
}
ERR ( " Can't find selected tab item " ) ;
}
static void
_tabs_selector_cb_exit ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _info EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
Tabs * tabs = data ;
_tabs_restore ( tabs ) ;
}
static void
2015-04-30 12:06:06 -07:00
_cb_tab_selector_show ( Tabs * tabs , Tab_Item * to_item )
2015-03-22 10:17:16 -07:00
{
Term_Container * tc = ( Term_Container * ) tabs ;
Eina_List * l ;
int count ;
double z ;
Win * wn = tc - > wn ;
Tab_Item * tab_item ;
Evas_Object * o ;
Evas_Coord x , y , w , h ;
2020-04-06 12:58:21 -07:00
Edje_Message_Int msg ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
if ( tabs - > selector_bg )
return ;
o = tc - > get_evas_object ( tc ) ;
evas_object_geometry_get ( o , & x , & y , & w , & h ) ;
tabs - > selector_bg = edje_object_add ( evas_object_evas_get ( tc - > wn - > win ) ) ;
theme_apply ( tabs - > selector_bg , wn - > config , " terminology/sel/base " ) ;
evas_object_geometry_set ( tabs - > selector_bg , x , y , w , h ) ;
evas_object_hide ( o ) ;
2020-04-06 13:59:26 -07:00
if ( wn - > config - > translucent )
2020-04-06 12:58:21 -07:00
msg . val = wn - > config - > opacity ;
else
msg . val = 100 ;
edje_object_message_send ( tabs - > selector_bg , EDJE_MESSAGE_INT , 1 , & msg ) ;
2017-11-11 14:16:15 -08:00
background_set_shine ( wn - > config , tabs - > selector_bg ) ;
2015-03-22 10:17:16 -07:00
edje_object_signal_emit ( tabs - > selector_bg , " begin " , " terminology " ) ;
tabs - > selector = sel_add ( wn - > win ) ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Evas_Object * img ;
Eina_Bool is_selected , missed_bell ;
Solo * solo ;
Term * term ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
_tabbar_clear ( term ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_unset ( term - > bg , " terminology.content " ) ;
2015-03-22 10:17:16 -07:00
term - > unswallowed = EINA_TRUE ;
img = evas_object_image_filled_add ( evas_object_evas_get ( wn - > win ) ) ;
2019-12-26 04:17:52 -08:00
o = term - > core ;
2015-03-22 10:17:16 -07:00
evas_object_lower ( o ) ;
evas_object_move ( o , - 9999 , - 9999 ) ;
evas_object_show ( o ) ;
evas_object_clip_unset ( o ) ;
evas_object_image_source_set ( img , o ) ;
evas_object_geometry_get ( o , NULL , NULL , & w , & h ) ;
evas_object_resize ( img , w , h ) ;
evas_object_data_set ( img , " tc " , tab_item - > tc ) ;
tab_item - > tc - > selector_img = img ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
is_selected = ( tab_item = = tabs - > current ) ;
missed_bell = term - > missed_bell ;
2015-08-29 06:23:50 -07:00
tab_item - > selector_entry = NULL ;
2015-03-22 10:17:16 -07:00
tab_item - > selector_entry = sel_entry_add ( tabs - > selector , img ,
is_selected ,
missed_bell , wn - > config ) ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
edje_object_part_swallow ( tabs - > selector_bg , " terminology.content " ,
tabs - > selector ) ;
evas_object_show ( tabs - > selector ) ;
/* XXX: refresh */
tc - > parent - > swallow ( tc - > parent , tc , tc ) ;
2015-04-30 12:06:06 -07:00
evas_object_show ( tabs - > selector_bg ) ;
2015-03-22 10:17:16 -07:00
evas_object_smart_callback_add ( tabs - > selector , " selected " ,
_tabs_selector_cb_selected , tabs ) ;
evas_object_smart_callback_add ( tabs - > selector , " exit " ,
_tabs_selector_cb_exit , tabs ) ;
2015-04-30 12:06:06 -07:00
evas_object_smart_callback_add ( tabs - > selector , " ending " ,
_tabs_selector_cb_ending , tabs ) ;
2015-03-22 10:17:16 -07:00
z = 1.0 ;
sel_go ( tabs - > selector ) ;
count = eina_list_count ( tabs - > tabs ) ;
if ( count > = 1 )
z = 1.0 / ( sqrt ( count ) * 0.8 ) ;
if ( z > 1.0 ) z = 1.0 ;
sel_orig_zoom_set ( tabs - > selector , z ) ;
sel_zoom ( tabs - > selector , z ) ;
2015-04-30 12:06:06 -07:00
if ( to_item )
{
sel_entry_selected_set ( tabs - > selector , to_item - > tc - > selector_img ,
EINA_TRUE ) ;
sel_exit ( tabs - > selector ) ;
}
2015-03-22 10:17:16 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_select ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2015-03-22 10:17:16 -07:00
{
Term * term = data ;
Term_Container * tc = term - > container ;
while ( tc )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
if ( tc - > type ! = TERM_CONTAINER_TYPE_TABS )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
tc = tc - > parent ;
continue ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
tabs = ( Tabs * ) tc ;
if ( eina_list_count ( tabs - > tabs ) < 2 )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
tc = tc - > parent ;
continue ;
}
2014-12-09 05:32:47 -08:00
2015-04-30 12:06:06 -07:00
_cb_tab_selector_show ( tabs , NULL ) ;
2015-03-22 10:17:16 -07:00
return ;
}
}
static Evas_Object *
2017-07-06 11:55:02 -07:00
_tabs_get_evas_object ( const Term_Container * container )
2015-03-22 10:17:16 -07:00
{
Tabs * tabs ;
Term_Container * tc ;
assert ( container - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) container ;
if ( tabs - > selector_bg )
return tabs - > selector_bg ;
assert ( tabs - > current ! = NULL ) ;
tc = tabs - > current - > tc ;
return tc - > get_evas_object ( tc ) ;
}
static Term *
2017-07-06 11:55:02 -07:00
_tabs_focused_term_get ( const Term_Container * tc )
2015-03-22 10:17:16 -07:00
{
Tabs * tabs ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
return tc - > is_focused ?
tabs - > current - > tc - > focused_term_get ( tabs - > current - > tc )
: NULL ;
}
static Term *
2017-07-06 11:55:02 -07:00
_tabs_find_term_at_coords ( const Term_Container * container ,
2015-03-22 10:17:16 -07:00
Evas_Coord mx ,
Evas_Coord my )
{
Tabs * tabs ;
Term_Container * tc ;
assert ( container - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) container ;
tc = tabs - > current - > tc ;
return tc - > find_term_at_coords ( tc , mx , my ) ;
}
static void
_tabs_size_eval ( Term_Container * container , Sizeinfo * info )
{
Tabs * tabs ;
Term_Container * tc ;
2017-07-23 08:33:24 -07:00
Config * config ;
2015-03-22 10:17:16 -07:00
assert ( container - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) container ;
tc = tabs - > current - > tc ;
2017-07-23 08:33:24 -07:00
config = tc - > wn - > config ;
2015-03-22 10:17:16 -07:00
tc - > size_eval ( tc , info ) ;
2017-07-23 08:33:24 -07:00
/* Current sizing code does not take the tab area correctly into account */
2019-09-29 14:03:12 -07:00
if ( config - > show_tabs )
2017-07-23 08:33:24 -07:00
{
info - > step_x = 1 ;
info - > step_y = 1 ;
}
2015-03-22 10:17:16 -07:00
}
static Eina_List *
2020-03-14 10:43:16 -07:00
_tab_item_find ( const Tabs * tabs , const Term_Container * child ,
int * pos )
2015-03-22 10:17:16 -07:00
{
Eina_List * l ;
Tab_Item * tab_item ;
2020-03-14 10:43:16 -07:00
int i = 0 ;
2015-03-22 10:17:16 -07:00
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
if ( tab_item - > tc = = child )
2020-03-14 10:43:16 -07:00
{
if ( pos )
* pos = i ;
return l ;
}
i + + ;
2015-03-22 10:17:16 -07:00
}
return NULL ;
}
static void
_tabs_close ( Term_Container * tc , Term_Container * child )
{
int count ;
Tabs * tabs ;
Eina_List * l ;
Tab_Item * item , * next_item ;
Eina_List * next ;
Term_Container * next_child , * tc_parent ;
Term * term ;
Solo * solo ;
2020-03-14 10:43:16 -07:00
int pos = 0 ;
2015-03-22 10:17:16 -07:00
2020-03-14 08:09:02 -07:00
/* TODO: figure out whether to move position if tab_drag */
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
tc_parent = tc - > parent ;
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , child , & pos ) ;
2015-03-22 10:17:16 -07:00
item = l - > data ;
next = eina_list_next ( l ) ;
if ( ! next )
next = tabs - > tabs ;
2020-01-19 07:51:17 -08:00
tabs - > tabs = eina_list_remove_list ( tabs - > tabs , l ) ;
2015-03-22 10:17:16 -07:00
next_item = next - > data ;
next_child = next_item - > tc ;
2016-07-31 06:21:42 -07:00
assert ( next_child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2015-03-22 10:17:16 -07:00
assert ( child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) child ;
term = solo - > term ;
2016-01-31 06:24:15 -08:00
child - > unfocus ( child , tc ) ;
2015-03-22 10:17:16 -07:00
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " tabcount,off " , " terminology " ) ;
2020-01-19 07:51:17 -08:00
elm_layout_signal_emit ( term - > bg , " tab_btn,off " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
count = eina_list_count ( tabs - > tabs ) ;
if ( count = = 1 )
{
2016-07-31 06:21:42 -07:00
Term * next_term ;
Solo * next_solo ;
2019-09-26 13:49:11 -07:00
Config * config ;
2016-07-31 06:21:42 -07:00
2015-03-22 10:17:16 -07:00
assert ( next_child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2016-07-31 06:21:42 -07:00
next_solo = ( Solo * ) next_child ;
next_term = next_solo - > term ;
2020-03-16 15:50:04 -07:00
assert ( next_term ! = term ) ;
assert ( tc ! = next_child ) ;
2019-09-26 13:49:11 -07:00
config = next_term - > config ;
2016-07-31 06:21:42 -07:00
2020-02-15 07:47:47 -08:00
_tabbar_clear ( term ) ;
2020-01-19 07:51:17 -08:00
evas_object_del ( next_term - > tab_spacer ) ;
next_term - > tab_spacer = NULL ;
if ( next_term - > tab_inactive )
2020-03-14 15:32:02 -07:00
{
evas_object_hide ( next_term - > tab_inactive ) ;
edje_object_signal_callback_del ( next_term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
}
2020-01-19 07:51:17 -08:00
elm_layout_signal_emit ( next_term - > bg , " tabcount,off " , " terminology " ) ;
elm_layout_signal_emit ( next_term - > bg , " tab_btn,off " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
if ( tabs - > selector )
_tabs_restore ( tabs ) ;
2020-01-19 07:51:17 -08:00
if ( config - > show_tabs )
2020-03-16 15:50:04 -07:00
_solo_tab_show ( next_child ) ;
2020-01-19 07:51:17 -08:00
2015-03-22 10:17:16 -07:00
eina_stringshare_del ( tc - > title ) ;
2016-07-31 06:21:42 -07:00
2015-03-22 10:17:16 -07:00
tc_parent - > swallow ( tc_parent , tc , next_child ) ;
if ( tc - > is_focused )
2016-01-31 06:24:15 -08:00
next_child - > focus ( next_child , tc ) ;
2015-03-22 10:17:16 -07:00
2020-03-14 10:43:16 -07:00
if ( ( _tab_drag ) & & ( _tab_drag - > parent_type = = TERM_CONTAINER_TYPE_TABS )
& & ( _tab_drag - > tabs_child = = tc ) )
{
_tab_drag - > tabs_child = next_child ;
2020-03-16 15:50:04 -07:00
_solo_tab_show ( next_child ) ;
2020-03-14 10:43:16 -07:00
}
2020-01-19 07:51:17 -08:00
_tab_item_free ( item ) ;
_tab_item_free ( next_item ) ;
2020-03-14 15:32:02 -07:00
EINA_LIST_FREE ( tabs - > tabs , item ) { }
2015-03-22 10:17:16 -07:00
free ( tc ) ;
2020-03-14 10:43:16 -07:00
2020-01-19 07:51:17 -08:00
return ;
2015-03-22 10:17:16 -07:00
}
2020-03-14 10:43:16 -07:00
if ( ( _tab_drag ) & & ( _tab_drag - > parent_type = = TERM_CONTAINER_TYPE_TABS )
& & ( _tab_drag - > tabs_child = = tc ) )
{
if ( pos < _tab_drag - > previous_position )
_tab_drag - > previous_position - - ;
}
2020-01-19 07:51:17 -08:00
if ( item - > tc - > selector_img )
{
Evas_Object * o ;
o = item - > tc - > selector_img ;
item - > tc - > selector_img = NULL ;
evas_object_del ( o ) ;
}
2015-03-22 10:17:16 -07:00
2020-01-19 07:51:17 -08:00
count - - ;
if ( item = = tabs - > current )
{
tc - > swallow ( tc , child , next_child ) ;
if ( tc - > is_focused )
next_child - > focus ( next_child , tc ) ;
_tab_item_free ( item ) ;
2020-03-14 15:32:02 -07:00
assert ( tabs - > current ! = item ) ;
2020-01-19 07:51:17 -08:00
return ;
}
_tab_item_free ( item ) ;
_tabs_recompute_drag ( tabs ) ;
2015-03-22 10:17:16 -07:00
}
static void
_tabs_update ( Term_Container * tc )
{
Tabs * tabs ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2020-01-19 07:51:17 -08:00
/* Update -> recreate the whole tabbar */
_tabs_recreate ( tabs ) ;
2015-03-22 10:17:16 -07:00
}
static Term *
2017-07-06 11:55:02 -07:00
_tabs_term_next ( const Term_Container * tc , const Term_Container * child )
2015-03-22 10:17:16 -07:00
{
Tabs * tabs ;
Tab_Item * tab_item ;
Eina_List * l ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , child , NULL ) ;
2015-03-22 10:17:16 -07:00
l = eina_list_next ( l ) ;
if ( l )
{
tab_item = l - > data ;
tc = tab_item - > tc ;
return tc - > term_first ( tc ) ;
}
else
{
return tc - > parent - > term_next ( tc - > parent , tc ) ;
2014-12-02 15:42:27 -08:00
}
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_tabs_term_prev ( const Term_Container * tc , const Term_Container * child )
2014-12-02 15:42:53 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
2014-12-02 15:42:53 -08:00
Eina_List * l ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , child , NULL ) ;
2015-03-22 10:17:16 -07:00
l = eina_list_prev ( l ) ;
if ( l )
{
tab_item = l - > data ;
tc = tab_item - > tc ;
return tc - > term_last ( tc ) ;
}
else
2014-12-02 15:42:53 -08:00
{
2015-03-22 10:17:16 -07:00
return tc - > parent - > term_prev ( tc - > parent , tc ) ;
2014-12-02 15:42:53 -08:00
}
}
2017-07-10 15:01:29 -07:00
static Term *
_tabs_term_up ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_up ( tc - > parent , tc ) ;
}
static Term *
_tabs_term_down ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_down ( tc - > parent , tc ) ;
}
static Term *
_tabs_term_left ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_left ( tc - > parent , tc ) ;
}
static Term *
_tabs_term_right ( const Term_Container * tc ,
const Term_Container * _child EINA_UNUSED )
{
return tc - > parent - > term_right ( tc - > parent , tc ) ;
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_tabs_term_first ( const Term_Container * tc )
2014-12-02 15:42:53 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
tab_item = tabs - > tabs - > data ;
tc = tab_item - > tc ;
return tc - > term_first ( tc ) ;
2014-12-02 15:42:53 -08:00
}
2015-03-22 10:17:16 -07:00
static Term *
2017-07-06 11:55:02 -07:00
_tabs_term_last ( const Term_Container * tc )
2014-12-02 15:42:53 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
Eina_List * l ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
l = eina_list_last ( tabs - > tabs ) ;
tab_item = l - > data ;
tc = tab_item - > tc ;
return tc - > term_last ( tc ) ;
2014-12-02 15:42:53 -08:00
}
2020-01-28 15:06:12 -08:00
static void
_tabcount_refresh ( Tabs * tabs )
{
Eina_List * l ;
Tab_Item * tab_item ;
Term * main_term = _tab_item_to_term ( tabs - > current ) ;
Evas * canvas = evas_object_evas_get ( main_term - > bg ) ;
char buf [ 32 ] , bufmissed [ 32 ] ;
int n = eina_list_count ( tabs - > tabs ) ;
Evas_Coord w = 0 , h = 0 ;
2020-01-28 15:09:24 -08:00
unsigned int missed = 0 ;
2020-01-28 15:06:12 -08:00
int i ;
if ( n < = 0 )
{
ERR ( " no tab " ) ;
return ;
}
buf [ 0 ] = ' \0 ' ;
i = 0 ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
Solo * solo ;
Term * term ;
i + + ;
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
if ( term - > tab_inactive )
2020-03-14 15:32:02 -07:00
{
evas_object_hide ( term - > tab_inactive ) ;
edje_object_signal_callback_del ( term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
}
2020-01-28 15:06:12 -08:00
if ( tabs - > current = = tab_item )
{
snprintf ( buf , sizeof ( buf ) , " %i/%i " , i , n ) ;
}
2020-01-28 15:09:24 -08:00
else if ( term - > missed_bell )
missed + + ;
2020-01-28 15:06:12 -08:00
}
if ( missed > 0 )
snprintf ( bufmissed , sizeof ( bufmissed ) , " %i " , missed ) ;
else
bufmissed [ 0 ] = ' \0 ' ;
if ( ! main_term - > tab_spacer )
{
main_term - > tab_spacer = evas_object_rectangle_add ( canvas ) ;
evas_object_color_set ( main_term - > tab_spacer , 0 , 0 , 0 , 0 ) ;
}
elm_coords_finger_size_adjust ( 1 , & w , 1 , & h ) ;
evas_object_size_hint_min_set ( main_term - > tab_spacer , w , h ) ;
elm_layout_content_set ( main_term - > bg , " terminology.tabcount.control " ,
main_term - > tab_spacer ) ;
elm_layout_text_set ( main_term - > bg , " terminology.tabcount.label " , buf ) ;
elm_layout_text_set ( main_term - > bg , " terminology.tabmissed.label " , bufmissed ) ;
elm_layout_signal_emit ( main_term - > bg , " tabcount,on " , " terminology " ) ;
_tabbar_clear ( main_term ) ;
if ( missed > 0 )
elm_layout_signal_emit ( main_term - > bg , " tabmissed,on " , " terminology " ) ;
else
elm_layout_signal_emit ( main_term - > bg , " tabmissed,off " , " terminology " ) ;
}
2014-12-02 15:42:27 -08:00
static void
2015-03-22 10:17:16 -07:00
_tabs_swallow ( Term_Container * tc , Term_Container * orig ,
Term_Container * new_child )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
Eina_List * l ;
2014-12-02 15:42:27 -08:00
Evas_Object * o ;
2015-03-22 10:17:16 -07:00
Evas_Coord x , y , w , h ;
2020-01-19 07:51:17 -08:00
Term * term_orig , * term_new ;
Solo * solo_orig , * solo_new ;
Term_Container * tc_parent = tc - > parent ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2014-12-02 15:42:27 -08:00
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , new_child , NULL ) ;
2015-03-22 10:17:16 -07:00
tab_item = l - > data ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
if ( tabs - > selector )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Evas_Object * img = tab_item - > tc - > selector_img ;
evas_object_image_source_set ( img ,
new_child - > get_evas_object ( new_child ) ) ;
evas_object_data_set ( img , " tc " , new_child ) ;
2015-08-29 06:23:50 -07:00
if ( tab_item - > selector_entry )
sel_entry_update ( tab_item - > selector_entry ) ;
2020-01-19 07:51:17 -08:00
return ;
2014-12-02 15:42:27 -08:00
}
2020-01-19 07:51:17 -08:00
if ( orig = = new_child )
2014-12-02 15:42:27 -08:00
{
2020-01-19 07:51:17 -08:00
assert ( tabs - > current = = tab_item ) ;
return ;
}
2015-03-22 10:17:16 -07:00
2020-01-19 07:51:17 -08:00
/* Occurs when closing current tab */
if ( tc - > is_focused )
tabs - > current - > tc - > unfocus ( tabs - > current - > tc , tc ) ;
2016-07-31 06:21:42 -07:00
2020-01-19 07:51:17 -08:00
assert ( orig - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo_orig = ( Solo * ) orig ;
term_orig = solo_orig - > term ;
assert ( new_child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo_new = ( Solo * ) new_child ;
term_new = solo_new - > term ;
2015-03-22 10:17:16 -07:00
2020-01-19 07:51:17 -08:00
tabs - > current = tab_item ;
/* Remove tab effects from the previous focused tab */
elm_layout_signal_emit ( term_orig - > bg , " tabcount,off " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
2020-01-28 15:06:12 -08:00
if ( term_new - > config - > show_tabs )
{
_tabs_get_or_create_boxes ( term_new , term_orig ) ;
assert ( term_new = = _tab_item_to_term ( tabs - > current ) ) ;
_tabbar_fill ( tabs ) ;
}
else
{
_tabcount_refresh ( tabs ) ;
}
2014-12-02 15:42:27 -08:00
2020-01-19 07:51:17 -08:00
o = orig - > get_evas_object ( orig ) ;
evas_object_geometry_get ( o , & x , & y , & w , & h ) ;
evas_object_hide ( o ) ;
o = new_child - > get_evas_object ( new_child ) ;
evas_object_geometry_set ( o , x , y , w , h ) ;
evas_object_show ( o ) ;
/* XXX: need to refresh */
tc_parent - > swallow ( tc_parent , tc , tc ) ;
2014-12-02 15:42:30 -08:00
}
2015-03-22 10:17:16 -07:00
static void
_tab_new_cb ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2014-12-02 15:42:30 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs = data ;
Term_Container * tc = ( Term_Container * ) tabs ,
2020-02-15 07:47:47 -08:00
* tc_new ;
2018-04-10 13:53:41 -07:00
Term * tm_new ;
2015-03-22 10:17:16 -07:00
Win * wn = tc - > wn ;
2015-12-26 02:59:08 -08:00
char * wdir = NULL ;
2016-01-07 13:55:42 -08:00
char buf [ PATH_MAX ] ;
2015-12-26 02:59:08 -08:00
// copy the current path to wdir if we should change the directory,
// passing wdir NULL otherwise:
if ( wn - > config - > changedir_to_current )
{
2018-04-10 13:53:41 -07:00
Term * tm ;
2020-02-15 07:47:47 -08:00
Term_Container * tc_old = tabs - > current - > tc ;
2018-04-10 13:53:41 -07:00
tm = tc_old - > term_first ( tc_old ) ;
2015-12-26 02:59:08 -08:00
if ( tm & & termio_cwd_get ( tm - > termio , buf , sizeof ( buf ) ) )
wdir = buf ;
}
2015-03-22 10:17:16 -07:00
tm_new = term_new ( wn , wn - > config ,
2015-04-30 10:11:31 -07:00
NULL , wn - > config - > login_shell , wdir ,
2017-08-28 12:36:48 -07:00
80 , 24 , EINA_FALSE , NULL ) ;
2015-03-22 10:17:16 -07:00
tc_new = _solo_new ( tm_new , wn ) ;
evas_object_data_set ( tm_new - > termio , " sizedone " , tm_new - > termio ) ;
2020-02-15 07:47:47 -08:00
_tabs_attach ( tc , tc_new ) ;
2014-12-02 15:42:30 -08:00
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_new ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
2015-03-22 10:17:16 -07:00
Term * term = data ;
Term_Container * tc = term - > container ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2014-11-08 12:43:47 -08:00
2015-03-22 10:17:16 -07:00
_solo_tabs_new ( tc ) ;
2020-03-29 04:33:44 -07:00
_focus_validator ( ) ;
2014-10-26 13:00:14 -07:00
}
2016-05-22 11:45:13 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_close ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2016-05-22 11:45:13 -07:00
{
Term * term = data ;
Term_Container * tc = term - > container ;
term_close ( tc - > wn - > win , term - > termio , EINA_FALSE ) ;
}
2014-10-26 13:00:14 -07:00
void
2019-10-26 09:13:25 -07:00
main_new ( Evas_Object * term )
2014-10-26 13:00:14 -07:00
{
2015-03-22 10:17:16 -07:00
Term * tm ;
tm = evas_object_data_get ( term , " term " ) ;
if ( ! tm ) return ;
2014-11-08 12:43:47 -08:00
2015-03-22 10:17:16 -07:00
_cb_new ( tm , term , NULL ) ;
2014-10-26 13:00:14 -07:00
}
2014-12-02 15:42:27 -08:00
static void
2015-03-22 10:17:16 -07:00
_tabs_focus ( Term_Container * tc , Term_Container * relative )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2015-07-15 14:17:24 -07:00
if ( ! tc - > parent )
return ;
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d " ,
tc , tc - > is_focused , tc - > parent = = relative ) ;
2015-03-22 10:17:16 -07:00
if ( tc - > parent = = relative )
{
if ( ! tc - > is_focused )
2015-05-06 12:30:18 -07:00
{
tc - > is_focused = EINA_TRUE ;
tabs - > current - > tc - > focus ( tabs - > current - > tc , tc ) ;
}
2015-03-22 10:17:16 -07:00
}
2014-12-02 15:42:27 -08:00
else
{
2015-03-22 10:17:16 -07:00
Eina_List * l ;
Tab_Item * tab_item ;
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , relative , NULL ) ;
2015-11-21 05:57:05 -08:00
if ( ! l )
return ;
2015-03-22 10:17:16 -07:00
tc - > is_focused = EINA_TRUE ;
tab_item = l - > data ;
if ( tab_item ! = tabs - > current )
{
2015-04-30 12:06:06 -07:00
Config * config = tc - > wn - > config ;
2015-03-22 10:17:16 -07:00
tabs - > current - > tc - > unfocus ( tabs - > current - > tc , tc ) ;
2015-04-30 12:06:06 -07:00
2019-09-29 14:03:12 -07:00
if ( config - > tab_zoom > = 0.01 & & ! config - > show_tabs )
2015-04-30 12:06:06 -07:00
{
_cb_tab_selector_show ( tabs , tab_item ) ;
return ;
}
2015-03-22 10:17:16 -07:00
tc - > swallow ( tc , tabs - > current - > tc , relative ) ;
}
tc - > parent - > focus ( tc - > parent , tc ) ;
2014-12-02 15:42:27 -08:00
}
}
2015-03-22 10:17:16 -07:00
static void
_tabs_unfocus ( Term_Container * tc , Term_Container * relative )
{
Tabs * tabs ;
2015-06-02 14:11:16 -07:00
DBG ( " tc:%p tc->is_focused:%d from_parent:%d " ,
tc , tc - > is_focused , tc - > parent = = relative ) ;
2015-03-22 10:17:16 -07:00
if ( ! tc - > is_focused )
return ;
2015-07-15 14:17:24 -07:00
if ( ! tc - > parent )
return ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
if ( tc - > parent = = relative )
2016-01-31 06:24:15 -08:00
{
tabs - > current - > tc - > unfocus ( tabs - > current - > tc , tc ) ;
tc - > is_focused = EINA_FALSE ;
}
2015-03-22 10:17:16 -07:00
else
2016-01-31 06:24:15 -08:00
{
Tab_Item * tab_item ;
Eina_List * l ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
if ( relative = = tab_item - > tc ) {
tc - > parent - > unfocus ( tc - > parent , tc ) ;
tc - > is_focused = EINA_FALSE ;
return ;
}
}
}
2015-03-22 10:17:16 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_tabs_bell ( Term_Container * tc ,
2020-01-19 07:51:17 -08:00
Term_Container * child )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
2020-01-19 07:51:17 -08:00
Term * term ;
Solo * solo ;
char bufmissed [ 32 ] ;
Eina_List * l ;
Tab_Item * tab_item ;
int missed = 0 ;
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2020-01-19 07:51:17 -08:00
assert ( child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) child ;
term = solo - > term ;
2014-12-02 15:42:27 -08:00
2020-01-19 07:51:17 -08:00
if ( tc - > is_focused & & child - > is_focused )
2015-03-22 10:17:16 -07:00
return ;
2020-01-19 07:51:17 -08:00
if ( term - > tab_inactive & & term - > missed_bell )
edje_object_signal_emit ( term - > tab_inactive , " bell " , " terminology " ) ;
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
{
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
if ( term - > missed_bell )
missed + + ;
}
tab_item = tabs - > current ;
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
if ( missed > 0 )
{
snprintf ( bufmissed , sizeof ( bufmissed ) , " %i " , missed ) ;
elm_layout_text_set ( term - > bg , " terminology.tabmissed.label " , bufmissed ) ;
elm_layout_signal_emit ( term - > bg , " tabmissed,on " , " terminology " ) ;
}
else
elm_layout_signal_emit ( term - > bg , " tabmissed,off " , " terminology " ) ;
edje_object_message_signal_process ( term - > bg_edj ) ;
2015-03-22 10:17:16 -07:00
tc - > parent - > bell ( tc - > parent , tc ) ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
static void
_tabs_set_title ( Term_Container * tc , Term_Container * child ,
const char * title )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Tabs * tabs ;
Tab_Item * tab_item ;
Eina_List * l ;
2020-01-19 07:51:17 -08:00
Solo * solo ;
Term * term ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
2020-03-14 10:43:16 -07:00
l = _tab_item_find ( tabs , child , NULL ) ;
2015-11-21 05:57:05 -08:00
if ( ! l )
return ;
2015-03-22 10:17:16 -07:00
tab_item = l - > data ;
2015-08-29 06:23:50 -07:00
if ( tabs - > selector & & tab_item - > selector_entry )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
sel_entry_title_set ( tab_item - > selector_entry , title ) ;
}
2020-01-19 07:51:17 -08:00
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
2015-03-22 10:17:16 -07:00
if ( tab_item = = tabs - > current )
{
eina_stringshare_del ( tc - > title ) ;
tc - > title = eina_stringshare_ref ( title ) ;
tc - > parent - > set_title ( tc - > parent , tc , title ) ;
2019-09-29 14:03:12 -07:00
if ( term - > config - > show_tabs )
2015-03-22 10:17:16 -07:00
{
2019-12-26 12:33:33 -08:00
elm_layout_text_set ( term - > bg , " terminology.tab.title " , title ) ;
2015-03-22 10:17:16 -07:00
}
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
else
2014-12-02 15:42:27 -08:00
{
2020-01-19 07:51:17 -08:00
if ( term - > tab_inactive )
edje_object_part_text_set ( term - > tab_inactive ,
" terminology.title " ,
title ) ;
2014-12-02 15:42:27 -08:00
}
}
2015-03-22 10:17:16 -07:00
static void
2020-01-19 07:51:17 -08:00
_tabs_recreate ( Tabs * tabs )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
Eina_List * l ;
Solo * solo ;
Term * term ;
Tab_Item * tab_item ;
Evas_Coord w = 0 , h = 0 ;
int missed = 0 ;
int n = eina_list_count ( tabs - > tabs ) ;
2014-12-02 15:42:27 -08:00
2015-04-25 05:56:53 -07:00
if ( n < = 0 )
2020-01-19 07:51:17 -08:00
{
ERR ( " no tab " ) ;
return ;
}
2015-04-25 05:56:53 -07:00
2015-03-22 10:17:16 -07:00
EINA_LIST_FOREACH ( tabs - > tabs , l , tab_item )
2014-12-02 15:42:27 -08:00
{
2015-03-22 10:17:16 -07:00
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
2020-01-19 09:02:18 -08:00
if ( term - > tab_inactive )
2020-03-14 15:32:02 -07:00
{
evas_object_hide ( term - > tab_inactive ) ;
edje_object_signal_callback_del ( term - > tab_inactive ,
" tab,activate " , " terminology " ,
_cb_tab_activate ) ;
}
2020-01-19 09:02:18 -08:00
2015-03-22 10:17:16 -07:00
if ( term - > missed_bell )
missed + + ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
tab_item = tabs - > current ;
assert ( tab_item - > tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
solo = ( Solo * ) tab_item - > tc ;
term = solo - > term ;
2014-12-02 15:42:27 -08:00
2016-01-31 06:24:15 -08:00
2015-03-22 10:17:16 -07:00
// this is all below just for tab bar at the top
2019-09-29 14:03:12 -07:00
if ( term - > config - > show_tabs )
2014-12-02 15:42:27 -08:00
{
2020-03-28 13:43:31 -07:00
_tabbar_clear ( term ) ;
2020-01-28 15:06:12 -08:00
if ( ! term - > tab_spacer )
{
term - > tab_spacer = evas_object_rectangle_add ( evas_object_evas_get ( term - > bg ) ) ;
evas_object_color_set ( term - > tab_spacer , 0 , 0 , 0 , 0 ) ;
}
elm_coords_finger_size_adjust ( 1 , & w , 1 , & h ) ;
evas_object_size_hint_min_set ( term - > tab_spacer , w , h ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.tab_btn " ,
term - > tab_spacer ) ;
2019-10-26 09:18:03 -07:00
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " tabcount,off " , " terminology " ) ;
elm_layout_signal_emit ( term - > bg , " tabbar,on " , " terminology " ) ;
elm_layout_signal_emit ( term - > bg , " tab_btn,on " , " terminology " ) ;
2020-01-19 07:51:17 -08:00
assert ( term = = _tab_item_to_term ( tabs - > current ) ) ;
_tabs_get_or_create_boxes ( term , NULL ) ;
2015-03-22 10:17:16 -07:00
_tabbar_fill ( tabs ) ;
2020-01-28 15:06:12 -08:00
edje_object_message_signal_process ( term - > bg_edj ) ;
2014-12-02 15:42:27 -08:00
}
else
{
2020-01-28 15:06:12 -08:00
_tabcount_refresh ( tabs ) ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
}
static Tab_Item *
tab_item_new ( Tabs * tabs , Term_Container * child )
{
Tab_Item * tab_item ;
2020-01-19 07:51:17 -08:00
Solo * solo ;
Term * term ;
2015-03-22 10:17:16 -07:00
tab_item = calloc ( 1 , sizeof ( Tab_Item ) ) ;
2020-01-19 07:51:17 -08:00
if ( ! tab_item )
return NULL ;
2015-03-22 10:17:16 -07:00
tab_item - > tc = child ;
assert ( child ! = NULL ) ;
assert ( child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2020-01-19 07:51:17 -08:00
solo = ( Solo * ) child ;
term = solo - > term ;
assert ( term - > tab_item = = NULL ) ;
term - > tab_item = tab_item ;
2015-03-22 10:17:16 -07:00
tabs - > tabs = eina_list_append ( tabs - > tabs , tab_item ) ;
return tab_item ;
}
static void
2016-10-05 13:00:22 -07:00
_tabs_split ( Term_Container * tc ,
Term_Container * _child EINA_UNUSED ,
2015-09-19 05:49:40 -07:00
Term * from ,
2016-10-05 13:00:22 -07:00
const char * cmd ,
Eina_Bool is_horizontal )
2015-03-22 10:17:16 -07:00
{
2015-09-19 05:49:40 -07:00
tc - > parent - > split ( tc - > parent , tc , from , cmd , is_horizontal ) ;
2015-03-22 10:17:16 -07:00
}
2020-02-29 07:18:07 -08:00
static int
_tabs_split_direction ( Term_Container * tc ,
Term_Container * child_orig EINA_UNUSED ,
Term_Container * child_new ,
Split_Direction direction )
{
return tc - > parent - > split_direction ( tc - > parent , tc , child_new , direction ) ;
}
2018-02-11 02:48:06 -08:00
static Eina_Bool
2020-04-11 01:01:13 -07:00
_tabs_is_visible ( const Term_Container * tc , const Term_Container * child )
2018-02-11 02:48:06 -08:00
{
Tabs * tabs ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
tabs = ( Tabs * ) tc ;
return child = = tabs - > current - > tc ;
}
2020-02-15 07:47:47 -08:00
static void
_tabs_detach ( Term_Container * tc , Term_Container * solo_child )
{
2020-03-16 15:50:04 -07:00
Evas_Object * o ;
2020-02-15 07:47:47 -08:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_TABS ) ;
assert ( solo_child - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
_tabs_close ( tc , solo_child ) ;
2020-03-07 05:58:12 -08:00
solo_child - > is_focused = EINA_FALSE ;
2020-03-16 15:50:04 -07:00
o = solo_child - > get_evas_object ( solo_child ) ;
evas_object_hide ( o ) ;
2020-03-22 02:53:30 -07:00
solo_child - > parent = ( Term_Container * ) solo_child - > wn ;
2020-02-15 07:47:47 -08:00
}
2015-03-22 10:17:16 -07:00
static Term_Container *
_tabs_new ( Term_Container * child , Term_Container * parent )
{
Win * wn ;
Term_Container * tc ;
Tabs * tabs ;
Tab_Item * tab_item ;
tabs = calloc ( 1 , sizeof ( Tabs ) ) ;
if ( ! tabs )
{
return NULL ;
}
wn = child - > wn ;
tc = ( Term_Container * ) tabs ;
tc - > term_next = _tabs_term_next ;
tc - > term_prev = _tabs_term_prev ;
2017-07-10 15:01:29 -07:00
tc - > term_up = _tabs_term_up ;
tc - > term_down = _tabs_term_down ;
tc - > term_left = _tabs_term_left ;
tc - > term_right = _tabs_term_right ;
2015-03-22 10:17:16 -07:00
tc - > term_first = _tabs_term_first ;
tc - > term_last = _tabs_term_last ;
tc - > focused_term_get = _tabs_focused_term_get ;
tc - > get_evas_object = _tabs_get_evas_object ;
tc - > split = _tabs_split ;
2020-02-29 07:18:07 -08:00
tc - > split_direction = _tabs_split_direction ;
2015-03-22 10:17:16 -07:00
tc - > find_term_at_coords = _tabs_find_term_at_coords ;
tc - > size_eval = _tabs_size_eval ;
tc - > swallow = _tabs_swallow ;
tc - > focus = _tabs_focus ;
tc - > unfocus = _tabs_unfocus ;
tc - > set_title = _tabs_set_title ;
tc - > bell = _tabs_bell ;
tc - > close = _tabs_close ;
tc - > update = _tabs_update ;
2018-02-11 02:48:06 -08:00
tc - > is_visible = _tabs_is_visible ;
2020-02-15 07:47:47 -08:00
tc - > detach = _tabs_detach ;
2015-03-22 10:17:16 -07:00
tc - > title = eina_stringshare_add ( " Terminology " ) ;
tc - > type = TERM_CONTAINER_TYPE_TABS ;
tc - > parent = parent ;
tc - > wn = wn ;
child - > parent = tc ;
tab_item = tab_item_new ( tabs , child ) ;
tabs - > current = tab_item ;
/* XXX: need to refresh */
parent - > swallow ( parent , child , tc ) ;
tc - > is_focused = child - > is_focused ;
return tc ;
2014-12-02 15:42:27 -08:00
}
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
/* }}} */
2019-10-10 13:29:30 -07:00
/* {{{ Popup Media */
struct Pop_Media {
const char * src ;
Eina_Bool from_user_interaction ;
} ;
2015-08-03 12:45:05 -07:00
2015-03-22 10:17:16 -07:00
Eina_Bool
term_has_popmedia ( const Term * term )
2014-12-02 15:42:55 -08:00
{
2015-03-22 10:17:16 -07:00
return ! ! term - > popmedia ;
}
2014-12-02 15:42:55 -08:00
2015-03-22 10:17:16 -07:00
void
term_popmedia_close ( Term * term )
{
if ( term - > popmedia )
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,off " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
}
2014-10-26 13:00:14 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_popmedia_del ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _o EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
term - > popmedia = NULL ;
term - > popmedia_deleted = EINA_TRUE ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_popmedia_done ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-02-21 03:24:28 -08:00
2014-10-26 13:00:14 -07:00
if ( term - > popmedia | | term - > popmedia_deleted )
{
if ( term - > popmedia )
{
evas_object_event_callback_del ( term - > popmedia , EVAS_CALLBACK_DEL ,
_cb_popmedia_del ) ;
evas_object_del ( term - > popmedia ) ;
term - > popmedia = NULL ;
}
term - > popmedia_deleted = EINA_FALSE ;
2015-03-22 07:11:10 -07:00
termio_mouseover_suspend_pushpop ( term - > termio , - 1 ) ;
2014-10-26 13:00:14 -07:00
_popmedia_queue_process ( term ) ;
}
}
static void
2015-03-22 10:17:16 -07:00
_cb_media_loop ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _info EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
if ( term - > popmedia_queue )
{
2019-12-26 12:33:33 -08:00
if ( term - > popmedia )
media_play_set ( term - > popmedia , EINA_FALSE ) ;
elm_layout_signal_emit ( term - > bg , " popmedia,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
}
}
2019-10-10 14:40:32 -07:00
static void
_popmedia_queue_free ( Term * term )
{
struct Pop_Media * pm ;
if ( ! term - > popmedia_queue )
return ;
EINA_LIST_FREE ( term - > popmedia_queue , pm )
{
eina_stringshare_del ( pm - > src ) ;
free ( pm ) ;
}
}
2019-10-10 13:55:21 -07:00
static void
_popmedia_queue_add ( Term * term , const char * src ,
Eina_Bool from_user_interaction )
{
struct Pop_Media * pm = calloc ( 1 , sizeof ( struct Pop_Media ) ) ;
if ( ! pm )
return ;
pm - > src = eina_stringshare_add ( src ) ;
pm - > from_user_interaction = from_user_interaction ;
term - > popmedia_queue = eina_list_append ( term - > popmedia_queue , pm ) ;
if ( ! term - > popmedia )
_popmedia_queue_process ( term ) ;
}
2019-10-10 14:40:32 -07:00
static void
_popmedia_now ( Term * term , const char * src ,
Eina_Bool from_user_interaction )
{
struct Pop_Media * pm ;
/* Flush queue */
EINA_LIST_FREE ( term - > popmedia_queue , pm )
{
eina_stringshare_del ( pm - > src ) ;
}
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,off " , " terminology " ) ;
2019-10-10 14:40:32 -07:00
_popmedia_queue_add ( term , src , from_user_interaction ) ;
}
2019-10-10 13:55:21 -07:00
2014-10-26 13:00:14 -07:00
static void
2015-02-15 11:32:16 -08:00
_popmedia_show ( Term * term , const char * src , Media_Type type )
2014-10-26 13:00:14 -07:00
{
Evas_Object * o ;
2015-03-22 07:11:10 -07:00
Config * config = termio_config_get ( term - > termio ) ;
2014-10-26 13:00:14 -07:00
2019-10-10 14:40:32 -07:00
assert ( ! term - > popmedia ) ;
2015-02-15 11:32:16 -08:00
EINA_SAFETY_ON_NULL_RETURN ( config ) ;
2015-03-22 07:11:10 -07:00
termio_mouseover_suspend_pushpop ( term - > termio , 1 ) ;
2014-10-26 13:00:14 -07:00
term - > popmedia = o = media_add ( win_evas_object_get ( term - > wn ) ,
src , config , MEDIA_POP , type ) ;
term - > popmedia_deleted = EINA_FALSE ;
evas_object_smart_callback_add ( o , " loop " , _cb_media_loop , term ) ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_DEL , _cb_popmedia_del , term ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.popmedia " , o ) ;
2014-10-26 13:00:14 -07:00
evas_object_show ( o ) ;
term - > poptype = type ;
switch ( type )
{
case MEDIA_TYPE_IMG :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,image " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_SCALE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,scale " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_EDJE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,edje " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_MOV :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,movie " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_UNKNOWN :
default :
break ;
}
}
2015-02-21 02:31:24 -08:00
# ifdef HAVE_ECORE_CON_URL_HEAD
2015-02-15 11:32:16 -08:00
typedef struct _Ty_Http_Head {
const char * handler ;
const char * src ;
Ecore_Con_Url * url ;
Ecore_Event_Handler * url_complete ;
2015-04-08 14:38:57 -07:00
Ecore_Timer * timeout ;
2015-02-15 11:32:16 -08:00
Term * term ;
2018-12-17 12:51:05 -08:00
Eina_Bool fallback_allowed ;
2015-02-15 11:32:16 -08:00
} Ty_Http_Head ;
static void
_ty_http_head_delete ( Ty_Http_Head * ty_head )
{
eina_stringshare_del ( ty_head - > handler ) ;
eina_stringshare_del ( ty_head - > src ) ;
ecore_con_url_free ( ty_head - > url ) ;
ecore_event_handler_del ( ty_head - > url_complete ) ;
2018-04-05 13:28:27 -07:00
if ( ty_head - > term )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( ty_head - > term - > bg , " done " , " terminology " ) ;
2018-04-05 13:28:27 -07:00
term_unref ( ty_head - > term ) ;
}
2015-04-08 14:38:57 -07:00
ecore_timer_del ( ty_head - > timeout ) ;
2015-02-15 11:32:16 -08:00
free ( ty_head ) ;
}
2015-04-08 14:38:57 -07:00
static Eina_Bool
_media_http_head_timeout ( void * data )
{
Ty_Http_Head * ty_head = data ;
2018-12-16 02:13:20 -08:00
2015-04-08 14:38:57 -07:00
ty_head - > timeout = NULL ;
2018-12-17 12:51:05 -08:00
if ( ty_head - > fallback_allowed )
{
media_unknown_handle ( ty_head - > handler , ty_head - > src ) ;
}
2015-04-08 14:38:57 -07:00
_ty_http_head_delete ( ty_head ) ;
return ECORE_CALLBACK_CANCEL ;
}
2015-02-15 11:32:16 -08:00
static Eina_Bool
2016-10-05 13:00:22 -07:00
_media_http_head_complete ( void * data ,
int _kind EINA_UNUSED ,
void * event_info )
2015-02-15 11:32:16 -08:00
{
Ecore_Con_Event_Url_Complete * ev = event_info ;
Ty_Http_Head * ty_head = data ;
const Eina_List * headers , * l ;
Media_Type type = MEDIA_TYPE_UNKNOWN ;
char * str ;
if ( ev - > status ! = 200 )
goto error ;
headers = ecore_con_url_response_headers_get ( ev - > url_con ) ;
EINA_LIST_FOREACH ( headers , l , str )
{
# define _CONTENT_TYPE_HDR "Content-Type: "
# define _LOCATION_HDR "Location: "
if ( ! strncmp ( str , _LOCATION_HDR , strlen ( _LOCATION_HDR ) ) )
{
unsigned int len ;
str + = strlen ( _LOCATION_HDR ) ;
2015-06-03 14:04:03 -07:00
if ( * str ! = ' / ' )
{
eina_stringshare_del ( ty_head - > src ) ;
2015-02-15 11:32:16 -08:00
2015-06-03 14:04:03 -07:00
/* skip the crlf */
len = strlen ( str ) ;
if ( len < = 2 )
goto error ;
2015-02-15 11:32:16 -08:00
2015-06-03 14:04:03 -07:00
ty_head - > src = eina_stringshare_add_length ( str , len - 2 ) ;
if ( ! ty_head - > src )
goto error ;
}
2015-02-15 11:32:16 -08:00
}
else if ( ! strncmp ( str , _CONTENT_TYPE_HDR , strlen ( _CONTENT_TYPE_HDR ) ) )
{
str + = strlen ( _CONTENT_TYPE_HDR ) ;
if ( ! strncmp ( str , " image/ " , strlen ( " image/ " ) ) )
{
type = MEDIA_TYPE_IMG ;
}
else if ( ! strncmp ( str , " video/ " , strlen ( " video/ " ) ) )
{
type = MEDIA_TYPE_MOV ;
}
if ( type ! = MEDIA_TYPE_UNKNOWN )
{
_popmedia_show ( ty_head - > term , ty_head - > src , type ) ;
break ;
}
}
# undef _CONTENT_TYPE_HDR
# undef _LOCATION_HDR
}
2015-02-23 11:17:48 -08:00
if ( type = = MEDIA_TYPE_UNKNOWN )
goto error ;
2015-02-15 11:32:16 -08:00
_ty_http_head_delete ( ty_head ) ;
return EINA_TRUE ;
error :
2018-12-17 12:51:05 -08:00
if ( ty_head - > fallback_allowed )
{
media_unknown_handle ( ty_head - > handler , ty_head - > src ) ;
}
2015-02-15 11:32:16 -08:00
_ty_http_head_delete ( ty_head ) ;
return EINA_TRUE ;
}
# endif
static void
2019-10-10 14:40:32 -07:00
_popmedia_unknown ( Term * term , const char * src , Eina_Bool from_user_interaction )
2015-02-15 11:32:16 -08:00
{
Media_Type type ;
2015-03-22 07:11:10 -07:00
Config * config = termio_config_get ( term - > termio ) ;
2015-02-15 11:32:16 -08:00
2015-04-03 03:50:16 -07:00
type = media_src_type_get ( src ) ;
if ( type = = MEDIA_TYPE_UNKNOWN )
2015-02-15 11:32:16 -08:00
{
2015-04-03 03:50:16 -07:00
# ifdef HAVE_ECORE_CON_URL_HEAD
Ty_Http_Head * ty_head = calloc ( 1 , sizeof ( Ty_Http_Head ) ) ;
2018-12-17 12:51:05 -08:00
if ( ! ty_head )
return ;
2015-02-15 11:32:16 -08:00
2015-04-03 03:50:16 -07:00
if ( config - > helper . local . general & & config - > helper . local . general [ 0 ] )
{
ty_head - > handler = eina_stringshare_add ( config - > helper . local . general ) ;
2018-12-17 12:51:05 -08:00
if ( ! ty_head - > handler )
goto error ;
2015-04-03 03:50:16 -07:00
}
2018-12-17 12:51:05 -08:00
/* If it comes from a user interaction (click on a link), allow
* fallback to " xdg-open "
* Otherwise , it ' s from terminology ' s escape code . Thus don ' t allow
* fallback and only display content " inline " .
*/
ty_head - > fallback_allowed = from_user_interaction ;
2015-04-03 03:50:16 -07:00
ty_head - > src = eina_stringshare_add ( src ) ;
2018-12-17 12:51:05 -08:00
if ( ! ty_head - > src )
goto error ;
2015-04-03 03:50:16 -07:00
ty_head - > url = ecore_con_url_new ( src ) ;
2018-12-17 12:51:05 -08:00
if ( ! ty_head - > url )
goto error ;
if ( ! ecore_con_url_head ( ty_head - > url ) )
goto error ;
2015-04-03 03:50:16 -07:00
ty_head - > url_complete = ecore_event_handler_add
( ECORE_CON_EVENT_URL_COMPLETE , _media_http_head_complete , ty_head ) ;
2015-04-08 14:38:57 -07:00
ty_head - > timeout = ecore_timer_add ( 2.5 , _media_http_head_timeout , ty_head ) ;
2018-12-17 12:51:05 -08:00
if ( ! ty_head - > url_complete )
goto error ;
2015-04-03 03:50:16 -07:00
ty_head - > term = term ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " busy " , " terminology " ) ;
2015-04-03 03:50:16 -07:00
term_ref ( term ) ;
return ;
2015-02-15 11:32:16 -08:00
error :
2015-04-03 03:50:16 -07:00
_ty_http_head_delete ( ty_head ) ;
2015-02-15 11:32:16 -08:00
# endif
2018-12-17 12:51:05 -08:00
if ( from_user_interaction )
{
media_unknown_handle ( config - > helper . local . general , src ) ;
}
2015-04-03 03:50:16 -07:00
}
else
{
2015-02-15 11:32:16 -08:00
_popmedia_show ( term , src , type ) ;
2015-04-03 03:50:16 -07:00
}
2015-02-15 11:32:16 -08:00
}
2014-10-26 13:00:14 -07:00
static void
2019-10-10 13:29:30 -07:00
_popmedia_queue_process ( Term * term )
{
struct Pop_Media * pm ;
if ( ! term - > popmedia_queue )
return ;
pm = term - > popmedia_queue - > data ;
term - > popmedia_queue = eina_list_remove_list ( term - > popmedia_queue ,
term - > popmedia_queue ) ;
if ( ! pm )
return ;
2019-10-10 14:40:32 -07:00
_popmedia_unknown ( term , pm - > src , pm - > from_user_interaction ) ;
2019-10-10 13:29:30 -07:00
eina_stringshare_del ( pm - > src ) ;
free ( pm ) ;
}
static void
_cb_popup ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * event )
{
Term * term = data ;
const char * src = event ;
Eina_Bool from_user_interaction = EINA_FALSE ;
if ( ! src )
{
/* Popup a link, there was user interaction on it. */
from_user_interaction = EINA_TRUE ;
src = termio_link_get ( term - > termio , NULL ) ;
}
if ( ! src )
return ;
2019-10-10 14:40:32 -07:00
_popmedia_unknown ( term , src , from_user_interaction ) ;
2019-10-10 13:29:30 -07:00
if ( ! event )
free ( ( void * ) src ) ;
}
static void
_cb_popup_queue ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * event )
{
Term * term = data ;
const char * src = event ;
Eina_Bool from_user_interaction = EINA_FALSE ;
if ( ! src )
{
from_user_interaction = EINA_TRUE ;
src = termio_link_get ( term - > termio , NULL ) ;
}
if ( ! src )
return ;
_popmedia_queue_add ( term , src , from_user_interaction ) ;
if ( ! event )
free ( ( void * ) src ) ;
}
/* }}} */
/* {{{ Term */
Eina_Bool
2020-04-11 01:01:13 -07:00
term_is_visible ( const Term * term )
2019-10-10 13:29:30 -07:00
{
2020-04-11 01:01:13 -07:00
const Term_Container * tc ;
2019-10-10 13:29:30 -07:00
if ( ! term )
return EINA_FALSE ;
tc = term - > container ;
if ( ! tc )
return EINA_FALSE ;
return tc - > is_visible ( tc , tc ) ;
}
void
2020-10-17 14:35:10 -07:00
background_set_shine ( const Config * config , Evas_Object * bg_edj )
2019-10-10 13:29:30 -07:00
{
Edje_Message_Int msg ;
if ( config )
msg . val = config - > shine ;
else
msg . val = 255 ;
2019-12-26 12:33:33 -08:00
if ( bg_edj )
edje_object_message_send ( bg_edj , EDJE_MESSAGE_INT , 2 , & msg ) ;
2019-10-10 13:29:30 -07:00
}
void
term_apply_shine ( Term * term , int shine )
{
Config * config = term - > config ;
if ( config - > shine ! = shine )
{
config - > shine = shine ;
2019-12-26 12:33:33 -08:00
background_set_shine ( config , term - > bg_edj ) ;
2019-10-10 13:29:30 -07:00
config_save ( config ) ;
}
}
static void
_term_config_set ( Term * term , Config * config )
{
Config * old_config = term - > config ;
term - > config = config ;
termio_config_set ( term - > termio , config ) ;
_term_media_update ( term , term - > config ) ;
if ( old_config ! = term - > wn - > config )
config_del ( old_config ) ;
}
Eina_Bool
2020-04-11 01:01:13 -07:00
term_is_focused ( const Term * term )
2019-10-10 13:29:30 -07:00
{
Term_Container * tc ;
if ( ! term )
return EINA_FALSE ;
tc = term - > container ;
if ( ! tc )
return EINA_FALSE ;
return tc - > is_focused ;
}
void change_theme ( Evas_Object * win , Config * config )
{
const Eina_List * terms , * l ;
Term * term ;
terms = terms_from_win_object ( win ) ;
if ( ! terms ) return ;
EINA_LIST_FOREACH ( terms , l , term )
{
2019-12-26 12:33:33 -08:00
Evas_Object * edje = term - > bg_edj ;
2019-10-10 13:29:30 -07:00
2020-08-29 09:38:11 -07:00
if ( ! theme_apply_elm ( term - > bg , config , " terminology/background " ) )
2019-10-10 13:29:30 -07:00
ERR ( " Couldn't find terminology theme! " ) ;
colors_term_init ( termio_textgrid_get ( term - > termio ) , edje , config ) ;
termio_config_set ( term - > termio , config ) ;
}
l = elm_theme_overlay_list_get ( NULL ) ;
if ( l ) l = eina_list_last ( l ) ;
if ( l ) elm_theme_overlay_del ( NULL , l - > data ) ;
elm_theme_overlay_add ( NULL , config_theme_path_get ( config ) ) ;
2020-04-05 13:59:46 -07:00
main_trans_update ( ) ;
2019-10-10 13:29:30 -07:00
}
void
term_focus ( Term * term )
{
Term_Container * tc ;
DBG ( " is focused? tc:%p " , term - > container ) ;
if ( term_is_focused ( term ) )
return ;
tc = term - > container ;
DBG ( " tc:%p " , tc ) ;
tc - > focus ( tc , tc ) ;
}
void
term_unfocus ( Term * term )
{
Term_Container * tc ;
DBG ( " is focused? tc:%p " , term - > container ) ;
if ( ! term_is_focused ( term ) )
return ;
tc = term - > container ;
DBG ( " tc:%p " , tc ) ;
tc - > unfocus ( tc , tc ) ;
}
enum term_to_direction {
TERM_TO_PREV ,
TERM_TO_NEXT ,
TERM_TO_UP ,
TERM_TO_DOWN ,
TERM_TO_LEFT ,
TERM_TO_RIGHT ,
} ;
static void
term_go_to ( Term * from , enum term_to_direction dir )
{
Term * new_term , * focused_term ;
Win * wn = from - > wn ;
Term_Container * tc ;
tc = ( Term_Container * ) wn ;
focused_term = tc - > focused_term_get ( tc ) ;
if ( ! focused_term )
focused_term = from ;
tc = focused_term - > container ;
switch ( dir )
{
case TERM_TO_PREV :
new_term = tc - > term_prev ( tc , tc ) ;
break ;
case TERM_TO_NEXT :
new_term = tc - > term_next ( tc , tc ) ;
break ;
case TERM_TO_UP :
new_term = tc - > term_up ( tc , tc ) ;
break ;
case TERM_TO_DOWN :
new_term = tc - > term_down ( tc , tc ) ;
break ;
case TERM_TO_LEFT :
new_term = tc - > term_left ( tc , tc ) ;
break ;
case TERM_TO_RIGHT :
new_term = tc - > term_right ( tc , tc ) ;
break ;
}
if ( new_term & & new_term ! = focused_term )
term_focus ( new_term ) ;
/* TODO: get rid of it? */
_term_miniview_check ( from ) ;
}
void
term_prev ( Term * term )
{
term_go_to ( term , TERM_TO_PREV ) ;
}
void
term_next ( Term * term )
{
term_go_to ( term , TERM_TO_NEXT ) ;
}
void
term_up ( Term * term )
{
term_go_to ( term , TERM_TO_UP ) ;
}
void
term_down ( Term * term )
{
term_go_to ( term , TERM_TO_DOWN ) ;
}
void
term_left ( Term * term )
{
term_go_to ( term , TERM_TO_LEFT ) ;
}
void
term_right ( Term * term )
{
term_go_to ( term , TERM_TO_RIGHT ) ;
}
Term *
term_prev_get ( const Term * term )
{
Term_Container * tc = term - > container ;
return tc - > term_prev ( tc , tc ) ;
}
Term *
term_next_get ( const Term * term )
{
Term_Container * tc = term - > container ;
return tc - > term_next ( tc , tc ) ;
}
static void
_term_miniview_check ( Term * term )
2014-10-26 13:00:14 -07:00
{
Eina_List * l , * wn_list ;
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
EINA_SAFETY_ON_NULL_RETURN ( term - > miniview ) ;
wn_list = win_terms_get ( term_win_get ( term ) ) ;
EINA_LIST_FOREACH ( wn_list , l , term )
{
if ( term - > miniview_shown )
{
2016-02-02 14:15:50 -08:00
DBG ( " is focused? tc:%p " , term - > container ) ;
2019-06-17 13:12:59 -07:00
if ( term_is_focused ( term ) )
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " miniview,on " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
}
}
}
void
term_miniview_hide ( Term * term )
{
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
EINA_SAFETY_ON_NULL_RETURN ( term - > miniview ) ;
if ( term - > miniview_shown )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " miniview,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
term - > miniview_shown = EINA_FALSE ;
}
}
void
term_miniview_toggle ( Term * term )
{
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
EINA_SAFETY_ON_NULL_RETURN ( term - > miniview ) ;
if ( term - > miniview_shown )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " miniview,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
term - > miniview_shown = EINA_FALSE ;
}
else
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " miniview,on " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
term - > miniview_shown = EINA_TRUE ;
}
}
2018-03-10 10:40:13 -08:00
static void
_on_popover_done ( Win * wn )
{
Term_Container * tc = ( Term_Container * ) wn ;
Eina_List * l ;
Term * term ;
wn - > on_popover - - ;
if ( wn - > on_popover )
return ;
if ( ! _win_is_focused ( wn ) )
return ;
EINA_LIST_FOREACH ( wn - > terms , l , term )
{
DBG ( " is focused? tc:%p " , term - > container ) ;
2019-06-17 13:12:59 -07:00
if ( term_is_focused ( term ) )
2018-03-10 10:40:13 -08:00
return ;
}
DBG ( " focus tc:%p " , tc ) ;
tc - > focus ( tc , tc ) ;
}
2016-03-02 06:37:02 -08:00
static void
2016-10-05 13:00:22 -07:00
_set_title_ok_cb ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2016-03-02 06:37:02 -08:00
{
2018-03-10 10:40:13 -08:00
Evas_Object * popup = data ;
Term * term = evas_object_data_get ( popup , " term " ) ;
Evas_Object * entry = elm_object_content_get ( popup ) ;
const char * title = elm_entry_entry_get ( entry ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
if ( ! title | | ! strlen ( title ) )
title = NULL ;
2016-03-02 06:37:02 -08:00
2018-04-22 08:27:14 -07:00
termio_user_title_set ( term - > termio , title ) ;
2018-03-10 10:40:13 -08:00
elm_object_focus_set ( entry , EINA_FALSE ) ;
elm_popup_dismiss ( popup ) ;
2016-03-02 06:37:02 -08:00
}
static void
2016-10-05 13:00:22 -07:00
_set_title_cancel_cb ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2016-03-02 06:37:02 -08:00
{
2018-03-10 10:40:13 -08:00
Evas_Object * popup = data ;
Evas_Object * entry = elm_object_content_get ( popup ) ;
2016-03-12 07:46:31 -08:00
2018-03-10 10:40:13 -08:00
elm_object_focus_set ( entry , EINA_FALSE ) ;
elm_popup_dismiss ( popup ) ;
}
static void
_cb_title_popup_hide ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
{
Term * term = data ;
Win * wn = term - > wn ;
_on_popover_done ( wn ) ;
term_unref ( term ) ;
2016-03-02 06:37:02 -08:00
}
void
term_set_title ( Term * term )
{
2018-03-10 10:40:13 -08:00
Evas_Object * o ;
Evas_Object * popup ;
Term_Container * tc = term - > container ;
2018-04-22 08:27:14 -07:00
const char * prev_title ;
2018-03-10 10:40:13 -08:00
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
term - > wn - > on_popover + + ;
term_ref ( term ) ;
tc - > unfocus ( tc , NULL ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
popup = elm_popup_add ( term - > wn - > win ) ;
evas_object_data_set ( popup , " term " , term ) ;
evas_object_event_callback_add ( popup , EVAS_CALLBACK_HIDE ,
_cb_title_popup_hide , term ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
elm_object_part_text_set ( popup , " title,text " , _ ( " Set title " ) ) ;
2016-03-12 07:46:31 -08:00
2018-03-10 10:40:13 -08:00
o = elm_button_add ( popup ) ;
evas_object_smart_callback_add ( o , " clicked " , _set_title_ok_cb , popup ) ;
elm_object_text_set ( o , _ ( " Ok " ) ) ;
elm_object_part_content_set ( popup , " button1 " , o ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
o = elm_button_add ( popup ) ;
evas_object_smart_callback_add ( o , " clicked " , _set_title_cancel_cb , popup ) ;
elm_object_text_set ( o , _ ( " Cancel " ) ) ;
elm_object_part_content_set ( popup , " button2 " , o ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
o = elm_entry_add ( popup ) ;
elm_entry_single_line_set ( o , EINA_TRUE ) ;
2018-04-22 08:27:14 -07:00
elm_entry_editable_set ( o , EINA_TRUE ) ;
prev_title = termio_user_title_get ( term - > termio ) ;
if ( prev_title )
{
elm_entry_entry_set ( o , prev_title ) ;
elm_entry_cursor_pos_set ( o , strlen ( prev_title ) ) ;
}
2018-03-10 10:40:13 -08:00
evas_object_smart_callback_add ( o , " activated " , _set_title_ok_cb , popup ) ;
evas_object_smart_callback_add ( o , " aborted " , _set_title_cancel_cb , popup ) ;
elm_object_content_set ( popup , o ) ;
evas_object_show ( o ) ;
2016-03-02 06:37:02 -08:00
2018-03-10 10:40:13 -08:00
evas_object_show ( popup ) ;
2017-12-04 20:41:51 -08:00
2018-03-10 10:40:13 -08:00
elm_object_focus_set ( o , EINA_TRUE ) ;
2016-03-02 06:37:02 -08:00
}
2014-10-26 13:00:14 -07:00
static void
_set_alpha ( Config * config , const char * val , Eina_Bool save )
{
int opacity ;
if ( ! config | | ! val ) return ;
config - > temporary = ! save ;
if ( isdigit ( * val ) )
{
opacity = atoi ( val ) ;
if ( opacity > = 100 )
{
config - > translucent = EINA_FALSE ;
config - > opacity = 100 ;
}
else if ( opacity > = 0 )
{
config - > translucent = EINA_TRUE ;
config - > opacity = opacity ;
}
}
else if ( ( ! strcasecmp ( val , " on " ) ) | |
( ! strcasecmp ( val , " true " ) ) | |
( ! strcasecmp ( val , " yes " ) ) )
config - > translucent = EINA_TRUE ;
else
config - > translucent = EINA_FALSE ;
2019-09-08 10:41:16 -07:00
if ( save )
config_save ( config ) ;
2020-04-05 13:59:46 -07:00
main_trans_update ( ) ;
2014-10-26 13:00:14 -07:00
}
2017-12-17 06:36:51 -08:00
static void
_sendfile_progress_del ( void * data EINA_UNUSED , Evas * e EINA_UNUSED , Evas_Object * obj , void * info EINA_UNUSED )
{
Evas_Object * o = obj ;
Term * term = evas_object_data_get ( o , " sendfile-progress-term " ) ;
Ecore_Timer * t ;
evas_object_data_del ( o , " sendfile-progress-term " ) ;
if ( term )
{
term - > sendfile_progress = NULL ;
term - > sendfile_progress_bar = NULL ;
}
t = evas_object_data_get ( o , " sendfile-progress-timer " ) ;
evas_object_data_del ( o , " sendfile-progress-term " ) ;
if ( t ) ecore_timer_del ( t ) ;
}
static Eina_Bool
_sendfile_progress_reset ( void * data )
{
Evas_Object * o = data ;
Term * term = evas_object_data_get ( o , " sendfile-progress-term " ) ;
if ( term )
{
term - > sendfile_progress = NULL ;
term - > sendfile_progress_bar = NULL ;
}
evas_object_data_del ( o , " sendfile-progress-timer " ) ;
evas_object_data_del ( o , " sendfile-progress-term " ) ;
evas_object_del ( o ) ;
return EINA_FALSE ;
}
static Eina_Bool
_sendfile_progress_hide_delay ( void * data )
{
Term * term = data ;
Ecore_Timer * t ;
term - > sendfile_progress_hide_timer = NULL ;
if ( ! term - > sendfile_progress_enabled ) return EINA_FALSE ;
term - > sendfile_progress_enabled = EINA_FALSE ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " sendfile,progress,off " , " terminology " ) ;
2017-12-17 06:36:51 -08:00
t = evas_object_data_get ( term - > sendfile_progress , " sendfile-progress-timer " ) ;
if ( t ) ecore_timer_del ( t ) ;
t = ecore_timer_add ( 10.0 , _sendfile_progress_reset , term - > sendfile_progress ) ;
evas_object_data_set ( term - > sendfile_progress , " sendfile-progress-timer " , t ) ;
return EINA_FALSE ;
}
static void
_sendfile_progress_hide ( Term * term )
{
if ( ! term - > sendfile_progress_enabled ) return ;
if ( term - > sendfile_progress_hide_timer )
ecore_timer_del ( term - > sendfile_progress_hide_timer ) ;
term - > sendfile_progress_hide_timer =
ecore_timer_add ( 0.5 , _sendfile_progress_hide_delay , term ) ;
2017-12-17 22:16:08 -08:00
if ( elm_object_focus_get ( term - > sendfile_progress ) )
{
elm_object_focus_set ( term - > sendfile_progress , EINA_FALSE ) ;
2018-03-19 14:11:53 -07:00
term_focus ( term ) ;
2017-12-17 22:16:08 -08:00
}
2017-12-17 06:36:51 -08:00
}
static void
_sendfile_progress_cancel ( void * data , Evas_Object * obj EINA_UNUSED , void * info EINA_UNUSED )
{
Term * term = data ;
if ( ! term - > sendfile_progress ) return ;
termio_file_send_cancel ( term - > termio ) ;
_sendfile_progress_hide ( term ) ;
}
static void
_sendfile_progress ( Term * term )
{
Evas_Object * o , * base ;
if ( term - > sendfile_progress )
{
evas_object_del ( term - > sendfile_progress ) ;
term - > sendfile_progress = NULL ;
}
2019-12-26 12:33:33 -08:00
if ( ! edje_object_part_exists ( term - > bg_edj , " terminology.sendfile.progress " ) )
2017-12-17 06:36:51 -08:00
{
return ;
}
if ( term - > sendfile_progress_hide_timer )
{
ecore_timer_del ( term - > sendfile_progress_hide_timer ) ;
term - > sendfile_progress_hide_timer = NULL ;
}
o = elm_box_add ( term - > wn - > win ) ;
evas_object_data_set ( o , " sendfile-progress-term " , term ) ;
base = o ;
term - > sendfile_progress = o ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_DEL , _sendfile_progress_del , NULL ) ;
elm_box_horizontal_set ( o , EINA_TRUE ) ;
o = elm_button_add ( term - > wn - > win ) ;
elm_object_text_set ( o , " Cancel " ) ;
evas_object_smart_callback_add ( o , " clicked " , _sendfile_progress_cancel , term ) ;
evas_object_size_hint_align_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
elm_box_pack_end ( base , o ) ;
evas_object_show ( o ) ;
o = elm_progressbar_add ( term - > wn - > win ) ;
term - > sendfile_progress_bar = o ;
elm_progressbar_unit_format_set ( o , " %1.0f%% " ) ;
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_align_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
elm_box_pack_end ( base , o ) ;
evas_object_show ( o ) ;
term - > sendfile_progress_enabled = EINA_TRUE ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.sendfile.progress " , base ) ;
2017-12-17 06:36:51 -08:00
evas_object_show ( base ) ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " sendfile,progress,on " , " terminology " ) ;
2017-12-17 06:36:51 -08:00
}
static void
_sendfile_request_del ( void * data EINA_UNUSED , Evas * e EINA_UNUSED , Evas_Object * obj , void * info EINA_UNUSED )
{
Evas_Object * o = obj ;
Term * term = evas_object_data_get ( o , " sendfile-request-term " ) ;
Ecore_Timer * t ;
evas_object_data_del ( o , " sendfile-request-term " ) ;
if ( term ) term - > sendfile_request = NULL ;
t = evas_object_data_get ( o , " sendfile-request-timer " ) ;
evas_object_data_del ( o , " sendfile-request-term " ) ;
if ( t ) ecore_timer_del ( t ) ;
}
static Eina_Bool
_sendfile_request_reset ( void * data )
{
Evas_Object * o = data ;
Term * term = evas_object_data_get ( o , " sendfile-request-term " ) ;
if ( term ) term - > sendfile_request = NULL ;
evas_object_data_del ( o , " sendfile-request-timer " ) ;
evas_object_data_del ( o , " sendfile-request-term " ) ;
evas_object_del ( o ) ;
return EINA_FALSE ;
}
static Eina_Bool
_sendfile_request_hide_delay ( void * data )
{
Term * term = data ;
Ecore_Timer * t ;
term - > sendfile_request_hide_timer = NULL ;
if ( ! term - > sendfile_request_enabled ) return EINA_FALSE ;
term - > sendfile_request_enabled = EINA_FALSE ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " sendfile,request,off " , " terminology " ) ;
2017-12-17 06:36:51 -08:00
t = evas_object_data_get ( term - > sendfile_request , " sendfile-request-timer " ) ;
if ( t ) ecore_timer_del ( t ) ;
t = ecore_timer_add ( 10.0 , _sendfile_request_reset , term - > sendfile_request ) ;
evas_object_data_set ( term - > sendfile_request , " sendfile-request-timer " , t ) ;
2017-12-17 22:16:08 -08:00
if ( elm_object_focus_get ( term - > sendfile_request ) )
{
elm_object_focus_set ( term - > sendfile_request , EINA_FALSE ) ;
2018-03-19 14:11:53 -07:00
term_focus ( term ) ;
2017-12-17 22:16:08 -08:00
}
2017-12-17 06:36:51 -08:00
return EINA_FALSE ;
}
static void
_sendfile_request_hide ( Term * term )
{
if ( ! term - > sendfile_request_enabled ) return ;
if ( term - > sendfile_request_hide_timer )
ecore_timer_del ( term - > sendfile_request_hide_timer ) ;
term - > sendfile_request_hide_timer =
ecore_timer_add ( 0.2 , _sendfile_request_hide_delay , term ) ;
}
static void
_sendfile_request_done ( void * data , Evas_Object * obj EINA_UNUSED , void * info )
{
Term * term = data ;
const char * path , * selpath = info ;
if ( ! term - > sendfile_request ) return ;
path = elm_fileselector_path_get ( term - > sendfile_request ) ;
eina_stringshare_replace ( & term - > sendfile_dir , path ) ;
if ( selpath )
{
_sendfile_progress ( term ) ;
termio_file_send_ok ( term - > termio , selpath ) ;
}
else termio_file_send_cancel ( term - > termio ) ;
_sendfile_request_hide ( term ) ;
}
static void
_sendfile_request ( Term * term , const char * path )
{
Evas_Object * o ;
const char * p ;
if ( term - > sendfile_request )
{
evas_object_del ( term - > sendfile_request ) ;
term - > sendfile_request = NULL ;
}
2019-12-26 12:33:33 -08:00
if ( ! edje_object_part_exists ( term - > bg_edj , " terminology.sendfile.request " ) )
2017-12-17 06:36:51 -08:00
{
termio_file_send_cancel ( term - > termio ) ;
return ;
}
if ( term - > sendfile_request_hide_timer )
{
ecore_timer_del ( term - > sendfile_request_hide_timer ) ;
term - > sendfile_request_hide_timer = NULL ;
}
o = elm_fileselector_add ( term - > wn - > win ) ;
evas_object_data_set ( o , " sendfile-request-term " , term ) ;
term - > sendfile_request = o ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_DEL , _sendfile_request_del , NULL ) ;
elm_fileselector_is_save_set ( o , EINA_TRUE ) ;
elm_fileselector_expandable_set ( o , EINA_FALSE ) ;
if ( ! term - > sendfile_dir )
{
const char * dir = eina_environment_home_get ( ) ;
if ( dir ) term - > sendfile_dir = eina_stringshare_add ( dir ) ;
}
if ( term - > sendfile_dir ) elm_fileselector_path_set ( o , term - > sendfile_dir ) ;
p = strrchr ( path , ' / ' ) ;
if ( p ) elm_fileselector_current_name_set ( o , p + 1 ) ;
else elm_fileselector_current_name_set ( o , path ) ;
evas_object_smart_callback_add ( o , " done " , _sendfile_request_done , term ) ;
term - > sendfile_request_enabled = EINA_TRUE ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.sendfile.request " , o ) ;
2017-12-17 06:36:51 -08:00
evas_object_show ( o ) ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " sendfile,request,on " , " terminology " ) ;
2017-12-17 06:36:51 -08:00
elm_object_focus_set ( o , EINA_TRUE ) ;
}
2014-10-26 13:00:14 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_command ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * event )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
const char * cmd = event ;
if ( cmd [ 0 ] = = ' p ' ) // popmedia
{
if ( cmd [ 1 ] = = ' n ' ) // now
{
2019-10-10 14:40:32 -07:00
_popmedia_now ( term , cmd + 2 , EINA_FALSE ) ;
2014-10-26 13:00:14 -07:00
}
else if ( cmd [ 1 ] = = ' q ' ) // queue it to display after current one
{
2018-12-17 12:51:05 -08:00
_popmedia_queue_add ( term , cmd + 2 , EINA_FALSE ) ;
2014-10-26 13:00:14 -07:00
}
}
else if ( cmd [ 0 ] = = ' b ' ) // set background
{
if ( cmd [ 1 ] = = ' t ' ) // temporary
{
2015-03-22 07:11:10 -07:00
Config * config = termio_config_get ( term - > termio ) ;
2014-10-26 13:00:14 -07:00
if ( config )
{
2015-08-03 12:45:05 -07:00
Config * new_config = config_fork ( config ) ;
new_config - > temporary = EINA_TRUE ;
2014-10-26 13:00:14 -07:00
if ( cmd [ 2 ] )
2015-08-03 12:45:05 -07:00
eina_stringshare_replace ( & ( new_config - > background ) , cmd + 2 ) ;
2014-10-26 13:00:14 -07:00
else
2015-08-03 12:45:05 -07:00
eina_stringshare_replace ( & ( new_config - > background ) , NULL ) ;
_term_config_set ( term , new_config ) ;
2014-10-26 13:00:14 -07:00
}
}
else if ( cmd [ 1 ] = = ' p ' ) // permanent
{
2015-03-22 07:11:10 -07:00
Config * config = termio_config_get ( term - > termio ) ;
2014-10-26 13:00:14 -07:00
if ( config )
{
config - > temporary = EINA_FALSE ;
if ( cmd [ 2 ] )
eina_stringshare_replace ( & ( config - > background ) , cmd + 2 ) ;
else
eina_stringshare_replace ( & ( config - > background ) , NULL ) ;
main_media_update ( config ) ;
2019-09-08 10:41:16 -07:00
config_save ( config ) ;
2014-10-26 13:00:14 -07:00
}
}
}
else if ( cmd [ 0 ] = = ' a ' ) // set alpha
{
if ( cmd [ 1 ] = = ' t ' ) // temporary
2015-03-22 07:11:10 -07:00
_set_alpha ( termio_config_get ( term - > termio ) , cmd + 2 , EINA_FALSE ) ;
2014-10-26 13:00:14 -07:00
else if ( cmd [ 1 ] = = ' p ' ) // permanent
2015-03-22 07:11:10 -07:00
_set_alpha ( termio_config_get ( term - > termio ) , cmd + 2 , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
}
2017-12-17 06:36:51 -08:00
else if ( cmd [ 0 ] = = ' f ' ) // file...
{
if ( cmd [ 1 ] = = ' r ' ) // receive
{
_sendfile_request ( term , cmd + 2 ) ;
}
else if ( cmd [ 1 ] = = ' d ' ) // data packet
{
}
else if ( cmd [ 1 ] = = ' x ' ) // exit data stream
{
}
}
2014-10-26 13:00:14 -07:00
}
2014-12-02 15:42:42 -08:00
static void
2019-10-26 09:18:03 -07:00
_cb_tab_go ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2014-12-02 15:42:42 -08:00
{
2015-03-22 10:17:16 -07:00
_cb_select ( data , NULL , NULL ) ;
2014-12-02 15:42:42 -08:00
}
2019-10-26 09:18:03 -07:00
static void
_cb_tab_new ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
{
Term * term = data ;
main_new ( term - > termio ) ;
}
2014-10-26 13:00:14 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_prev ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
term_prev ( term ) ;
}
static void
2016-10-05 13:00:22 -07:00
_cb_next ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
term_next ( term ) ;
}
static void
2016-10-05 13:00:22 -07:00
_cb_split_h ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc = term - > container ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2015-09-19 05:49:40 -07:00
tc - > split ( tc , tc , term , NULL , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_split_v ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc = term - > container ;
assert ( tc - > type = = TERM_CONTAINER_TYPE_SOLO ) ;
2015-09-19 05:49:40 -07:00
tc - > split ( tc , tc , term , NULL , EINA_FALSE ) ;
2014-10-26 13:00:14 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_title ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc = term - > container ;
const char * title = termio_title_get ( term - > termio ) ;
2014-12-09 05:32:47 -08:00
2015-03-22 10:17:16 -07:00
if ( title )
tc - > set_title ( tc , tc , title ) ;
2014-10-26 13:00:14 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_icon ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2016-02-02 14:15:50 -08:00
DBG ( " is focused? tc:%p " , term - > container ) ;
2019-06-17 13:12:59 -07:00
if ( term_is_focused ( term ) )
2015-03-22 07:11:10 -07:00
elm_win_icon_name_set ( term - > wn - > win , termio_icon_name_get ( term - > termio ) ) ;
2014-10-26 13:00:14 -07:00
}
2017-12-17 06:36:51 -08:00
static void
_cb_send_progress ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
{
Term * term = data ;
elm_progressbar_value_set ( term - > sendfile_progress_bar ,
termio_file_send_progress_get ( term - > termio ) ) ;
}
static void
_cb_send_end ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
{
Term * term = data ;
if ( ! term - > sendfile_progress ) return ;
_sendfile_request_hide ( term ) ;
_sendfile_progress_hide ( term ) ;
}
2014-10-26 13:00:14 -07:00
static Eina_Bool
_cb_cmd_del ( void * data )
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
wn - > cmdbox_del_timer = NULL ;
if ( wn - > cmdbox )
{
evas_object_del ( wn - > cmdbox ) ;
wn - > cmdbox = NULL ;
}
return EINA_FALSE ;
}
static void
2016-10-05 13:00:22 -07:00
_cb_cmd_activated ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Win * wn = data ;
char * cmd = NULL ;
Term * term ;
2015-03-22 10:17:16 -07:00
Term_Container * tc ;
2019-05-22 14:03:03 -07:00
elm_layout_signal_emit ( wn - > base , " cmdbox,hide " , " terminology " ) ;
2015-03-22 10:17:16 -07:00
tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
2014-10-26 13:00:14 -07:00
if ( wn - > cmdbox ) cmd = ( char * ) elm_entry_entry_get ( wn - > cmdbox ) ;
if ( cmd )
{
cmd = elm_entry_markup_to_utf8 ( cmd ) ;
if ( cmd )
{
2019-12-26 12:33:33 -08:00
if ( term )
termcmd_do ( term - > termio , term - > wn - > win , term - > bg , cmd ) ;
2014-10-26 13:00:14 -07:00
free ( cmd ) ;
}
}
2019-12-06 01:14:40 -08:00
elm_object_focus_set ( wn - > base , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
wn - > cmdbox_up = EINA_FALSE ;
if ( wn - > cmdbox_del_timer ) ecore_timer_del ( wn - > cmdbox_del_timer ) ;
wn - > cmdbox_del_timer = ecore_timer_add ( 5.0 , _cb_cmd_del , wn ) ;
}
static void
2015-03-22 10:17:16 -07:00
_cb_cmd_aborted ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
2019-05-22 14:03:03 -07:00
elm_layout_signal_emit ( wn - > base , " cmdbox,hide " , " terminology " ) ;
2019-12-06 01:14:40 -08:00
elm_object_focus_set ( wn - > base , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
wn - > cmdbox_up = EINA_FALSE ;
if ( wn - > cmdbox_del_timer ) ecore_timer_del ( wn - > cmdbox_del_timer ) ;
wn - > cmdbox_del_timer = ecore_timer_add ( 5.0 , _cb_cmd_del , wn ) ;
}
static void
2015-03-22 10:17:16 -07:00
_cb_cmd_changed ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Win * wn = data ;
char * cmd = NULL ;
Term * term ;
2015-03-22 10:17:16 -07:00
Term_Container * tc ;
tc = ( Term_Container * ) wn ;
term = tc - > focused_term_get ( tc ) ;
2014-10-26 13:00:14 -07:00
if ( ! term ) return ;
if ( wn - > cmdbox ) cmd = ( char * ) elm_entry_entry_get ( wn - > cmdbox ) ;
if ( cmd )
{
cmd = elm_entry_markup_to_utf8 ( cmd ) ;
if ( cmd )
{
2015-03-22 07:11:10 -07:00
termcmd_watch ( term - > termio , term - > wn - > win , term - > bg , cmd ) ;
2014-10-26 13:00:14 -07:00
free ( cmd ) ;
}
}
}
static void
2016-10-05 13:00:22 -07:00
_cb_cmd_hints_changed ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Win * wn = data ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
if ( wn - > cmdbox )
{
evas_object_show ( wn - > cmdbox ) ;
2019-05-22 14:03:03 -07:00
elm_layout_content_set ( wn - > base , " terminology.cmdbox " , wn - > cmdbox ) ;
2014-10-26 13:00:14 -07:00
}
}
static void
2015-03-22 10:17:16 -07:00
_cb_cmdbox ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
term - > wn - > cmdbox_up = EINA_TRUE ;
if ( ! term - > wn - > cmdbox )
{
Evas_Object * o ;
Win * wn = term - > wn ;
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
wn - > cmdbox = o = elm_entry_add ( wn - > win ) ;
elm_entry_single_line_set ( o , EINA_TRUE ) ;
elm_entry_scrollable_set ( o , EINA_FALSE ) ;
elm_scroller_policy_set ( o , ELM_SCROLLER_POLICY_OFF , ELM_SCROLLER_POLICY_OFF ) ;
elm_entry_input_panel_layout_set ( o , ELM_INPUT_PANEL_LAYOUT_TERMINAL ) ;
elm_entry_autocapital_type_set ( o , ELM_AUTOCAPITAL_TYPE_NONE ) ;
elm_entry_input_panel_enabled_set ( o , EINA_TRUE ) ;
elm_entry_input_panel_language_set ( o , ELM_INPUT_PANEL_LANG_ALPHABET ) ;
elm_entry_input_panel_return_key_type_set ( o , ELM_INPUT_PANEL_RETURN_KEY_TYPE_GO ) ;
elm_entry_prediction_allow_set ( o , EINA_FALSE ) ;
evas_object_show ( o ) ;
evas_object_smart_callback_add ( o , " activated " , _cb_cmd_activated , wn ) ;
evas_object_smart_callback_add ( o , " aborted " , _cb_cmd_aborted , wn ) ;
evas_object_smart_callback_add ( o , " changed,user " , _cb_cmd_changed , wn ) ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_CHANGED_SIZE_HINTS ,
_cb_cmd_hints_changed , wn ) ;
2019-05-22 14:03:03 -07:00
elm_layout_content_set ( wn - > base , " terminology.cmdbox " , o ) ;
2014-10-26 13:00:14 -07:00
}
2019-05-22 14:03:03 -07:00
elm_layout_signal_emit ( term - > wn - > base , " cmdbox,show " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
elm_entry_entry_set ( term - > wn - > cmdbox , " " ) ;
evas_object_show ( term - > wn - > cmdbox ) ;
2019-12-06 01:14:40 -08:00
elm_object_focus_set ( term - > wn - > cmdbox , EINA_TRUE ) ;
2014-10-26 13:00:14 -07:00
if ( term - > wn - > cmdbox_del_timer )
{
ecore_timer_del ( term - > wn - > cmdbox_del_timer ) ;
term - > wn - > cmdbox_del_timer = NULL ;
}
}
static void
2016-10-05 13:00:22 -07:00
_cb_media_del ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * _obj EINA_UNUSED ,
void * _event_info EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
Config * config = NULL ;
2015-03-22 10:17:16 -07:00
if ( term - > termio )
config = termio_config_get ( term - > termio ) ;
2014-10-26 13:00:14 -07:00
term - > media = NULL ;
if ( term - > bg )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,off " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
}
if ( ! config ) return ;
if ( config - > temporary )
eina_stringshare_replace ( & ( config - > background ) , NULL ) ;
}
static void
_term_media_update ( Term * term , const Config * config )
{
if ( ( config - > background ) & & ( config - > background [ 0 ] ) )
{
Evas_Object * o ;
Media_Type type ;
if ( term - > media )
{
evas_object_event_callback_del ( term - > media ,
EVAS_CALLBACK_DEL ,
_cb_media_del ) ;
evas_object_del ( term - > media ) ;
}
type = media_src_type_get ( config - > background ) ;
term - > media = o = media_add ( term - > wn - > win ,
config - > background , config ,
MEDIA_BG , type ) ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_DEL ,
_cb_media_del , term ) ;
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.background " , o ) ;
2014-10-26 13:00:14 -07:00
evas_object_show ( o ) ;
term - > mediatype = type ;
switch ( type )
{
case MEDIA_TYPE_IMG :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,image " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,image " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_SCALE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,scale " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,scale " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_EDJE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,edje " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,edje " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_MOV :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,movie " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,movie " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_UNKNOWN :
default :
break ;
}
}
else
{
if ( term - > media )
{
evas_object_event_callback_del ( term - > media ,
EVAS_CALLBACK_DEL ,
_cb_media_del ) ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,off " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,off " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
evas_object_del ( term - > media ) ;
term - > media = NULL ;
}
}
}
void
main_media_update ( const Config * config )
{
Win * wn ;
Term * term ;
Eina_List * l , * ll ;
EINA_LIST_FOREACH ( wins , l , wn )
{
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
if ( term - > config ! = config ) continue ;
if ( ! config ) continue ;
_term_media_update ( term , config ) ;
}
}
}
void
main_media_mute_update ( const Config * config )
{
Win * wn ;
Term * term ;
Eina_List * l , * ll ;
EINA_LIST_FOREACH ( wins , l , wn )
{
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
if ( term - > media ) media_mute_set ( term - > media , config - > mute ) ;
2015-03-22 07:11:10 -07:00
termio_media_mute_set ( term - > termio , config - > mute ) ;
2014-10-26 13:00:14 -07:00
}
}
}
void
main_media_visualize_update ( const Config * config )
{
Win * wn ;
Term * term ;
Eina_List * l , * ll ;
EINA_LIST_FOREACH ( wins , l , wn )
{
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
if ( term - > media ) media_visualize_set ( term - > media , config - > visualize ) ;
2015-03-22 07:11:10 -07:00
termio_media_visualize_set ( term - > termio , config - > visualize ) ;
2014-10-26 13:00:14 -07:00
}
}
}
void
main_config_sync ( const Config * config )
{
Win * wn ;
Term * term ;
Eina_List * l , * ll ;
Config * main_config = main_config_get ( ) ;
if ( config ! = main_config ) config_sync ( config , main_config ) ;
EINA_LIST_FOREACH ( wins , l , wn )
{
if ( wn - > config ! = config ) config_sync ( config , wn - > config ) ;
EINA_LIST_FOREACH ( wn - > terms , ll , term )
{
if ( term - > config ! = config )
{
Evas_Coord mw = 1 , mh = 1 , w , h , tsize_w = 0 , tsize_h = 0 ;
config_sync ( config , term - > config ) ;
2015-03-22 07:11:10 -07:00
evas_object_geometry_get ( term - > termio , NULL , NULL ,
2014-10-26 13:00:14 -07:00
& tsize_w , & tsize_h ) ;
2015-03-22 07:11:10 -07:00
evas_object_data_del ( term - > termio , " sizedone " ) ;
termio_config_update ( term - > termio ) ;
evas_object_size_hint_min_get ( term - > termio , & mw , & mh ) ;
2014-10-26 13:00:14 -07:00
if ( mw < 1 ) mw = 1 ;
if ( mh < 1 ) mh = 1 ;
w = tsize_w / mw ;
h = tsize_h / mh ;
2015-03-22 07:11:10 -07:00
evas_object_data_del ( term - > termio , " sizedone " ) ;
evas_object_size_hint_request_set ( term - > termio ,
2014-10-26 13:00:14 -07:00
w * mw , h * mh ) ;
}
}
}
}
static void
2015-03-22 10:17:16 -07:00
_term_free ( Term * term )
2014-10-26 13:00:14 -07:00
{
2020-02-25 11:54:24 -08:00
if ( _tab_drag & & _tab_drag - > term = = term )
{
_tab_drag_free ( ) ;
}
2020-02-25 14:43:16 -08:00
if ( _tab_drag & & _tab_drag - > term_over = = term )
{
_tab_drag - > term_over = NULL ;
2020-02-29 07:18:07 -08:00
_tab_drag - > split_direction = SPLIT_DIRECTION_NONE ;
2020-02-25 14:43:16 -08:00
}
2017-12-17 06:36:51 -08:00
if ( term - > sendfile_request )
{
evas_object_del ( term - > sendfile_request ) ;
term - > sendfile_request = NULL ;
}
if ( term - > sendfile_progress )
{
evas_object_del ( term - > sendfile_progress ) ;
term - > sendfile_progress = NULL ;
}
if ( term - > sendfile_request_hide_timer )
{
ecore_timer_del ( term - > sendfile_request_hide_timer ) ;
term - > sendfile_request_hide_timer = NULL ;
}
if ( term - > sendfile_progress_hide_timer )
{
ecore_timer_del ( term - > sendfile_progress_hide_timer ) ;
term - > sendfile_progress_hide_timer = NULL ;
}
2019-11-29 10:59:57 -08:00
eina_stringshare_del ( term - > sendfile_dir ) ;
term - > sendfile_dir = NULL ;
2019-10-10 14:40:32 -07:00
_popmedia_queue_free ( term ) ;
2014-10-26 13:00:14 -07:00
if ( term - > media )
{
evas_object_event_callback_del ( term - > media ,
EVAS_CALLBACK_DEL ,
_cb_media_del ) ;
evas_object_del ( term - > media ) ;
}
2015-03-22 10:17:16 -07:00
term - > media = NULL ;
if ( term - > popmedia ) evas_object_del ( term - > popmedia ) ;
2014-10-26 13:00:14 -07:00
if ( term - > miniview )
{
evas_object_del ( term - > miniview ) ;
term - > miniview = NULL ;
}
2015-03-22 10:17:16 -07:00
term - > popmedia = NULL ;
term - > popmedia_deleted = EINA_FALSE ;
2020-01-19 07:51:17 -08:00
_term_tabregion_free ( term ) ;
if ( term - > tabbar . l . box )
{
elm_box_unpack_all ( term - > tabbar . l . box ) ;
evas_object_del ( term - > tabbar . l . box ) ;
term - > tabbar . l . box = NULL ;
}
if ( term - > tabbar . r . box )
{
elm_box_unpack_all ( term - > tabbar . r . box ) ;
evas_object_del ( term - > tabbar . r . box ) ;
term - > tabbar . r . box = NULL ;
}
evas_object_del ( term - > tab_inactive ) ;
term - > tab_inactive = NULL ;
term - > tab_item = NULL ;
2015-03-22 07:11:10 -07:00
evas_object_del ( term - > termio ) ;
term - > termio = NULL ;
2015-06-11 14:55:35 -07:00
2019-12-26 04:17:52 -08:00
evas_object_del ( term - > core ) ;
term - > core = NULL ;
2014-10-26 13:00:14 -07:00
evas_object_del ( term - > bg ) ;
term - > bg = NULL ;
2019-12-26 12:33:33 -08:00
term - > bg_edj = NULL ;
2016-08-08 03:51:27 -07:00
2019-10-26 09:18:03 -07:00
if ( term - > tab_spacer )
2015-03-22 10:17:16 -07:00
{
2019-10-26 09:18:03 -07:00
evas_object_del ( term - > tab_spacer ) ;
term - > tab_spacer = NULL ;
2015-03-22 10:17:16 -07:00
}
2014-10-26 13:00:14 -07:00
free ( term ) ;
}
static void
2019-10-26 09:18:03 -07:00
_cb_tab_prev ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
_cb_prev ( data , NULL , NULL ) ;
}
static void
2019-10-26 09:18:03 -07:00
_cb_tab_next ( void * data ,
2016-10-05 13:00:22 -07:00
Evas_Object * _obj EINA_UNUSED ,
const char * _sig EINA_UNUSED ,
const char * _src EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
_cb_next ( data , NULL , NULL ) ;
}
2017-11-11 11:12:56 -08:00
2014-10-26 13:00:14 -07:00
static void
2015-03-22 10:17:16 -07:00
_term_bg_config ( Term * term )
2014-10-26 13:00:14 -07:00
{
2020-04-06 12:58:21 -07:00
_term_trans ( term ) ;
2019-12-26 12:33:33 -08:00
background_set_shine ( term - > config , term - > bg_edj ) ;
2014-10-26 13:00:14 -07:00
2019-12-26 12:33:33 -08:00
termio_theme_set ( term - > termio , term - > bg_edj ) ;
elm_layout_signal_callback_add ( term - > bg , " popmedia,done " , " terminology " ,
2015-03-22 10:17:16 -07:00
_cb_popmedia_done , term ) ;
2019-12-26 12:33:33 -08:00
elm_layout_signal_callback_add ( term - > bg , " tab,go " , " terminology " ,
_cb_tab_go , term ) ;
elm_layout_signal_callback_add ( term - > bg , " tab,new " , " terminology " ,
_cb_tab_new , term ) ;
elm_layout_signal_callback_add ( term - > bg , " tab,prev " , " terminology " ,
_cb_tab_prev , term ) ;
elm_layout_signal_callback_add ( term - > bg , " tab,next " , " terminology " ,
_cb_tab_next , term ) ;
elm_layout_signal_callback_add ( term - > bg , " tab,close " , " terminology " ,
_cb_tab_close , term ) ;
elm_layout_signal_callback_add ( term - > bg , " tab,title " , " terminology " ,
2017-02-17 12:47:10 -08:00
_cb_tab_title , term ) ;
2020-02-07 11:09:27 -08:00
elm_layout_signal_callback_add ( term - > bg , " tab,hdrag " , " * " ,
2020-02-09 04:09:05 -08:00
_term_on_horizontal_drag , term ) ;
2020-02-07 11:09:27 -08:00
elm_layout_signal_callback_add ( term - > bg , " tab,drag,move " , " * " ,
_tabs_drag_mouse_move , term ) ;
2020-01-19 07:51:17 -08:00
elm_layout_signal_callback_add ( term - > bg , " tab,drag,stop " , " * " ,
2020-02-09 04:09:05 -08:00
_term_on_drag_stop , term ) ;
2020-02-07 11:09:27 -08:00
elm_layout_signal_callback_add ( term - > bg , " tab,mouse,down " , " * " ,
_tabs_mouse_down , term ) ;
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.content " , term - > termio ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.content " , term - > core ) ;
elm_layout_content_set ( term - > bg , " terminology.miniview " , term - > miniview ) ;
2014-10-26 13:00:14 -07:00
if ( term - > popmedia )
{
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.popmedia " , term - > popmedia ) ;
2014-10-26 13:00:14 -07:00
switch ( term - > poptype )
{
case MEDIA_TYPE_IMG :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,image " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_SCALE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,scale " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_EDJE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,edje " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_MOV :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " popmedia,movie " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
default :
break ;
}
}
if ( term - > media )
{
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.background " , term - > media ) ;
2014-10-26 13:00:14 -07:00
switch ( term - > mediatype )
{
case MEDIA_TYPE_IMG :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,image " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,image " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_SCALE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,scale " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,scale " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_EDJE :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,edje " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,edje " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_MOV :
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " media,movie " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " media,movie " , " terminology " ) ;
2014-10-26 13:00:14 -07:00
break ;
case MEDIA_TYPE_UNKNOWN :
default :
break ;
}
}
2016-02-02 14:15:50 -08:00
DBG ( " is focused? tc:%p " , term - > container ) ;
2019-06-17 13:12:59 -07:00
if ( term_is_focused ( term ) & & ( _win_is_focused ( term - > wn ) ) )
2014-10-26 13:00:14 -07:00
{
2017-03-13 09:02:52 -07:00
if ( term - > config - > disable_focus_visuals )
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focused,set " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focused,set " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
else
{
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " focus,in " , " terminology " ) ;
2019-12-26 04:17:52 -08:00
elm_layout_signal_emit ( term - > core , " focus,in " , " terminology " ) ;
2017-03-13 09:02:52 -07:00
}
2014-10-26 13:00:14 -07:00
}
if ( term - > miniview_shown )
2019-12-26 12:33:33 -08:00
elm_layout_signal_emit ( term - > bg , " miniview,on " , " terminology " ) ;
2015-04-30 10:33:00 -07:00
_term_media_update ( term , term - > config ) ;
2014-10-26 13:00:14 -07:00
}
2014-12-09 05:32:47 -08:00
static void
2016-10-05 13:00:22 -07:00
_cb_tabregion_change ( void * data ,
Evas * _e EINA_UNUSED ,
Evas_Object * obj ,
void * _info EINA_UNUSED )
2014-12-09 05:32:47 -08:00
{
Term * term = data ;
Evas_Coord w , h ;
evas_object_geometry_get ( obj , NULL , NULL , & w , & h ) ;
evas_object_size_hint_min_set ( term - > tab_region_base , w , h ) ;
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.tabregion " ,
2019-05-22 14:03:03 -07:00
term - > tab_region_base ) ;
2014-12-09 05:32:47 -08:00
}
static void
_term_tabregion_setup ( Term * term )
{
Evas_Object * o ;
if ( term - > tab_region_bg ) return ;
term - > tab_region_bg = o = evas_object_rectangle_add ( evas_object_evas_get ( term - > bg ) ) ;
evas_object_color_set ( o , 0 , 0 , 0 , 0 ) ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_RESIZE , _cb_tabregion_change , term ) ;
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.tabregion " , o ) ;
2014-12-09 05:32:47 -08:00
term - > tab_region_base = o = evas_object_rectangle_add ( evas_object_evas_get ( term - > bg ) ) ;
evas_object_color_set ( o , 0 , 0 , 0 , 0 ) ;
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.tabregion " , o ) ;
2014-12-09 05:32:47 -08:00
}
2016-08-08 03:51:27 -07:00
static void
_term_tabregion_free ( Term * term )
{
evas_object_del ( term - > tab_region_bg ) ;
term - > tab_region_bg = NULL ;
evas_object_del ( term - > tab_region_base ) ;
term - > tab_region_base = NULL ;
}
2014-10-26 13:00:14 -07:00
Eina_Bool
main_term_popup_exists ( const Term * term )
{
return term - > popmedia | | term - > popmedia_queue ;
}
Win *
2017-07-06 11:55:02 -07:00
term_win_get ( const Term * term )
2014-10-26 13:00:14 -07:00
{
return term - > wn ;
}
Evas_Object *
2017-07-06 11:55:02 -07:00
term_termio_get ( const Term * term )
2014-10-26 13:00:14 -07:00
{
2015-03-22 07:11:10 -07:00
return term - > termio ;
2014-10-26 13:00:14 -07:00
}
Evas_Object *
2017-07-06 11:55:02 -07:00
term_miniview_get ( const Term * term )
2014-10-26 13:00:14 -07:00
{
if ( term )
return term - > miniview ;
return NULL ;
}
2019-05-26 13:52:57 -07:00
Evas_Object *
term_bg_get ( const Term * term )
{
if ( term )
2019-12-26 12:33:33 -08:00
return term - > bg_edj ;
2019-05-26 13:52:57 -07:00
return NULL ;
}
2014-10-26 13:00:14 -07:00
static void
2016-10-05 13:00:22 -07:00
_cb_bell ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2015-03-22 10:17:16 -07:00
Term_Container * tc ;
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
tc = term - > container ;
2014-12-02 15:42:36 -08:00
2015-03-22 10:17:16 -07:00
tc - > bell ( tc , tc ) ;
2014-10-26 13:00:14 -07:00
}
static void
2015-03-22 10:17:16 -07:00
_cb_options_done ( void * data )
2014-10-26 13:00:14 -07:00
{
2018-01-30 14:31:26 -08:00
Term * orig_term = data ;
Win * wn = orig_term - > wn ;
2018-03-10 10:40:13 -08:00
_on_popover_done ( wn ) ;
2018-01-30 14:31:26 -08:00
term_unref ( orig_term ) ;
2014-10-26 13:00:14 -07:00
}
static void
2016-10-05 13:00:22 -07:00
_cb_options ( void * data ,
Evas_Object * _obj EINA_UNUSED ,
void * _event EINA_UNUSED )
2014-10-26 13:00:14 -07:00
{
Term * term = data ;
2018-01-30 14:31:26 -08:00
Term_Container * tc = term - > container ;
2018-03-10 10:40:13 -08:00
term - > wn - > on_popover + + ;
2018-01-30 14:31:26 -08:00
term_ref ( term ) ;
tc - > unfocus ( tc , NULL ) ;
2014-10-26 13:00:14 -07:00
2019-12-26 12:33:33 -08:00
controls_show ( term - > wn - > win , term - > wn - > base , term - > bg_edj , term - > termio ,
2018-01-30 14:31:26 -08:00
_cb_options_done , term ) ;
2014-10-26 13:00:14 -07:00
}
2015-02-15 11:32:16 -08:00
void
term_ref ( Term * term )
{
term - > refcnt + + ;
}
2015-03-22 10:17:16 -07:00
void
term_unref ( Term * term )
2015-02-15 11:32:16 -08:00
{
EINA_SAFETY_ON_NULL_RETURN ( term ) ;
term - > refcnt - - ;
if ( term - > refcnt < = 0 )
{
2015-03-22 10:17:16 -07:00
_term_free ( term ) ;
2015-02-15 11:32:16 -08:00
}
}
2014-10-26 13:00:14 -07:00
2015-03-22 10:17:16 -07:00
2014-10-26 13:00:14 -07:00
Term *
term_new ( Win * wn , Config * config , const char * cmd ,
Eina_Bool login_shell , const char * cd ,
2017-08-28 12:36:48 -07:00
int size_w , int size_h , Eina_Bool hold ,
const char * title )
2014-10-26 13:00:14 -07:00
{
Term * term ;
Evas_Object * o ;
2015-02-15 11:32:16 -08:00
2014-10-26 13:00:14 -07:00
term = calloc ( 1 , sizeof ( Term ) ) ;
if ( ! term ) return NULL ;
2015-02-15 11:32:16 -08:00
term_ref ( term ) ;
2014-10-26 13:00:14 -07:00
if ( ! config ) abort ( ) ;
termpty_init ( ) ;
miniview_init ( ) ;
gravatar_init ( ) ;
term - > wn = wn ;
term - > hold = hold ;
term - > config = config ;
2015-03-22 10:17:16 -07:00
2019-12-26 04:17:52 -08:00
term - > core = o = elm_layout_add ( wn - > win ) ;
2019-05-22 14:03:03 -07:00
theme_apply_elm ( o , term - > config , " terminology/core " ) ;
2015-03-22 10:17:16 -07:00
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
2014-10-26 13:00:14 -07:00
2015-03-21 23:13:34 -07:00
theme_auto_reload_enable ( o ) ;
2015-03-22 10:17:16 -07:00
evas_object_data_set ( o , " theme_reload_func " , _term_bg_config ) ;
2014-10-26 13:00:14 -07:00
evas_object_data_set ( o , " theme_reload_func_data " , term ) ;
evas_object_show ( o ) ;
2019-12-26 12:33:33 -08:00
term - > bg = o = elm_layout_add ( wn - > win ) ;
2020-09-01 10:08:52 -07:00
term - > bg_edj = elm_layout_edje_get ( o ) ;
2014-10-26 13:00:14 -07:00
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
2020-08-29 09:38:11 -07:00
if ( ! theme_apply_elm ( o , config , " terminology/background " ) )
2014-10-26 13:00:14 -07:00
{
2017-11-11 15:14:00 -08:00
CRITICAL ( _ ( " Couldn't find terminology theme! Forgot 'ninja install'? " ) ) ;
2014-10-26 13:00:14 -07:00
evas_object_del ( term - > bg ) ;
free ( term ) ;
return NULL ;
}
theme_auto_reload_enable ( o ) ;
2015-03-22 10:17:16 -07:00
evas_object_data_set ( o , " theme_reload_func " , _term_bg_config ) ;
2014-10-26 13:00:14 -07:00
evas_object_data_set ( o , " theme_reload_func_data " , term ) ;
evas_object_show ( o ) ;
2014-12-09 05:32:47 -08:00
_term_tabregion_setup ( term ) ;
2014-10-26 13:00:14 -07:00
2015-08-02 13:44:20 -07:00
if ( term - > config - > mv_always_show )
term - > miniview_shown = EINA_TRUE ;
2020-04-06 12:58:21 -07:00
_term_trans ( term ) ;
2019-12-26 12:33:33 -08:00
background_set_shine ( term - > config , term - > bg_edj ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 07:11:10 -07:00
term - > termio = o = termio_add ( wn - > win , config , cmd , login_shell , cd ,
2017-08-28 12:36:48 -07:00
size_w , size_h , term , title ) ;
2015-03-22 10:17:16 -07:00
evas_object_data_set ( o , " term " , term ) ;
2019-12-26 12:33:33 -08:00
colors_term_init ( termio_textgrid_get ( term - > termio ) , term - > bg_edj , config ) ;
2014-10-26 13:00:14 -07:00
2019-12-26 12:33:33 -08:00
termio_theme_set ( o , term - > bg_edj ) ;
2014-10-26 13:00:14 -07:00
2015-03-22 07:11:10 -07:00
term - > miniview = o = miniview_add ( wn - > win , term - > termio ) ;
2014-10-26 13:00:14 -07:00
evas_object_size_hint_weight_set ( o , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
2015-03-22 07:11:10 -07:00
o = term - > termio ;
2014-10-26 13:00:14 -07:00
evas_object_size_hint_weight_set ( o , 0 , EVAS_HINT_EXPAND ) ;
evas_object_size_hint_fill_set ( o , 0 , EVAS_HINT_FILL ) ;
evas_object_event_callback_add ( o , EVAS_CALLBACK_CHANGED_SIZE_HINTS ,
_cb_size_hint , term ) ;
2019-12-26 04:17:52 -08:00
elm_layout_content_set ( term - > core , " terminology.content " , o ) ;
2020-04-10 15:31:04 -07:00
2019-12-26 12:33:33 -08:00
elm_layout_content_set ( term - > bg , " terminology.content " , term - > core ) ;
elm_layout_content_set ( term - > bg , " terminology.miniview " , term - > miniview ) ;
2020-04-10 15:31:04 -07:00
2014-10-26 13:00:14 -07:00
evas_object_smart_callback_add ( o , " options " , _cb_options , term ) ;
evas_object_smart_callback_add ( o , " bell " , _cb_bell , term ) ;
evas_object_smart_callback_add ( o , " popup " , _cb_popup , term ) ;
evas_object_smart_callback_add ( o , " popup,queue " , _cb_popup_queue , term ) ;
evas_object_smart_callback_add ( o , " cmdbox " , _cb_cmdbox , term ) ;
evas_object_smart_callback_add ( o , " command " , _cb_command , term ) ;
evas_object_smart_callback_add ( o , " prev " , _cb_prev , term ) ;
evas_object_smart_callback_add ( o , " next " , _cb_next , term ) ;
evas_object_smart_callback_add ( o , " new " , _cb_new , term ) ;
2016-05-22 11:45:13 -07:00
evas_object_smart_callback_add ( o , " close " , _cb_close , term ) ;
2014-10-26 13:00:14 -07:00
evas_object_smart_callback_add ( o , " select " , _cb_select , term ) ;
evas_object_smart_callback_add ( o , " split,h " , _cb_split_h , term ) ;
evas_object_smart_callback_add ( o , " split,v " , _cb_split_v , term ) ;
evas_object_smart_callback_add ( o , " title,change " , _cb_title , term ) ;
evas_object_smart_callback_add ( o , " icon,change " , _cb_icon , term ) ;
2017-12-17 06:36:51 -08:00
evas_object_smart_callback_add ( o , " send,progress " , _cb_send_progress , term ) ;
evas_object_smart_callback_add ( o , " send,end " , _cb_send_end , term ) ;
2014-10-26 13:00:14 -07:00
evas_object_show ( o ) ;
wn - > terms = eina_list_append ( wn - > terms , term ) ;
2015-03-22 10:17:16 -07:00
_term_bg_config ( term ) ;
2014-12-02 15:42:27 -08:00
2015-03-22 10:17:16 -07:00
return term ;
2014-12-02 15:42:27 -08:00
}
/* }}} */
2015-08-06 12:26:43 -07:00
static Eina_Bool
_font_size_set ( Term * term , void * data )
{
int fontsize = ( intptr_t ) data ;
termio_font_size_set ( term - > termio , fontsize ) ;
return ECORE_CALLBACK_PASS_ON ;
}
void
win_font_size_set ( Win * wn , int new_size )
{
for_each_term_do ( wn , & _font_size_set , ( void * ) ( intptr_t ) new_size ) ;
}
2017-07-14 13:10:54 -07:00
static Eina_Bool
_font_update ( Term * term , void * _data EINA_UNUSED )
{
termio_font_update ( term - > termio ) ;
return ECORE_CALLBACK_PASS_ON ;
}
void
win_font_update ( Term * term )
{
Win * wn = term - > wn ;
for_each_term_do ( wn , & _font_update , NULL ) ;
}
2014-12-02 15:42:42 -08:00
void
windows_free ( void )
{
2019-10-14 13:15:07 -07:00
Eina_List * l , * l_next ;
2014-12-02 15:42:42 -08:00
Win * wn ;
2019-10-14 13:15:07 -07:00
EINA_LIST_FOREACH_SAFE ( wins , l , l_next , wn )
2014-12-02 15:42:42 -08:00
{
win_free ( wn ) ;
}
2015-06-02 14:11:16 -07:00
/* TODO: ugly */
if ( _win_log_dom < 0 ) return ;
eina_log_domain_unregister ( _win_log_dom ) ;
_win_log_dom = - 1 ;
2014-12-02 15:42:42 -08:00
}
2014-12-09 05:32:47 -08:00
void
windows_update ( void )
{
Eina_List * l ;
Win * wn ;
2015-03-22 10:17:16 -07:00
EINA_LIST_FOREACH ( wins , l , wn )
{
Term_Container * tc = ( Term_Container * ) wn ;
tc - > update ( tc ) ;
}
2014-12-09 05:32:47 -08:00
}
2015-08-06 12:26:43 -07:00
Eina_Bool
for_each_term_do ( Win * wn , For_Each_Term cb , void * data )
{
Eina_List * l ;
Term * term ;
Eina_Bool res = ECORE_CALLBACK_DONE ;
EINA_LIST_FOREACH ( wn - > terms , l , term )
{
res = cb ( term , data ) ;
if ( res = = ECORE_CALLBACK_CANCEL )
return res ;
}
return res ;
}