make wl_pointer cursor handling state-based to correctly handle cursor visuals
this fixes a lot of corner cases such as apps which set their cursor before receiving pointer.enter events
This commit is contained in:
parent
58e686caec
commit
b8f8c42aec
|
@ -211,11 +211,15 @@ _e_comp_wl_mouse_in(E_Client *ec, Evas_Event_Mouse_In *ev)
|
||||||
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
||||||
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
||||||
{
|
{
|
||||||
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(res);
|
||||||
|
|
||||||
if (!e_comp_wl_input_pointer_check(res)) continue;
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
||||||
if (wl_resource_get_client(res) != wc) continue;
|
if (wl_resource_get_client(res) != wc) continue;
|
||||||
|
ptr->entered = 1;
|
||||||
wl_pointer_send_enter(res, serial, ec->comp_data->surface,
|
wl_pointer_send_enter(res, serial, ec->comp_data->surface,
|
||||||
wl_fixed_from_int(ev->canvas.x - ec->client.x),
|
wl_fixed_from_int(ev->canvas.x - ec->client.x),
|
||||||
wl_fixed_from_int(ev->canvas.y - ec->client.y));
|
wl_fixed_from_int(ev->canvas.y - ec->client.y));
|
||||||
|
e_comp_wl_input_pointer_cursor_update(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +271,10 @@ _e_comp_wl_mouse_out(E_Client *ec)
|
||||||
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
serial = wl_display_next_serial(e_comp_wl->wl.disp);
|
||||||
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
||||||
{
|
{
|
||||||
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(res);
|
||||||
if (!e_comp_wl_input_pointer_check(res)) continue;
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
||||||
if (wl_resource_get_client(res) != wc) continue;
|
if (wl_resource_get_client(res) != wc) continue;
|
||||||
|
ptr->entered = 0;
|
||||||
wl_pointer_send_leave(res, serial, ec->comp_data->surface);
|
wl_pointer_send_leave(res, serial, ec->comp_data->surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2591,11 +2597,21 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
|
||||||
_e_comp_wl_mouse_out(ec);
|
_e_comp_wl_mouse_out(ec);
|
||||||
else if (ec->comp_data->cursor)
|
else if (ec->comp_data->cursor)
|
||||||
{
|
{
|
||||||
Evas_Object *o;
|
Eina_List *l;
|
||||||
|
struct wl_resource *res;
|
||||||
|
|
||||||
ecore_evas_cursor_get(e_comp->ee, &o, NULL, NULL, NULL);
|
EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
|
||||||
if (o == ec->frame)
|
{
|
||||||
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(res);
|
||||||
|
|
||||||
|
if (ptr->cursor_set && (ptr->cursor == ec))
|
||||||
|
{
|
||||||
|
ptr->cursor = NULL;
|
||||||
|
ptr->cursor_set = 0;
|
||||||
|
if (ptr->entered)
|
||||||
|
e_comp_wl_input_pointer_cursor_update(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ec->comp_data->aux_hint.hints)
|
if (ec->comp_data->aux_hint.hints)
|
||||||
|
|
|
@ -5,6 +5,7 @@ typedef struct _E_Comp_Wl_Subsurf_Data E_Comp_Wl_Subsurf_Data;
|
||||||
typedef struct _E_Comp_Wl_Surface_State E_Comp_Wl_Surface_State;
|
typedef struct _E_Comp_Wl_Surface_State E_Comp_Wl_Surface_State;
|
||||||
typedef struct _E_Comp_Wl_Client_Data E_Comp_Wl_Client_Data;
|
typedef struct _E_Comp_Wl_Client_Data E_Comp_Wl_Client_Data;
|
||||||
typedef struct _E_Comp_Wl_Output E_Comp_Wl_Output;
|
typedef struct _E_Comp_Wl_Output E_Comp_Wl_Output;
|
||||||
|
typedef struct _E_Comp_Wl_Pointer E_Comp_Wl_Pointer;
|
||||||
typedef struct E_Shell_Data E_Shell_Data;
|
typedef struct E_Shell_Data E_Shell_Data;
|
||||||
typedef struct Tizen_Extensions Tizen_Extensions;
|
typedef struct Tizen_Extensions Tizen_Extensions;
|
||||||
typedef void (*E_Comp_Wl_Grab_End_Cb)(E_Client*);
|
typedef void (*E_Comp_Wl_Grab_End_Cb)(E_Client*);
|
||||||
|
@ -394,6 +395,14 @@ struct _E_Comp_Wl_Output
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _E_Comp_Wl_Pointer
|
||||||
|
{
|
||||||
|
E_Client *cursor;
|
||||||
|
Evas_Point offset;
|
||||||
|
Eina_Bool entered : 1;
|
||||||
|
Eina_Bool cursor_set : 1;
|
||||||
|
};
|
||||||
|
|
||||||
E_API Eina_Bool e_comp_wl_init(void);
|
E_API Eina_Bool e_comp_wl_init(void);
|
||||||
EINTERN void e_comp_wl_shutdown(void);
|
EINTERN void e_comp_wl_shutdown(void);
|
||||||
|
|
||||||
|
|
|
@ -43,39 +43,18 @@ _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struc
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
|
_e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
E_Client *ec;
|
E_Client *ec;
|
||||||
Eina_Bool got_mouse = EINA_FALSE;
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(resource);
|
||||||
|
|
||||||
E_CLIENT_FOREACH(ec)
|
|
||||||
{
|
|
||||||
if (e_object_is_del(E_OBJECT(ec))) continue;
|
|
||||||
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
|
|
||||||
if (!ec->comp_data->surface) continue;
|
|
||||||
if (client != wl_resource_get_client(ec->comp_data->surface)) continue;
|
|
||||||
if (ec->mouse.in)
|
|
||||||
{
|
|
||||||
if (e_client_has_xwindow(ec))
|
|
||||||
got_mouse = E_INSIDE(ec->mouse.current.mx, ec->mouse.current.my,
|
|
||||||
ec->client.x, ec->client.y, ec->client.w, ec->client.h);
|
|
||||||
else
|
|
||||||
got_mouse = EINA_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!got_mouse)
|
|
||||||
{
|
|
||||||
if (ec && ec->mouse.in && (!surface_resource))
|
|
||||||
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!surface_resource)
|
if (!surface_resource)
|
||||||
{
|
{
|
||||||
if (e_comp_object_frame_exists(ec->frame) &&
|
ptr->cursor_set = 1;
|
||||||
ec->mouse.in && (!ec->comp_data->ssd_mouse_in))
|
ptr->cursor = NULL;
|
||||||
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
ptr->offset.x = x;
|
||||||
else
|
ptr->offset.y = y;
|
||||||
|
if (ptr->entered)
|
||||||
{
|
{
|
||||||
ecore_evas_cursor_unset(e_comp->ee);
|
ecore_evas_cursor_unset(e_comp->ee);
|
||||||
evas_object_hide(e_comp->pointer->o_ptr);
|
evas_object_hide(e_comp->pointer->o_ptr);
|
||||||
|
@ -89,6 +68,10 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
|
||||||
* are being processed... let's BAIL.
|
* are being processed... let's BAIL.
|
||||||
*/
|
*/
|
||||||
if (!ec) return;
|
if (!ec) return;
|
||||||
|
ptr->cursor_set = 1;
|
||||||
|
ptr->cursor = ec;
|
||||||
|
ptr->offset.x = x;
|
||||||
|
ptr->offset.y = y;
|
||||||
if (ec->comp_data->pending.input)
|
if (ec->comp_data->pending.input)
|
||||||
eina_tiler_clear(ec->comp_data->pending.input);
|
eina_tiler_clear(ec->comp_data->pending.input);
|
||||||
else
|
else
|
||||||
|
@ -113,9 +96,8 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
|
||||||
EC_CHANGED(ec);
|
EC_CHANGED(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ignore cursor changes during resize/move I guess */
|
if (ptr->entered)
|
||||||
if (e_client_action_get()) return;
|
e_comp_wl_input_pointer_cursor_update(ptr);
|
||||||
e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_pointer_interface _e_pointer_interface =
|
static const struct wl_pointer_interface _e_pointer_interface =
|
||||||
|
@ -137,14 +119,20 @@ static const struct wl_touch_interface _e_touch_interface =
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
|
_e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
|
E_Comp_Wl_Pointer *ptr = wl_resource_get_user_data(resource);
|
||||||
|
|
||||||
|
if (ptr->cursor_set && ptr->entered)
|
||||||
|
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
||||||
e_comp_wl->ptr.resources =
|
e_comp_wl->ptr.resources =
|
||||||
eina_list_remove(e_comp_wl->ptr.resources, resource);
|
eina_list_remove(e_comp_wl->ptr.resources, resource);
|
||||||
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
_e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
||||||
{
|
{
|
||||||
struct wl_resource *res;
|
struct wl_resource *res;
|
||||||
|
E_Comp_Wl_Pointer *ptr;
|
||||||
|
|
||||||
/* try to create pointer resource */
|
/* try to create pointer resource */
|
||||||
res = wl_resource_create(client, &wl_pointer_interface,
|
res = wl_resource_create(client, &wl_pointer_interface,
|
||||||
|
@ -156,12 +144,12 @@ _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *re
|
||||||
wl_client_post_no_memory(client);
|
wl_client_post_no_memory(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ptr = E_NEW(E_Comp_Wl_Pointer, 1);
|
||||||
|
|
||||||
e_comp_wl->ptr.resources =
|
e_comp_wl->ptr.resources =
|
||||||
eina_list_append(e_comp_wl->ptr.resources, res);
|
eina_list_append(e_comp_wl->ptr.resources, res);
|
||||||
wl_resource_set_user_data(res, resource);
|
|
||||||
wl_resource_set_implementation(res, &_e_pointer_interface,
|
wl_resource_set_implementation(res, &_e_pointer_interface,
|
||||||
e_comp->wl_comp_data,
|
ptr,
|
||||||
_e_comp_wl_input_cb_pointer_unbind);
|
_e_comp_wl_input_cb_pointer_unbind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,6 +535,24 @@ e_comp_wl_input_shutdown(void)
|
||||||
e_comp_wl->seat.global = NULL;
|
e_comp_wl->seat.global = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EINTERN void
|
||||||
|
e_comp_wl_input_pointer_cursor_update(E_Comp_Wl_Pointer *ptr)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_TRUE_RETURN(!ptr->entered);
|
||||||
|
if (ptr->cursor_set && (!e_comp_util_mouse_grabbed()))
|
||||||
|
{
|
||||||
|
if (ptr->cursor)
|
||||||
|
e_pointer_object_set(e_comp->pointer, ptr->cursor->frame, ptr->offset.x, ptr->offset.y);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ecore_evas_cursor_unset(e_comp->ee);
|
||||||
|
evas_object_hide(e_comp->pointer->o_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
EINTERN Eina_Bool
|
EINTERN Eina_Bool
|
||||||
e_comp_wl_input_pointer_check(struct wl_resource *res)
|
e_comp_wl_input_pointer_check(struct wl_resource *res)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
|
||||||
EINTERN Eina_Bool e_comp_wl_input_keyboard_check(struct wl_resource *res);
|
EINTERN Eina_Bool e_comp_wl_input_keyboard_check(struct wl_resource *res);
|
||||||
EINTERN Eina_Bool e_comp_wl_input_touch_check(struct wl_resource *res);
|
EINTERN Eina_Bool e_comp_wl_input_touch_check(struct wl_resource *res);
|
||||||
|
|
||||||
|
EINTERN void e_comp_wl_input_pointer_cursor_update(E_Comp_Wl_Pointer *ptr);
|
||||||
|
|
||||||
EINTERN Eina_Bool e_comp_wl_input_keyboard_modifiers_serialize(void);
|
EINTERN Eina_Bool e_comp_wl_input_keyboard_modifiers_serialize(void);
|
||||||
EINTERN void e_comp_wl_input_keyboard_modifiers_update(void);
|
EINTERN void e_comp_wl_input_keyboard_modifiers_update(void);
|
||||||
EINTERN void e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed);
|
EINTERN void e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed);
|
||||||
|
|
Loading…
Reference in New Issue