From 20d281d9d3cc1be530f50fc91a3e55dbf8015b55 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 9 Jul 2015 14:42:55 -0400 Subject: [PATCH] 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 --- src/bin/e_comp_x.c | 2 + src/bin/e_pointer.c | 152 ++++++++++++++++++++++---------------------- src/bin/e_pointer.h | 4 +- 3 files changed, 82 insertions(+), 76 deletions(-) diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index fe4c2731d..e52828762 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -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(); { diff --git a/src/bin/e_pointer.c b/src/bin/e_pointer.c index 696658a2e..f7c4e04ac 100644 --- a/src/bin/e_pointer.c +++ b/src/bin/e_pointer.c @@ -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; diff --git a/src/bin/e_pointer.h b/src/bin/e_pointer.h index ba383983d..8aeed7ff4 100644 --- a/src/bin/e_pointer.h +++ b/src/bin/e_pointer.h @@ -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;