elementary: Provide EFL mouse pointers for Wayland Client applications

This commit allows EFL wayland client applications to make use of EFL
mouse pointers instead of the wayland-cursor provided ones.

NB: There are still some minor hiccups with this (move pointer does
not change, mouse pointer getting clipped off when on the lower
border, etc) but those will get sorted out soon.

Feature request by the old man ;)

@feature

Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
Chris Michael 2016-10-21 15:28:13 -04:00
parent 2b493bf4ab
commit 0a46096337
2 changed files with 126 additions and 65 deletions

View File

@ -919,8 +919,22 @@ _elm_win_mouse_in(Ecore_Evas *ee)
_elm_win_throttle_ok = EINA_TRUE;
if (sd->resizing) sd->resizing = EINA_FALSE;
#ifdef HAVE_ELEMENTARY_WL2
if (sd->wl.win && (!sd->frame_obj))
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
ecore_evas_object_cursor_set(sd->ee, sd->pointer.obj,
ELM_OBJECT_LAYER_CURSOR,
sd->pointer.hot_x, sd->pointer.hot_y);
#endif
}
static void
_elm_win_mouse_out(Ecore_Evas *ee)
{
Efl_Ui_Win_Data *sd = _elm_win_associate_get(ee);
if (!sd) return;
#ifdef HAVE_ELEMENTARY_WL2
sd->pointer.obj = ecore_evas_cursor_unset(sd->ee);
#endif
}
@ -3503,10 +3517,14 @@ _elm_win_frame_cb_move_start(void *data,
if (!sd) return;
#ifdef HAVE_ELEMENTARY_WL2
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
if (!strcmp(source, "elm"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win, ELM_CURSOR_HAND1);
_elm_theme_object_set(sd->obj, sd->pointer.obj,
"pointer", "base", "move");
else
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
_elm_theme_object_set(sd->obj, sd->pointer.obj,
"pointer", "base", "default");
#else
(void)source;
#endif
@ -3534,6 +3552,7 @@ _elm_win_frame_cb_move_stop(void *data,
#ifdef HAVE_ELEMENTARY_WL2
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base", "default");
#endif
}
@ -3561,19 +3580,6 @@ static struct _resize_info _border_corner[4] =
};
#endif
static void
_elm_win_frame_obj_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
#ifdef HAVE_ELEMENTARY_WL2
Efl_Ui_Win_Data *sd = data;
if (sd->wl.win)
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
#else
(void)data;
#endif
}
static void
_elm_win_frame_obj_move(void *data,
Evas *e EINA_UNUSED,
@ -3614,34 +3620,44 @@ _elm_win_frame_cb_resize_show(void *data,
if (sd->resizing) return;
#ifdef HAVE_ELEMENTARY_WL2
Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
int i;
i = sd->rot / 90;
if (!strcmp(source, "elm.event.resize.t"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_side[(0 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_side[(0 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.b"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_side[(2 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_side[(2 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.l"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_side[(1 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_side[(1 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.r"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_side[(3 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_side[(3 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.tl"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_corner[(0 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_corner[(0 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.tr"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_corner[(3 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_corner[(3 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.bl"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_corner[(1 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_corner[(1 + i) % 4].name);
else if (!strcmp(source, "elm.event.resize.br"))
ecore_wl2_window_cursor_from_name_set(sd->wl.win,
_border_corner[(2 + i) % 4].name);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base",
_border_corner[(2 + i) % 4].name);
else
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base", "default");
edje_object_size_min_calc(sd->pointer.obj, &mw, &mh);
evas_object_resize(sd->pointer.obj, mw, mh);
edje_object_part_geometry_get(sd->pointer.obj, "elm.swallow.hotspot",
&hx, &hy, NULL, NULL);
sd->pointer.hot_x = hx;
sd->pointer.hot_y = hy;
#else
(void)source;
#endif
@ -3659,7 +3675,7 @@ _elm_win_frame_cb_resize_hide(void *data,
if (sd->resizing) return;
#ifdef HAVE_ELEMENTARY_WL2
ecore_wl2_window_cursor_from_name_set(sd->wl.win, NULL);
_elm_theme_object_set(sd->obj, sd->pointer.obj, "pointer", "base", "default");
#endif
}
@ -3817,6 +3833,39 @@ _elm_win_frame_pre_render(void *data, Evas *e EINA_UNUSED, void *ev EINA_UNUSED)
}
#endif
static void
_elm_win_frame_cb_mouse_down(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_Win_Data *sd;
if (!(sd = data)) return;
if (!sd->pointer.obj) return;
edje_object_signal_emit(sd->pointer.obj, "elm,action,mouse,down", "elm");
}
static void
_elm_win_frame_cb_mouse_up(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_Win_Data *sd;
if (!(sd = data)) return;
if (!sd->pointer.obj) return;
edje_object_signal_emit(sd->pointer.obj, "elm,action,mouse,up", "elm");
}
static void
_elm_win_frame_cb_mouse_move(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_Win_Data *sd;
if (!(sd = data)) return;
if (!sd->pointer.obj) return;
edje_object_signal_emit(sd->pointer.obj, "elm,action,mouse,move", "elm");
}
static void
_elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
{
@ -3861,15 +3910,18 @@ _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
}
}
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon",
sd->icon);
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOUSE_IN, _elm_win_frame_obj_mouse_in, sd);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOUSE_DOWN, _elm_win_frame_cb_mouse_down, sd);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOUSE_UP, _elm_win_frame_cb_mouse_up, sd);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOUSE_MOVE, _elm_win_frame_cb_mouse_move, sd);
/* NB: Do NOT remove these calls !! Needed to calculate proper
* framespace on initial show of the window */
@ -3987,7 +4039,6 @@ _debug_key_down(void *data EINA_UNUSED,
INF("Tree graph generated.");
elm_object_tree_dot_dump(obj, "./dump.dot");
}
#endif
static void
@ -4653,7 +4704,11 @@ _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Elm_W
ecore_evas_callback_move_set(sd->ee, _elm_win_move);
ecore_evas_callback_pre_render_set(sd->ee, _elm_win_pre_render);
if (type != ELM_WIN_FAKE)
ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in);
{
ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in);
ecore_evas_callback_mouse_out_set(sd->ee, _elm_win_mouse_out);
}
evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _elm_win_cb_hide, NULL);
evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _elm_win_cb_show, NULL);
@ -4707,10 +4762,16 @@ _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Elm_W
if (type != ELM_WIN_FAKE)
{
/* NB: As we do not want to use standard X/FDO cursors for EFL
* Wayland Client Apps, we can use Elm Softcursor to provide an
* EFL mouse pointer for Wayland Client Apps */
if ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_ON) ||
((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_AUTO) &&
((engine) &&
((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))))))
((engine) &&
((!strcmp(engine, ELM_SOFTWARE_FB)) ||
(!strcmp(engine, ELM_DRM)) ||
(!strcmp(engine, ELM_WAYLAND_SHM)) ||
(!strcmp(engine, ELM_WAYLAND_EGL))))))
{
Evas_Object *o;
Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
@ -4723,8 +4784,15 @@ _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Elm_W
&hx, &hy, NULL, NULL);
sd->pointer.hot_x = hx;
sd->pointer.hot_y = hy;
evas_object_show(o);
ecore_evas_object_cursor_set(tmp_sd.ee, o, EVAS_LAYER_MAX, hx, hy);
/* NB: Sadly we have to mark pointer as a frame object now due
* to the recent changes in evas_render wrt framespace & context
* clipping...if we do not, then the pointer never gets drawn
* over the frame object due to clipping */
evas_object_is_frame_object_set(sd->pointer.obj, EINA_TRUE);
ecore_evas_object_cursor_set(tmp_sd.ee, o,
ELM_OBJECT_LAYER_CURSOR, hx, hy);
}
else if (_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_OFF)
{

View File

@ -282,6 +282,7 @@ _elm_cursor_set(Elm_Cursor *cur)
if (cur->visible) return;
evas_event_freeze(cur->evas);
if (!cur->use_engine)
{
if (!cur->obj)
@ -305,10 +306,6 @@ _elm_cursor_set(Elm_Cursor *cur)
if (cur->x.win)
ecore_x_window_cursor_set(cur->x.win, cur->x.cursor);
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (cur->wl.win)
ecore_wl2_window_cursor_from_name_set(cur->wl.win, cur->cursor_name);
#endif
#ifdef HAVE_ELEMENTARY_COCOA
if (cur->cocoa.win)
@ -365,18 +362,15 @@ _elm_cursor_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_
}
if (!cur->use_engine)
ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR,
cur->hot_x, cur->hot_y);
cur->obj = ecore_evas_cursor_unset(cur->ee);
/* ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR, */
/* cur->hot_x, cur->hot_y); */
else
{
#ifdef HAVE_ELEMENTARY_X
if (cur->x.win)
ecore_x_window_cursor_set(cur->x.win, ECORE_X_CURSOR_X);
#endif
#ifdef HAVE_ELEMENTARY_WL2
if (cur->wl.win)
ecore_wl2_window_cursor_from_name_set(cur->wl.win, NULL);
#endif
#ifdef HAVE_ELEMENTARY_COCOA
if (cur->cocoa.win)
@ -427,12 +421,15 @@ _elm_cursor_cur_set(Elm_Cursor *cur)
cur->use_engine = EINA_TRUE;
}
#ifdef HAVE_ELEMENTARY_DRM
#if defined (HAVE_ELEMENTARY_DRM) || defined(HAVE_ELEMENTARY_WL2)
const char *engine_name;
engine_name = ecore_evas_engine_name_get(cur->ee);
if ((engine_name) && (!strcmp(engine_name, ELM_DRM)))
cur->use_engine = EINA_FALSE;
if ((engine_name) &&
((!strcmp(engine_name, ELM_DRM)) ||
(!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
(!strcmp(engine_name, ELM_WAYLAND_EGL))))
cur->use_engine = EINA_FALSE;
#endif
if (cur->use_engine)
@ -481,9 +478,9 @@ _elm_cursor_cur_set(Elm_Cursor *cur)
}
#endif
#ifdef HAVE_ELEMENTARY_WL2
cur->wl.win = elm_win_wl_window_get(top);
#endif
/* #ifdef HAVE_ELEMENTARY_WL2 */
/* cur->wl.win = elm_win_wl_window_get(top); */
/* #endif */
#ifdef HAVE_ELEMENTARY_WIN32
cur->win32.win = elm_win_win32_window_get(top);
if (cur->win32.win)
@ -627,10 +624,6 @@ elm_object_cursor_unset(Evas_Object *obj)
else if (cur->cocoa.win)
ecore_cocoa_window_cursor_set(cur->cocoa.win, ECORE_COCOA_CURSOR_DEFAULT);
#endif
#ifdef HAVE_ELEMENTARY_WL2
else if (cur->wl.win)
ecore_wl2_window_cursor_from_name_set(cur->wl.win, NULL);
#endif
#ifdef HAVE_ELEMENTARY_WIN32
else
ecore_win32_window_cursor_set(cur->win32.win, ecore_win32_cursor_shaped_new(ECORE_WIN32_CURSOR_SHAPE_ARROW));