This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efm2.
View the commit online.
commit 6dd4012162a8542c7e4439040ec45266425e6c96
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Tue Feb 25 22:39:52 2025 +0000
handle some initial actual opening of files... not complete but working
doesnt handle if desktop is "run in terminal". doesn't handle if no
desktop was found to open to pop up a requester
---
src/backends/default/open.c | 84 ++++++++++++++++++++++----------------
src/efm/efm.c | 10 +++--
src/efm/efm_back_end.c | 89 +++++++++++++++++++++++++++++++++++++++-
src/efm/efm_util.c | 39 ++++++++++++++++--
src/efm/efm_util.h | 5 ++-
src/efm/meson.build | 1 +
src/shared/mimeapps.c | 99 +++++++++++++++++++++++++++++++++++++++++++++
src/shared/mimeapps.h | 9 +++++
8 files changed, 293 insertions(+), 43 deletions(-)
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index aae342c..6ff7a6b 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -1408,61 +1408,77 @@ do_handle_cmd(Cmd *c)
}
else if (!strcmp(c->command, "file-run"))
{
+ const char *open_with_desktop = cmd_key_find(c, "open-with");
+ Eina_List *files = NULL;
+ const char *file;
+ int file_num = 0, dir_num = 0;
+
+ fprintf(stderr, "BACKEND: open-with...\n");
+ // open-with path=/path/one path=/opath/2 path=/blah/3 ...
KEY_WALK_BEGIN
{
if (!strcmp(key, "path"))
{
char **plist, **p;
- int files = 0, dirs = 0;
+ fprintf(stderr, "BACKEND: open-with... path...\n");
plist = eina_str_split(data, "\n", -1);
- for (p = plist; *p; p++)
+ if (plist)
{
- Efreet_Uri *uri = efreet_uri_decode(*p);
-
- if (uri)
- {
- if ((uri->protocol) && (!strcmp(uri->protocol, "file")))
- {
- files++;
- if (ecore_file_is_dir(uri->path)) dirs++;
- }
- efreet_uri_free(uri);
- }
- }
- if ((files == 1) && (dirs == 1))
- { // open a single dir, so set view to that dir
- Efreet_Uri *uri = efreet_uri_decode(*plist);
-
- if (uri)
- {
- Eina_Strbuf *strbuf;
-
- strbuf = cmd_strbuf_new("dir-request");
- cmd_strbuf_append(strbuf, "path", uri->path);
- cmd_strbuf_print_consume(strbuf);
- efreet_uri_free(uri);
- }
- }
- else
- { // walk through all files and "run" them
for (p = plist; *p; p++)
{
Efreet_Uri *uri = efreet_uri_decode(*p);
if (uri)
{
- fprintf(stderr, "FFF: [%s][%s][%s]\n", uri->protocol,
- uri->hostname, uri->path);
+ if ((uri->protocol) && (!strcmp(uri->protocol, "file")))
+ {
+ file_num++;
+ if (ecore_file_is_dir(uri->path)) dir_num++;
+ files = eina_list_append(files, eina_stringshare_add(uri->path));
+ }
efreet_uri_free(uri);
}
}
+ free(*plist);
+ free(plist);
}
- free(*plist);
- free(plist);
}
}
KEY_WALK_END
+ if ((file_num == 1) && (dir_num == 1))
+ { // open a single dir, so set view to that dir
+ Eina_Strbuf *strbuf;
+
+ strbuf = cmd_strbuf_new("dir-request");
+ if (strbuf)
+ {
+ fprintf(stderr, "BACKEND: path=[%s]\n", (char *)files->data);
+ cmd_strbuf_append(strbuf, "path", files->data);
+ cmd_strbuf_print_consume(strbuf);
+ }
+ }
+ else
+ { // walk through all files and set a file-run back rto front end
+ // this is an option to change this but policy in the default
+ // backend is to bounce it back to the front end to handle
+ Eina_Strbuf *strbuf;
+ Eina_List *l;
+
+ strbuf = cmd_strbuf_new("file-run");
+ if (strbuf)
+ {
+ if (open_with_desktop)
+ cmd_strbuf_append(strbuf, "open-with", open_with_desktop);
+ EINA_LIST_FOREACH(files, l, file)
+ {
+ fprintf(stderr, "BACKEND: path=[%s]\n", file);
+ cmd_strbuf_append(strbuf, "path", file);
+ }
+ cmd_strbuf_print_consume(strbuf);
+ }
+ }
+ EINA_LIST_FREE(files, file) eina_stringshare_del(file);
}
else if (!strcmp(c->command, "dnd-drop"))
{ // "over" key means dnd was on that dir
diff --git a/src/efm/efm.c b/src/efm/efm.c
index 733ee1a..ecf87a5 100644
--- a/src/efm/efm.c
+++ b/src/efm/efm.c
@@ -206,6 +206,7 @@ _cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
{
Eina_Strbuf *buf = cmd_strbuf_new("file-run");
+ _icon_open_with_cmd_strbuf_append(buf, "open-with", sd);
_uri_list_cmd_strbuf_append(buf, "path",
eina_strbuf_string_get(strbuf));
cmd_strbuf_exe_consume(buf, sd->exe_open);
@@ -223,9 +224,12 @@ _cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
{ // range select
- if (icon->sd->last_selected)
- _select_range(icon->sd->last_selected, icon);
- else _icon_select(icon);
+ if (!icon->selected)
+ {
+ if (icon->sd->last_selected)
+ _select_range(icon->sd->last_selected, icon);
+ else _icon_select(icon);
+ }
}
else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
{ // multi-single select toggle
diff --git a/src/efm/efm_back_end.c b/src/efm/efm_back_end.c
index 99f6437..ee59c5d 100644
--- a/src/efm/efm_back_end.c
+++ b/src/efm/efm_back_end.c
@@ -1,4 +1,6 @@
#include "cmd.h"
+#include "efm_structs.h"
+#include "efreet_desktop.h"
#include "sort.h"
#include "efm.h"
#include "efm_util.h"
@@ -405,6 +407,33 @@ _cb_smart_timer(void *data)
return EINA_FALSE;
}
+static void *
+_file_run_command_get(void *data, Efreet_Desktop *desktop EINA_UNUSED,
+ char *command, int remaining EINA_UNUSED)
+{
+ Eina_List **p_cmd = data;
+ *p_cmd = eina_list_append(*p_cmd, command);
+ return NULL;
+}
+
+static void
+_file_run(Smart_Data *sd EINA_UNUSED, Efreet_Desktop *d, Eina_List *files)
+{
+ Eina_List *cmds = NULL;
+ char *cmd;
+
+ efreet_desktop_command_get(d, files, _file_run_command_get, &cmds);
+ if (d->terminal)
+ {
+ // XXX: handle run in terminal
+ }
+ EINA_LIST_FREE(cmds, cmd)
+ {
+ ecore_exe_run(cmd, NULL);
+ free(cmd);
+ }
+}
+
void
_cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
{ // handle data from the view thread to the UI - this will be a batch of cmds
@@ -415,8 +444,8 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
Eina_List *l, *il2, *il = NULL;
Icon *icon, *icon2;
Block *block;
- const char *path, *file, *label, *s;
- int file_adds = 0, file_dels = 0, tries = 0;
+ const char *path, *file, *label, *s, *key, *kdata;
+ int file_adds = 0, file_dels = 0, tries = 0, i;
Eina_Bool found;
if (!sd)
@@ -605,6 +634,62 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
_reset(sd);
CMD_DONE;
}
+#define KEY_WALK_BEGIN \
+ for (i = 0; c->dict[i]; i += 2) \
+ { \
+ key = c->dict[i]; \
+ kdata = c->dict[i + 1]; \
+ if (kdata)
+#define KEY_WALK_END }
+
+ if (!strcmp(c->command, "file-run"))
+ {
+ char **plist, **p;
+ Efreet_Desktop *d = NULL;
+ Eina_List *files = NULL;
+ const char *file;
+
+ const char *open_with_desktop = cmd_key_find(c, "open-with");
+
+ path = cmd_key_find(c, "path");
+
+ KEY_WALK_BEGIN
+ {
+ if (!strcmp(key, "path"))
+ {
+ plist = eina_str_split(kdata, "\n", -1);
+ for (p = plist; *p; p++)
+ {
+ fprintf(stderr, "ADD [%s]\n", *p);
+ files = eina_list_append(files, eina_stringshare_add(*p));
+ }
+ free(*plist);
+ free(plist);
+ }
+ }
+ KEY_WALK_END
+
+ if (open_with_desktop) d = efreet_desktop_new(open_with_desktop);
+ if (d)
+ {
+ _file_run(sd, d, files);
+ efreet_desktop_unref(d);
+ }
+ EINA_LIST_FREE(files, file)
+ {
+ if (d)
+ {
+ fprintf(stderr, "FRONT OPEN: [%s] [%s]\n", open_with_desktop,
+ file);
+ }
+ else
+ {
+ fprintf(stderr, "FRONT OPEN: [%s]\n", file);
+ }
+ eina_stringshare_del(file);
+ }
+ CMD_DONE;
+ }
label = cmd_key_find(c, "link-label");
if (!label) label = cmd_key_find(c, "label");
diff --git a/src/efm/efm_util.c b/src/efm/efm_util.c
index b9150b2..d2d2a19 100644
--- a/src/efm/efm_util.c
+++ b/src/efm/efm_util.c
@@ -8,6 +8,7 @@
#include "efm_private.h"
#include "eina_strbuf.h"
#include "eina_types.h"
+#include "mimeapps.h"
// util funcs for the efm view
static inline int
@@ -734,6 +735,34 @@ _icon_path_cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key,
eina_strbuf_free(buf);
}
+void
+_icon_open_with_cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key,
+ Smart_Data *sd)
+{
+ Eina_List *bl, *il;
+ Block *block;
+ Icon *icon;
+
+ EINA_LIST_FOREACH(sd->blocks, bl, block)
+ {
+ if (block->selected_num == 0) continue; // skip blocks with 0 sel
+ EINA_LIST_FOREACH(block->icons, il, icon)
+ {
+ if (!icon->selected) continue; // skip icons not selected
+ // FIXME: for now just pick the first found and use its mime. later
+ // let's use the most common mme type instead amongst all selected
+ // files
+ if (!icon->info.mime) continue;
+ Efreet_Desktop *d = _mimeapps_handler_find(icon->info.mime);
+ if (!d) continue;
+ // open-with=/path/to/file.desktop
+ cmd_strbuf_append(strbuf, key, d->orig_path);
+ efreet_desktop_unref(d);
+ return;
+ }
+ }
+}
+
void
_uri_list_cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key,
const char *urilist)
@@ -809,6 +838,7 @@ _cb_icon_mouse_down(void *data, Evas *e EINA_UNUSED,
if (strbuf)
{
_icon_path_cmd_strbuf_append(buf, "over", icon->sd, icon);
+ _icon_open_with_cmd_strbuf_append(buf, "open-with", icon->sd);
_selected_icons_uri_strbuf_append(icon->sd, strbuf);
_uri_list_cmd_strbuf_append(buf, "path",
eina_strbuf_string_get(strbuf));
@@ -1040,9 +1070,12 @@ _cb_icon_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
cmd_strbuf_exe_consume(buf, icon->sd->exe_open);
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
{ // range select
- if (icon->sd->last_selected)
- _select_range(icon->sd->last_selected, icon);
- else _icon_select(icon);
+ if (!icon->selected)
+ {
+ if (icon->sd->last_selected)
+ _select_range(icon->sd->last_selected, icon);
+ else _icon_select(icon);
+ }
}
else if (evas_key_modifier_is_set(ev->modifiers, "Control"))
{ // multi-single select toggle
diff --git a/src/efm/efm_util.h b/src/efm/efm_util.h
index 0b4d291..9c62570 100644
--- a/src/efm/efm_util.h
+++ b/src/efm/efm_util.h
@@ -23,7 +23,10 @@ double _scale_get(Smart_Data *sd);
Eina_List *_icons_path_find(const char *path);
Eina_Bool _icon_focus_dir(Smart_Data *sd, Efm_Focus_Dir dir);
void _icon_rename_end(Icon *icon);
-void _icon_path_cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key,
+void _icon_open_with_cmd_strbuf_append(Eina_Strbuf *strbuf,
+ const char *key, Smart_Data *sd);
+void _icon_path_cmd_strbuf_append(Eina_Strbuf *strbuf,
+ const char *key,
Smart_Data *sd, Icon *icon);
void _uri_list_cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key,
const char *urilist);
diff --git a/src/efm/meson.build b/src/efm/meson.build
index a7c2039..3c3bfc2 100644
--- a/src/efm/meson.build
+++ b/src/efm/meson.build
@@ -6,6 +6,7 @@ inc = include_directories(
)
executable('efm', [
'../shared/cmd.c',
+ '../shared/mimeapps.c',
'efm.c',
'sort.c',
'bitmap.c',
diff --git a/src/shared/mimeapps.c b/src/shared/mimeapps.c
new file mode 100644
index 0000000..b7d679d
--- /dev/null
+++ b/src/shared/mimeapps.c
@@ -0,0 +1,99 @@
+#include "mimeapps.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+static const char *
+_xdg_defaults_get(const char *path, const char *mime)
+{
+ Efreet_Ini *ini;
+ const char *str;
+
+ if (access(path, R_OK) != 0) return NULL;
+ ini = efreet_ini_new(path);
+ if (!ini) return NULL;
+
+ efreet_ini_section_set(ini, "Default Applications");
+ str = eina_stringshare_add(efreet_ini_string_get(ini, mime));
+ efreet_ini_free(ini);
+ return str;
+}
+
+static Efreet_Desktop *
+_xdg_desktop_from_string_list(const char *strlist)
+{
+ Efreet_Desktop *desktop = NULL;
+ char **array = eina_str_split(strlist, ";", 0);
+ unsigned int i;
+
+ if (!array) return NULL;
+ for (i = 0; array[i] != NULL; i++)
+ {
+ const char *name = array[i];
+
+ if (name[0] == '/') desktop = efreet_desktop_new(name);
+ else desktop = efreet_util_desktop_file_id_find(name);
+ if (desktop)
+ {
+ if (desktop->exec) break;
+ else
+ {
+ efreet_desktop_free(desktop);
+ desktop = NULL;
+ }
+ }
+ }
+ free(array[0]);
+ free(array);
+ return desktop;
+}
+
+static Efreet_Desktop *
+_desktop_first_free_others(Eina_List *lst)
+{
+ Efreet_Desktop *desktop, *d;
+
+ if (!lst) return NULL;
+ desktop = lst->data;
+ efreet_desktop_ref(desktop);
+ EINA_LIST_FREE(lst, d) efreet_desktop_free(d);
+ return desktop;
+}
+
+Efreet_Desktop *
+_mimeapps_handler_find(const char *mime)
+{
+ Efreet_Desktop *desktop = NULL;
+ char path[PATH_MAX];
+ const char *name;
+
+ snprintf(path, sizeof(path), "%s/mimeapps.list",
+ efreet_config_home_get());
+ name = _xdg_defaults_get(path, mime);
+ if (!name)
+ {
+ const Eina_List *n, *dirs = efreet_data_dirs_get();
+ const char *d;
+ EINA_LIST_FOREACH(dirs, n, d)
+ {
+ snprintf(path, sizeof(path), "%s/applications/defaults.list", d);
+ name = _xdg_defaults_get(path, mime);
+ if (name) break;
+ }
+ }
+ if (name)
+ {
+ desktop = _xdg_desktop_from_string_list(name);
+ eina_stringshare_del(name);
+ }
+ if (!desktop)
+ {
+ if (!strcmp(mime, "inode/directory"))
+ desktop = efreet_util_desktop_file_id_find("enlightenment_filemanager.desktop");
+ }
+ if (!desktop)
+ desktop = _desktop_first_free_others(efreet_util_desktop_mime_list(mime));
+ return desktop;
+}
diff --git a/src/shared/mimeapps.h b/src/shared/mimeapps.h
new file mode 100644
index 0000000..e5bcc67
--- /dev/null
+++ b/src/shared/mimeapps.h
@@ -0,0 +1,9 @@
+#ifndef MIMEAPPS_H
+#define MIMEAPPS_H 1
+
+#include <Eina.h>
+#include <Efreet.h>
+
+Efreet_Desktop *_mimeapps_handler_find(const char *mime);
+
+#endif
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.