shot - allow copy of image to selection in addition to shave and share

uses elm cnp to store the image in a selection attached to your
compositor elm win. note... some apps are fussy about what file
formats they accept... we've found through much pain that chrome (and
i assume anything based on it like electron) only accept png for cnp.
firefox accepts most sane formats (png, jpg). libreoffice too accepts
png and jpg, efl accept sjust anout anything you throw at it, so ymmv.
if paste doesnt work either the target for paste doesn't support
pasting images at all or it is fussy about formats - maybe set quality
to 100% to force png and try that as shot saves just png and jpg
(100% quality == png, evrything below is jpg).

if you want pastes of lower quality to work e.g. jpegs in chrome -
file a bug with the chrome team... :)
This commit is contained in:
Carsten Haitzler 2020-09-05 15:51:47 +01:00
parent 951bb66fa0
commit fbaa8984df
4 changed files with 84 additions and 20 deletions

View File

@ -11,7 +11,7 @@ extern E_Module *shot_module;
#define MAXZONES 64
void share_save (const char *cmd);
void share_save (const char *cmd, const char *file, Eina_Bool copy);
void share_write_end_watch (void *data);
void share_write_status_watch(void *data);
void share_dialog_show (void);
@ -22,8 +22,8 @@ void preview_dialog_show (E_Zone *zone, E_Client *ec, const char *pa
Eina_Bool preview_have (void);
void preview_abort (void);
Evas_Object *preview_image_get (void);
void save_to (const char *file);
void save_show (void);
void save_to (const char *file, Eina_Bool copy);
void save_show (Eina_Bool save);
Evas_Object *ui_edit(Evas_Object *window, Evas_Object *o_bg, E_Zone *zone,
E_Client *ec, void *dst, int sx, int sy, int sw, int sh,

View File

@ -9,7 +9,13 @@ Eina_Rectangle crop = { 0, 0, 0, 0 };
static void
_win_save_cb(void *data EINA_UNUSED, void *data2 EINA_UNUSED)
{
save_show();
save_show(EINA_FALSE);
}
static void
_win_copy_cb(void *data EINA_UNUSED, void *data2 EINA_UNUSED)
{
save_show(EINA_TRUE);
}
static void
@ -88,6 +94,8 @@ preview_dialog_show(E_Zone *zone, E_Client *ec, const char *params, void *dst,
e_widget_list_object_append(o_box, o, 1, 0, 0.5);
o = e_widget_button_add(evas, _("Share"), NULL, _win_share_cb, win, NULL);
e_widget_list_object_append(o_box, o, 1, 0, 0.5);
o = e_widget_button_add(evas, _("Copy"), NULL, _win_copy_cb, win, NULL);
e_widget_list_object_append(o_box, o, 1, 0, 0.5);
if (!ec)
{
o = e_widget_button_add(evas, _("Delay"), NULL, _win_delay_cb, win, NULL);

View File

@ -7,6 +7,7 @@ typedef struct
int w, h, stride, quality;
size_t size;
int fd;
Eina_Bool copy;
} Rgba_Writer_Data;
static void
@ -43,7 +44,7 @@ _cb_rgba_writer_done(void *data, Ecore_Thread *th EINA_UNUSED)
e_module_dir_get(shot_module), MODULE_ARCH,
rdata->path, rdata->w, rdata->h, rdata->stride,
rdata->quality);
share_save(buf);
share_save(buf, rdata->outfile, rdata->copy);
_rgba_data_free(rdata);
}
@ -55,7 +56,7 @@ _cb_rgba_writer_cancel(void *data, Ecore_Thread *th EINA_UNUSED)
}
void
save_to(const char *file)
save_to(const char *file, Eina_Bool copy)
{
int fd;
char tmpf[256] = "e-shot-rgba-XXXXXX";
@ -71,7 +72,6 @@ save_to(const char *file)
Evas_Object *img = preview_image_get();
ui_edit_prepare();
printf("C: %i %i %ix%i\n", crop.x, crop.y, crop.w, crop.h);
if ((crop.x == 0) && (crop.y == 0) &&
(crop.w == 0) && (crop.h == 0))
{
@ -115,7 +115,6 @@ save_to(const char *file)
imh = crop.h;
imstride = imw * 4;
d = data;
printf("Cpy dat %p -> %p | %ix%i\n", src_data, data, imw, imh);
for (y = crop.y; y < (crop.y + crop.h); y++)
{
s = src_data + (stride * y) + (crop.x * 4);
@ -144,6 +143,7 @@ save_to(const char *file)
thdat->h = imh;
thdat->stride = imstride;
thdat->quality = quality;
thdat->copy = copy;
ecore_thread_run(_cb_rgba_writer_do,
_cb_rgba_writer_done,
_cb_rgba_writer_cancel, thdat);
@ -167,7 +167,7 @@ save_to(const char *file)
}
void
save_show(void)
save_show(Eina_Bool copy)
{
char path[PATH_MAX + 512];
char path2[PATH_MAX + 512];
@ -185,21 +185,24 @@ save_show(void)
else
strftime(buf, sizeof(buf), "shot-%Y-%m-%d_%H-%M-%S.jpg", tm);
e_user_dir_snprintf(path, sizeof(path), "shots/%s", buf);
save_to(path);
save_to(path, copy);
snprintf(path, sizeof(path), "%s/shots.desktop",
e_module_dir_get(shot_module));
snprintf(path2, sizeof(path2), "%s/fileman/favorites/shots.desktop",
e_user_dir_get());
if (!ecore_file_exists(path2)) ecore_file_cp(path, path2);
a = e_action_find("fileman_show");
if (a)
if (!copy)
{
a->func.go(NULL, "$E_HOME_DIR/shots");
a = e_action_find("fileman_show");
if (a)
{
a->func.go(NULL, "$E_HOME_DIR/shots");
}
else
e_util_dialog_show
(_("Error - No Filemanager"),
_("No filemanager action and/or module was found.<br>"
"Cannot show the location of your screenshots."));
}
else
e_util_dialog_show
(_("Error - No Filemanager"),
_("No filemanager action and/or module was found.<br>"
"Cannot show the location of your screenshots."));
preview_abort();
}

View File

@ -6,6 +6,8 @@ static Evas_Object *o_label = NULL;
static Evas_Object *o_entry = NULL;
static Eina_List *handlers = NULL;
static char *url_ret = NULL;
static const char *cnp_file = NULL;
static Eina_Bool cnp = EINA_FALSE;
// clean up and be done
static void
@ -19,6 +21,47 @@ _share_done(void)
preview_abort();
}
static void
_cnp_thread_io(void *data, Ecore_Thread *eth EINA_UNUSED)
{
char *file = data;
unsigned char *fdata = NULL;
ssize_t fsize = 0;
FILE *f = fopen(file, "r");
if (!f) goto err;
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
if (fsize > 0)
{
fdata = malloc(fsize);
if (fdata)
{
if (fread(fdata, fsize, 1, f) == 1)
{
ecore_thread_main_loop_begin();
elm_cnp_selection_set(e_comp->elm,
ELM_SEL_TYPE_CLIPBOARD,
ELM_SEL_FORMAT_IMAGE,
fdata, fsize);
ecore_thread_main_loop_end();
}
free(fdata);
}
}
fclose(f);
eina_file_unlink(file);
err:
free(file);
}
static void
_cnp_file(const char *file)
{
ecore_thread_run(_cnp_thread_io, NULL, NULL, strdup(file));
}
// the upload dialog
static void
_upload_ok_cb(void *data EINA_UNUSED, E_Dialog *dia)
@ -46,6 +89,11 @@ _img_write_end_cb(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event)
if (ev->exe != img_write_exe) return EINA_TRUE;
_share_done();
if (cnp)
{
_cnp_file(cnp_file);
eina_stringshare_replace(&cnp_file, NULL);
}
return EINA_FALSE;
}
@ -102,8 +150,13 @@ done:
}
void
share_save(const char *cmd)
share_save(const char *cmd, const char *file, Eina_Bool copy)
{
if (copy)
{
eina_stringshare_replace(&cnp_file, file);
cnp = copy;
}
share_write_end_watch(NULL);
img_write_exe = ecore_exe_pipe_run
(cmd, ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_READ_LINE_BUFFERED |
@ -142,7 +195,7 @@ share_dialog_show(void)
E_FREE_LIST(handlers, ecore_event_handler_del);
save_to(NULL);
save_to(NULL, EINA_FALSE);
E_FREE_FUNC(win, evas_object_del);