diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c index b6571087d..22a904205 100644 --- a/src/bin/e_comp_canvas.c +++ b/src/bin/e_comp_canvas.c @@ -128,7 +128,6 @@ e_comp_canvas_init(E_Comp *c) evas_event_callback_add(c->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_render_post, c); c->ee_win = ecore_evas_window_get(c->ee); - c->pointer = e_pointer_window_new(c->man->root, 1); for (layer = 0; layer <= e_comp_canvas_layer_map(E_LAYER_MAX); layer++) { diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 8c94fc85b..31c56ef56 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1738,6 +1738,10 @@ _e_comp_wl_cb_surface_destroy(struct wl_resource *resource) buffer->ews = NULL; ews->buffers = eina_inlist_remove(ews->buffers, EINA_INLIST_GET(buffer)); } + if (e_comp_get(NULL)->pointer->pixmap == ews->pixmap) + { + e_pointer_image_set(e_comp_get(NULL)->pointer, NULL, 0, 0, 0, 0); + } e_pixmap_parent_window_set(ews->pixmap, NULL); e_pixmap_free(ews->pixmap); @@ -2277,53 +2281,17 @@ _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, /* do we have a focused surface ? */ if (!input->wl.seat.pointer->focus) return; - if ((focus = wl_resource_get_user_data(input->wl.seat.pointer->focus))) - { - /* NB: Ideally, I wanted to use the e_pointer methods here so that - * the cursor would match the E theme, however Wayland currently - * provides NO Method to get the cursor name :( so we are stuck - * using the pixels from their cursor surface */ + focus = wl_resource_get_user_data(input->wl.seat.pointer->focus); + if (!focus) return; + /* NB: Ideally, I wanted to use the e_pointer methods here so that + * the cursor would match the E theme, however Wayland currently + * provides NO Method to get the cursor name :( so we are stuck + * using the pixels from their cursor surface */ - /* is it mapped ? */ - if ((focus->mapped) && (focus->ec)) - { - Ecore_Window win; - - /* try to get the ecore_window */ -#warning CURSOR BROKEN -#if 0 - if ((win = ecore_evas_window_get(focus->ee))) - { - E_Wayland_Buffer_Reference *ref; - struct wl_shm_buffer *shm_buffer; - void *pixels; - - ref = &ews->buffer_reference; - - shm_buffer = wl_shm_buffer_get(ref->buffer->wl.resource); - - /* grab the pixels from the cursor surface */ - if ((pixels = wl_shm_buffer_get_data(shm_buffer))) - { - Ecore_X_Cursor cur; - - /* create the new X cursor with this image */ - cur = ecore_x_cursor_new(win, pixels, w, h, - input->pointer.hot.x, - input->pointer.hot.y); - - /* set the cursor on this window */ - ecore_x_window_cursor_set(win, cur); - - /* free the cursor */ - ecore_x_cursor_free(cur); - } - else - ecore_x_window_cursor_set(win, 0); - } -#endif - } - } + /* is it mapped ? */ + if ((!focus->mapped) || (!focus->ec)) return; + e_pixmap_dirty(ews->pixmap); + e_pointer_image_set(focus->ec->comp->pointer, ews->pixmap, w, h, input->pointer.hot.x, input->pointer.hot.y); } static void @@ -2404,7 +2372,11 @@ _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *r input->pointer.surface = ews; /* if we don't have a pointer surface, we are done here */ - if (!ews) return; + if (!ews) + { + e_pointer_hide(e_comp_get(NULL)->pointer); + return; + } /* set the destroy listener */ wl_signal_add(&ews->wl.destroy_signal, diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index 279f20a2c..ca959af38 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -4651,6 +4651,8 @@ _e_comp_x_setup(E_Comp *c, Ecore_X_Window root, int w, int h) } ecore_evas_lower(c->ee); + c->pointer = e_pointer_window_new(c->man->root, 1); + c->pointer->color = c->pointer->e_cursor && ecore_x_cursor_color_supported_get(); _e_comp_x_manage_windows(c); return !!c->bg_blank_object; diff --git a/src/bin/e_pointer.c b/src/bin/e_pointer.c index 87ccaa1d8..5529c39b7 100644 --- a/src/bin/e_pointer.c +++ b/src/bin/e_pointer.c @@ -17,54 +17,519 @@ struct _E_Pointer_Stack static Eina_List *_e_pointers = NULL; static Eina_List *handlers = NULL; -static void _e_pointer_canvas_add(E_Pointer *p); static void _e_pointer_canvas_del(E_Pointer *p); -static void _e_pointer_cb_move(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info); static void _e_pointer_free(E_Pointer *p); static void _e_pointer_stack_free(E_Pointer_Stack *elem); static void _e_pointer_type_set(E_Pointer *p, const char *type); static void _e_pointer_active_handle(E_Pointer *p); -static Eina_Bool _e_pointer_cb_mouse_down(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_up(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_move(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_wheel(void *data, - int type, - void *event); static Eina_Bool _e_pointer_cb_idle_timer_pre(void *data); static Eina_Bool _e_pointer_cb_idle_timer_wait(void *data); static Eina_Bool _e_pointer_cb_idle_poller(void *data); + +static void +_e_pointer_hot_update(E_Pointer *p, int x, int y) +{ + if ((p->hot.x != x) || (p->hot.y != y)) + { + p->hot.x = x; + p->hot.y = y; + p->hot.update = 1; + } +} + +static void +_e_pointer_active(E_Pointer *p) +{ + if (!p->idle) return; + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,state,mouse,active", "e"); + p->idle = 0; +} + +static void +_e_pointer_idle(E_Pointer *p) +{ + if (p->idle) return; + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, "e,state,mouse,idle", "e"); + p->idle = 1; +} + +static void +_e_pointer_cb_show(void *data, + Evas *e __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + int x, y; + edje_object_part_geometry_get(obj, "e.swallow.hotspot", + &x, &y, NULL, NULL); + _e_pointer_hot_update(data, x, y); +} + +static void +_e_pointer_cb_move(void *data, + Evas *e __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + E_Pointer *p; + Evas_Coord x, y; + + if (!e_config->show_cursor) return; + if (!(p = data)) return; + if (!p->e_cursor) return; + if (!evas_object_visible_get(p->pointer_object)) return; + edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", + &x, &y, NULL, NULL); + _e_pointer_hot_update(p, x, y); +} + +static void +_e_pointer_canvas_resize(E_Pointer *p, int w, int h) +{ + Evas_Engine_Info_Buffer *einfo; + + if ((p->w == w) && (p->h == h)) return; + p->w = w, p->h = h; + evas_output_size_set(p->evas, p->w, p->h); + evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); + + p->pixels = realloc(p->pixels, p->w * p->h * sizeof(int)); + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); + + EINA_SAFETY_ON_NULL_RETURN(einfo); + einfo->info.dest_buffer = p->pixels; + einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); + evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); + + evas_object_move(p->pointer_object, 0, 0); + evas_object_resize(p->pointer_object, p->w, p->h); + if (p->pointer_image) evas_object_resize(p->pointer_image, p->w, p->h); +} + +/* local subsystem functions */ +static void +_e_pointer_canvas_add(E_Pointer *p) +{ + Evas_Engine_Info_Buffer *einfo; + Evas_Object *o; + int rmethod; + + if (!p) return; + p->w = e_config->cursor_size; + p->h = e_config->cursor_size; + + /* create evas */ + p->evas = evas_new(); + if (!p->evas) + { + e_object_del(E_OBJECT(p)); + return; + } + rmethod = evas_render_method_lookup("buffer"); + evas_output_method_set(p->evas, rmethod); + evas_output_size_set(p->evas, p->w, p->h); + evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); + + p->pixels = malloc(p->w * p->h * sizeof(int)); + if (!p->pixels) + { + _e_pointer_canvas_del(p); + return; + } + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); + if (!einfo) + { + _e_pointer_canvas_del(p); + return; + } + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = p->pixels; + einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); + + /* set the pointer edje */ + o = edje_object_add(p->evas); + p->pointer_object = o; + /* Create the hotspot object */ + o = evas_object_rectangle_add(p->evas); + evas_object_color_set(o, 0, 0, 0, 0); + p->hot_object = o; + evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, + _e_pointer_cb_move, p); + evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, + _e_pointer_cb_show, p); + /* init edje */ + evas_object_move(p->pointer_object, 0, 0); + evas_object_resize(p->pointer_object, p->w, p->h); + evas_object_show(p->pointer_object); +} + +static void +_e_pointer_canvas_del(E_Pointer *p) +{ + if (!p) return; + E_FREE_FUNC(p->pointer_object, evas_object_del); + E_FREE_FUNC(p->hot_object, evas_object_del); + if (p->evas && (!p->canvas)) evas_free(p->evas); + p->evas = NULL; + E_FREE(p->pixels); +} + +static void +_e_pointer_free(E_Pointer *p) +{ + if (!p) return; + _e_pointers = eina_list_remove(_e_pointers, p); + + _e_pointer_canvas_del(p); + E_FREE_FUNC(p->pointer_image, evas_object_del); + + E_FREE_LIST(p->stack, _e_pointer_stack_free); + + if (p->type) eina_stringshare_del(p->type); + if (p->idle_timer) ecore_timer_del(p->idle_timer); + if (p->idle_poller) ecore_poller_del(p->idle_poller); + + p->type = NULL; + p->idle_timer = NULL; + p->idle_poller = NULL; + E_FREE(p); +} + +static void +_e_pointer_stack_free(E_Pointer_Stack *elem) +{ + if (elem->type) eina_stringshare_del(elem->type); + free(elem); +} + +static void +_e_pointer_type_set(E_Pointer *p, + const char *type) +{ + if (!p) return; + + /* Check if this pointer is already set */ + if (!e_util_strcmp(p->type, type)) return; + + eina_stringshare_replace(&p->type, type); + + /* Do not set type if in "hidden mode" */ + if (!e_config->show_cursor) + { +#ifdef WAYLAND_ONLY + evas_object_hide(p->pointer_image); +#else + if (!p->canvas) + ecore_x_window_cursor_set(p->win, 0); +#endif + return; + } + + if (p->e_cursor) + { + char cursor[1024]; + Evas_Coord x, y; + + if (!p->evas) _e_pointer_canvas_add(p); + if (p->color) + snprintf(cursor, sizeof(cursor), + "e/pointer/enlightenment/%s/color", type); + else + snprintf(cursor, sizeof(cursor), + "e/pointer/enlightenment/%s/mono", type); + if (!e_theme_edje_object_set(p->pointer_object, + "base/theme/pointer", cursor)) + goto fallback; + edje_object_part_swallow(p->pointer_object, "e.swallow.hotspot", + p->hot_object); + edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", + &x, &y, NULL, NULL); + if ((p->hot.x != x) || (p->hot.y != y)) + { + p->hot.x = x; + p->hot.y = y; + } + p->hot.update = 1; + evas_object_show(p->pointer_object); + return; + } +fallback: +#ifndef WAYLAND_ONLY + if (p->canvas) return; + { + Ecore_X_Cursor cursor = 0; + + E_FREE_FUNC(p->pointer_image, evas_object_del); + if (p->evas) _e_pointer_canvas_del(p); + if (!strcmp(type, "move")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR); +#if 0 + else if (!strcmp(type, "resize")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING); +#endif + else if (!strcmp(type, "resize_tl")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_LEFT_CORNER); + else if (!strcmp(type, "resize_t")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_SIDE); + else if (!strcmp(type, "resize_tr")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_RIGHT_CORNER); + else if (!strcmp(type, "resize_r")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_RIGHT_SIDE); + else if (!strcmp(type, "resize_br")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER); + else if (!strcmp(type, "resize_b")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_SIDE); + else if (!strcmp(type, "resize_bl")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_LEFT_CORNER); + else if (!strcmp(type, "resize_l")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_SIDE); + else if (!strcmp(type, "entry")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_XTERM); + else if (!strcmp(type, "default")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_PTR); + else if (!strcmp(type, "plus")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_PLUS); + else if (!strcmp(type, "hand")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_HAND1); + else if (!strcmp(type, "rotate")) + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_EXCHANGE); + else + { + printf("Unknown pointer type: %s\n", type); + cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW); + } + if (!cursor) printf("X Cursor for %s is missing\n", type); + ecore_x_window_cursor_set(p->win, cursor); + if (cursor) ecore_x_cursor_free(cursor); + } +#endif +} + +static void +_e_pointer_active_handle(E_Pointer *p) +{ + if (!p) return; + _e_pointer_active(p); + if (p->canvas) + { + ecore_timer_reset(p->idle_timer); + return; + } + + /* we got some mouse event - if there was an idle timer emit an active + * signal as we WERE idle, NOW we are active */ + E_FREE_FUNC(p->idle_timer, ecore_timer_del); + E_FREE_FUNC(p->idle_poller, ecore_poller_del); + if (e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) return; + /* and schedule a pre-idle check in 1 second if no more events happen */ + if (!e_config->idle_cursor) return; + p->idle_timer = ecore_timer_loop_add(1.0, _e_pointer_cb_idle_timer_pre, p); +} + +static Eina_Bool +_e_pointer_cb_mouse_down(void *data __UNUSED__, + int type __UNUSED__, + void *event __UNUSED__) +{ + Eina_List *l; + E_Pointer *p; + + EINA_LIST_FOREACH(_e_pointers, l, p) + { + _e_pointer_active_handle(p); + if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) + { + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,action,mouse,down", "e"); + } + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_pointer_cb_mouse_up(void *data __UNUSED__, + int type __UNUSED__, + void *event __UNUSED__) +{ + Eina_List *l; + E_Pointer *p; + + EINA_LIST_FOREACH(_e_pointers, l, p) + { + _e_pointer_active_handle(p); + if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) + { + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,action,mouse,up", "e"); + } + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_pointer_cb_mouse_move(void *data __UNUSED__, + int type __UNUSED__, + Ecore_Event_Mouse_Move *ev) +{ + Eina_List *l; + E_Pointer *p; + + EINA_LIST_FOREACH(_e_pointers, l, p) + { + _e_pointer_active_handle(p); + if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH) + { + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,action,mouse,move", "e"); + } + if (p->canvas) + { + evas_object_move(p->pointer_image, + e_comp_canvas_x_root_adjust(e_comp_get(NULL), ev->root.x), + e_comp_canvas_y_root_adjust(e_comp_get(NULL), ev->root.y) + ); + } + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_pointer_cb_mouse_wheel(void *data __UNUSED__, + int type __UNUSED__, + void *event __UNUSED__) +{ + Eina_List *l; + E_Pointer *p; + + EINA_LIST_FOREACH(_e_pointers, l, p) + { + _e_pointer_active_handle(p); + if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) + { + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,action,mouse,wheel", "e"); + } + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_pointer_idle_timer(void *data) +{ + E_Pointer *p = data; + + if (e_config->idle_cursor) + _e_pointer_idle(p); + + return EINA_TRUE; +} + +#ifndef WAYLAND_ONLY +static Eina_Bool +_e_pointer_cb_idle_timer_pre(void *data) +{ + E_Pointer *p; + int x, y; + + if (!(p = data)) return ECORE_CALLBACK_RENEW; + ecore_x_pointer_xy_get(p->win, &x, &y); + p->x = x; + p->y = y; + if (p->canvas) + evas_object_move(p->pointer_image, + e_comp_canvas_x_root_adjust(e_comp_get(NULL), x), + e_comp_canvas_y_root_adjust(e_comp_get(NULL), y) + ); + p->idle_timer = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_timer_wait, p); + return ECORE_CALLBACK_CANCEL; +} + + +static Eina_Bool +_e_pointer_cb_idle_timer_wait(void *data) +{ + E_Pointer *p; + + if (!(p = data)) return ECORE_CALLBACK_RENEW; + if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || + (!e_config->idle_cursor)) + { + if (p->idle_poller) ecore_poller_del(p->idle_poller); + p->idle_poller = NULL; + p->idle_timer = NULL; + return ECORE_CALLBACK_CANCEL; + } + if (!p->idle_poller) + p->idle_poller = ecore_poller_add(ECORE_POLLER_CORE, 64, + _e_pointer_cb_idle_poller, p); + p->idle_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_e_pointer_cb_idle_poller(void *data) +{ + E_Pointer *p; + int x, y; + + if (!(p = data)) return ECORE_CALLBACK_RENEW; + if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || + (!e_config->idle_cursor)) + { + p->idle_poller = NULL; + return ECORE_CALLBACK_CANCEL; + } + /* check if pointer actually moved since the 1 second post-mouse move idle + * pre-timer that fetches the position */ + ecore_x_pointer_xy_get(p->win, &x, &y); + if ((x != p->x) || (y != p->y)) + { + /* it moved - so we are not idle yet - record position and wait + * 4 secons more */ + p->x = x; + p->y = y; + if (p->idle) + _e_pointer_active(p); + + /* use poller to check from now on */ + return ECORE_CALLBACK_RENEW; + } + /* we are idle - report it if not idle before */ + if (!p->idle) + _e_pointer_idle(p); + return ECORE_CALLBACK_RENEW; +} +#endif + + /* externally accessible functions */ EINTERN int e_pointer_init(void) { - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, - _e_pointer_cb_mouse_down, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, - _e_pointer_cb_mouse_up, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, - _e_pointer_cb_mouse_move, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, - _e_pointer_cb_mouse_wheel, NULL)); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, + _e_pointer_cb_mouse_down, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_UP, + _e_pointer_cb_mouse_up, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE, + _e_pointer_cb_mouse_move, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_WHEEL, + _e_pointer_cb_mouse_wheel, NULL); return 1; } @@ -76,27 +541,110 @@ e_pointer_shutdown(void) } EAPI E_Pointer * -e_pointer_window_new(Ecore_X_Window win, +e_pointer_window_new(Ecore_Window win, int filled) { E_Pointer *p = NULL; - if (!win) return NULL; + EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL); p = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_free); if (!p) return NULL; p->e_cursor = e_config->use_e_cursor; p->win = win; p->color = 0; - if (e_config->use_e_cursor) - if (ecore_x_cursor_color_supported_get()) p->color = 1; +#ifndef WAYLAND_ONLY ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); +#endif if (filled) e_pointer_type_push(p, p, "default"); _e_pointers = eina_list_append(_e_pointers, p); return p; } +EAPI E_Pointer * +e_pointer_canvas_new(Evas *e, int filled) +{ + E_Pointer *p = NULL; + + EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL); + p = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_free); + if (!p) return NULL; + + p->e_cursor = p->canvas = 1; + p->color = 1; + p->w = p->h = e_config->cursor_size; + p->idle_timer = ecore_timer_loop_add(4.0, _e_pointer_idle_timer, p); + p->pointer_image = evas_object_image_filled_add(e); + evas_object_pass_events_set(p->pointer_image, 1); + evas_object_layer_set(p->pointer_image, EVAS_LAYER_MAX); + evas_object_image_alpha_set(p->pointer_image, 1); + evas_object_show(p->pointer_image); + + if (filled) e_pointer_type_push(p, p, "default"); + _e_pointers = eina_list_append(_e_pointers, p); + return p; +} + +EAPI void +e_pointer_image_set(E_Pointer *p, E_Pixmap *cp, int w, int h, int hot_x, int hot_y) +{ + void *img = NULL; + + EINA_SAFETY_ON_NULL_RETURN(p); + + p->pixmap = cp; + if (cp) + { + e_pixmap_refresh(cp); + e_pixmap_image_refresh(cp); + img = e_pixmap_image_data_get(cp); + } + else + { + Eina_Stringshare *type; + + type = p->type; + if (type) + { + p->type = NULL; + _e_pointer_type_set(p, type); + eina_stringshare_del(type); + } + } + _e_pointer_hot_update(p, hot_x, hot_y); + + if (p->evas) + { + /* e cursor: edje or image */ + if (!p->canvas) + _e_pointer_canvas_resize(p, w, h); + evas_object_hide(p->pointer_object); + if (!p->pointer_image) + { + p->pointer_image = evas_object_image_filled_add(p->evas); + evas_object_image_alpha_set(p->pointer_image, 1); + } + evas_object_image_size_set(p->pointer_image, w, h); + evas_object_image_data_set(p->pointer_image, img); + evas_object_resize(p->pointer_image, w, h); + evas_object_show(p->pointer_image); + } +#ifndef WAYLAND_ONLY + else + { + Ecore_X_Cursor cur; + + if (cp) + cur = ecore_x_cursor_new(p->win, img, w, h, + p->hot.x, p->hot.y); + ecore_x_window_cursor_set(p->win, cp ? cur : 0); + if (cp) + ecore_x_cursor_free(cur); + } +#endif +} + EAPI void e_pointers_size_set(int size) { @@ -106,39 +654,22 @@ e_pointers_size_set(int size) if (!e_config->show_cursor) return; EINA_LIST_FOREACH(_e_pointers, l, p) { - Evas_Engine_Info_Buffer *einfo; - + Eina_Stringshare *type; if (p->evas) { - p->w = p->h = size; - evas_output_size_set(p->evas, p->w, p->h); - evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); - - p->pixels = realloc(p->pixels, p->w * p->h * sizeof(int)); - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); - if (einfo) - { - einfo->info.dest_buffer = p->pixels; - einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); - evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); - } - - evas_object_move(p->pointer_object, 0, 0); - evas_object_resize(p->pointer_object, p->w, p->h); + if (!p->canvas) + _e_pointer_canvas_resize(p, size, size); } +#ifndef WAYLAND_ONLY else + ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); +#endif + type = p->type; + if (type) { - const char *type; - - ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); - type = p->type; - if (type) - { - p->type = NULL; - _e_pointer_type_set(p, type); - eina_stringshare_del(type); - } + p->type = NULL; + _e_pointer_type_set(p, type); + eina_stringshare_del(type); } } } @@ -147,7 +678,14 @@ EAPI void e_pointer_hide(E_Pointer *p) { if (!p) return; +#ifdef WAYLAND_ONLY +#else if (p->win) ecore_x_window_cursor_set(p->win, 0); +#endif + if (p->canvas) + evas_object_hide(p->pointer_image); + else + E_FREE_FUNC(p->pointer_image, evas_object_del); if (p->evas) _e_pointer_canvas_del(p); } @@ -161,17 +699,25 @@ e_pointer_type_push(E_Pointer *p, if (!p) return; p->e_cursor = e_config->use_e_cursor; + if (!p->canvas) + { + evas_object_hide(p->pointer_image); +#ifndef WAYLAND_ONLY + if (p->blocks) + { + ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); + _e_pointer_canvas_resize(p, e_config->cursor_size, e_config->cursor_size); + } +#endif + } _e_pointer_type_set(p, type); p->obj = obj; stack = E_NEW(E_Pointer_Stack, 1); - if (stack) - { - stack->type = eina_stringshare_add(p->type); - stack->obj = p->obj; - p->stack = eina_list_prepend(p->stack, stack); - } + stack->type = eina_stringshare_ref(p->type); + stack->obj = p->obj; + p->stack = eina_list_prepend(p->stack, stack); } EAPI void @@ -185,7 +731,7 @@ e_pointer_type_pop(E_Pointer *p, if (!p) return; EINA_LIST_FOREACH_SAFE(p->stack, l, l_next, stack) { - if ((stack->obj == obj) && ((!type) || (!strcmp(stack->type, type)))) + if ((stack->obj == obj) && ((!type) || (!e_util_strcmp(stack->type, type)))) { _e_pointer_stack_free(stack); p->stack = eina_list_remove_list(p->stack, l); @@ -195,18 +741,29 @@ e_pointer_type_pop(E_Pointer *p, if (!p->stack) { - if (p->evas) _e_pointer_canvas_del(p); - ecore_x_window_cursor_set(p->win, 0); - if (p->type) eina_stringshare_del(p->type); - p->type = NULL; + e_pointer_hide(p); + eina_stringshare_replace(&p->type, NULL); return; } stack = eina_list_data_get(p->stack); _e_pointer_type_set(p, stack->type); + if ((p->blocks) && (stack->obj == p)) + { + evas_object_hide(p->pointer_object); + evas_object_show(p->pointer_image); +#ifndef WAYLAND_ONLY + if (!p->canvas) + { + int w, h; - if (p->type) eina_stringshare_del(p->type); - p->type = eina_stringshare_add(stack->type); + e_pixmap_size_get(p->pixmap, &w, &h); + _e_pointer_canvas_resize(p, w, h); + } +#endif + } + + eina_stringshare_refplace(&p->type, stack->type); p->obj = stack->obj; /* try the default cursor next time */ @@ -216,6 +773,7 @@ e_pointer_type_pop(E_Pointer *p, EAPI void e_pointer_idler_before(void) { +#ifndef WAYLAND_ONLY Eina_List *l; E_Pointer *p; @@ -226,21 +784,33 @@ e_pointer_idler_before(void) if (!p->e_cursor) continue; if (!p->evas) continue; - if (!p->win) continue; updates = evas_render_updates(p->evas); if ((updates) || (p->hot.update)) { - Ecore_X_Cursor cur; + if (p->canvas) + { + if (!p->blocks) + { + evas_object_resize(p->pointer_image, p->w, p->h); + evas_object_image_size_set(p->pointer_image, p->w, p->h); + evas_object_image_data_set(p->pointer_image, p->pixels); + } + } + else + { + Ecore_X_Cursor cur; - cur = ecore_x_cursor_new(p->win, p->pixels, p->w, p->h, - p->hot.x, p->hot.y); - ecore_x_window_cursor_set(p->win, cur); - ecore_x_cursor_free(cur); + cur = ecore_x_cursor_new(p->win, p->pixels, p->w, p->h, + p->hot.x, p->hot.y); + ecore_x_window_cursor_set(p->win, cur); + ecore_x_cursor_free(cur); + } evas_render_updates_free(updates); - p->hot.update = 0; } + p->hot.update = 0; } +#endif } /** @@ -337,410 +907,36 @@ e_pointer_mode_pop(void *obj, E_Pointer_Mode mode) } } -/* local subsystem functions */ -static void -_e_pointer_canvas_add(E_Pointer *p) +EAPI void +e_pointer_block_add(E_Pointer *p) { - Evas_Engine_Info_Buffer *einfo; - Evas_Object *o; - int rmethod; - - if (!p) return; - p->w = e_config->cursor_size; - p->h = e_config->cursor_size; - - /* create evas */ - p->evas = evas_new(); - if (!p->evas) + if (!p->blocks) { - e_object_del(E_OBJECT(p)); - return; - } - rmethod = evas_render_method_lookup("buffer"); - evas_output_method_set(p->evas, rmethod); - evas_output_size_set(p->evas, p->w, p->h); - evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); + evas_object_hide(p->pointer_object); + if (p->pixmap) + { + int w, h; - p->pixels = malloc(p->w * p->h * sizeof(int)); - if (!p->pixels) - { - _e_pointer_canvas_del(p); - return; + e_pixmap_size_get(p->pixmap, &w, &h); + e_pointer_image_set(p, p->pixmap, w, h, p->hot.x, p->hot.y); + } } - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); - if (!einfo) - { - _e_pointer_canvas_del(p); - return; - } - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - einfo->info.dest_buffer = p->pixels; - einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); - einfo->info.use_color_key = 0; - einfo->info.alpha_threshold = 0; - einfo->info.func.new_update_region = NULL; - einfo->info.func.free_update_region = NULL; - evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); - - /* set the pointer edje */ - o = edje_object_add(p->evas); - p->pointer_object = o; - /* Create the hotspot object */ - o = evas_object_rectangle_add(p->evas); - evas_object_color_set(o, 0, 0, 0, 0); - p->hot_object = o; - evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, - _e_pointer_cb_move, p); - /* init edje */ - evas_object_move(p->pointer_object, 0, 0); - evas_object_resize(p->pointer_object, p->w, p->h); - evas_object_show(p->pointer_object); + p->blocks++; + } -static void -_e_pointer_canvas_del(E_Pointer *p) +EAPI void +e_pointer_block_del(E_Pointer *p) { - if (!p) return; - if (p->pointer_object) evas_object_del(p->pointer_object); - if (p->hot_object) evas_object_del(p->hot_object); - if (p->evas) evas_free(p->evas); - free(p->pixels); - p->pointer_object = NULL; - p->hot_object = NULL; - p->evas = NULL; - p->pixels = NULL; -} - -static void -_e_pointer_cb_move(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - E_Pointer *p; - Evas_Coord x, y; - - if (!e_config->show_cursor) return; - - if (!(p = data)) return; - if (!p->e_cursor) return; - edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", - &x, &y, NULL, NULL); - if ((p->hot.x != x) || (p->hot.y != y)) + if (!p->blocks) return; + p->blocks--; + if (p->blocks) return; + e_pointers_size_set(e_config->cursor_size); + if (p->pointer_image) { - p->hot.x = x; - p->hot.y = y; - p->hot.update = 1; - } -} - -static void -_e_pointer_free(E_Pointer *p) -{ - if (!p) return; - _e_pointers = eina_list_remove(_e_pointers, p); - - _e_pointer_canvas_del(p); - - E_FREE_LIST(p->stack, _e_pointer_stack_free); - - if (p->type) eina_stringshare_del(p->type); - if (p->idle_timer) ecore_timer_del(p->idle_timer); - if (p->idle_poller) ecore_poller_del(p->idle_poller); - - p->type = NULL; - p->idle_timer = NULL; - p->idle_poller = NULL; - E_FREE(p); -} - -static void -_e_pointer_stack_free(E_Pointer_Stack *elem) -{ - if (elem->type) eina_stringshare_del(elem->type); - free(elem); -} - -static void -_e_pointer_type_set(E_Pointer *p, - const char *type) -{ - if (!p) return; - - /* Check if this pointer is already set */ - if ((p->type) && (!strcmp(p->type, type))) return; - - eina_stringshare_replace(&p->type, type); - - /* Do not set type if in "hidden mode" */ - if (!e_config->show_cursor) - { - ecore_x_window_cursor_set(p->win, 0); - return; - } - - if (p->e_cursor) - { - char cursor[1024]; - Evas_Coord x, y; - - if (!p->evas) _e_pointer_canvas_add(p); - if (p->color) - snprintf(cursor, sizeof(cursor), - "e/pointer/enlightenment/%s/color", type); + if (p->canvas) + evas_object_resize(p->pointer_image, p->w, p->h); else - snprintf(cursor, sizeof(cursor), - "e/pointer/enlightenment/%s/mono", type); - if (!e_theme_edje_object_set(p->pointer_object, - "base/theme/pointer", cursor)) - goto fallback; - edje_object_part_swallow(p->pointer_object, "e.swallow.hotspot", - p->hot_object); - edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", - &x, &y, NULL, NULL); - if ((p->hot.x != x) || (p->hot.y != y)) - { - p->hot.x = x; - p->hot.y = y; - } - p->hot.update = 1; - return; + evas_object_hide(p->pointer_image); } -fallback: - { - Ecore_X_Cursor cursor = 0; - - if (p->evas) _e_pointer_canvas_del(p); - if (!strcmp(type, "move")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR); -#if 0 - else if (!strcmp(type, "resize")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING); -#endif - else if (!strcmp(type, "resize_tl")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_LEFT_CORNER); - else if (!strcmp(type, "resize_t")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_SIDE); - else if (!strcmp(type, "resize_tr")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_RIGHT_CORNER); - else if (!strcmp(type, "resize_r")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_RIGHT_SIDE); - else if (!strcmp(type, "resize_br")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER); - else if (!strcmp(type, "resize_b")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_SIDE); - else if (!strcmp(type, "resize_bl")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_LEFT_CORNER); - else if (!strcmp(type, "resize_l")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_SIDE); - else if (!strcmp(type, "entry")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_XTERM); - else if (!strcmp(type, "default")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_PTR); - else if (!strcmp(type, "plus")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_PLUS); - else if (!strcmp(type, "hand")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_HAND1); - else if (!strcmp(type, "rotate")) - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_EXCHANGE); - else - { - printf("Unknown pointer type: %s\n", type); - cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW); - } - if (!cursor) printf("X Cursor for %s is missing\n", type); - ecore_x_window_cursor_set(p->win, cursor); - if (cursor) ecore_x_cursor_free(cursor); - } } - -static void -_e_pointer_active_handle(E_Pointer *p) -{ - if (!p) return; - - /* we got some mouse event - if there was an idle timer emit an active - * signal as we WERE idle, NOW we are active */ - if (p->idle_timer) - { - ecore_timer_del(p->idle_timer); - p->idle_timer = NULL; - } - if (p->idle_poller) - { - ecore_poller_del(p->idle_poller); - p->idle_poller = NULL; - } - if (p->idle) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, "e,state,mouse,active", "e"); - p->idle = 0; - } - if (e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) return; - /* and schedule a pre-idle check in 1 second if no more events happen */ - if (!e_config->idle_cursor) return; - p->idle_timer = ecore_timer_loop_add(1.0, _e_pointer_cb_idle_timer_pre, p); -} - -static Eina_Bool -_e_pointer_cb_mouse_down(void *data __UNUSED__, - int type __UNUSED__, - void *event __UNUSED__) -{ - Eina_List *l; - E_Pointer *p; - - EINA_LIST_FOREACH(_e_pointers, l, p) - { - _e_pointer_active_handle(p); - if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,action,mouse,down", "e"); - } - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_pointer_cb_mouse_up(void *data __UNUSED__, - int type __UNUSED__, - void *event __UNUSED__) -{ - Eina_List *l; - E_Pointer *p; - - EINA_LIST_FOREACH(_e_pointers, l, p) - { - _e_pointer_active_handle(p); - if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,action,mouse,up", "e"); - } - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_pointer_cb_mouse_move(void *data __UNUSED__, - int type __UNUSED__, - void *event __UNUSED__) -{ - Eina_List *l; - E_Pointer *p; - - EINA_LIST_FOREACH(_e_pointers, l, p) - { - _e_pointer_active_handle(p); - if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,action,mouse,move", "e"); - } - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_pointer_cb_mouse_wheel(void *data __UNUSED__, - int type __UNUSED__, - void *event __UNUSED__) -{ - Eina_List *l; - E_Pointer *p; - - EINA_LIST_FOREACH(_e_pointers, l, p) - { - _e_pointer_active_handle(p); - if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,action,mouse,wheel", "e"); - } - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_pointer_cb_idle_timer_pre(void *data) -{ - E_Pointer *p; - int x, y; - - if (!(p = data)) return ECORE_CALLBACK_RENEW; - ecore_x_pointer_xy_get(p->win, &x, &y); - p->x = x; - p->y = y; - p->idle_timer = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_timer_wait, p); - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_e_pointer_cb_idle_timer_wait(void *data) -{ - E_Pointer *p; - - if (!(p = data)) return ECORE_CALLBACK_RENEW; - if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || - (!e_config->idle_cursor)) - { - if (p->idle_poller) ecore_poller_del(p->idle_poller); - p->idle_poller = NULL; - p->idle_timer = NULL; - return ECORE_CALLBACK_CANCEL; - } - if (!p->idle_poller) - p->idle_poller = ecore_poller_add(ECORE_POLLER_CORE, 64, - _e_pointer_cb_idle_poller, p); - p->idle_timer = NULL; - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_e_pointer_cb_idle_poller(void *data) -{ - E_Pointer *p; - int x, y; - - if (!(p = data)) return ECORE_CALLBACK_RENEW; - if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || - (!e_config->idle_cursor)) - { - p->idle_poller = NULL; - return ECORE_CALLBACK_CANCEL; - } - /* check if pointer actually moved since the 1 second post-mouse move idle - * pre-timer that fetches the position */ - ecore_x_pointer_xy_get(p->win, &x, &y); - if ((x != p->x) || (y != p->y)) - { - /* it moved - so we are not idle yet - record position and wait - * 4 secons more */ - p->x = x; - p->y = y; - if (p->idle) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,state,mouse,active", "e"); - p->idle = 0; - } - /* use poller to check from now on */ - return ECORE_CALLBACK_RENEW; - } - /* we are idle - report it if not idle before */ - if (!p->idle) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, "e,state,mouse,idle", "e"); - p->idle = 1; - } - return ECORE_CALLBACK_RENEW; -} - diff --git a/src/bin/e_pointer.h b/src/bin/e_pointer.h index f96f6ba78..d808b17d3 100644 --- a/src/bin/e_pointer.h +++ b/src/bin/e_pointer.h @@ -31,16 +31,20 @@ struct _E_Pointer unsigned char e_cursor : 1; unsigned char color : 1; unsigned char idle : 1; + unsigned char canvas : 1; Evas *evas; + E_Pixmap *pixmap; Evas_Object *pointer_object; + Evas_Object *pointer_image; Evas_Object *hot_object; int *pixels; - Ecore_X_Window win; + Ecore_Window win; int w, h; Ecore_Timer *idle_timer; Ecore_Poller *idle_poller; int x, y; + unsigned int blocks; const char *type; void *obj; @@ -54,8 +58,10 @@ struct _E_Pointer EINTERN int e_pointer_init(void); EINTERN int e_pointer_shutdown(void); -EAPI E_Pointer *e_pointer_window_new(Ecore_X_Window win, int filled); +EAPI E_Pointer *e_pointer_window_new(Ecore_Window win, int filled); EAPI void e_pointer_hide(E_Pointer *p); +EAPI E_Pointer *e_pointer_canvas_new(Evas *e, int filled); +EAPI void e_pointer_image_set(E_Pointer *p, E_Pixmap *cp, int w, int h, int hot_x, int hot_y); EAPI void e_pointer_type_push(E_Pointer *p, void *obj, const char *type); EAPI void e_pointer_type_pop(E_Pointer *p, void *obj, const char *type); EAPI void e_pointers_size_set(int size); @@ -64,5 +70,8 @@ EAPI void e_pointer_idler_before(void); EAPI void e_pointer_mode_push(void *obj, E_Pointer_Mode mode); EAPI void e_pointer_mode_pop(void *obj, E_Pointer_Mode mode); +EAPI void e_pointer_block_add(E_Pointer *p); +EAPI void e_pointer_block_del(E_Pointer *p); + #endif #endif diff --git a/src/bin/e_win.c b/src/bin/e_win.c index ba65fb1bf..89246e44d 100644 --- a/src/bin/e_win.c +++ b/src/bin/e_win.c @@ -318,9 +318,13 @@ e_win_new(E_Comp *c) win->max_aspect = 0.0; wins = eina_list_append(wins, win); -#warning FIXME WL POINTERS - if (c->man->root) - win->pointer = e_pointer_window_new(win->evas_win, 1); +#ifndef WAYLAND_ONLY + if (c->comp_type == E_PIXMAP_TYPE_X) + { + win->pointer = e_pointer_window_new(win->evas_win, 1); + win->pointer->color = c->pointer->color; + } +#endif return win; } diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index f344b904d..d9d3ff24f 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -43,6 +43,7 @@ static void _e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, v static int _e_wl_shell_shell_surface_cb_ping_timeout(void *data); static void _e_wl_shell_render_post(void *data, Evas *e EINA_UNUSED, void *event EINA_UNUSED); +static void _e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); @@ -625,6 +626,8 @@ _e_wl_shell_shell_surface_create_toplevel(E_Wayland_Surface *ews) EC_CHANGED(ews->ec); /* hook object callbacks */ + evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, _e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, @@ -686,6 +689,8 @@ _e_wl_shell_shell_surface_create_popup(E_Wayland_Surface *ews) EC_CHANGED(ews->ec); /* hook object callbacks */ + evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, _e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, @@ -913,8 +918,10 @@ _e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews) if (ews->ec) { - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, - _e_wl_shell_shell_surface_cb_mouse_out, ews); + evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); + //evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, + //_e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, _e_wl_shell_shell_surface_cb_mouse_move, ews); evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_UP, @@ -1122,6 +1129,14 @@ _e_wl_shell_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event } } +static void +_e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Wayland_Surface *ews = data; + + e_pointer_block_add(ews->ec->comp->pointer); +} + static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { @@ -1131,6 +1146,9 @@ _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Obj /* try to cast data to our surface structure */ if (!(ews = data)) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; + if (ews->ec->comp->pointer) e_pointer_block_del(ews->ec->comp->pointer); + if (e_object_is_del(E_OBJECT(ews->ec))) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1158,6 +1176,7 @@ _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Ob /* try to cast data to our surface structure */ if (!(ews = data)) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1186,7 +1205,7 @@ _e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Obje /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1220,7 +1239,7 @@ _e_wl_shell_shell_surface_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Ob /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1273,7 +1292,7 @@ _e_wl_shell_shell_surface_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_O /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) diff --git a/src/modules/wl_fb/e_mod_main.c b/src/modules/wl_fb/e_mod_main.c index e92f52c15..85a7e607d 100644 --- a/src/modules/wl_fb/e_mod_main.c +++ b/src/modules/wl_fb/e_mod_main.c @@ -42,6 +42,7 @@ e_modapi_init(E_Module *m) e_comp_wl_init(); e_comp_canvas_init(comp); e_comp_canvas_fake_layers_init(comp); + comp->pointer = e_pointer_canvas_new(comp->evas, 1); ecore_wl_init(NULL); ecore_wl_server_mode_set(1); diff --git a/src/modules/wl_x11/e_mod_main.c b/src/modules/wl_x11/e_mod_main.c index 3545dc710..297838636 100644 --- a/src/modules/wl_x11/e_mod_main.c +++ b/src/modules/wl_x11/e_mod_main.c @@ -44,10 +44,10 @@ e_modapi_init(E_Module *m) e_xinerama_screens_set(eina_list_append(NULL, screen)); } comp->man = e_manager_new(0, comp, SCREEN_W, SCREEN_H); - comp->pointer = e_pointer_window_new(comp->man->root, 1); e_comp_wl_init(); e_comp_canvas_init(comp); e_comp_canvas_fake_layers_init(comp); + comp->pointer = e_pointer_canvas_new(comp->evas, 1); ecore_evas_callback_delete_request_set(ee, _cb_delete_request);