From 230c484f3f3eda8b20f365af31ebc6984359b046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Fri, 6 Sep 2013 15:39:37 -0300 Subject: [PATCH] Implementation of elm_app_server This is disabled by default, and enabled in settings. Also there a option to automatic restore opened terminals. --- configure.ac | 3 + m4/efl_beta.m4 | 5 + m4/efl_eo.m4 | 6 + src/bin/Makefile.am | 4 +- src/bin/app_server.c | 408 +++++++++++++++++++++++++++++++++++++ src/bin/app_server.h | 8 + src/bin/app_server_eet.c | 255 +++++++++++++++++++++++ src/bin/app_server_eet.h | 41 ++++ src/bin/config.c | 11 + src/bin/config.h | 2 + src/bin/main.c | 11 +- src/bin/options_behavior.c | 72 +++++++ src/bin/win.c | 5 + 13 files changed, 829 insertions(+), 2 deletions(-) create mode 100644 m4/efl_beta.m4 create mode 100644 m4/efl_eo.m4 create mode 100644 src/bin/app_server.c create mode 100644 src/bin/app_server.h create mode 100644 src/bin/app_server_eet.c create mode 100644 src/bin/app_server_eet.h diff --git a/configure.ac b/configure.ac index cc2c80b3..13b259a0 100644 --- a/configure.ac +++ b/configure.ac @@ -36,6 +36,9 @@ requirements="\ ethumb_client >= 1.7.0 \ " +EFL_ENABLE_EO_API_SUPPORT +EFL_ENABLE_BETA_API_SUPPORT + PKG_CHECK_MODULES([TERMINOLOGY], [${requirements}]) PKG_CHECK_MODULES([ELDBUS], diff --git a/m4/efl_beta.m4 b/m4/efl_beta.m4 new file mode 100644 index 00000000..c8047299 --- /dev/null +++ b/m4/efl_beta.m4 @@ -0,0 +1,5 @@ +dnl use: EFL_ENABLE_BETA_API_SUPPORT +AC_DEFUN([EFL_ENABLE_BETA_API_SUPPORT], +[ + AC_DEFINE([EFL_BETA_API_SUPPORT], [1], [Enable access to unstable EFL API that are still in beta]) +]) diff --git a/m4/efl_eo.m4 b/m4/efl_eo.m4 new file mode 100644 index 00000000..864baf5f --- /dev/null +++ b/m4/efl_eo.m4 @@ -0,0 +1,6 @@ +dnl use: EFL_ENABLE_EO_API_SUPPORT +AC_DEFUN([EFL_ENABLE_EO_API_SUPPORT], +[ + AC_DEFINE([EFL_EO_API_SUPPORT], [1], [Enable access to unstable EFL Eo API]) +]) + diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index e95dae79..b18e4402 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -42,7 +42,9 @@ utf8.c utf8.h \ win.c win.h \ utils.c utils.h \ dbus.c dbus.h \ -extns.h +extns.h \ +app_server.c app_server.h \ +app_server_eet.c app_server_eet.h tybg_SOURCES = \ tybg.c diff --git a/src/bin/app_server.c b/src/bin/app_server.c new file mode 100644 index 00000000..d96b08ba --- /dev/null +++ b/src/bin/app_server.c @@ -0,0 +1,408 @@ +#include "private.h" + +#include + +#include "main.h" +#include "termio.h" +#include "app_server_eet.h" + +static Elm_App_Server *server = NULL; +static Eina_Bool _ignore_term_add = EINA_FALSE; +static Terminology_Item *views_eet = NULL; + +static void +_user_config_file_path_build(char *dir, unsigned int size, const char *id) +{ + const char *home = getenv("HOME"); + + if (!home) + home = ""; + + snprintf(dir, size, "%s/.terminology/", home); + if (!ecore_file_is_dir(dir)) + ecore_file_mkpath(dir); + + snprintf(dir, size, "%s/.terminology/%s", home, id); +} + +void +app_server_term_del(Evas_Object *term) +{ + Elm_App_Server_View *view; + const char *id; + + view = evas_object_data_del(term, "app_view"); + if (!view) + return; + + eo_do(view, elm_app_server_view_id_get(&id)); + terminology_item_term_entries_del(views_eet, id); + + eo_del(view); +} + +static Eina_Bool +_view_closed_cb(void *data, Eo *view, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Term *term = data; + const char *id; + char eet_dir[PATH_MAX]; + + if (term) + { + Evas_Object *term_object; + + term_object = main_term_evas_object_get(term); + evas_object_data_del(term_object, "app_view"); + main_close(main_win_evas_object_get(main_term_win_get(term)), + term_object); + } + + eo_do(view, elm_app_server_view_id_get(&id)); + terminology_item_term_entries_del(views_eet, id); + + eo_del(view); + return EINA_TRUE; +} + +static void +_term_title_changed_cb(void *data, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + const char *title = termio_title_get(obj); + eo_do(data, elm_app_server_view_title_set(title)); +} + +static void +_term_icon_changed_cb(void *data, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + const char *icon = termio_icon_name_get(obj); + eo_do(data, elm_app_server_view_icon_set(icon)); +} + +static Eina_Bool +_view_save_cb(void *data, Eo *view, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Term *term = data; + char dir[PATH_MAX]; + Evas_Object *term_object; + const char *id; + Term_Item *term_eet; + + term_object = main_term_evas_object_get(data); + + /* + * if we call elm_app_server_save() in some case that the terminology + * will continue run, this data_del will lead to issues. + */ + evas_object_data_del(term_object, "app_view"); + + termio_cwd_get(term_object, dir, sizeof(dir)); + eo_do(view, elm_app_server_view_id_get(&id)); + + term_eet = terminology_item_term_entries_get(views_eet, id); + if (term_eet) + { + term_item_dir_set(term_eet, dir); + return EINA_TRUE; + } + + term_eet = term_item_new(id, dir); + terminology_item_term_entries_add(views_eet, id, term_eet); + + return EINA_TRUE; +} + +static Eina_Bool +_view_resumed_cb(void *data, Eo *view, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Term *term = data; + Win *wn; + Eina_List **wins; + const char *title, *id; + Evas_Object *term_object; + const char *dir = NULL; + Term_Item *term_eet; + + if (term) + { + main_term_focus(term); + return EINA_TRUE; + } + + eo_do(server, eo_base_data_get("wins", (void **)&wins)); + wn = eina_list_data_get(*wins); + if (!wn) + { + ERR("There is no window open"); + return EINA_TRUE; + } + + term = eina_list_data_get(main_win_terms_get(wn)); + + eo_do(view, elm_app_server_view_id_get(&id)); + term_eet = terminology_item_term_entries_get(views_eet, id); + if (term_eet) + { + dir = term_item_dir_get(term_eet); + //not valid data saved + if (!dir || dir[0] != '/') + { + terminology_item_term_entries_del(views_eet, id); + dir = NULL; + } + } + + _ignore_term_add = EINA_TRUE; + if (dir) + main_new_with_dir(main_win_evas_object_get(wn), + main_term_evas_object_get(term), dir); + else + main_new(main_win_evas_object_get(wn), main_term_evas_object_get(term)); + _ignore_term_add = EINA_FALSE; + + //just add term + term = eina_list_last_data_get(main_win_terms_get(wn)); + term_object = main_term_evas_object_get(term); + title = termio_title_get(term_object); + + evas_object_data_set(term_object, "app_view", view); + + eo_do(view, elm_app_server_view_title_set(title), + elm_app_server_view_window_set( + main_win_evas_object_get(main_term_win_get(term))), + eo_event_callback_del(ELM_APP_SERVER_VIEW_EV_CLOSED, _view_closed_cb, + NULL), + eo_event_callback_del(ELM_APP_SERVER_VIEW_EV_RESUMED, _view_resumed_cb, + NULL), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED, _view_closed_cb, + term), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED, _view_resumed_cb, + term), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_SAVE, _view_save_cb, + term)); + + evas_object_smart_callback_add(term_object, "title,change", + _term_title_changed_cb, view); + evas_object_smart_callback_add(term_object, "icon,change", + _term_icon_changed_cb, term); + + return EINA_TRUE; +} + +static Eina_Bool +_server_terminate_cb(void *data, Eo *obj, + const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Eina_List **wins = data, *l, *l2; + Win *wn; + + EINA_LIST_FOREACH_SAFE(*wins, l, l2, wn) + evas_object_del(main_win_evas_object_get(wn)); + + return EINA_TRUE; +} + +void +app_server_shutdown(void) +{ + char lock_file[PATH_MAX]; + + if (!server) + return; + + _user_config_file_path_build(lock_file, sizeof(lock_file), ".lock"); + ecore_file_remove(lock_file); + + eo_do(server, elm_app_server_save()); + + if (views_eet) + { + char eet_dir[PATH_MAX]; + + _user_config_file_path_build(eet_dir, sizeof(eet_dir), "terms.eet"); + terminology_item_save(views_eet, eet_dir); + + terminology_item_free(views_eet); + } + app_server_eet_shutdown(); + + eo_unref(server); + server = NULL; +} + +void +_app_server_win_del_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + Eina_List **wins; + + if (!server) + return; + + eo_do(server, eo_base_data_get("wins", (void **)&wins)); + + if (eina_list_count(*wins) > 1) + return; + + /* + * this way the terms of view are already alive + * and we can get pwd and backlog + */ + app_server_shutdown(); +} + +static Elm_App_Server_View * +_app_server_term_add(Term *term) +{ + Elm_App_Server_View *view; + const char *title; + Evas_Object *term_object; + + if (_ignore_term_add) + return NULL; + + view = eo_add_custom(ELM_APP_SERVER_VIEW_CLASS, server, + elm_app_server_view_constructor(NULL)); + + term_object = main_term_evas_object_get(term); + + title = termio_title_get(term_object); + + eo_do(view, elm_app_server_view_title_set(title), + elm_app_server_view_window_set( + main_win_evas_object_get(main_term_win_get(term))), + elm_app_server_view_resume(), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED, + _view_closed_cb, term), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED, + _view_resumed_cb, term), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_SAVE, + _view_save_cb, term)); + + evas_object_smart_callback_add(term_object, "title,change", + _term_title_changed_cb, view); + evas_object_smart_callback_add(term_object, "icon,change", + _term_icon_changed_cb, term); + evas_object_data_set(term_object, "app_view", view); + + return view; +} + +void +app_server_term_add(Term *term) +{ + Elm_App_Server_View *view; + + if (!server) + return; + + view = _app_server_term_add(term); + if (!view) + return; + eo_do(server, elm_app_server_view_add(view)); +} + +static Elm_App_Server_View * +_app_server_create_view_cb(Elm_App_Server *server, const Eina_Value *args EINA_UNUSED, + Eina_Stringshare **error_name, + Eina_Stringshare **error_message EINA_UNUSED) +{ + Win *wn; + Term *term; + Elm_App_Server_View *view; + Eina_List **wins; + + eo_do(server, eo_base_data_get("wins", (void **)&wins)); + wn = eina_list_data_get(*wins); + if (!wn) + { + ERR("There is no window open"); + *error_name = eina_stringshare_add("There is no window open"); + return NULL; + } + term = eina_list_data_get(main_win_terms_get(wn)); + + _ignore_term_add = EINA_TRUE; + main_new(main_win_evas_object_get(wn), main_term_evas_object_get(term)); + _ignore_term_add = EINA_FALSE; + + //Term just added by main_new() + term = eina_list_last_data_get(main_win_terms_get(wn)); + + return _app_server_term_add(term); +} + +static Eina_Bool +_restore_view_cb(void *data) +{ + Elm_App_Server_View *view = data; + eo_do(view, elm_app_server_view_resume()); + return EINA_FALSE; +} + +void +app_server_init(Eina_List **wins, Eina_Bool restore_views) +{ + Win *wn; + Eina_Iterator *views; + Elm_App_Server_View *view; + const char *title; + char lock_file[PATH_MAX], eet_dir[PATH_MAX]; + FILE *f; + + wn = eina_list_data_get(*wins); + if (!wn) + return; + + //we only can have one instance of Terminology running app_server + _user_config_file_path_build(lock_file, sizeof(lock_file), ".lock"); + if (ecore_file_exists(lock_file)) + return; + + //create lock file + f = fopen(lock_file, "w"); + if (!f) + return; + fprintf(f, "locked"); + fclose(f); + + app_server_eet_init(); + _user_config_file_path_build(eet_dir, sizeof(eet_dir), "terms.eet"); + views_eet = terminology_item_load(eet_dir); + if (!views_eet) + views_eet = terminology_item_new(1); + + title = elm_win_title_get(main_win_evas_object_get(wn)); + + + server = eo_add_custom(ELM_APP_SERVER_CLASS, NULL, + elm_app_server_constructor( + "org.enlightenment.Terminology", + _app_server_create_view_cb)); + + eo_do(server, elm_app_server_title_set(title), + eo_base_data_set("wins", wins, NULL), + elm_app_server_views_get(&views), + eo_event_callback_add(ELM_APP_SERVER_EV_TERMINATE, + _server_terminate_cb, wins)); + //views saved + EINA_ITERATOR_FOREACH(views, view) + { + if (restore_views) + ecore_idler_add(_restore_view_cb, view); + eo_do(view, + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED, + _view_closed_cb, NULL), + eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED, + _view_resumed_cb, NULL)); + } + eina_iterator_free(views); +} diff --git a/src/bin/app_server.h b/src/bin/app_server.h new file mode 100644 index 00000000..44be376f --- /dev/null +++ b/src/bin/app_server.h @@ -0,0 +1,8 @@ +void app_server_init(Eina_List **wins); +void app_server_shutdown(void); + +void app_server_term_add(Term *term); + +void app_server_term_del(Evas_Object *term); + +void _app_server_win_del_request_cb(void *data, Evas_Object *obj, void *event_info); diff --git a/src/bin/app_server_eet.c b/src/bin/app_server_eet.c new file mode 100644 index 00000000..03397416 --- /dev/null +++ b/src/bin/app_server_eet.c @@ -0,0 +1,255 @@ +/* This file has been automatically generated by geneet.py */ +/* DO NOT MODIFY */ + +#include +#include +#include +#include +#include + +#include "app_server_eet.h" + +struct _Term_Item { + const char * id; + const char * dir; +}; + +struct _Terminology_Item { + unsigned int version; + Eina_Hash * term_entries; + const char *__eet_filename; +}; + +static const char TERM_ITEM_ENTRY[] = "term_item"; +static const char TERMINOLOGY_ITEM_ENTRY[] = "terminology_item"; + +static Eet_Data_Descriptor *_term_item_descriptor = NULL; +static Eet_Data_Descriptor *_terminology_item_descriptor = NULL; + +static inline void +_term_item_init(void) +{ + Eet_Data_Descriptor_Class eddc; + + if (_term_item_descriptor) return; + + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Term_Item); + _term_item_descriptor = eet_data_descriptor_stream_new(&eddc); + + EET_DATA_DESCRIPTOR_ADD_BASIC(_term_item_descriptor, Term_Item, "id", id, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_term_item_descriptor, Term_Item, "dir", dir, EET_T_STRING); +} + +static inline void +_term_item_shutdown(void) +{ + if (!_term_item_descriptor) return; + eet_data_descriptor_free(_term_item_descriptor); + _term_item_descriptor = NULL; +} + +Term_Item * +term_item_new(const char * id, const char * dir) +{ + Term_Item *term_item = calloc(1, sizeof(Term_Item)); + + if (!term_item) + { + fprintf(stderr, "ERROR: could not calloc Term_Item\n"); + return NULL; + } + + term_item->id = eina_stringshare_add(id ? id : ""); + term_item->dir = eina_stringshare_add(dir ? dir : "/"); + + return term_item; +} + +void +term_item_free(Term_Item *term_item) +{ + eina_stringshare_del(term_item->id); + eina_stringshare_del(term_item->dir); + free(term_item); +} + +inline const char * +term_item_id_get(const Term_Item *term_item) +{ + return term_item->id; +} + +inline void +term_item_id_set(Term_Item *term_item, const char *id) +{ + EINA_SAFETY_ON_NULL_RETURN(term_item); + eina_stringshare_replace(&(term_item->id), id); +} + +inline const char * +term_item_dir_get(const Term_Item *term_item) +{ + return term_item->dir; +} + +inline void +term_item_dir_set(Term_Item *term_item, const char *dir) +{ + EINA_SAFETY_ON_NULL_RETURN(term_item); + eina_stringshare_replace(&(term_item->dir), dir); +} + + +static inline void +_terminology_item_init(void) +{ + Eet_Data_Descriptor_Class eddc; + + if (_terminology_item_descriptor) return; + + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Terminology_Item); + _terminology_item_descriptor = eet_data_descriptor_stream_new(&eddc); + + EET_DATA_DESCRIPTOR_ADD_BASIC(_terminology_item_descriptor, Terminology_Item, "version", version, EET_T_UINT); + EET_DATA_DESCRIPTOR_ADD_HASH(_terminology_item_descriptor, Terminology_Item, "term_entries", term_entries, _term_item_descriptor); +} + +static inline void +_terminology_item_shutdown(void) +{ + if (!_terminology_item_descriptor) return; + eet_data_descriptor_free(_terminology_item_descriptor); + _terminology_item_descriptor = NULL; +} + +Terminology_Item * +terminology_item_new(unsigned int version) +{ + Terminology_Item *terminology_item = calloc(1, sizeof(Terminology_Item)); + + if (!terminology_item) + { + fprintf(stderr, "ERROR: could not calloc Terminology_Item\n"); + return NULL; + } + + terminology_item->version = version; + terminology_item->term_entries = eina_hash_stringshared_new(EINA_FREE_CB(term_item_free)); + + return terminology_item; +} + +void +terminology_item_free(Terminology_Item *terminology_item) +{ + if (terminology_item->term_entries) eina_hash_free(terminology_item->term_entries); + free(terminology_item); +} + +inline unsigned int +terminology_item_version_get(const Terminology_Item *terminology_item) +{ + return terminology_item->version; +} + +inline void +terminology_item_version_set(Terminology_Item *terminology_item, unsigned int version) +{ + EINA_SAFETY_ON_NULL_RETURN(terminology_item); + terminology_item->version = version; +} + +void +terminology_item_term_entries_add(Terminology_Item *terminology_item, const char * id, Term_Item *term_item) +{ + EINA_SAFETY_ON_NULL_RETURN(terminology_item); + eina_hash_add(terminology_item->term_entries, id, term_item); +} + +void +terminology_item_term_entries_del(Terminology_Item *terminology_item, const char * id) +{ + EINA_SAFETY_ON_NULL_RETURN(terminology_item); + eina_hash_del(terminology_item->term_entries, id, NULL); +} + +inline Term_Item * +terminology_item_term_entries_get(const Terminology_Item *terminology_item, const char * id) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(terminology_item, NULL); + return eina_hash_find(terminology_item->term_entries, id); +} + +inline Eina_Hash * +terminology_item_term_entries_hash_get(const Terminology_Item *terminology_item) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(terminology_item, NULL); + return terminology_item->term_entries; +} + +void +terminology_item_term_entries_modify(Terminology_Item *terminology_item, const char * key, void *value) +{ + EINA_SAFETY_ON_NULL_RETURN(terminology_item); + eina_hash_modify(terminology_item->term_entries, key, value); +} + +Terminology_Item * +terminology_item_load(const char *filename) +{ + Terminology_Item *terminology_item = NULL; + Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ); + if (!ef) + { + fprintf(stderr, "ERROR: could not open '%s' for read\n", filename); + return NULL; + } + + terminology_item = eet_data_read(ef, _terminology_item_descriptor, TERMINOLOGY_ITEM_ENTRY); + if (!terminology_item) goto end; + terminology_item->__eet_filename = eina_stringshare_add(filename); + + if (!terminology_item->term_entries) terminology_item->term_entries = eina_hash_stringshared_new(EINA_FREE_CB(term_item_free)); + +end: + eet_close(ef); + return terminology_item; +} + +Eina_Bool +terminology_item_save(Terminology_Item *terminology_item, const char *filename) +{ + Eet_File *ef; + Eina_Bool ret; + + if (filename) eina_stringshare_replace(&(terminology_item->__eet_filename), filename); + else if (terminology_item->__eet_filename) filename = terminology_item->__eet_filename; + else return EINA_FALSE; + + ef = eet_open(filename, EET_FILE_MODE_READ_WRITE); + if (!ef) + { + fprintf(stderr, "ERROR: could not open '%s' for write\n", filename); + return EINA_FALSE; + } + + ret = !!eet_data_write(ef, _terminology_item_descriptor, TERMINOLOGY_ITEM_ENTRY, terminology_item, EINA_TRUE); + eet_close(ef); + + return ret; +} + +void +app_server_eet_init(void) +{ + _term_item_init(); + _terminology_item_init(); +} + +void +app_server_eet_shutdown(void) +{ + _term_item_shutdown(); + _terminology_item_shutdown(); +} + diff --git a/src/bin/app_server_eet.h b/src/bin/app_server_eet.h new file mode 100644 index 00000000..3809caab --- /dev/null +++ b/src/bin/app_server_eet.h @@ -0,0 +1,41 @@ +/* This file has been automatically generated by geneet.py */ +/* DO NOT MODIFY */ + +#ifndef __TERMINOLOGY_EET_H__ +#define __TERMINOLOGY_EET_H__ + +#include +#include + +typedef struct _Term_Item Term_Item; +typedef struct _Terminology_Item Terminology_Item; + +/* Term_Item */ +Term_Item *term_item_new(const char * id, const char * dir); +void term_item_free(Term_Item *term_item); + +void term_item_id_set(Term_Item *term_item, const char * id); +const char * term_item_id_get(const Term_Item *term_item); +void term_item_dir_set(Term_Item *term_item, const char * dir); +const char * term_item_dir_get(const Term_Item *term_item); + +/* Terminology_Item */ +Terminology_Item *terminology_item_new(unsigned int version); +void terminology_item_free(Terminology_Item *terminology_item); + +void terminology_item_version_set(Terminology_Item *terminology_item, unsigned int version); +unsigned int terminology_item_version_get(const Terminology_Item *terminology_item); +void terminology_item_term_entries_add(Terminology_Item *terminology_item, const char * id, Term_Item *term_item); +void terminology_item_term_entries_del(Terminology_Item *terminology_item, const char * id); +Term_Item *terminology_item_term_entries_get(const Terminology_Item *terminology_item, const char * key); +Eina_Hash *terminology_item_term_entries_hash_get(const Terminology_Item *terminology_item); +void terminology_item_term_entries_modify(Terminology_Item *terminology_item, const char * key, void *value); + +Terminology_Item *terminology_item_load(const char *filename); +Eina_Bool terminology_item_save(Terminology_Item *terminology_item, const char *filename); + +/* Global initializer / shutdown functions */ +void app_server_eet_init(void); +void app_server_eet_shutdown(void); + +#endif /* __TERMINOLOGY_EET_H__ */ diff --git a/src/bin/config.c b/src/bin/config.c index 22441205..34a9e0db 100644 --- a/src/bin/config.c +++ b/src/bin/config.c @@ -91,6 +91,11 @@ config_init(void) (edd_base, Config, "cg_height", cg_height, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC (edd_base, Config, "drag_links", drag_links, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC + (edd_base, Config, "application_server", application_server, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC + (edd_base, Config, "application_server_restore_views", + application_server_restore_views, EET_T_UCHAR); } void @@ -169,6 +174,8 @@ config_sync(const Config *config_src, Config *config) config->mute = config_src->mute; config->urg_bell = config_src->urg_bell; config->multi_instance = config_src->multi_instance; + config->application_server = config_src->application_server; + config->application_server_restore_views = config_src->application_server_restore_views; config->temporary = config_src->temporary; config->custom_geometry = config_src->custom_geometry; config->cg_width = config_src->cg_width; @@ -425,6 +432,8 @@ config_load(const char *key) config->mute = EINA_FALSE; config->urg_bell = EINA_TRUE; config->multi_instance = EINA_FALSE; + config->application_server = EINA_FALSE; + config->application_server_restore_views = EINA_FALSE; config->custom_geometry = EINA_FALSE; config->cg_width = 80; config->cg_height = 24; @@ -473,6 +482,8 @@ config_fork(Config *config) CPY(mute); CPY(urg_bell); CPY(multi_instance); + CPY(application_server); + CPY(application_server_restore_views); CPY(custom_geometry); CPY(cg_width); CPY(cg_height); diff --git a/src/bin/config.h b/src/bin/config.h index a40b207e..78446f51 100644 --- a/src/bin/config.h +++ b/src/bin/config.h @@ -40,6 +40,8 @@ struct _Config Eina_Bool mute; Eina_Bool urg_bell; Eina_Bool multi_instance; + Eina_Bool application_server; + Eina_Bool application_server_restore_views; Eina_Bool custom_geometry; Eina_Bool drag_links; int cg_width; diff --git a/src/bin/main.c b/src/bin/main.c index fa65df32..625f2860 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -592,6 +592,8 @@ main_close(Evas_Object *win, Evas_Object *term) Eina_List *l; const char *slot = PANES_TOP; + app_server_term_del(term); + if (!sp) return; if (!sp->term) return; if (sp->sel) _sel_restore(sp); @@ -2194,6 +2196,7 @@ main_term_new(Win *wn, Config *config, const char *cmd, // edje_object_signal_emit(term->base, "focus,in", "terminology"); } wn->terms = eina_list_append(wn->terms, term); + app_server_term_add(term); return term; } @@ -2935,6 +2938,10 @@ remote: } config = config_fork(config); + + if (config->application_server) + app_server_init(&wins, config->application_server_restore_views); + term = main_term_new(wn, config, cmd, login_shell, cd, size_w, size_h, hold); if (!term) @@ -2947,7 +2954,7 @@ remote: edje_object_part_swallow(wn->base, "terminology.content", term->bg); _cb_size_hint(term, evas_object_evas_get(wn->win), term->term, NULL); } - + sp = wn->split = calloc(1, sizeof(Split)); sp->wn = wn; sp->term = term; @@ -2976,6 +2983,8 @@ remote: elm_run(); + app_server_shutdown(); + ty_dbus_shutdown(); end: #if (ECORE_VERSION_MAJOR > 1) || (ECORE_VERSION_MINOR >= 8) diff --git a/src/bin/options_behavior.c b/src/bin/options_behavior.c index 00ebcd98..47b39d04 100644 --- a/src/bin/options_behavior.c +++ b/src/bin/options_behavior.c @@ -85,6 +85,64 @@ _cb_op_behavior_multi_instance_chg(void *data, Evas_Object *obj, void *event EIN config_save(config, NULL); } +static void +_cb_op_behavior_application_server_restore_views_chg(void *data, Evas_Object *obj, + void *event EINA_UNUSED) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + config->application_server_restore_views = elm_check_state_get(obj); + config_save(config, NULL); +} + +static void +_behavior_option_restore_opened_views_add(Evas_Object *term, + Evas_Object *check) +{ + Evas_Object *bx = evas_object_data_get(check, "box"); + Evas_Object *o; + Config *config = termio_config_get(term); + + o = elm_check_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_object_text_set(o, "Restore opened views"); + elm_check_state_set(o, config->application_server_restore_views); + elm_box_pack_after(bx, o, check); + evas_object_show(o); + evas_object_data_set(check, "restore_views", o); + evas_object_smart_callback_add(o, "changed", + _cb_op_behavior_application_server_restore_views_chg, + term); +} + + +static void +_behavior_option_restore_opened_views_del(Evas_Object *check) +{ + Evas_Object *o = evas_object_data_del(check, "restore_views"); + if (o) + evas_object_del(o); +} + +static void +_cb_op_behavior_application_server_chg(void *data, Evas_Object *obj, void *event EINA_UNUSED) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + Eina_Bool old = config->application_server; + config->application_server = elm_check_state_get(obj); + + if (old == config->application_server) + return; + + if (!config->application_server) + _behavior_option_restore_opened_views_del(obj); + else + _behavior_option_restore_opened_views_add(term, obj); + config_save(config, NULL); +} + static void _cb_op_behavior_wsep_chg(void *data, Evas_Object *obj, void *event EINA_UNUSED) { @@ -264,6 +322,20 @@ options_behavior(Evas_Object *opbox, Evas_Object *term) evas_object_smart_callback_add(o, "changed", _cb_op_behavior_urg_bell_chg, term); + o = elm_check_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_object_text_set(o, "Enable application server"); + elm_check_state_set(o, config->application_server); + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_behavior_application_server_chg, term); + + evas_object_data_set(o, "box", bx); + if (config->application_server) + _behavior_option_restore_opened_views_add(term, o); + o = elm_check_add(bx); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); diff --git a/src/bin/win.c b/src/bin/win.c index f5ca6249..51c2e3ce 100644 --- a/src/bin/win.c +++ b/src/bin/win.c @@ -1,6 +1,8 @@ #include #include "win.h" #include "config.h" +#include "main.h" +#include "app_server.h" Evas_Object * tg_win_add(const char *name, const char *role, const char *title, const char *icon_name) @@ -17,6 +19,9 @@ tg_win_add(const char *name, const char *role, const char *title, const char *ic elm_win_icon_name_set(win, icon_name); if (role) elm_win_role_set(win, role); + evas_object_smart_callback_add(win, "delete,request", + _app_server_win_del_request_cb, win); + elm_win_autodel_set(win, EINA_TRUE); o = evas_object_image_add(evas_object_evas_get(win));