add core of sub-open to default open to handle cnp/dnd over icons

This commit is contained in:
Carsten Haitzler 2024-03-05 13:05:29 +00:00
parent 73ddc5bf6d
commit 5661ec1913
3 changed files with 242 additions and 4 deletions

View File

@ -7,6 +7,8 @@
// itself at all and do everything via fs handlers for open, delete, rename
// copy, import, export etc.
#include "cmd.h"
#include "ecore_exe_eo.legacy.h"
#include "eina_stringshare.h"
#include "eina_types.h"
#include "sha.h"
#include "meta.h"
@ -42,6 +44,235 @@ static Eina_List *thumb_busy_queue = NULL;
static unsigned int thumb_busy_max = 8;
static double thumb_update_delay = 0.25;
typedef struct
{
const char *op;
const char *src;
const char *dst;
const char *uuid;
Ecore_Exe *exe;
} Op;
//static Eina_List *op_queue = NULL;
typedef struct
{
const char *path;
Ecore_Event_Handler *handler_exe_del;
Ecore_Event_Handler *handler_exe_data;
Ecore_Exe *exe;
Eina_List *cmd_pending;
Eina_List *timers;
Eina_Bool ready : 1;
} Sub;
typedef struct
{
Sub *sub;
Eina_Stringshare *name;
Ecore_Timer *timer;
double delay;
Eina_Bool repeat : 1;
} Sub_Timer;
static Eina_List *sub_queue = NULL;
static Sub *_sub_open(const char *path, const char *backend);
static Eina_Bool
_cb_sub_timer(void *data)
{
Sub_Timer *st = data;
Eina_Strbuf *buf = cmd_strbuf_new("timer");
cmd_strbuf_append(buf, "name", st->name);
cmd_strbuf_exe_consume(buf, st->sub->exe);
if (st->repeat) return EINA_TRUE;
st->sub->timers = eina_list_remove(st->sub->timers, st);
eina_stringshare_del(st->name);
free(st);
return EINA_FALSE;
}
static void
_sub_del(Sub *sub)
{
sub_queue = eina_list_remove(sub_queue, sub);
eina_stringshare_replace(&(sub->path), NULL);
ecore_event_handler_del(sub->handler_exe_del);
ecore_event_handler_del(sub->handler_exe_data);
ecore_exe_free(sub->exe);
free(sub);
}
static void
_sub_cmd_flush(Sub *sub)
{
Eina_Strbuf *buf;
if ((!sub->ready) || (!sub->cmd_pending)) return;
EINA_LIST_FREE(sub->cmd_pending, buf)
{
cmd_strbuf_exe_consume(buf, sub->exe);
}
}
static void
_sub_cmd_send(Sub *sub, Eina_Strbuf *buf)
{
if (!sub->ready)
{
sub->cmd_pending = eina_list_append(sub->cmd_pending, buf);
return;
}
cmd_strbuf_exe_consume(buf, sub->exe);
}
static void
_sub_command(Sub *sub, const char *str)
{
Eina_Strbuf *buf;
Cmd *c = cmd_parse(str);
if (!c) return;
if (!strcmp(c->command, "backend-set"))
{ // *** must call before list-begin
const char *backend = cmd_key_find(c, "backend");
if (backend)
{
Sub *sub2 = _sub_open(sub->path, backend);
EINA_LIST_FREE(sub->cmd_pending, buf)
{
_sub_cmd_send(sub2, buf);
}
ecore_exe_kill(sub->exe);
_sub_del(sub);
}
}
else if (!strcmp(c->command, "list-end"))
{
sub->ready = EINA_TRUE;
_sub_cmd_flush(sub);
}
else if (!strcmp(c->command, "timer-add"))
{
const char *name = cmd_key_find(c, "name");
const char *delay = cmd_key_find(c, "delay");
const char *repeat = cmd_key_find(c, "repeat");
if (name && delay)
{
Sub_Timer *st = calloc(1, sizeof(Sub_Timer));
if (st)
{
st->sub = sub;
st->name = eina_stringshare_add(name);
st->repeat = repeat ? EINA_TRUE : EINA_FALSE;
st->delay = (double)atoi(delay) / 1000.0;
st->timer = ecore_timer_add(st->delay, _cb_sub_timer, st);
sub->timers = eina_list_append(sub->timers, st);
}
}
}
else if (!strcmp(c->command, "timer-del"))
{
const char *name = cmd_key_find(c, "name");
Sub_Timer *st;
Eina_List *l;
if (name)
{
EINA_LIST_FOREACH(sub->timers, l, st)
{
if (!strcmp(st->name, name))
{
sub->timers = eina_list_remove_list(sub->timers, l);
eina_stringshare_del(st->name);
ecore_timer_del(st->timer);
free(st);
}
}
}
}
// XXX: handle: dir-request
cmd_free(c);
}
static Eina_Bool
_cb_sub_exe_del(void *data, int ev_type EINA_UNUSED, void *event)
{
Sub *sub = data;
Ecore_Exe_Event_Del *ev = event;
if (sub->exe != ev->exe) return ECORE_CALLBACK_PASS_ON;
// XXX: handle anything on sub del
_sub_del(sub);
return ECORE_CALLBACK_DONE;
}
static Eina_Bool
_cb_sub_exe_data(void *data, int ev_type EINA_UNUSED, void *event)
{
Sub *sub = data;
Ecore_Exe_Event_Data *ev = event;
int i;
if (sub->exe != ev->exe) return ECORE_CALLBACK_PASS_ON;
for (i = 0; ev->lines[i].line; i++) _sub_command(sub, ev->lines[i].line);
return ECORE_CALLBACK_DONE;
}
static Sub *
_sub_open(const char *path, const char *backend)
{
Eina_Strbuf *buf;
const char *s;
Sub *sub = calloc(1, sizeof(Sub));
if (!sub) return NULL;
sub->path = eina_stringshare_add(path);
buf = eina_strbuf_new();
s = getenv("E_HOME_DIR");
if (s) eina_strbuf_append(buf, s);
else
{
s = getenv("HOME");
eina_strbuf_append(buf, s);
eina_strbuf_append(buf, "/.e/e");
}
eina_strbuf_append(buf, "/efm/backends/");
eina_strbuf_append(buf, backend);
eina_strbuf_append(buf, "/open");
if (!ecore_file_can_exec(eina_strbuf_string_get(buf)))
{
eina_strbuf_reset(buf);
eina_strbuf_append(buf, elm_app_lib_dir_get());
eina_strbuf_append(buf, "/efm/backends/");
eina_strbuf_append(buf, backend);
eina_strbuf_append(buf, "/open");
}
sub->handler_exe_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
_cb_sub_exe_del, sub);
sub->handler_exe_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
_cb_sub_exe_data, sub);
sub->exe = ecore_exe_pipe_run(eina_strbuf_string_get(buf),
ECORE_EXE_PIPE_READ |
ECORE_EXE_PIPE_READ_LINE_BUFFERED |
ECORE_EXE_PIPE_WRITE,
sub);
eina_strbuf_free(buf);
buf = cmd_strbuf_new("dir-set");
cmd_strbuf_append(buf, "path", path);
cmd_strbuf_exe_consume(buf, sub->exe);
sub_queue = eina_list_append(sub_queue, sub);
return sub;
}
static Eina_Bool _file_add_mod_info(Eina_Strbuf *strbuf, const char *path,
Eina_Bool delay);
@ -954,11 +1185,18 @@ _path_in_mon_dir(const char *path)
static void
_handle_drop_paste(const char *over, const char *action, const char *path)
{
const char *mondir;
if (!mon) return;
mondir = ecore_file_monitor_path_get(mon);
if (!mondir) return;
if (over)
fprintf(stderr, "DROP over=[%s] action=[%s] > [%s]\n", over, action, path);
else
fprintf(stderr, "DROP action=[%s] > [%s]\n", action, path);
// XXX: decide what to do with file and tell frontend
// XXX: action = copy, move, ask, list, link, description
// XXX: if over, then spin up backedn for that over dir and hand work to that
}
void

View File

@ -447,7 +447,7 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
CMD_DONE;
}
else if (!strcmp(c->command, "timer-add"))
{ // *** must call before list-begin
{
const char *name = cmd_key_find(c, "name");
const char *delay = cmd_key_find(c, "delay");
const char *repeat = cmd_key_find(c, "repeat");
@ -469,7 +469,7 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
CMD_DONE;
}
else if (!strcmp(c->command, "timer-del"))
{ // *** must call before list-begin
{
const char *name = cmd_key_find(c, "name");
Smart_Data_Timer *st;
Eina_List *l;

View File

@ -30,8 +30,8 @@ struct _Smart_Data_Timer
Eina_Bool repeat : 1;
};
// an icon view gui data
struct _Smart_Data
// an icon view gui data
struct _Smart_Data
{
Evas_Object_Smart_Clipped_Data __clipped_data;