discomfitor pushed a commit to branch master.

http://git.enlightenment.org/enlightenment/modules/desksanity.git/commit/?id=a0d72c5d914213b6b57654d0ea278eb68476bb5c

commit a0d72c5d914213b6b57654d0ea278eb68476bb5c
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Fri Aug 11 18:50:23 2017 -0400

    add sandbox gadget type for runner gadgets
---
 loader/start.desktop.in |   5 ++
 loader/test.desktop.in  |   4 +
 meson.build             |  39 ++++++---
 src/runner.c            | 220 +++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 238 insertions(+), 30 deletions(-)

diff --git a/loader/start.desktop.in b/loader/start.desktop.in
new file mode 100644
index 0000000..6e8ada9
--- /dev/null
+++ b/loader/start.desktop.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Type=Application
+Name=Start
+Exec=@GADGET_DIR@/start/e_gadget_start
+Icon=e/gadget/start/main
diff --git a/loader/test.desktop.in b/loader/test.desktop.in
new file mode 100644
index 0000000..c1c323a
--- /dev/null
+++ b/loader/test.desktop.in
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Test
+Exec=@GADGET_DIR@/test/e_gadget_test
diff --git a/meson.build b/meson.build
index ff130de..445076c 100644
--- a/meson.build
+++ b/meson.build
@@ -130,7 +130,7 @@ build_files = [
        'src/desksanity.c'
 ]
 
-if dep_efl_wl.found() == true
+if dep_efl_wl.found() == true and dep_e.get_pkgconfig_variable('wayland') == 
'true'
        build_files += 'src/runner.c'
        config_h.set('HAVE_RUNNER', '1')
 
@@ -169,23 +169,42 @@ if dep_efl_wl.found() == true
                install_dir: join_paths([dir_module_e, module_arch]),
                install: true)
 
+       dir_gadgets = join_paths([dir_lib, 'enlightenment/gadgets', 
dep_e.get_pkgconfig_variable('release')])
        executable('e_gadget_start',
                'loader/start.c',
+               c_args: '-fPIE',
+               link_args: '-fPIE',
                dependencies: [dependency('elementary'), 
dependency('enlightenment')],
-               install_dir: dir_bin,
+               install_dir: join_paths([dir_gadgets, 'start']),
                install: true)
+
+       executable('e_gadget_test',
+               'loader/test.c',
+               c_args: '-fPIE',
+               link_args: '-fPIE',
+               dependencies: dependency('elementary'),
+               install_dir: join_paths([dir_gadgets, 'test']),
+               install: true)
+
+       config_h.set_quoted('GADGET_DIR', dir_gadgets)
+       desktop_data = configuration_data()
+       desktop_data.set('GADGET_DIR', dir_gadgets)
+       configure_file(input: 'loader/test.desktop.in',
+               output: 'test.desktop',
+               install: true,
+               install_dir: join_paths([dir_gadgets, 'test']),
+               configuration: desktop_data)
+       configure_file(input: 'loader/start.desktop.in',
+               output: 'start.desktop',
+               install: true,
+               install_dir: join_paths([dir_gadgets, 'start']),
+               configuration: desktop_data)
 endif
 
 
 configure_file(output: 'config.h',
-        install: false,
-        configuration: config_h)
-
-executable('e_gadget_test',
-       'loader/test.c',
-       dependencies: dependency('elementary'),
-       install_dir: dir_bin,
-       install: true)
+       install: false,
+       configuration: config_h)
 
 shared_module('desksanity', build_files,
        include_directories: include_directories(['src']),
diff --git a/src/runner.c b/src/runner.c
index bd15a27..30e406c 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -45,7 +45,11 @@ static RConfig *rconfig;
 static Eina_List *instances;
 static Eina_List *wizards;
 
-static Ecore_Event_Handler *exit_handler;
+static Eina_Hash *sandbox_gadgets;
+
+static Eina_List *handlers;
+static Eio_Monitor *gadget_monitor;
+static Eio_File *gadget_lister;
 
 typedef struct Wizard_Item
 {
@@ -54,6 +58,7 @@ typedef struct Wizard_Item
    E_Gadget_Wizard_End_Cb cb;
    void *data;
    int id;
+   Eina_Bool sandbox : 1;
 } Wizard_Item;
 
 static void
@@ -330,10 +335,11 @@ static void
 runner_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info 
EINA_UNUSED)
 {
    Instance *inst = data;
+   Evas_Object *site = e_gadget_site_get(obj);
 
-   evas_object_smart_callback_del_full(e_gadget_site_get(obj), 
"gadget_removed", runner_removed, inst);
-   evas_object_smart_callback_del_full(e_gadget_site_get(obj), 
"gadget_site_anchor", runner_site_anchor, inst);
-   evas_object_smart_callback_del_full(e_gadget_site_get(obj), 
"gadget_site_gravity", runner_site_gravity, inst);
+   evas_object_smart_callback_del_full(site, "gadget_removed", runner_removed, 
inst);
+   evas_object_smart_callback_del_full(site, "gadget_site_anchor", 
runner_site_anchor, inst);
+   evas_object_smart_callback_del_full(site, "gadget_site_gravity", 
runner_site_gravity, inst);
    if (inst->ci)
      {
         inst->ci->inst = NULL;
@@ -523,23 +529,27 @@ popup_added(void *data, Evas_Object *obj EINA_UNUSED, 
void *event_info)
    evas_object_focus_set(event_info, 1);
 }
 
+static void
+runner_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void 
*event_info EINA_UNUSED)
+{
+   Instance *inst = data;
+   int w, h;
+   Evas_Aspect_Control aspect;
+
+   evas_object_size_hint_min_get(obj, &w, &h);
+   evas_object_size_hint_min_set(inst->box, w, h);
+   evas_object_size_hint_max_get(obj, &w, &h);
+   evas_object_size_hint_max_set(inst->box, w, h);
+   evas_object_size_hint_aspect_get(obj, &aspect, &w, &h);
+   evas_object_size_hint_aspect_set(inst->box, aspect, w, h);
+}
+
 static Evas_Object *
-runner_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
+gadget_create(Evas_Object *parent, Config_Item *ci, int *id, 
E_Gadget_Site_Orient orient)
 {
-   Evas_Object *obj;
    Instance *inst;
-   Config_Item *ci = NULL;
    int ar_version;
 
-   if (orient) return NULL;
-   if (*id > 0) ci = _conf_item_get(id);
-   if ((*id < 0) || ci->inst)
-     {
-        obj = elm_image_add(parent);
-        elm_image_file_set(obj, e_theme_edje_file_get(NULL, 
"e/icons/modules-launcher"), "e/icons/modules-launcher");
-        evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
-        return obj;
-     }
    inst = E_NEW(Instance, 1);
    instances = eina_list_append(instances, inst);
    inst->ci = ci;
@@ -565,14 +575,34 @@ runner_create(Evas_Object *parent, int *id, 
E_Gadget_Site_Orient orient)
    evas_object_smart_callback_add(parent, "gadget_site_anchor", 
runner_site_anchor, inst);
    evas_object_smart_callback_add(parent, "gadget_site_gravity", 
runner_site_gravity, inst);
    runner_run(inst);
+   e_util_size_debug_set(inst->obj, 1);
    ecore_exe_data_set(inst->exe, inst);
    evas_object_event_callback_add(inst->box, EVAS_CALLBACK_DEL, runner_del, 
inst);
    inst->box = elm_box_add(e_comp->elm);
+   evas_object_event_callback_add(inst->obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, 
runner_hints, inst);
    elm_box_homogeneous_set(inst->box, 1);
    elm_box_pack_end(inst->box, inst->obj);
    return inst->box;
 }
 
+static Evas_Object *
+runner_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
+{
+   Evas_Object *obj;
+   Config_Item *ci = NULL;
+
+   if (orient) return NULL;
+   if (*id > 0) ci = _conf_item_get(id);
+   if ((*id < 0) || ci->inst)
+     {
+        obj = elm_image_add(parent);
+        elm_image_file_set(obj, e_theme_edje_file_get(NULL, 
"e/icons/modules-launcher"), "e/icons/modules-launcher");
+        evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+        return obj;
+     }
+   return gadget_create(parent, ci, id, orient);
+}
+
 static Eina_Bool
 runner_exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Del *ev)
 {
@@ -582,8 +612,14 @@ runner_exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, 
Ecore_Exe_Event_Del *ev)
    switch (inst->ci->exit_mode)
      {
       case EXIT_MODE_RESTART:
-        runner_run(inst);
-        ecore_exe_data_set(inst->exe, inst);
+        /* FIXME: probably notify? */
+        if (ev->exit_code == 255) //exec error
+          e_gadget_del(inst->box);
+        else
+          {
+             runner_run(inst);
+             ecore_exe_data_set(inst->exe, inst);
+          }
         break;
       case EXIT_MODE_DELETE:
         e_gadget_del(inst->box);
@@ -594,6 +630,138 @@ runner_exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, 
Ecore_Exe_Event_Del *ev)
 
 ///////////////////////////////
 
+static Evas_Object *
+sandbox_create(Evas_Object *parent, const char *type, int *id, 
E_Gadget_Site_Orient orient)
+{
+   Efreet_Desktop *ed = eina_hash_find(sandbox_gadgets, type);
+   Config_Item *ci = NULL;
+
+   if (*id > 0) ci = _conf_item_get(id);
+   if ((*id < 0) || (ci && ci->inst))
+     {
+        if (ed->icon)
+          {
+             int w, h;
+             Eina_Bool fail = EINA_FALSE;
+             Evas_Object *obj;
+
+             obj = elm_image_add(parent);
+             if (ed->icon[0] == '/')
+               {
+                  if (eina_str_has_extension(ed->icon, ".edj"))
+                    fail = !elm_image_file_set(obj, ed->icon, "icon");
+                  else
+                    fail = !elm_image_file_set(obj, ed->icon, NULL);
+               }
+             else
+               {
+                  if (!elm_image_file_set(obj, e_theme_edje_file_get(NULL, 
ed->icon), ed->icon))
+                    fail = !elm_icon_standard_set(obj, ed->icon);
+               }
+             if (!fail)
+               {
+                  elm_image_object_size_get(obj, &w, &h);
+                  if (w && h)
+                    evas_object_size_hint_aspect_set(obj, 
EVAS_ASPECT_CONTROL_BOTH, w, h);
+                  return obj;
+               }
+             evas_object_del(obj);
+          }
+     }
+   if (!ci)
+     {
+        ci = _conf_item_get(id);
+        ci->cmd = eina_stringshare_add(ed->exec);
+        ci->exit_mode = EXIT_MODE_RESTART;
+     }
+   return gadget_create(parent, ci, id, orient);
+}
+
+static char *
+sandbox_name(const char *filename)
+{
+   Efreet_Desktop *ed = eina_hash_find(sandbox_gadgets, filename);
+   const char *name = ed->name ?: ed->generic_name;
+   char buf[1024];
+
+   if (name) return strdup(name);
+   strncpy(buf, ed->orig_path, sizeof(buf) - 1);
+   buf[0] = toupper(buf[0]);
+   return strdup(buf);
+}
+
+///////////////////////////////
+
+static void
+gadget_dir_add(const char *filename)
+{
+   const char *file;
+   char buf[PATH_MAX];
+   Efreet_Desktop *ed;
+
+   file = ecore_file_file_get(filename);
+   snprintf(buf, sizeof(buf), "%s/%s.desktop", filename, file);
+   ed = efreet_desktop_new(buf);
+   EINA_SAFETY_ON_NULL_RETURN(ed);
+   eina_hash_add(sandbox_gadgets, filename, ed);
+   e_gadget_external_type_add("runner_sandbox", filename, sandbox_create, 
NULL);
+   e_gadget_external_type_name_cb_set("runner_sandbox", filename, 
sandbox_name);
+}
+
+static Eina_Bool
+monitor_dir_create(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Event 
*ev)
+{
+   if (!eina_hash_find(sandbox_gadgets, ev->filename))
+     gadget_dir_add(ev->filename);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+monitor_dir_del(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Event *ev)
+{
+   eina_hash_del_by_key(sandbox_gadgets, ev->filename);
+   e_gadget_external_type_del("runner_sandbox", ev->filename);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+monitor_error(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Error *ev)
+{
+   /* panic? */
+   return ECORE_CALLBACK_RENEW;
+}
+
+
+static Eina_Bool
+list_filter_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, const 
Eina_File_Direct_Info *info)
+{
+   struct stat st;
+   char buf[PATH_MAX];
+
+   if (info->type != EINA_FILE_DIR) return EINA_FALSE;
+   if (info->path[info->name_start] == '.') return EINA_FALSE;
+   snprintf(buf, sizeof(buf), "%s/%s.desktop", info->path, info->path + 
info->name_start);
+   return !stat(info->path, &st);
+}
+
+static void
+list_main_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, const 
Eina_File_Direct_Info *info)
+{
+   gadget_dir_add(info->path);
+}
+
+static void
+list_done_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED)
+{
+   gadget_lister = NULL;
+}
+
+static void
+list_error_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, int error 
EINA_UNUSED)
+{
+   gadget_lister = NULL;
+}
+
 EINTERN void
 runner_init(void)
 {
@@ -617,13 +785,23 @@ runner_init(void)
    if (!rconfig) rconfig = E_NEW(RConfig, 1);
 
    e_gadget_type_add("runner", runner_create, runner_wizard);
-   exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, 
(Ecore_Event_Handler_Cb)runner_exe_del, NULL);
+   {
+      gadget_monitor = eio_monitor_add(GADGET_DIR);
+      gadget_lister = eio_file_direct_ls(GADGET_DIR, list_filter_cb, 
list_main_cb, list_done_cb, list_error_cb, NULL);
+   }
+   E_LIST_HANDLER_APPEND(handlers, ECORE_EXE_EVENT_DEL, runner_exe_del, NULL);
+   E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_DIRECTORY_CREATED, 
monitor_dir_create, NULL);
+   E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_DIRECTORY_DELETED, 
monitor_dir_del, NULL);
+   E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_ERROR, monitor_error, NULL);
+
+   sandbox_gadgets = 
eina_hash_string_superfast_new((Eina_Free_Cb)efreet_desktop_free);
 }
 
 EINTERN void
 runner_shutdown(void)
 {
    e_gadget_type_del("runner");
+   e_gadget_external_type_del("runner_sandbox", NULL);
 
    if (rconfig)
      {
@@ -645,7 +823,9 @@ runner_shutdown(void)
    E_FREE(rconfig);
    E_CONFIG_DD_FREE(conf_edd);
    E_CONFIG_DD_FREE(conf_item_edd);
-   E_FREE_FUNC(exit_handler, ecore_event_handler_del);
+   E_FREE_LIST(handlers, ecore_event_handler_del);
+   E_FREE_FUNC(sandbox_gadgets, eina_hash_free);
+   E_FREE_FUNC(gadget_lister, eio_file_cancel);
 }
 
 EINTERN void

-- 


Reply via email to