Compare commits
No commits in common. "master" and "devs/discomfitor/sandblog2017" have entirely different histories.
master
...
devs/disco
|
@ -30,9 +30,6 @@
|
|||
<event name="gadget_gravity">
|
||||
<arg name="gravity" type="uint" enum="gravity"/>
|
||||
</event>
|
||||
<request name="open_uri">
|
||||
<arg name="uri" type="string"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
#include "config.h"
|
||||
#define EFL_BETA_API_SUPPORT
|
||||
#include <Ecore_Wl2.h>
|
||||
#include <Elementary.h>
|
||||
#include <dlfcn.h>
|
||||
#include "e-gadget-client-protocol.h"
|
||||
#include "action_route-client-protocol.h"
|
||||
#include <uuid.h>
|
||||
|
||||
static Ecore_Event_Handler *handler;
|
||||
|
||||
static Eina_Hash *wins;
|
||||
static Eina_Hash *gadget_globals;
|
||||
static Eina_Hash *ar_globals;
|
||||
static Eina_Hash *display_actions;
|
||||
|
||||
typedef struct Gadget_Action
|
||||
{
|
||||
Ecore_Wl2_Display *d;
|
||||
Eina_Stringshare *action;
|
||||
char handle[37];
|
||||
Eina_List *requestors;
|
||||
struct action_route_bind *ar_bind;
|
||||
} Gadget_Action;
|
||||
|
||||
static inline Ecore_Wl2_Display *
|
||||
win_display_get(Evas_Object *win)
|
||||
{
|
||||
Ecore_Wl2_Window *ww;
|
||||
ww = elm_win_wl_window_get(win);
|
||||
return ecore_wl2_window_display_get(ww);
|
||||
}
|
||||
|
||||
static void
|
||||
wins_emit(Ecore_Wl2_Display *d, const char *sig, uint32_t val)
|
||||
{
|
||||
Eina_List *l, *ll;
|
||||
Evas_Object *win;
|
||||
|
||||
l = eina_hash_find(wins, &d);
|
||||
EINA_LIST_FOREACH(l, ll, win)
|
||||
evas_object_smart_callback_call(win, sig, (uintptr_t*)(uintptr_t)val);
|
||||
}
|
||||
|
||||
static void
|
||||
_gadget_anchor(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t anchor)
|
||||
{
|
||||
wins_emit(data, "gadget_site_anchor", anchor);
|
||||
}
|
||||
|
||||
static void
|
||||
_gadget_orient(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t orient)
|
||||
{
|
||||
wins_emit(data, "gadget_site_orient", orient);
|
||||
}
|
||||
|
||||
static void
|
||||
_gadget_gravity(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t gravity)
|
||||
{
|
||||
wins_emit(data, "gadget_site_gravity", gravity);
|
||||
}
|
||||
|
||||
static const struct e_gadget_listener _gadget_listener =
|
||||
{
|
||||
_gadget_anchor,
|
||||
_gadget_orient,
|
||||
_gadget_gravity,
|
||||
};
|
||||
|
||||
static void
|
||||
_gadget_global_bind(Ecore_Wl2_Display *d, uint32_t id)
|
||||
{
|
||||
struct e_gadget *gadget_global = wl_registry_bind(ecore_wl2_display_registry_get(d), id, &e_gadget_interface, 1);
|
||||
e_gadget_add_listener(gadget_global, &_gadget_listener, d);
|
||||
eina_hash_add(gadget_globals, &d, gadget_global);
|
||||
}
|
||||
|
||||
static void
|
||||
_ar_global_bind(Ecore_Wl2_Display *d, uint32_t id)
|
||||
{
|
||||
struct action_route *ar_global = wl_registry_bind(ecore_wl2_display_registry_get(d), id, &action_route_interface, 1);
|
||||
eina_hash_add(ar_globals, &d, ar_global);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event_Global *ev)
|
||||
{
|
||||
if (eina_streq(ev->interface, "e_gadget"))
|
||||
_gadget_global_bind(ev->display, ev->id);
|
||||
else if (eina_streq(ev->interface, "action_route"))
|
||||
_ar_global_bind(ev->display, ev->id);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_gadget_init(Ecore_Wl2_Display *d)
|
||||
{
|
||||
Eina_Iterator *it;
|
||||
Ecore_Wl2_Global *g;
|
||||
|
||||
if (wins)
|
||||
{
|
||||
if (eina_hash_find(gadget_globals, &d)) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
gadget_globals = eina_hash_pointer_new(NULL);
|
||||
ar_globals = eina_hash_pointer_new(NULL);
|
||||
}
|
||||
it = ecore_wl2_display_globals_get(d);
|
||||
EINA_ITERATOR_FOREACH(it, g)
|
||||
{
|
||||
if (eina_streq(g->interface, "e_gadget"))
|
||||
_gadget_global_bind(d, g->id);
|
||||
else if (eina_streq(g->interface, "action_route"))
|
||||
_ar_global_bind(d, g->id);
|
||||
}
|
||||
eina_iterator_free(it);
|
||||
if (!handler)
|
||||
handler = ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_ADDED, (Ecore_Event_Handler_Cb)_global_added, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_ar_bind_activate(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||
{
|
||||
const char *params = event_info;
|
||||
Gadget_Action *ga = data;
|
||||
|
||||
if (params && (!params[0])) params = NULL;
|
||||
action_route_bind_activate(ga->ar_bind, params);
|
||||
}
|
||||
|
||||
static void
|
||||
_ar_bind_del(Gadget_Action *ga)
|
||||
{
|
||||
Evas_Object *r;
|
||||
eina_stringshare_del(ga->action);
|
||||
EINA_LIST_FREE(ga->requestors, r)
|
||||
evas_object_smart_callback_del_full(r, ga->handle, _ar_bind_activate, ga);
|
||||
free(ga);
|
||||
}
|
||||
|
||||
static void
|
||||
_ar_bind_end(void *data, struct action_route_bind *action_route_bind EINA_UNUSED)
|
||||
{
|
||||
Gadget_Action *ga = data;
|
||||
Eina_List *l;
|
||||
Evas_Object *r;
|
||||
|
||||
EINA_LIST_FOREACH(ga->requestors, l, r)
|
||||
evas_object_smart_callback_call(r, "gadget_action_end", ga->handle);
|
||||
}
|
||||
|
||||
static void
|
||||
_ar_bind_status(void *data, struct action_route_bind *action_route_bind, uint32_t state)
|
||||
{
|
||||
uuid_t u;
|
||||
Gadget_Action *ga = data;
|
||||
Evas_Object *r;
|
||||
|
||||
if (state == ACTION_ROUTE_BIND_STATE_REJECTED)
|
||||
{
|
||||
Eina_Hash *h;
|
||||
Eina_List *l;
|
||||
h = eina_hash_find(display_actions, &ga->d);
|
||||
EINA_LIST_FOREACH(ga->requestors, l, r)
|
||||
{
|
||||
if (ga->handle[0])
|
||||
evas_object_smart_callback_call(r, "gadget_action_deleted", ga->handle);
|
||||
else
|
||||
evas_object_smart_callback_call(r, "gadget_action", NULL);
|
||||
}
|
||||
eina_hash_del_by_key(h, ga->action);
|
||||
return;
|
||||
}
|
||||
uuid_generate(u);
|
||||
uuid_unparse_lower(u, ga->handle);
|
||||
ga->ar_bind = action_route_bind;
|
||||
r = eina_list_data_get(ga->requestors);
|
||||
evas_object_smart_callback_add(r, ga->handle, _ar_bind_activate, ga);
|
||||
evas_object_smart_callback_call(r, "gadget_action", ga->handle);
|
||||
}
|
||||
|
||||
static const struct action_route_bind_listener _ar_bind_interface =
|
||||
{
|
||||
_ar_bind_status,
|
||||
_ar_bind_end
|
||||
};
|
||||
|
||||
static void
|
||||
action_request(void *data, Evas_Object *obj, void *event_info)
|
||||
{
|
||||
Gadget_Action *ga;
|
||||
const char *action = event_info;
|
||||
Ecore_Wl2_Display *d = data;
|
||||
void *ar_global;
|
||||
struct action_route_bind *ar_bind;
|
||||
Eina_Hash *h;
|
||||
|
||||
if ((!action) || (!action[0]))
|
||||
{
|
||||
evas_object_smart_callback_call(obj, "gadget_action", NULL);
|
||||
return;
|
||||
}
|
||||
if (display_actions)
|
||||
{
|
||||
h = eina_hash_find(display_actions, &d);
|
||||
if (h)
|
||||
{
|
||||
ga = eina_hash_find(h, action);
|
||||
if (ga && (!eina_list_data_find(ga->requestors, obj)))
|
||||
{
|
||||
ga->requestors = eina_list_append(ga->requestors, obj);
|
||||
evas_object_smart_callback_add(obj, ga->handle, _ar_bind_activate, ga);
|
||||
}
|
||||
evas_object_smart_callback_call(obj, "gadget_action", ga ? ga->handle : NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ar_global = eina_hash_find(ar_globals, &d);
|
||||
if (!ar_global)
|
||||
{
|
||||
evas_object_smart_callback_call(obj, "gadget_action", NULL);
|
||||
return;
|
||||
}
|
||||
ga = calloc(1, sizeof(Gadget_Action));
|
||||
ga->d = d;
|
||||
ga->requestors = eina_list_append(ga->requestors, obj);
|
||||
ga->action = eina_stringshare_add(action);
|
||||
if (!display_actions)
|
||||
display_actions = eina_hash_string_superfast_new(NULL);
|
||||
h = eina_hash_find(display_actions, &d);
|
||||
if (!h)
|
||||
{
|
||||
h = eina_hash_pointer_new((Eina_Free_Cb)_ar_bind_del);
|
||||
eina_hash_add(display_actions, &d, h);
|
||||
}
|
||||
|
||||
ar_bind = action_route_bind_action(ar_global, action);
|
||||
action_route_bind_add_listener(ar_bind, &_ar_bind_interface, ga);
|
||||
wl_display_roundtrip(ecore_wl2_display_get(d));
|
||||
}
|
||||
|
||||
static void
|
||||
win_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Ecore_Wl2_Display *d = win_display_get(obj);
|
||||
eina_hash_list_remove(wins, &d, obj);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
win_add(Evas_Object *win)
|
||||
{
|
||||
Ecore_Wl2_Display *d;
|
||||
if (!win) return NULL;
|
||||
d = win_display_get(win);
|
||||
_gadget_init(d);
|
||||
if (!wins)
|
||||
wins = eina_hash_pointer_new(NULL);
|
||||
eina_hash_list_append(wins, &d, win);
|
||||
evas_object_smart_callback_add(win, "gadget_action_request", action_request, d);
|
||||
evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, win_del, NULL);
|
||||
return win;
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
elm_win_util_dialog_add(Evas_Object *parent, const char *name, const char *title)
|
||||
{
|
||||
Evas_Object *(*_elm_win_util_dialog_add)(Evas_Object *, const char *, const char *) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
return win_add(_elm_win_util_dialog_add(parent, name, title));
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
elm_win_util_standard_add(const char *name, const char *title)
|
||||
{
|
||||
Evas_Object *(*_elm_win_util_standard_add)(const char *, const char *) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
return win_add(_elm_win_util_standard_add(name, title));
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
|
||||
{
|
||||
Evas_Object *(*_elm_win_add)(Evas_Object *,const char*, Elm_Win_Type) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
return win_add(_elm_win_add(parent, name, type));
|
||||
}
|
|
@ -97,8 +97,6 @@ main(int argc, char *argv[])
|
|||
elm_win_alpha_set(win, EINA_TRUE);
|
||||
|
||||
ic = elm_icon_add(win);
|
||||
elm_object_tooltip_text_set(ic, "this is some test text which is probably going to be a lot longer than the overall icon size haHAA");
|
||||
elm_object_tooltip_window_mode_set(ic, 1);
|
||||
snprintf(buf, sizeof(buf), "%s/images/logo.png", elm_app_data_dir_get());
|
||||
elm_image_file_set(ic, buf, NULL);
|
||||
elm_image_object_size_get(ic, &w, &h);
|
||||
|
|
44
meson.build
44
meson.build
|
@ -40,8 +40,7 @@ endif
|
|||
endforeach
|
||||
add_global_arguments(dev_cflags, language: 'c')
|
||||
|
||||
dep_e = dependency('enlightenment')
|
||||
release = dep_e.get_pkgconfig_variable('release')
|
||||
release = 'ver-0.22'
|
||||
host_os = host_machine.system()
|
||||
if host_os == 'linux'
|
||||
if cc.has_header_symbol('features.h', '__UCLIBC__')
|
||||
|
@ -110,7 +109,8 @@ add_global_arguments('-DPACKAGE_LIB_DIR="@0@"'.format(dir_lib), language: 'c')
|
|||
add_global_arguments('-DPACKAGE_DATA_DIR="@0@"'.format(join_paths(dir_data, meson.project_name())), language: 'c')
|
||||
add_global_arguments('-DPACKAGE_SYSCONF_DIR="@0@"'.format(dir_sysconf), language: 'c')
|
||||
|
||||
dep_efl_wl = dependency('efl-wl', required: false)
|
||||
dep_efl_wl = dependency('efl-wl', version: '1.21', required: false)
|
||||
dep_e = dependency('enlightenment')
|
||||
|
||||
dir_module_e = join_paths([dep_e.get_pkgconfig_variable('modules'), 'desksanity'])
|
||||
edje_cc = find_program('edje_cc')
|
||||
|
@ -132,9 +132,45 @@ build_files = [
|
|||
]
|
||||
|
||||
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')
|
||||
|
||||
dir_gadgets = join_paths([dir_lib, 'enlightenment/gadgets', module_arch])
|
||||
wayland_scanner = find_program('wayland-scanner')
|
||||
gen_scanner_client = generator(wayland_scanner,
|
||||
output: '@BASENAME@-client-protocol.h',
|
||||
arguments: ['client-header', '@INPUT@', '@OUTPUT@'])
|
||||
gen_scanner_server = generator(wayland_scanner,
|
||||
output: '@BASENAME@-server-protocol.h',
|
||||
arguments: ['server-header', '@INPUT@', '@OUTPUT@'])
|
||||
gen_scanner_impl = generator(wayland_scanner,
|
||||
output: '@BASENAME@-protocol.c',
|
||||
arguments: ['code', '@INPUT@', '@OUTPUT@'])
|
||||
protos = [
|
||||
'e-gadget.xml',
|
||||
'action_route.xml',
|
||||
]
|
||||
|
||||
loader_src = ['loader/loader.c']
|
||||
foreach proto: protos
|
||||
loader_src += gen_scanner_client.process(proto)
|
||||
loader_src += gen_scanner_impl.process(proto)
|
||||
endforeach
|
||||
foreach proto: protos
|
||||
build_files += gen_scanner_server.process(proto)
|
||||
build_files += gen_scanner_impl.process(proto)
|
||||
endforeach
|
||||
|
||||
shared_library('loader', loader_src,
|
||||
name_prefix: '',
|
||||
dependencies: [
|
||||
dependency('elementary'),
|
||||
dependency('ecore-wl2'),
|
||||
dependency('wayland-client'),
|
||||
cc.find_library('uuid')],
|
||||
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',
|
||||
|
|
|
@ -19,6 +19,10 @@ src/zoom.c \
|
|||
src/magnify.c \
|
||||
src/desksanity.c
|
||||
|
||||
if BUILD_RUNNER
|
||||
module_la_SOURCES += src/runner.c
|
||||
endif
|
||||
|
||||
module_la_LIBADD = @E_LIBS@
|
||||
module_la_LDFLAGS = -module -avoid-version
|
||||
module_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
|
|
|
@ -261,6 +261,9 @@ e_modapi_init(E_Module *m)
|
|||
pip_init();
|
||||
zoom_init();
|
||||
mag_init();
|
||||
#ifdef HAVE_RUNNER
|
||||
runner_init();
|
||||
#endif
|
||||
E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY, ds_client_urgent, NULL);
|
||||
E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_REMOVE, ds_client_remove, NULL);
|
||||
E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_AFTER_SHOW, ds_desk_after_show, NULL);
|
||||
|
@ -275,6 +278,9 @@ e_modapi_init(E_Module *m)
|
|||
E_API int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
#ifdef HAVE_RUNNER
|
||||
runner_shutdown();
|
||||
#endif
|
||||
mag_shutdown();
|
||||
zoom_shutdown();
|
||||
pip_shutdown();
|
||||
|
@ -307,6 +313,9 @@ E_API int
|
|||
e_modapi_save(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
e_config_domain_save("module.desksanity", conf_edd, ds_config);
|
||||
#ifdef HAVE_RUNNER
|
||||
runner_save();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,4 +106,9 @@ EINTERN void zoom_shutdown(void);
|
|||
EINTERN void mag_init(void);
|
||||
EINTERN void mag_shutdown(void);
|
||||
|
||||
#ifdef HAVE_RUNNER
|
||||
EINTERN void runner_init(void);
|
||||
EINTERN void runner_shutdown(void);
|
||||
EINTERN void runner_save(void);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -30,7 +30,6 @@ pips_noedit()
|
|||
|
||||
editing = EINA_FALSE;
|
||||
ds_fade_end(NULL, pips_noedit);
|
||||
e_comp_ungrab_input(1, 1);
|
||||
it = eina_hash_iterator_data_new(pips);
|
||||
EINA_ITERATOR_FOREACH(it, pip)
|
||||
{
|
||||
|
@ -51,7 +50,6 @@ pips_edit(void)
|
|||
if (e_comp->nocomp) return;
|
||||
editing = EINA_TRUE;
|
||||
ds_fade_setup(pips_noedit);
|
||||
e_comp_grab_input(1, 1);
|
||||
it = eina_hash_iterator_data_new(pips);
|
||||
EINA_ITERATOR_FOREACH(it, pip)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,855 @@
|
|||
#define HAVE_WAYLAND
|
||||
#include "e_mod_main.h"
|
||||
#include <Efl_Wl.h>
|
||||
#include "e-gadget-server-protocol.h"
|
||||
#include "action_route-server-protocol.h"
|
||||
#include <sched.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EXIT_MODE_RESTART,
|
||||
EXIT_MODE_DELETE,
|
||||
} Exit_Mode;
|
||||
|
||||
typedef struct Config_Item
|
||||
{
|
||||
int id;
|
||||
int exit_mode;
|
||||
Eina_Stringshare *cmd;
|
||||
void *inst;
|
||||
Eina_Bool cmd_changed : 1;
|
||||
} Config_Item;
|
||||
|
||||
typedef struct Instance
|
||||
{
|
||||
Evas_Object *box;
|
||||
Evas_Object *obj;
|
||||
Ecore_Exe *exe;
|
||||
Config_Item *ci;
|
||||
Eina_Hash *allowed_pids;
|
||||
void *gadget_resource;
|
||||
Evas_Object *popup;
|
||||
Evas_Object *ctxpopup;
|
||||
Eina_List *extracted;
|
||||
} Instance;
|
||||
|
||||
typedef struct RConfig
|
||||
{
|
||||
Eina_List *items;
|
||||
Evas_Object *config_dialog;
|
||||
} RConfig;
|
||||
|
||||
static E_Config_DD *conf_edd = NULL;
|
||||
static E_Config_DD *conf_item_edd = NULL;
|
||||
|
||||
static int ns_fd = -1;
|
||||
|
||||
static RConfig *rconfig;
|
||||
static Eina_List *instances;
|
||||
static Eina_List *wizards;
|
||||
|
||||
static Eina_Hash *sandbox_gadgets;
|
||||
|
||||
static Eina_List *handlers;
|
||||
static Eio_Monitor *gadget_monitor;
|
||||
static Eio_File *gadget_lister;
|
||||
|
||||
typedef struct Wizard_Item
|
||||
{
|
||||
Evas_Object *site;
|
||||
Evas_Object *popup;
|
||||
E_Gadget_Wizard_End_Cb cb;
|
||||
void *data;
|
||||
int id;
|
||||
Eina_Bool sandbox : 1;
|
||||
} Wizard_Item;
|
||||
|
||||
static void
|
||||
runner_run(Instance *inst)
|
||||
{
|
||||
char *preload = eina_strdup(getenv("LD_PRELOAD"));
|
||||
char buf[PATH_MAX];
|
||||
char *file = ecore_file_dir_get(mod->module->file);
|
||||
int pid;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/loader.so", file);
|
||||
e_util_env_set("LD_PRELOAD", buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d", inst->ci->id);
|
||||
e_util_env_set("E_GADGET_ID", buf);
|
||||
|
||||
unshare(CLONE_NEWPID);
|
||||
|
||||
inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
|
||||
|
||||
setns(ns_fd, CLONE_NEWPID);
|
||||
|
||||
e_util_env_set("E_GADGET_ID", NULL);
|
||||
e_util_env_set("LD_PRELOAD", preload);
|
||||
free(file);
|
||||
free(preload);
|
||||
eina_hash_free_buckets(inst->allowed_pids);
|
||||
pid = ecore_exe_pid_get(inst->exe);
|
||||
eina_hash_add(inst->allowed_pids, &pid, (void*)1);
|
||||
}
|
||||
|
||||
static void
|
||||
_config_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Config_Item *ci = data;
|
||||
Instance *inst = ci->inst;
|
||||
|
||||
e_comp_ungrab_input(1, 1);
|
||||
rconfig->config_dialog = NULL;
|
||||
if (ci->cmd_changed)
|
||||
{
|
||||
char *cmd;
|
||||
|
||||
cmd = elm_entry_markup_to_utf8(elm_entry_entry_get(evas_object_data_get(obj, "entry")));
|
||||
eina_stringshare_replace(&ci->cmd, cmd);
|
||||
free(cmd);
|
||||
e_config_save_queue();
|
||||
}
|
||||
if (!inst) ci->cmd_changed = 0;
|
||||
if (!ci->cmd_changed) return;
|
||||
ci->cmd_changed = 0;
|
||||
if (inst->exe) ecore_exe_quit(inst->exe);
|
||||
runner_run(inst);
|
||||
}
|
||||
|
||||
static void
|
||||
_config_label_add(Evas_Object *tb, const char *txt, int row)
|
||||
{
|
||||
Evas_Object *o;
|
||||
|
||||
o = elm_label_add(tb);
|
||||
E_ALIGN(o, 0, 0.5);
|
||||
elm_object_text_set(o, txt);
|
||||
evas_object_show(o);
|
||||
elm_table_pack(tb, o, 0, row, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_config_cmd_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Config_Item *ci = data;
|
||||
|
||||
ci->cmd_changed = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_config_cmd_activate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Config_Item *ci = data;
|
||||
Instance *inst = ci->inst;
|
||||
char *cmd;
|
||||
|
||||
ci->cmd_changed = 0;
|
||||
cmd = elm_entry_markup_to_utf8(elm_entry_entry_get(obj));
|
||||
eina_stringshare_replace(&ci->cmd, cmd);
|
||||
free(cmd);
|
||||
e_config_save_queue();
|
||||
if (!inst) return;
|
||||
if (inst->exe) ecore_exe_quit(inst->exe);
|
||||
runner_run(inst);
|
||||
}
|
||||
|
||||
EINTERN Evas_Object *
|
||||
config_runner(Config_Item *ci, E_Zone *zone)
|
||||
{
|
||||
Evas_Object *popup, *tb, *o, *ent, *rg;
|
||||
int row = 0;
|
||||
|
||||
if (!zone) zone = e_zone_current_get();
|
||||
popup = elm_popup_add(e_comp->elm);
|
||||
E_EXPAND(popup);
|
||||
evas_object_layer_set(popup, E_LAYER_POPUP);
|
||||
elm_popup_allow_events_set(popup, 1);
|
||||
elm_popup_scrollable_set(popup, 1);
|
||||
|
||||
tb = elm_table_add(popup);
|
||||
elm_table_align_set(tb, 0, 0.5);
|
||||
E_EXPAND(tb);
|
||||
evas_object_show(tb);
|
||||
elm_object_content_set(popup, tb);
|
||||
|
||||
o = evas_object_rectangle_add(e_comp->evas);
|
||||
evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(200), 1);
|
||||
elm_table_pack(tb, o, 0, row++, 2, 1);
|
||||
|
||||
_config_label_add(tb, D_("Command:"), row);
|
||||
ent = o = elm_entry_add(tb);
|
||||
E_FILL(o);
|
||||
evas_object_show(o);
|
||||
elm_entry_single_line_set(o, 1);
|
||||
elm_entry_entry_set(o, ci->cmd);
|
||||
evas_object_smart_callback_add(o, "changed,user", _config_cmd_changed, ci);
|
||||
evas_object_smart_callback_add(o, "activated", _config_cmd_activate, ci);
|
||||
elm_table_pack(tb, o, 1, row++, 1, 1);
|
||||
|
||||
_config_label_add(tb, D_("On Exit:"), row);
|
||||
o = rg = elm_radio_add(tb);
|
||||
E_FILL(o);
|
||||
evas_object_show(o);
|
||||
elm_object_text_set(o, D_("Restart"));
|
||||
elm_radio_state_value_set(o, EXIT_MODE_RESTART);
|
||||
elm_radio_value_pointer_set(o, &ci->exit_mode);
|
||||
elm_table_pack(tb, o, 1, row++, 1, 1);
|
||||
|
||||
o = elm_radio_add(tb);
|
||||
E_FILL(o);
|
||||
elm_radio_group_add(o, rg);
|
||||
evas_object_show(o);
|
||||
elm_object_text_set(o, D_("Delete"));
|
||||
elm_radio_state_value_set(o, EXIT_MODE_DELETE);
|
||||
elm_table_pack(tb, o, 1, row++, 1, 1);
|
||||
|
||||
|
||||
popup = e_comp_object_util_add(popup, E_COMP_OBJECT_TYPE_NONE);
|
||||
evas_object_layer_set(popup, E_LAYER_POPUP);
|
||||
evas_object_move(popup, zone->x, zone->y);
|
||||
evas_object_resize(popup, zone->w / 4, zone->h / 3);
|
||||
e_comp_object_util_center(popup);
|
||||
evas_object_show(popup);
|
||||
e_comp_object_util_autoclose(popup, NULL, e_comp_object_util_autoclose_on_escape, NULL);
|
||||
evas_object_event_callback_priority_add(popup, EVAS_CALLBACK_DEL, EVAS_CALLBACK_PRIORITY_BEFORE, _config_close, ci);
|
||||
evas_object_data_set(popup, "entry", ent);
|
||||
e_comp_grab_input(1, 1);
|
||||
|
||||
elm_object_focus_set(ent, 1);
|
||||
|
||||
return rconfig->config_dialog = popup;
|
||||
}
|
||||
|
||||
static Config_Item *
|
||||
_conf_item_get(int *id)
|
||||
{
|
||||
Config_Item *ci;
|
||||
Eina_List *l;
|
||||
|
||||
if (*id > 0)
|
||||
{
|
||||
EINA_LIST_FOREACH(rconfig->items, l, ci)
|
||||
if (*id == ci->id) return ci;
|
||||
}
|
||||
|
||||
ci = E_NEW(Config_Item, 1);
|
||||
if (!*id)
|
||||
*id = ci->id = rconfig->items ? eina_list_count(rconfig->items) + 1 : 1;
|
||||
else
|
||||
ci->id = *id;
|
||||
|
||||
if (ci->id < 1) return ci;
|
||||
rconfig->items = eina_list_append(rconfig->items, ci);
|
||||
e_config_save_queue();
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
static void
|
||||
wizard_site_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Wizard_Item *wi = data;
|
||||
wi->site = NULL;
|
||||
evas_object_hide(wi->popup);
|
||||
evas_object_del(wi->popup);
|
||||
}
|
||||
|
||||
static void
|
||||
_wizard_config_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Wizard_Item *wi = data;
|
||||
Eina_List *l;
|
||||
Config_Item *ci;
|
||||
|
||||
EINA_LIST_FOREACH(rconfig->items, l, ci)
|
||||
{
|
||||
if (ci->id == wi->id)
|
||||
{
|
||||
if (ci->cmd) break;
|
||||
wi->id = 0;
|
||||
free(ci);
|
||||
rconfig->items = eina_list_remove_list(rconfig->items, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (wi->site)
|
||||
wi->cb(wi->data, wi->id);
|
||||
wizards = eina_list_remove(wizards, wi);
|
||||
if (wi->site)
|
||||
evas_object_event_callback_del_full(wi->site, EVAS_CALLBACK_DEL, wizard_site_del, wi);
|
||||
free(wi);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
runner_wizard(E_Gadget_Wizard_End_Cb cb, void *data, Evas_Object *site)
|
||||
{
|
||||
int id = 0;
|
||||
Config_Item *ci;
|
||||
Wizard_Item *wi;
|
||||
|
||||
wi = E_NEW(Wizard_Item, 1);
|
||||
wi->cb = cb;
|
||||
wi->data = data;
|
||||
wi->site = site;
|
||||
evas_object_event_callback_add(wi->site, EVAS_CALLBACK_DEL, wizard_site_del, wi);
|
||||
wizards = eina_list_append(wizards, wi);
|
||||
|
||||
ci = _conf_item_get(&id);
|
||||
wi->id = ci->id;
|
||||
wi->popup = config_runner(ci, NULL);
|
||||
evas_object_event_callback_add(wi->popup, EVAS_CALLBACK_DEL, _wizard_config_end, wi);
|
||||
return wi->popup;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
static void
|
||||
mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
evas_object_focus_set(inst->obj, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
runner_removed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||
{
|
||||
Instance *inst = data;
|
||||
if (inst->box != event_info) return;
|
||||
rconfig->items = eina_list_remove(rconfig->items, inst->ci);
|
||||
eina_stringshare_del(inst->ci->cmd);
|
||||
E_FREE(inst->ci);
|
||||
}
|
||||
|
||||
static void
|
||||
runner_site_gravity(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
if (inst->gadget_resource)
|
||||
e_gadget_send_gadget_gravity(inst->gadget_resource, e_gadget_site_gravity_get(obj));
|
||||
}
|
||||
|
||||
static void
|
||||
runner_site_anchor(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
if (inst->gadget_resource)
|
||||
e_gadget_send_gadget_anchor(inst->gadget_resource, e_gadget_site_anchor_get(obj));
|
||||
}
|
||||
|
||||
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(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;
|
||||
E_FREE_FUNC(inst->exe, ecore_exe_quit);
|
||||
}
|
||||
else
|
||||
E_FREE_FUNC(inst->exe, ecore_exe_terminate);
|
||||
instances = eina_list_remove(instances, inst);
|
||||
eina_hash_free(inst->allowed_pids);
|
||||
free(inst);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
runner_gadget_configure(Evas_Object *g)
|
||||
{
|
||||
Instance *inst = evas_object_data_get(g, "runner");
|
||||
return config_runner(inst->ci, e_comp_object_util_zone_get(g));
|
||||
}
|
||||
|
||||
static void
|
||||
runner_created(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
if (inst->box != event_info) return;
|
||||
e_gadget_configure_cb_set(inst->box, runner_gadget_configure);
|
||||
evas_object_smart_callback_del_full(obj, "gadget_created", runner_created, data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gadget_unbind(struct wl_resource *resource)
|
||||
{
|
||||
Instance *inst = wl_resource_get_user_data(resource);
|
||||
inst->gadget_resource = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gadget_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
||||
{
|
||||
struct wl_resource *res;
|
||||
Instance *inst = data;
|
||||
pid_t pid;
|
||||
Evas_Object *site;
|
||||
|
||||
wl_client_get_credentials(client, &pid, NULL, NULL);
|
||||
if (pid != ecore_exe_pid_get(inst->exe))
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
res = wl_resource_create(client, &e_gadget_interface, version, id);
|
||||
wl_resource_set_implementation(res, NULL, data, gadget_unbind);
|
||||
inst->gadget_resource = res;
|
||||
site = e_gadget_site_get(inst->box);
|
||||
e_gadget_send_gadget_orient(res, e_gadget_site_orient_get(site));
|
||||
e_gadget_send_gadget_gravity(res, e_gadget_site_gravity_get(site));
|
||||
e_gadget_send_gadget_anchor(res, e_gadget_site_anchor_get(site));
|
||||
}
|
||||
|
||||
static void
|
||||
ar_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
||||
{
|
||||
struct wl_resource *res;
|
||||
Instance *inst = data;
|
||||
int v;
|
||||
const void *ar_interface;
|
||||
pid_t pid;
|
||||
|
||||
wl_client_get_credentials(client, &pid, NULL, NULL);
|
||||
if (pid != ecore_exe_pid_get(inst->exe))
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
ar_interface = e_comp_wl_extension_action_route_interface_get(&v);
|
||||
|
||||
if (!(res = wl_resource_create(client, &action_route_interface, MIN(v, version), id)))
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(res, ar_interface, inst->allowed_pids, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
child_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
Evas_Object *ext;
|
||||
|
||||
inst->popup = NULL;
|
||||
ext = evas_object_data_get(obj, "extracted");
|
||||
elm_box_unpack_all(obj);
|
||||
inst->extracted = eina_list_remove(inst->extracted, ext);
|
||||
evas_object_hide(ext);
|
||||
}
|
||||
|
||||
static void
|
||||
child_added(void *data, Evas_Object *obj, void *event_info)
|
||||
{
|
||||
Evas_Object *popup, *bx;
|
||||
E_Zone *zone = e_comp_object_util_zone_get(obj);
|
||||
Instance *inst = data;
|
||||
|
||||
if (!efl_wl_surface_extract(event_info)) return;
|
||||
inst->extracted = eina_list_append(inst->extracted, event_info);
|
||||
|
||||
popup = elm_popup_add(e_comp->elm);
|
||||
E_EXPAND(popup);
|
||||
evas_object_layer_set(popup, E_LAYER_POPUP);
|
||||
elm_popup_allow_events_set(popup, 1);
|
||||
elm_popup_scrollable_set(popup, 1);
|
||||
|
||||
bx = elm_box_add(popup);
|
||||
E_EXPAND(event_info);
|
||||
E_FILL(event_info);
|
||||
elm_box_homogeneous_set(bx, 1);
|
||||
evas_object_show(bx);
|
||||
elm_box_pack_end(bx, event_info);
|
||||
elm_object_content_set(popup, bx);
|
||||
|
||||
inst->popup = popup = e_comp_object_util_add(popup, E_COMP_OBJECT_TYPE_NONE);
|
||||
evas_object_layer_set(popup, E_LAYER_POPUP);
|
||||
evas_object_move(popup, zone->x, zone->y);
|
||||
evas_object_resize(popup, zone->w / 4, zone->h / 3);
|
||||
e_comp_object_util_center(popup);
|
||||
evas_object_show(popup);
|
||||
e_comp_canvas_feed_mouse_up(0);
|
||||
e_comp_object_util_autoclose(popup, NULL, e_comp_object_util_autoclose_on_escape, NULL);
|
||||
evas_object_event_callback_add(bx, EVAS_CALLBACK_DEL, child_close, inst);
|
||||
evas_object_data_set(bx, "extracted", event_info);
|
||||
evas_object_focus_set(event_info, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
Evas_Object *ext;
|
||||
|
||||
inst->ctxpopup = NULL;
|
||||
ext = evas_object_data_get(obj, "extracted");
|
||||
elm_box_unpack_all(obj);
|
||||
inst->extracted = eina_list_remove(inst->extracted, ext);
|
||||
evas_object_hide(ext);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_dismissed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
evas_object_del(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
elm_ctxpopup_dismiss(inst->ctxpopup);
|
||||
evas_object_del(elm_object_content_get(inst->ctxpopup));
|
||||
}
|
||||
|
||||
static void
|
||||
popup_added(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||
{
|
||||
Instance *inst = data;
|
||||
Evas_Object *bx;
|
||||
|
||||
if (!efl_wl_surface_extract(event_info)) return;
|
||||
inst->extracted = eina_list_append(inst->extracted, event_info);
|
||||
|
||||
inst->ctxpopup = elm_ctxpopup_add(inst->box);
|
||||
elm_object_style_set(inst->ctxpopup, "noblock");
|
||||
evas_object_smart_callback_add(inst->ctxpopup, "dismissed", popup_dismissed, inst);
|
||||
evas_object_event_callback_add(event_info, EVAS_CALLBACK_DEL, popup_hide, inst);
|
||||
|
||||
bx = elm_box_add(inst->ctxpopup);
|
||||
elm_box_homogeneous_set(bx, 1);
|
||||
evas_object_show(bx);
|
||||
elm_box_pack_end(bx, event_info);
|
||||
evas_object_data_set(bx, "extracted", event_info);
|
||||
evas_object_event_callback_add(bx, EVAS_CALLBACK_DEL, popup_del, inst);
|
||||
elm_object_content_set(inst->ctxpopup, bx);
|
||||
|
||||
e_gadget_util_ctxpopup_place(inst->box, inst->ctxpopup, NULL);
|
||||
evas_object_show(inst->ctxpopup);
|
||||
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 *
|
||||
gadget_create(Evas_Object *parent, Config_Item *ci, int *id, E_Gadget_Site_Orient orient)
|
||||
{
|
||||
Instance *inst;
|
||||
int ar_version;
|
||||
|
||||
inst = E_NEW(Instance, 1);
|
||||
instances = eina_list_append(instances, inst);
|
||||
inst->ci = ci;
|
||||
if (!inst->ci)
|
||||
inst->ci = _conf_item_get(id);
|
||||
inst->ci->inst = inst;
|
||||
inst->allowed_pids = eina_hash_int32_new(NULL);
|
||||
inst->obj = efl_wl_add(e_comp->evas);
|
||||
E_EXPAND(inst->obj);
|
||||
E_FILL(inst->obj);
|
||||
evas_object_show(inst->obj);
|
||||
efl_wl_aspect_set(inst->obj, 1);
|
||||
efl_wl_minmax_set(inst->obj, 1);
|
||||
efl_wl_global_add(inst->obj, &e_gadget_interface, 1, inst, gadget_bind);
|
||||
evas_object_smart_callback_add(inst->obj, "child_added", child_added, inst);
|
||||
evas_object_smart_callback_add(inst->obj, "popup_added", popup_added, inst);
|
||||
e_comp_wl_extension_action_route_interface_get(&ar_version);
|
||||
efl_wl_global_add(inst->obj, &action_route_interface, ar_version, inst, ar_bind);
|
||||
evas_object_data_set(inst->obj, "runner", inst);
|
||||
evas_object_event_callback_add(inst->obj, EVAS_CALLBACK_MOUSE_DOWN, mouse_down, inst);
|
||||
evas_object_smart_callback_add(parent, "gadget_created", runner_created, inst);
|
||||
evas_object_smart_callback_add(parent, "gadget_removed", runner_removed, inst);
|
||||
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);
|
||||
ecore_exe_data_set(inst->exe, inst);
|
||||
inst->box = elm_box_add(e_comp->elm);
|
||||
e_util_size_debug_set(inst->box, 1);
|
||||
evas_object_event_callback_add(inst->box, EVAS_CALLBACK_DEL, runner_del, inst);
|
||||
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)
|
||||
{
|
||||
Instance *inst = ecore_exe_data_get(ev->exe);
|
||||
|
||||
if ((!inst) || (!instances) || (!eina_list_data_find(instances, inst))) return ECORE_CALLBACK_RENEW;
|
||||
switch (inst->ci->exit_mode)
|
||||
{
|
||||
case EXIT_MODE_RESTART:
|
||||
/* 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);
|
||||
break;
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
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)
|
||||
{
|
||||
conf_item_edd = E_CONFIG_DD_NEW("Config_Item", Config_Item);
|
||||
#undef T
|
||||
#undef D
|
||||
#define T Config_Item
|
||||
#define D conf_item_edd
|
||||
E_CONFIG_VAL(D, T, id, INT);
|
||||
E_CONFIG_VAL(D, T, exit_mode, INT);
|
||||
E_CONFIG_VAL(D, T, cmd, STR);
|
||||
|
||||
conf_edd = E_CONFIG_DD_NEW("RConfig", RConfig);
|
||||
#undef T
|
||||
#undef D
|
||||
#define T RConfig
|
||||
#define D conf_edd
|
||||
E_CONFIG_LIST(D, T, items, conf_item_edd);
|
||||
|
||||
rconfig = e_config_domain_load("module.runner", conf_edd);
|
||||
if (!rconfig) rconfig = E_NEW(RConfig, 1);
|
||||
|
||||
e_gadget_type_add("runner", runner_create, runner_wizard);
|
||||
{
|
||||
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);
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
|
||||
snprintf(buf, sizeof(buf), "/proc/%d/ns/pid", getpid());
|
||||
ns_fd = open(buf, O_RDONLY);
|
||||
}
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
runner_shutdown(void)
|
||||
{
|
||||
e_gadget_type_del("runner");
|
||||
e_gadget_external_type_del("runner_sandbox", NULL);
|
||||
|
||||
if (rconfig)
|
||||
{
|
||||
Config_Item *ci;
|
||||
|
||||
if (rconfig->config_dialog)
|
||||
{
|
||||
evas_object_hide(rconfig->config_dialog);
|
||||
evas_object_del(rconfig->config_dialog);
|
||||
}
|
||||
|
||||
EINA_LIST_FREE(rconfig->items, ci)
|
||||
{
|
||||
eina_stringshare_del(ci->cmd);
|
||||
free(ci);
|
||||
}
|
||||
|
||||
}
|
||||
E_FREE(rconfig);
|
||||
E_CONFIG_DD_FREE(conf_edd);
|
||||
E_CONFIG_DD_FREE(conf_item_edd);
|
||||
E_FREE_LIST(handlers, ecore_event_handler_del);
|
||||
E_FREE_FUNC(sandbox_gadgets, eina_hash_free);
|
||||
E_FREE_FUNC(gadget_lister, eio_file_cancel);
|
||||
close(ns_fd);
|
||||
ns_fd = -1;
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
runner_save(void)
|
||||
{
|
||||
e_config_domain_save("module.runner", conf_edd, rconfig);
|
||||
}
|
|
@ -474,13 +474,12 @@ _zoom_client_property(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Pro
|
|||
static void
|
||||
_hiding(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
||||
{
|
||||
Eina_List *clients = evas_object_data_del(obj, "__DSCLIENTS");
|
||||
Eina_List *clients = evas_object_data_get(obj, "__DSCLIENTS");
|
||||
Evas_Object *m, *e;
|
||||
|
||||
EINA_LIST_FREE(clients, m)
|
||||
{
|
||||
e = evas_object_smart_parent_get(m);
|
||||
evas_object_pass_events_set(e, 1);
|
||||
edje_object_signal_emit(e, "e,action,hide", "e");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue