redo e_pointer to support xwayland cursors
this requires that both canvas cursors and window cursors be present for the same E_Pointer object, even though only the canvas cursor is actually visible #kansas
This commit is contained in:
parent
cc5aa9153d
commit
20d281d9d3
|
@ -5183,6 +5183,8 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
|
|||
e_pointer_type_push(e_comp->pointer, e_comp->pointer, "default");
|
||||
ecore_x_icccm_state_set(ecore_evas_window_get(e_comp->ee), ECORE_X_WINDOW_STATE_HINT_NORMAL);
|
||||
}
|
||||
else
|
||||
e_comp->pointer->win = e_comp->root;
|
||||
_e_comp_x_manage_windows();
|
||||
|
||||
{
|
||||
|
|
|
@ -55,12 +55,12 @@ _e_pointer_cb_idle_poller(void *data)
|
|||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (!ptr->canvas)
|
||||
ecore_x_pointer_xy_get(ptr->win, &x, &y);
|
||||
else
|
||||
#endif
|
||||
if (ptr->canvas)
|
||||
ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
else
|
||||
ecore_x_pointer_xy_get(ptr->win, &x, &y);
|
||||
#endif
|
||||
|
||||
if ((ptr->x != x) || (ptr->y != y))
|
||||
{
|
||||
|
@ -103,12 +103,12 @@ _e_pointer_cb_idle_pre(void *data)
|
|||
|
||||
if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
|
||||
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (!ptr->canvas)
|
||||
ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
|
||||
else
|
||||
#endif
|
||||
if (ptr->canvas)
|
||||
ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
else
|
||||
ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
|
||||
#endif
|
||||
|
||||
ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
|
||||
|
||||
|
@ -209,10 +209,9 @@ _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev
|
|||
static void
|
||||
_e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
||||
{
|
||||
E_Pointer *ptr;
|
||||
E_Pointer *ptr = data;
|
||||
int x = 0, y = 0;
|
||||
|
||||
if (!(ptr = data)) return;
|
||||
if (!ptr->e_cursor) return;
|
||||
if (!evas_object_visible_get(ptr->o_ptr)) return;
|
||||
edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
|
||||
|
@ -223,22 +222,40 @@ _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA
|
|||
static void
|
||||
_e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
||||
{
|
||||
E_Pointer *ptr;
|
||||
E_Pointer *ptr = data;
|
||||
int x = 0, y = 0;
|
||||
|
||||
if (!(ptr = data)) return;
|
||||
if (!ptr->e_cursor) return;
|
||||
edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
|
||||
&x, &y, NULL, NULL);
|
||||
_e_pointer_hot_update(ptr, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_pointer_pointer_canvas_init(E_Pointer *ptr, Evas *e, Evas_Object **o_ptr, Evas_Object **o_hot)
|
||||
{
|
||||
/* create pointer object */
|
||||
*o_ptr = edje_object_add(e);
|
||||
|
||||
/* create hotspot object */
|
||||
*o_hot = evas_object_rectangle_add(e);
|
||||
evas_object_color_set(*o_hot, 0, 0, 0, 0);
|
||||
|
||||
evas_object_event_callback_add(*o_hot, EVAS_CALLBACK_MOVE,
|
||||
_e_pointer_cb_hot_move, ptr);
|
||||
evas_object_event_callback_add(*o_hot, EVAS_CALLBACK_SHOW,
|
||||
_e_pointer_cb_hot_show, ptr);
|
||||
|
||||
evas_object_move(*o_ptr, 0, 0);
|
||||
evas_object_resize(*o_ptr, ptr->w, ptr->h);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_pointer_canvas_del(E_Pointer *ptr)
|
||||
{
|
||||
E_FREE_FUNC(ptr->o_hot, evas_object_del);
|
||||
E_FREE_FUNC(ptr->o_ptr, evas_object_del);
|
||||
if (ptr->evas) evas_free(ptr->evas);
|
||||
ptr->evas = NULL;
|
||||
E_FREE_FUNC(ptr->buffer_o_hot, evas_object_del);
|
||||
E_FREE_FUNC(ptr->buffer_o_ptr, evas_object_del);
|
||||
E_FREE_FUNC(ptr->buffer_evas, evas_free);
|
||||
E_FREE(ptr->pixels);
|
||||
}
|
||||
|
||||
|
@ -249,19 +266,19 @@ _e_pointer_canvas_add(E_Pointer *ptr)
|
|||
int method = 0;
|
||||
|
||||
/* try to create new canvas */
|
||||
if (!(ptr->evas = evas_new())) goto err;
|
||||
if (!(ptr->buffer_evas = evas_new())) goto err;
|
||||
|
||||
method = evas_render_method_lookup("buffer");
|
||||
evas_output_method_set(ptr->evas, method);
|
||||
evas_output_size_set(ptr->evas, ptr->w, ptr->h);
|
||||
evas_output_viewport_set(ptr->evas, 0, 0, ptr->w, ptr->h);
|
||||
evas_output_method_set(ptr->buffer_evas, method);
|
||||
evas_output_size_set(ptr->buffer_evas, ptr->w, ptr->h);
|
||||
evas_output_viewport_set(ptr->buffer_evas, 0, 0, ptr->w, ptr->h);
|
||||
|
||||
/* try to allocate space for pixels */
|
||||
if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
|
||||
goto err;
|
||||
|
||||
/* try to get the buffer engine info */
|
||||
einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
|
||||
einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->buffer_evas);
|
||||
if (!einfo) goto err;
|
||||
|
||||
/* fill in buffer engine info */
|
||||
|
@ -274,23 +291,15 @@ _e_pointer_canvas_add(E_Pointer *ptr)
|
|||
einfo->info.func.free_update_region = NULL;
|
||||
|
||||
/* set buffer engine info */
|
||||
evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
|
||||
|
||||
/* create pointer object */
|
||||
ptr->o_ptr = edje_object_add(ptr->evas);
|
||||
|
||||
/* create hotspot object */
|
||||
ptr->o_hot = evas_object_rectangle_add(ptr->evas);
|
||||
evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
|
||||
|
||||
evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE,
|
||||
_e_pointer_cb_hot_move, ptr);
|
||||
evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW,
|
||||
_e_pointer_cb_hot_show, ptr);
|
||||
|
||||
evas_object_move(ptr->o_ptr, 0, 0);
|
||||
evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
|
||||
evas_engine_info_set(ptr->buffer_evas, (Evas_Engine_Info *)einfo);
|
||||
|
||||
_e_pointer_pointer_canvas_init(ptr, ptr->buffer_evas, &ptr->buffer_o_ptr, &ptr->buffer_o_hot);
|
||||
if (!ptr->evas)
|
||||
{
|
||||
ptr->evas = ptr->buffer_evas;
|
||||
ptr->o_ptr = ptr->buffer_o_ptr;
|
||||
ptr->o_hot = ptr->buffer_o_hot;
|
||||
}
|
||||
return;
|
||||
|
||||
err:
|
||||
|
@ -305,20 +314,20 @@ _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
|
|||
if ((ptr->w == w) && (ptr->h == h)) return;
|
||||
ptr->w = w;
|
||||
ptr->h = h;
|
||||
evas_output_size_set(ptr->evas, w, h);
|
||||
evas_output_viewport_set(ptr->evas, 0, 0, w, h);
|
||||
evas_output_size_set(ptr->buffer_evas, w, h);
|
||||
evas_output_viewport_set(ptr->buffer_evas, 0, 0, w, h);
|
||||
|
||||
ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
|
||||
|
||||
einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
|
||||
einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->buffer_evas);
|
||||
EINA_SAFETY_ON_NULL_RETURN(einfo);
|
||||
|
||||
einfo->info.dest_buffer = ptr->pixels;
|
||||
einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
|
||||
evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
|
||||
evas_engine_info_set(ptr->buffer_evas, (Evas_Engine_Info *)einfo);
|
||||
|
||||
evas_object_move(ptr->o_ptr, 0, 0);
|
||||
evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
|
||||
evas_object_move(ptr->buffer_o_ptr, 0, 0);
|
||||
evas_object_resize(ptr->buffer_o_ptr, ptr->w, ptr->h);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -340,7 +349,7 @@ _e_pointer_cb_free(E_Pointer *ptr)
|
|||
E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
|
||||
E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
|
||||
|
||||
if (!ptr->canvas) _e_pointer_canvas_del(ptr);
|
||||
if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
@ -366,7 +375,7 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
|
|||
int x = 0, y = 0;
|
||||
|
||||
/* create a pointer canvas if we need to */
|
||||
if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
|
||||
if ((!ptr->buffer_evas) && ptr->win) _e_pointer_canvas_add(ptr);
|
||||
|
||||
if (ptr->color)
|
||||
snprintf(cursor, sizeof(cursor),
|
||||
|
@ -378,8 +387,11 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
|
|||
/* try to set the edje object theme */
|
||||
if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
|
||||
goto fallback;
|
||||
|
||||
edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
|
||||
if (ptr->buffer_o_ptr && (ptr->buffer_o_ptr != ptr->o_ptr))
|
||||
{
|
||||
e_theme_edje_object_set(ptr->buffer_o_ptr, "base/theme/pointer", cursor);
|
||||
edje_object_part_swallow(ptr->buffer_o_ptr, "e.swallow.hotspot", ptr->buffer_o_hot);
|
||||
}
|
||||
|
||||
edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
|
||||
&x, &y, NULL, NULL);
|
||||
|
@ -394,8 +406,9 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
|
|||
}
|
||||
|
||||
fallback:
|
||||
if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
|
||||
if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (!e_comp_util_has_x()) return;
|
||||
Ecore_X_Cursor cursor = 0;
|
||||
|
||||
if (!strcmp(type, "move"))
|
||||
|
@ -439,7 +452,6 @@ fallback:
|
|||
ecore_x_window_cursor_set(ptr->win, cursor);
|
||||
if (cursor) ecore_x_cursor_free(cursor);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
EINTERN int
|
||||
|
@ -510,18 +522,7 @@ e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
|
|||
|
||||
ptr->ee = ee;
|
||||
ptr->evas = ecore_evas_get(ee);
|
||||
|
||||
ptr->o_ptr = edje_object_add(ptr->evas);
|
||||
|
||||
ptr->o_hot = evas_object_rectangle_add(ptr->evas);
|
||||
evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
|
||||
evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE,
|
||||
_e_pointer_cb_hot_move, ptr);
|
||||
evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW,
|
||||
_e_pointer_cb_hot_show, ptr);
|
||||
|
||||
evas_object_move(ptr->o_ptr, 0, 0);
|
||||
evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
|
||||
_e_pointer_pointer_canvas_init(ptr, ptr->evas, &ptr->o_ptr, &ptr->o_hot);
|
||||
|
||||
/* set pointer default type */
|
||||
if (filled) e_pointer_type_push(ptr, ptr, "default");
|
||||
|
@ -545,30 +546,31 @@ e_pointers_size_set(int size)
|
|||
EINA_LIST_FOREACH(_ptrs, l, ptr)
|
||||
{
|
||||
if ((ptr->w == size) && (ptr->h == size)) continue;
|
||||
if ((ptr->evas) && (!ptr->canvas))
|
||||
if (ptr->buffer_evas)
|
||||
_e_pointer_canvas_resize(ptr, size, size);
|
||||
else if (ptr->canvas)
|
||||
if (ptr->canvas)
|
||||
{
|
||||
ptr->w = size;
|
||||
ptr->h = size;
|
||||
evas_object_resize(ptr->o_ptr, size, size);
|
||||
}
|
||||
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
|
||||
#endif
|
||||
}
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (e_comp_util_has_x())
|
||||
ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_pointer_hide(E_Pointer *ptr)
|
||||
{
|
||||
if ((ptr->evas) && (!ptr->canvas))
|
||||
if (ptr->buffer_evas)
|
||||
_e_pointer_canvas_del(ptr);
|
||||
else if (ptr->canvas)
|
||||
if (ptr->canvas)
|
||||
evas_object_hide(ptr->o_ptr);
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
ecore_x_window_cursor_set(ptr->win, 0);
|
||||
if (ptr->win)
|
||||
ecore_x_window_cursor_set(ptr->win, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -720,16 +722,16 @@ e_pointer_idler_before(void)
|
|||
|
||||
EINA_LIST_FOREACH(_ptrs, l, ptr)
|
||||
{
|
||||
if ((!ptr->e_cursor) || (!ptr->evas)) continue;
|
||||
if ((!ptr->e_cursor) || (!ptr->buffer_evas)) continue;
|
||||
|
||||
if (ptr->hot.update)
|
||||
_e_pointer_type_set(ptr, ptr->type);
|
||||
|
||||
if (!ptr->canvas)
|
||||
if (ptr->buffer_evas)
|
||||
{
|
||||
Eina_List *updates;
|
||||
|
||||
if ((updates = evas_render_updates(ptr->evas)))
|
||||
if ((updates = evas_render_updates(ptr->buffer_evas)))
|
||||
{
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
Ecore_X_Cursor cur;
|
||||
|
|
|
@ -29,10 +29,12 @@ struct _E_Pointer
|
|||
|
||||
Evas *evas;
|
||||
Ecore_Evas *ee;
|
||||
Evas *buffer_evas;
|
||||
Evas_Object *o_ptr;
|
||||
Evas_Object *o_hot;
|
||||
Evas_Object *buffer_o_ptr;
|
||||
Evas_Object *buffer_o_hot;
|
||||
|
||||
// E_Pixmap *pixmap;
|
||||
Ecore_Window win;
|
||||
|
||||
int *pixels;
|
||||
|
|
Loading…
Reference in New Issue