summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2018-12-17 21:51:05 +0100
committerBoris Faure <billiob@gmail.com>2018-12-17 21:53:01 +0100
commite7cbae77e1856d5c960d636584622492be65a58d (patch)
tree270063d9793a8301d6f40432871ed1fa0c4c5804
parenta01f9ba65beeced76062f6174bda3236784c0ab7 (diff)
media/win: allow fallback to xdg-open after user interaction
Closes T7504
-rw-r--r--src/bin/media.c17
-rw-r--r--src/bin/media.h1
-rw-r--r--src/bin/win.c97
3 files changed, 92 insertions, 23 deletions
diff --git a/src/bin/media.c b/src/bin/media.c
index d715519..bda41b4 100644
--- a/src/bin/media.c
+++ b/src/bin/media.c
@@ -1531,3 +1531,20 @@ media_control_get(const Evas_Object *obj)
1531 if (!sd) return NULL; 1531 if (!sd) return NULL;
1532 return sd->o_ctrl; 1532 return sd->o_ctrl;
1533} 1533}
1534
1535void
1536media_unknown_handle(const char *handler, const char *src)
1537{
1538 const char *cmd;
1539 char buf[PATH_MAX];
1540 char *escaped;
1541 cmd = "xdg-open";
1542 escaped = ecore_file_escape_name(src);
1543 if (!escaped)
1544 return;
1545 if (handler && *handler)
1546 cmd = handler;
1547 snprintf(buf, sizeof(buf), "%s %s", cmd, escaped);
1548 free(escaped);
1549 ecore_exe_run(buf, NULL);
1550}
diff --git a/src/bin/media.h b/src/bin/media.h
index 014ed8f..5f33cd4 100644
--- a/src/bin/media.h
+++ b/src/bin/media.h
@@ -38,5 +38,6 @@ void media_stop(Evas_Object *obj);
38const char *media_get(const Evas_Object *obj); 38const char *media_get(const Evas_Object *obj);
39Media_Type media_src_type_get(const char *src); 39Media_Type media_src_type_get(const char *src);
40Evas_Object *media_control_get(const Evas_Object *obj); 40Evas_Object *media_control_get(const Evas_Object *obj);
41void media_unknown_handle(const char *handler, const char *src);
41 42
42#endif 43#endif
diff --git a/src/bin/win.c b/src/bin/win.c
index 75c7cd8..a53efd0 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -4058,6 +4058,7 @@ typedef struct _Ty_Http_Head {
4058 Ecore_Event_Handler *url_complete; 4058 Ecore_Event_Handler *url_complete;
4059 Ecore_Timer *timeout; 4059 Ecore_Timer *timeout;
4060 Term *term; 4060 Term *term;
4061 Eina_Bool fallback_allowed;
4061} Ty_Http_Head; 4062} Ty_Http_Head;
4062 4063
4063static void 4064static void
@@ -4084,6 +4085,10 @@ _media_http_head_timeout(void *data)
4084 Ty_Http_Head *ty_head = data; 4085 Ty_Http_Head *ty_head = data;
4085 4086
4086 ty_head->timeout = NULL; 4087 ty_head->timeout = NULL;
4088 if (ty_head->fallback_allowed)
4089 {
4090 media_unknown_handle(ty_head->handler, ty_head->src);
4091 }
4087 _ty_http_head_delete(ty_head); 4092 _ty_http_head_delete(ty_head);
4088 return ECORE_CALLBACK_CANCEL; 4093 return ECORE_CALLBACK_CANCEL;
4089} 4094}
@@ -4151,13 +4156,17 @@ _media_http_head_complete(void *data,
4151 _ty_http_head_delete(ty_head); 4156 _ty_http_head_delete(ty_head);
4152 return EINA_TRUE; 4157 return EINA_TRUE;
4153error: 4158error:
4159 if (ty_head->fallback_allowed)
4160 {
4161 media_unknown_handle(ty_head->handler, ty_head->src);
4162 }
4154 _ty_http_head_delete(ty_head); 4163 _ty_http_head_delete(ty_head);
4155 return EINA_TRUE; 4164 return EINA_TRUE;
4156} 4165}
4157#endif 4166#endif
4158 4167
4159static void 4168static void
4160_popmedia(Term *term, const char *src) 4169_popmedia(Term *term, const char *src, Eina_Bool from_user_interaction)
4161{ 4170{
4162 Media_Type type; 4171 Media_Type type;
4163 Config *config = termio_config_get(term->termio); 4172 Config *config = termio_config_get(term->termio);
@@ -4167,22 +4176,34 @@ _popmedia(Term *term, const char *src)
4167 { 4176 {
4168#ifdef HAVE_ECORE_CON_URL_HEAD 4177#ifdef HAVE_ECORE_CON_URL_HEAD
4169 Ty_Http_Head *ty_head = calloc(1, sizeof(Ty_Http_Head)); 4178 Ty_Http_Head *ty_head = calloc(1, sizeof(Ty_Http_Head));
4170 if (!ty_head) return; 4179 if (!ty_head)
4180 return;
4171 4181
4172 if (config->helper.local.general && config->helper.local.general[0]) 4182 if (config->helper.local.general && config->helper.local.general[0])
4173 { 4183 {
4174 ty_head->handler = eina_stringshare_add(config->helper.local.general); 4184 ty_head->handler = eina_stringshare_add(config->helper.local.general);
4175 if (!ty_head->handler) goto error; 4185 if (!ty_head->handler)
4186 goto error;
4176 } 4187 }
4188 /* If it comes from a user interaction (click on a link), allow
4189 * fallback to "xdg-open"
4190 * Otherwise, it's from terminology's escape code. Thus don't allow
4191 * fallback and only display content "inline".
4192 */
4193 ty_head->fallback_allowed = from_user_interaction;
4177 ty_head->src = eina_stringshare_add(src); 4194 ty_head->src = eina_stringshare_add(src);
4178 if (!ty_head->src) goto error; 4195 if (!ty_head->src)
4196 goto error;
4179 ty_head->url = ecore_con_url_new(src); 4197 ty_head->url = ecore_con_url_new(src);
4180 if (!ty_head->url) goto error; 4198 if (!ty_head->url)
4181 if (!ecore_con_url_head(ty_head->url)) goto error; 4199 goto error;
4200 if (!ecore_con_url_head(ty_head->url))
4201 goto error;
4182 ty_head->url_complete = ecore_event_handler_add 4202 ty_head->url_complete = ecore_event_handler_add
4183 (ECORE_CON_EVENT_URL_COMPLETE, _media_http_head_complete, ty_head); 4203 (ECORE_CON_EVENT_URL_COMPLETE, _media_http_head_complete, ty_head);
4184 ty_head->timeout = ecore_timer_add(2.5, _media_http_head_timeout, ty_head); 4204 ty_head->timeout = ecore_timer_add(2.5, _media_http_head_timeout, ty_head);
4185 if (!ty_head->url_complete) goto error; 4205 if (!ty_head->url_complete)
4206 goto error;
4186 ty_head->term = term; 4207 ty_head->term = term;
4187 edje_object_signal_emit(term->bg, "busy", "terminology"); 4208 edje_object_signal_emit(term->bg, "busy", "terminology");
4188 term_ref(term); 4209 term_ref(term);
@@ -4191,6 +4212,10 @@ _popmedia(Term *term, const char *src)
4191error: 4212error:
4192 _ty_http_head_delete(ty_head); 4213 _ty_http_head_delete(ty_head);
4193#endif 4214#endif
4215 if (from_user_interaction)
4216 {
4217 media_unknown_handle(config->helper.local.general, src);
4218 }
4194 } 4219 }
4195 else 4220 else
4196 { 4221 {
@@ -4368,26 +4393,43 @@ term_set_title(Term *term)
4368 elm_object_focus_set(o, EINA_TRUE); 4393 elm_object_focus_set(o, EINA_TRUE);
4369} 4394}
4370 4395
4396struct Pop_Media {
4397 const char *src;
4398 Eina_Bool from_user_interaction;
4399};
4400
4371static void 4401static void
4372_popmedia_queue_process(Term *term) 4402_popmedia_queue_process(Term *term)
4373{ 4403{
4374 const char *src; 4404 struct Pop_Media *pm;
4375 4405
4376 if (!term->popmedia_queue) return; 4406 if (!term->popmedia_queue)
4377 src = term->popmedia_queue->data; 4407 return;
4408 pm = term->popmedia_queue->data;
4378 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue, 4409 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
4379 term->popmedia_queue); 4410 term->popmedia_queue);
4380 if (!src) return; 4411 if (!pm)
4381 _popmedia(term, src); 4412 return;
4382 eina_stringshare_del(src); 4413 _popmedia(term, pm->src, pm->from_user_interaction);
4414 eina_stringshare_del(pm->src);
4415 free(pm);
4383} 4416}
4384 4417
4385static void 4418static void
4386_popmedia_queue_add(Term *term, const char *src) 4419_popmedia_queue_add(Term *term, const char *src,
4420 Eina_Bool from_user_interaction)
4387{ 4421{
4388 term->popmedia_queue = eina_list_append(term->popmedia_queue, 4422 struct Pop_Media *pm = calloc(1, sizeof(struct Pop_Media));
4389 eina_stringshare_add(src)); 4423
4390 if (!term->popmedia) _popmedia_queue_process(term); 4424 if (!pm)
4425 return;
4426
4427 pm->src = eina_stringshare_add(src);
4428 pm->from_user_interaction = from_user_interaction;
4429
4430 term->popmedia_queue = eina_list_append(term->popmedia_queue, pm);
4431 if (!term->popmedia)
4432 _popmedia_queue_process(term);
4391} 4433}
4392 4434
4393static void 4435static void
@@ -4397,12 +4439,17 @@ _cb_popup(void *data,
4397{ 4439{
4398 Term *term = data; 4440 Term *term = data;
4399 const char *src = event; 4441 const char *src = event;
4442 Eina_Bool from_user_interaction = EINA_FALSE;
4400 4443
4401 if (!src) 4444 if (!src)
4402 src = termio_link_get(term->termio); 4445 {
4446 /* Popup a link, there was user interaction on it. */
4447 from_user_interaction = EINA_TRUE;
4448 src = termio_link_get(term->termio);
4449 }
4403 if (!src) 4450 if (!src)
4404 return; 4451 return;
4405 _popmedia(term, src); 4452 _popmedia(term, src, from_user_interaction);
4406 if (!event) 4453 if (!event)
4407 free((void*)src); 4454 free((void*)src);
4408} 4455}
@@ -4414,12 +4461,16 @@ _cb_popup_queue(void *data,
4414{ 4461{
4415 Term *term = data; 4462 Term *term = data;
4416 const char *src = event; 4463 const char *src = event;
4464 Eina_Bool from_user_interaction = EINA_FALSE;
4417 4465
4418 if (!src) 4466 if (!src)
4419 src = termio_link_get(term->termio); 4467 {
4468 from_user_interaction = EINA_TRUE;
4469 src = termio_link_get(term->termio);
4470 }
4420 if (!src) 4471 if (!src)
4421 return; 4472 return;
4422 _popmedia_queue_add(term, src); 4473 _popmedia_queue_add(term, src, from_user_interaction);
4423 if (!event) 4474 if (!event)
4424 free((void*)src); 4475 free((void*)src);
4425} 4476}
@@ -4718,11 +4769,11 @@ _cb_command(void *data,
4718 { 4769 {
4719 if (cmd[1] == 'n') // now 4770 if (cmd[1] == 'n') // now
4720 { 4771 {
4721 _popmedia(term, cmd + 2); 4772 _popmedia(term, cmd + 2, EINA_FALSE);
4722 } 4773 }
4723 else if (cmd[1] == 'q') // queue it to display after current one 4774 else if (cmd[1] == 'q') // queue it to display after current one
4724 { 4775 {
4725 _popmedia_queue_add(term, cmd + 2); 4776 _popmedia_queue_add(term, cmd + 2, EINA_FALSE);
4726 } 4777 }
4727 } 4778 }
4728 else if (cmd[0] == 'b') // set background 4779 else if (cmd[0] == 'b') // set background