summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-11-01 19:26:03 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-11-01 19:26:03 -0200
commit016faae65041a1f5c56b3ddf4c34e71ee2cc0ffe (patch)
treed6c47ab14c542d139e00ef253b4d78d9ea522d29
parent1745503b893095e3742549e2d74781d92c2c0dfd (diff)
termio: right click on links show special menu.
This patches uses ctxpopup (ugh, this bitch is awful) to show a contextual menu about that link with options such Preview (if able to inline), Open (forces xdg-open) and Copy, then you don't have to select a link in order to copy it :-) This fixes T430 (terminology should copy link on right-click and no selection)
-rw-r--r--src/bin/termio.c135
1 files changed, 113 insertions, 22 deletions
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 422c956..eca40bc 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -53,6 +53,7 @@ struct _Termio
53 int x1, y1, x2, y2; 53 int x1, y1, x2, y2;
54 int suspend; 54 int suspend;
55 Eina_List *objs; 55 Eina_List *objs;
56 Evas_Object *ctxpopup;
56 struct { 57 struct {
57 Evas_Object *dndobj; 58 Evas_Object *dndobj;
58 Evas_Coord x, y; 59 Evas_Coord x, y;
@@ -66,6 +67,7 @@ struct _Termio
66 unsigned int last_keyup; 67 unsigned int last_keyup;
67 Eina_List *mirrors; 68 Eina_List *mirrors;
68 Eina_List *seq; 69 Eina_List *seq;
70 Evas_Object *self;
69 Evas_Object *event; 71 Evas_Object *event;
70 Termpty *pty; 72 Termpty *pty;
71 Ecore_Animator *anim; 73 Ecore_Animator *anim;
@@ -102,6 +104,7 @@ static Eina_List *terms = NULL;
102static void _smart_calculate(Evas_Object *obj); 104static void _smart_calculate(Evas_Object *obj);
103static void _smart_mirror_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *info EINA_UNUSED); 105static void _smart_mirror_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *info EINA_UNUSED);
104static void _lost_selection(void *data, Elm_Sel_Type selection); 106static void _lost_selection(void *data, Elm_Sel_Type selection);
107static void _take_selection_text(Evas_Object *obj, Elm_Sel_Type type, const char *text);
105 108
106static void 109static void
107_sel_set(Evas_Object *obj, Eina_Bool enable) 110_sel_set(Evas_Object *obj, Eina_Bool enable)
@@ -133,7 +136,7 @@ _should_inline(const Evas_Object *obj)
133} 136}
134 137
135static void 138static void
136_activate_link(Evas_Object *obj) 139_activate_link(Evas_Object *obj, Eina_Bool may_inline)
137{ 140{
138 Termio *sd = evas_object_smart_data_get(obj); 141 Termio *sd = evas_object_smart_data_get(obj);
139 Config *config = termio_config_get(obj); 142 Config *config = termio_config_get(obj);
@@ -196,7 +199,7 @@ _activate_link(Evas_Object *obj)
196 if (escaped) 199 if (escaped)
197 { 200 {
198 type = media_src_type_get(sd->link.string); 201 type = media_src_type_get(sd->link.string);
199 if (_should_inline(obj)) 202 if (may_inline && _should_inline(obj))
200 { 203 {
201 if ((type == TYPE_IMG) || 204 if ((type == TYPE_IMG) ||
202 (type == TYPE_SCALE) || 205 (type == TYPE_SCALE) ||
@@ -247,7 +250,7 @@ _activate_link(Evas_Object *obj)
247 if (escaped) 250 if (escaped)
248 { 251 {
249 type = media_src_type_get(sd->link.string); 252 type = media_src_type_get(sd->link.string);
250 if (_should_inline(obj)) 253 if (may_inline && _should_inline(obj))
251 { 254 {
252 if ((type == TYPE_IMG) || 255 if ((type == TYPE_IMG) ||
253 (type == TYPE_SCALE) || 256 (type == TYPE_SCALE) ||
@@ -301,16 +304,86 @@ _activate_link(Evas_Object *obj)
301} 304}
302 305
303static void 306static void
307_cb_ctxp_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
308{
309 Termio *sd = data;
310 sd->link.ctxpopup = NULL;
311 elm_object_focus_set(sd->self, EINA_TRUE);
312}
313
314static void
315_cb_ctxp_dismissed(void *data, Evas_Object *obj, void *event EINA_UNUSED)
316{
317 evas_object_del(obj);
318}
319
320static void
321_cb_ctxp_link_preview(void *data, Evas_Object *obj, void *event EINA_UNUSED)
322{
323 Evas_Object *term = data;
324 _activate_link(term, EINA_TRUE);
325 evas_object_del(obj);
326}
327
328static void
329_cb_ctxp_link_open(void *data, Evas_Object *obj, void *event EINA_UNUSED)
330{
331 Evas_Object *term = data;
332 _activate_link(term, EINA_FALSE);
333 evas_object_del(obj);
334}
335
336static void
337_cb_ctxp_link_copy(void *data, Evas_Object *obj, void *event EINA_UNUSED)
338{
339 Evas_Object *term = data;
340 Termio *sd = evas_object_smart_data_get(term);
341 EINA_SAFETY_ON_NULL_RETURN(sd);
342 EINA_SAFETY_ON_NULL_RETURN(sd->link.string);
343 _take_selection_text(term, ELM_SEL_TYPE_CLIPBOARD, sd->link.string);
344 evas_object_del(obj);
345}
346
347static void
304_cb_link_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) 348_cb_link_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
305{ 349{
306 Evas_Event_Mouse_Down *ev = event; 350 Evas_Event_Mouse_Down *ev = event;
307 Termio *sd = evas_object_smart_data_get(data); 351 Termio *sd = evas_object_smart_data_get(data);
308 if (!sd) return; 352 if (!sd) return;
309 353
310 if (ev->button != 1) return; 354 if (ev->button == 1)
311 sd->link.down.down = EINA_TRUE; 355 {
312 sd->link.down.x = ev->canvas.x; 356 sd->link.down.down = EINA_TRUE;
313 sd->link.down.y = ev->canvas.y; 357 sd->link.down.x = ev->canvas.x;
358 sd->link.down.y = ev->canvas.y;
359 }
360 else if (ev->button == 3)
361 {
362 Evas_Object *ctxp = elm_ctxpopup_add(sd->win);
363 sd->link.ctxpopup = ctxp;
364
365 if (sd->config->helper.inline_please)
366 {
367 int type = media_src_type_get(sd->link.string);
368
369 if ((type == TYPE_IMG) ||
370 (type == TYPE_SCALE) ||
371 (type == TYPE_EDJE) ||
372 (type == TYPE_MOV))
373 elm_ctxpopup_item_append(ctxp, "Preview", NULL,
374 _cb_ctxp_link_preview, sd->self);
375 }
376 elm_ctxpopup_item_append(ctxp, "Open", NULL, _cb_ctxp_link_open,
377 sd->self);
378 elm_ctxpopup_item_append(ctxp, "Copy", NULL, _cb_ctxp_link_copy,
379 sd->self);
380 evas_object_move(ctxp, ev->canvas.x, ev->canvas.y);
381 evas_object_show(ctxp);
382 evas_object_smart_callback_add(ctxp, "dismissed",
383 _cb_ctxp_dismissed, sd);
384 evas_object_event_callback_add(ctxp, EVAS_CALLBACK_DEL,
385 _cb_ctxp_del, sd);
386 }
314} 387}
315 388
316static Eina_Bool 389static Eina_Bool
@@ -320,7 +393,7 @@ _cb_link_up_delay(void *data)
320 if (!sd) return EINA_FALSE; 393 if (!sd) return EINA_FALSE;
321 394
322 sd->link_do_timer = NULL; 395 sd->link_do_timer = NULL;
323 if (!sd->didclick) _activate_link(data); 396 if (!sd->didclick) _activate_link(data, EINA_TRUE);
324 sd->didclick = EINA_FALSE; 397 sd->didclick = EINA_FALSE;
325 return EINA_FALSE; 398 return EINA_FALSE;
326} 399}
@@ -1695,6 +1768,28 @@ _lost_selection(void *data, Elm_Sel_Type selection)
1695} 1768}
1696 1769
1697static void 1770static void
1771_take_selection_text(Evas_Object *obj, Elm_Sel_Type type, const char *text)
1772{
1773 Termio *sd = evas_object_smart_data_get(obj);
1774
1775 text = eina_stringshare_add(text);
1776
1777 sd->have_sel = EINA_FALSE;
1778 sd->reset_sel = EINA_FALSE;
1779 sd->set_sel_at = ecore_time_get(); // hack
1780 sd->sel_type = type;
1781 elm_cnp_selection_set(sd->win, type,
1782 ELM_SEL_FORMAT_TEXT,
1783 text,
1784 eina_stringshare_strlen(text));
1785 elm_cnp_selection_loss_callback_set(sd->win, type,
1786 _lost_selection, obj);
1787 sd->have_sel = EINA_TRUE;
1788 if (sd->sel_str) eina_stringshare_del(sd->sel_str);
1789 sd->sel_str = text;
1790}
1791
1792static void
1698_take_selection(Evas_Object *obj, Elm_Sel_Type type) 1793_take_selection(Evas_Object *obj, Elm_Sel_Type type)
1699{ 1794{
1700 Termio *sd = evas_object_smart_data_get(obj); 1795 Termio *sd = evas_object_smart_data_get(obj);
@@ -1754,19 +1849,7 @@ _take_selection(Evas_Object *obj, Elm_Sel_Type type)
1754 if (s) 1849 if (s)
1755 { 1850 {
1756 if ((sd->win) && (len > 0)) 1851 if ((sd->win) && (len > 0))
1757 { 1852 _take_selection_text(obj, type, s);
1758 sd->have_sel = EINA_FALSE;
1759 sd->reset_sel = EINA_FALSE;
1760 sd->set_sel_at = ecore_time_get(); // hack
1761 sd->sel_type = type;
1762 elm_cnp_selection_set(sd->win, type,
1763 ELM_SEL_FORMAT_TEXT, s, len);
1764 elm_cnp_selection_loss_callback_set(sd->win, type,
1765 _lost_selection, obj);
1766 sd->have_sel = EINA_TRUE;
1767 if (sd->sel_str) eina_stringshare_del(sd->sel_str);
1768 sd->sel_str = eina_stringshare_add(s);
1769 }
1770 free(s); 1853 free(s);
1771 } 1854 }
1772} 1855}
@@ -2247,6 +2330,9 @@ _smart_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
2247 2330
2248 sd = evas_object_smart_data_get(data); 2331 sd = evas_object_smart_data_get(data);
2249 if (!sd) return; 2332 if (!sd) return;
2333
2334 if (sd->link.ctxpopup) return; /* ctxp triggers focus out we should ignore */
2335
2250 edje_object_signal_emit(sd->cur.obj, "focus,out", "terminology"); 2336 edje_object_signal_emit(sd->cur.obj, "focus,out", "terminology");
2251 if (!sd->win) return; 2337 if (!sd->win) return;
2252 elm_win_keyboard_mode_set(sd->win, ELM_WIN_KEYBOARD_OFF); 2338 elm_win_keyboard_mode_set(sd->win, ELM_WIN_KEYBOARD_OFF);
@@ -3059,7 +3145,8 @@ _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUS
3059 else if (ev->button == 3) 3145 else if (ev->button == 3)
3060 { 3146 {
3061 elm_object_focus_set(data, EINA_TRUE); 3147 elm_object_focus_set(data, EINA_TRUE);
3062 evas_object_smart_callback_call(data, "options", NULL); 3148 if (!sd->link.string)
3149 evas_object_smart_callback_call(data, "options", NULL);
3063 } 3150 }
3064} 3151}
3065 3152
@@ -3202,6 +3289,9 @@ _smart_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
3202 3289
3203 sd = evas_object_smart_data_get(data); 3290 sd = evas_object_smart_data_get(data);
3204 if (!sd) return; 3291 if (!sd) return;
3292
3293 if (sd->link.ctxpopup) return; /* ctxp triggers mouse out we should ignore */
3294
3205 termio_mouseover_suspend_pushpop(data, 1); 3295 termio_mouseover_suspend_pushpop(data, 1);
3206 ty_dbus_link_hide(); 3296 ty_dbus_link_hide();
3207 if ((ev->canvas.x == 0) || (ev->canvas.y == 0)) 3297 if ((ev->canvas.x == 0) || (ev->canvas.y == 0))
@@ -3496,6 +3586,7 @@ _smart_add(Evas_Object *obj)
3496 evas_object_smart_data_set(obj, sd); 3586 evas_object_smart_data_set(obj, sd);
3497 3587
3498 _parent_sc.add(obj); 3588 _parent_sc.add(obj);
3589 sd->self = obj;
3499 3590
3500 /* Terminal output widget */ 3591 /* Terminal output widget */
3501 o = evas_object_textgrid_add(evas_object_evas_get(obj)); 3592 o = evas_object_textgrid_add(evas_object_evas_get(obj));