diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h index 45dd047ca3..c2295f8e78 100644 --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -314,7 +314,7 @@ EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, i */ EAPI void ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); /** - * @brief Set the focus of an Ecore_Evas' window. + * @brief Set the Ecore_Evas window focus for the default seat. * * @param ee The Ecore_Evas * @param on @c EINA_TRUE for focus, @c EINA_FALSE to defocus. @@ -323,17 +323,47 @@ EAPI void ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, i * @p on is @c EINA_FALSE. * * @warning Support for this depends on the underlying windowing system. + * @see ecore_evas_focus_device_set() */ EAPI void ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on); /** - * @brief Query whether an Ecore_Evas' window is focused or not. + * @brief Query whether the default seat has the Ecore_Evas focus. * * @param ee The Ecore_Evas to set * @return @c EINA_TRUE if @p ee if focused, @c EINA_FALSE if not. * * @see ecore_evas_focus_set() + * @see ecore_evas_focus_device_get() */ EAPI Eina_Bool ecore_evas_focus_get(const Ecore_Evas *ee); + +/** + * @brief Set the Ecore_Evas windows focus for a given seat. + * + * @param ee The Ecore_Evas + * @param seat An Efl_Input_Device that represents the seat or @c NULL for the default seat. + * @param on @c EINA_TRUE for focus, @c EINA_FALSE to defocus. + * + * This function focuses @p ee if @p on is @c EINA_TRUE, or unfocuses @p ee if + * @p on is @c EINA_FALSE. + * + * @warning Support for this depends on the underlying windowing system. + * @see ecore_evas_focus_device_get() + * @since 1.19 + */ +EAPI void ecore_evas_focus_device_set(Ecore_Evas *ee, Eo *seat, + Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is focused or not. + * + * @param ee The Ecore_Evas to set + * @param seat An Efl_Input_Device that represents the seat or @c NULL for the default seat. + * @return @c EINA_TRUE if @p ee if focused, @c EINA_FALSE if not. + * + * @see ecore_evas_focus_device_set() + * @since 1.19 + */ +EAPI Eina_Bool ecore_evas_focus_device_get(const Ecore_Evas *ee, Eo *seat); /** * @brief Iconify or uniconify an Ecore_Evas' window. * @@ -1751,6 +1781,8 @@ EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Even * * @warning If and when this function is called depends on the underlying * windowing system. + * @note This function only reports focus in events for the default seat! + * @see ecore_evas_callback_focus_device_in_set() */ EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** @@ -1763,8 +1795,38 @@ EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Eve * * @warning If and when this function is called depends on the underlying * windowing system. + * @note This function only reports focus in events for the default seat! + * @see ecore_evas_callback_focus_device_out_set() */ EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); +/** + * @brief Set a callback for Ecore_Evas focus in events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee gets focus. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + * @see ecore_evas_callback_focus_device_out_set() + * @since 1.19 + */ +EAPI void ecore_evas_callback_focus_device_in_set(Ecore_Evas *ee, Ecore_Evas_Focus_Device_Event_Cb func); +/** + * @brief Set a callback for Ecore_Evas focus out events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee loses focus. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + * @see ecore_evas_callback_focus_device_in_set() + * @since 1.19 + */ +EAPI void ecore_evas_callback_focus_device_out_set(Ecore_Evas *ee, Ecore_Evas_Focus_Device_Event_Cb func); /** * @brief Set a callback for Ecore_Evas sticky events. * @param ee The Ecore_Evas to set callbacks on @@ -1799,8 +1861,9 @@ EAPI void ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Eve * * @warning If and when this function is called depends on the underlying * windowing system. + * @since 1.19 */ -EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); +EAPI void ecore_evas_callback_device_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Mouse_IO_Cb func); /** * @brief Set a callback for Ecore_Evas mouse out events. * @param ee The Ecore_Evas to set callbacks on @@ -1811,6 +1874,35 @@ EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Eve * * @warning If and when this function is called depends on the underlying * windowing system. + * @since 1.19 + */ +EAPI void ecore_evas_callback_device_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Mouse_IO_Cb func); +/** + * @brief Set a callback for Ecore_Evas mouse in events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever the mouse enters @p ee. + * + * @note the @p func will only report events for the default mouse. + * @warning If and when this function is called depends on the underlying + * windowing system. + * @see ecore_evas_callback_device_mouse_in_set + */ +EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); +/** + * @brief Set a callback for Ecore_Evas mouse out events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever the mouse leaves @p ee. + * + * @note the @p func will only report events for the default mouse. + * @warning If and when this function is called depends on the underlying + * windowing system. + * @see ecore_evas_callback_device_mouse_out_set */ EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); /** diff --git a/src/lib/ecore_evas/Ecore_Evas_Types.h b/src/lib/ecore_evas/Ecore_Evas_Types.h index eeff920f81..442e07b072 100644 --- a/src/lib/ecore_evas/Ecore_Evas_Types.h +++ b/src/lib/ecore_evas/Ecore_Evas_Types.h @@ -41,6 +41,8 @@ typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window; /* basic data types */ typedef struct _Ecore_Evas Ecore_Evas; typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); /**< Callback used for several ecore evas events @since 1.2 */ +typedef void (*Ecore_Evas_Focus_Device_Event_Cb) (Ecore_Evas *ee, Eo *seat); /** Callback used to report an focus in/out event originated from a seat. @since 1.19*/ +typedef void (*Ecore_Evas_Mouse_IO_Cb) (Ecore_Evas *ee, Eo *mouse); /**< Callback used to report mouse in/out events. @since 1.19 */ #endif #ifndef _ECORE_WAYLAND_H_ diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 421345daa9..293b1e3170 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -65,6 +65,39 @@ static int _ecore_evas_fps_debug = 0; //RENDER_SYNC static int _ecore_evas_render_sync = 1; +static void +_ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat) +{ + evas_canvas_seat_focus_out(ee->evas, seat); + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + if (ee->func.fn_focus_device_out) ee->func.fn_focus_device_out(ee, seat); +} + +static void +_ecore_evas_device_del_cb(void *data, const Efl_Event *ev) +{ + Ecore_Evas *ee = data; + + ee->prop.focused_by = eina_list_remove(ee->prop.focused_by, ev->object); + _ecore_evas_focus_out_dispatch(ee, ev->object); +} + +static void +_ecore_evas_mouse_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *mouse) +{ + if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + if (ee->func.fn_device_mouse_out) ee->func.fn_device_mouse_out(ee, mouse); +} + +static void +_ecore_evas_mouse_del_cb(void *data, const Efl_Event *ev) +{ + Ecore_Evas *ee = data; + + ee->mice_in = eina_list_remove(ee->mice_in, ev->object); + _ecore_evas_mouse_out_dispatch(ee, ev->object); +} + static void _ecore_evas_animator(void *data, const Efl_Event *ev EINA_UNUSED) { @@ -1004,6 +1037,16 @@ ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) ee->func.fn_focus_in = func; } +EAPI void +ecore_evas_callback_focus_device_in_set(Ecore_Evas *ee, + Ecore_Evas_Focus_Device_Event_Cb func) +{ + ECORE_EVAS_CHECK(ee); + IFC(ee, fn_callback_focus_device_in_set) (ee, func); + IFE; + ee->func.fn_focus_device_in = func; +} + EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) { @@ -1013,6 +1056,16 @@ ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) ee->func.fn_focus_out = func; } +EAPI void +ecore_evas_callback_focus_device_out_set(Ecore_Evas *ee, + Ecore_Evas_Focus_Device_Event_Cb func) +{ + ECORE_EVAS_CHECK(ee); + IFC(ee, fn_callback_focus_device_out_set) (ee, func); + IFE; + ee->func.fn_focus_device_out = func; +} + EAPI void ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) { @@ -1553,30 +1606,75 @@ ecore_evas_layer_get(const Ecore_Evas *ee) return ee->prop.layer; } +EAPI Eina_Bool +ecore_evas_focus_device_get(const Ecore_Evas *ee, Efl_Input_Device *seat) +{ + ECORE_EVAS_CHECK(ee, EINA_FALSE); + if (!seat) + seat = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_SEAT); + return eina_list_data_find(ee->prop.focused_by, seat) ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +_ecore_evas_focus_device_set(Ecore_Evas *ee, Efl_Input_Device *seat, + Eina_Bool on) +{ + Eina_Bool present; + + if (!seat) + seat = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_SEAT); + EINA_SAFETY_ON_NULL_RETURN(seat); + + if (efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_CLASS_SEAT) + { + ERR("The Input device must be an seat"); + return; + } + + present = ecore_evas_focus_device_get(ee, seat); + if (on) + { + if (present) return; + ee->prop.focused_by = eina_list_append(ee->prop.focused_by, seat); + efl_event_callback_add(seat, EFL_EVENT_DEL, + _ecore_evas_device_del_cb, ee); + evas_canvas_seat_focus_in(ee->evas, seat); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + if (ee->func.fn_focus_device_in) ee->func.fn_focus_device_in(ee, seat); + } + else + { + if (!present) return; + ee->prop.focused_by = eina_list_remove(ee->prop.focused_by, seat); + efl_event_callback_del(seat, EFL_EVENT_DEL, + _ecore_evas_device_del_cb, ee); + _ecore_evas_focus_out_dispatch(ee, seat); + } +} + +EAPI void +ecore_evas_focus_device_set(Ecore_Evas *ee, Efl_Input_Device *seat, + Eina_Bool on) +{ + ECORE_EVAS_CHECK(ee); + IFC(ee, fn_focus_device_set) (ee, seat, on); + IFE; + _ecore_evas_focus_device_set(ee, seat, on); +} + EAPI void ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on) { ECORE_EVAS_CHECK(ee); IFC(ee, fn_focus_set) (ee, on); IFE; - if (on) - { - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - } - else - { - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - } - ee->prop.focused = !!on; + ecore_evas_focus_device_set(ee, NULL, on); } EAPI Eina_Bool ecore_evas_focus_get(const Ecore_Evas *ee) { - ECORE_EVAS_CHECK(ee, EINA_FALSE); - return ee->prop.focused ? EINA_TRUE : EINA_FALSE; + return ecore_evas_focus_device_get(ee, NULL); } EAPI void @@ -2672,6 +2770,7 @@ _ecore_evas_vnc_stop(Ecore_Evas *ee) EAPI void _ecore_evas_free(Ecore_Evas *ee) { + Efl_Input_Device *dev; Ecore_Evas_Interface *iface; ee->deleted = EINA_TRUE; @@ -2695,6 +2794,16 @@ _ecore_evas_free(Ecore_Evas *ee) { _ecore_evas_free(ee->sub_ecore_evas->data); } + EINA_LIST_FREE(ee->prop.focused_by, dev) + { + efl_event_callback_del(dev, EFL_EVENT_DEL, + _ecore_evas_device_del_cb, ee); + } + EINA_LIST_FREE(ee->mice_in, dev) + { + efl_event_callback_del(dev, EFL_EVENT_DEL, + _ecore_evas_mouse_del_cb, ee); + } if (ee->data) eina_hash_free(ee->data); ee->data = NULL; if (ee->name) free(ee->name); @@ -4155,3 +4264,63 @@ _ecore_evas_input_direct_cb(void *window, int type, const void *info) return EINA_FALSE; } } + +EAPI void +_ecore_evas_mouse_inout_set(Ecore_Evas *ee, Efl_Input_Device *mouse, + Eina_Bool in, Eina_Bool force_out) +{ + Efl_Input_Device *present; + + if (!mouse) + mouse = evas_default_device_get(ee->evas, + EFL_INPUT_DEVICE_CLASS_MOUSE);; + + EINA_SAFETY_ON_NULL_RETURN(mouse); + present = eina_list_data_find(ee->mice_in, mouse); + + if (in) + { + if (present) return; + ee->mice_in = eina_list_append(ee->mice_in, mouse); + efl_event_callback_add(mouse, EFL_EVENT_DEL, + _ecore_evas_mouse_del_cb, ee); + if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + } + else + { + if (present) ee->mice_in = eina_list_remove(ee->mice_in, mouse); + else if (!present && !force_out) return; + efl_event_callback_del(mouse, EFL_EVENT_DEL, + _ecore_evas_mouse_del_cb, ee); + _ecore_evas_mouse_out_dispatch(ee, mouse); + } +} + +EAPI Eina_Bool +_ecore_evas_mouse_in_check(Ecore_Evas *ee, Efl_Input_Device *mouse) +{ + if (!mouse) + mouse = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(mouse, EINA_FALSE); + return eina_list_data_find(ee->mice_in, mouse) ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_callback_device_mouse_out_set(Ecore_Evas *ee, + Ecore_Evas_Mouse_IO_Cb func) +{ + ECORE_EVAS_CHECK(ee); + IFC(ee, fn_callback_device_mouse_out_set) (ee, func); + IFE; + ee->func.fn_device_mouse_out = func; +} + +EAPI void +ecore_evas_callback_device_mouse_in_set(Ecore_Evas *ee, + Ecore_Evas_Mouse_IO_Cb func) +{ + ECORE_EVAS_CHECK(ee); + IFC(ee, fn_callback_device_mouse_in_set) (ee, func); + IFE; + ee->func.fn_device_mouse_in = func; +} diff --git a/src/lib/ecore_evas/ecore_evas_buffer.c b/src/lib/ecore_evas/ecore_evas_buffer.c index deb2387001..0d1643cdfb 100644 --- a/src/lib/ecore_evas/ecore_evas_buffer.c +++ b/src/lib/ecore_evas/ecore_evas_buffer.c @@ -105,12 +105,10 @@ _ecore_evas_show(Ecore_Evas *ee) Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data; if (bdata->image) return; - if (ee->prop.focused) return; - ee->prop.focused = EINA_TRUE; + if (ecore_evas_focus_device_get(ee, NULL)) return; ee->prop.withdrawn = EINA_FALSE; if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); } static int @@ -413,9 +411,7 @@ _ecore_evas_buffer_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj Ecore_Evas *ee; ee = data; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); } static void @@ -424,9 +420,7 @@ _ecore_evas_buffer_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *ob Ecore_Evas *ee; ee = data; - ee->prop.focused = EINA_FALSE; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); } static void @@ -608,6 +602,11 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; static void * @@ -672,7 +671,6 @@ ecore_evas_buffer_allocfunc_new(int w, int h, ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_TRUE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_TRUE; @@ -727,7 +725,8 @@ ecore_evas_buffer_allocfunc_new(int w, int h, _ecore_evas_register(ee); evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); + return ee; } @@ -811,7 +810,6 @@ ecore_evas_object_image_new(Ecore_Evas *ee_target) ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_FALSE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_FALSE; diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c index 6f90654f6b..693e9db126 100644 --- a/src/lib/ecore_evas/ecore_evas_ews.c +++ b/src/lib/ecore_evas/ecore_evas_ews.c @@ -465,19 +465,11 @@ static void _ecore_evas_ews_focus_set(Ecore_Evas *ee, Eina_Bool on) { evas_object_focus_set(ee->engine.ews.image, on); - ee->prop.focused = on; + _ecore_evas_focus_device_set(ee, NULL, on); if (on) - { - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FOCUS); - } + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FOCUS); else - { - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_UNFOCUS); - } + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_UNFOCUS); } static void @@ -501,7 +493,8 @@ _ecore_evas_ews_override_set(Ecore_Evas *ee, Eina_Bool on) { if (ee->prop.override == on) return; if (ee->visible) evas_object_show(ee->engine.ews.image); - if (ee->prop.focused) evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); + if (ecore_evas_focus_device_get(ee, NULL)) + evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); ee->prop.override = on; _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); } @@ -721,6 +714,11 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; void diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index 5184e94d2b..f9c66fea1d 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -158,6 +158,13 @@ struct _Ecore_Evas_Engine_Func void (*fn_animator_unregister)(Ecore_Evas *ee); void (*fn_evas_changed)(Ecore_Evas *ee, Eina_Bool changed); + + void (*fn_focus_device_set) (Ecore_Evas *ee, Efl_Input_Device *seat, Eina_Bool on); + void (*fn_callback_focus_device_in_set) (Ecore_Evas *ee, Ecore_Evas_Focus_Device_Event_Cb func); + void (*fn_callback_focus_device_out_set) (Ecore_Evas *ee, Ecore_Evas_Focus_Device_Event_Cb func); + + void (*fn_callback_device_mouse_in_set) (Ecore_Evas *ee, Ecore_Evas_Mouse_IO_Cb func); + void (*fn_callback_device_mouse_out_set) (Ecore_Evas *ee, Ecore_Evas_Mouse_IO_Cb func); }; struct _Ecore_Evas_Interface @@ -194,10 +201,10 @@ struct _Ecore_Evas Eina_Bool should_be_visible : 1; Eina_Bool alpha : 1; Eina_Bool transparent : 1; - Eina_Bool in : 1; Eina_Bool events_block : 1; /* @since 1.14 */ Eina_Hash *data; + Eina_List *mice_in; void *vnc_server; /* @since 1.19 */ @@ -257,13 +264,13 @@ struct _Ecore_Evas Eina_List *hints; int id; } aux_hint; + Eina_List *focused_by; int layer; Ecore_Window window; unsigned char avoid_damage; Ecore_Evas *group_ee; Ecore_Window group_ee_win; double aspect; - Eina_Bool focused : 1; Eina_Bool iconified : 1; Eina_Bool borderless : 1; Eina_Bool override : 1; @@ -300,6 +307,10 @@ struct _Ecore_Evas void (*fn_msg_handle) (Ecore_Evas *ee, int maj, int min, void *data, int size); void (*fn_pointer_xy_get) (const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y); Eina_Bool (*fn_pointer_warp) (const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y); + void (*fn_focus_device_in) (Ecore_Evas *ee, Efl_Input_Device *seat); + void (*fn_focus_device_out) (Ecore_Evas *ee, Efl_Input_Device *seat); + void (*fn_device_mouse_in) (Ecore_Evas *ee, Efl_Input_Device *mouse); + void (*fn_device_mouse_out) (Ecore_Evas *ee, Efl_Input_Device *mouse); } func; Ecore_Evas_Engine engine; @@ -445,6 +456,13 @@ EAPI void ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, dou Eina_Module *_ecore_evas_vnc_server_module_load(void); + +EAPI void _ecore_evas_focus_device_set(Ecore_Evas *ee, Efl_Input_Device *seat, + Eina_Bool on); + +EAPI Eina_Bool _ecore_evas_mouse_in_check(Ecore_Evas *ee, Efl_Input_Device *mouse); +EAPI void _ecore_evas_mouse_inout_set(Ecore_Evas *ee, Efl_Input_Device *mouse, + Eina_Bool in, Eina_Bool force_out); #undef EAPI #define EAPI diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 9dcae3a926..37a0ed1924 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -86,12 +86,14 @@ typedef struct _Ecore_Wl2_Event_Focus_In { unsigned int window; unsigned int timestamp; + Eo *dev; //The seat device } Ecore_Wl2_Event_Focus_In; typedef struct _Ecore_Wl2_Event_Focus_Out { unsigned int window; unsigned int timestamp; + Eo *dev; //The seat device } Ecore_Wl2_Event_Focus_Out; typedef struct _Ecore_Wl2_Event_Dnd_Enter diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 3df8f46997..d272dc42f9 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -23,6 +23,7 @@ typedef struct _Ecore_Wl2_Input_Devices Eo *pointer_dev; Eo *keyboard_dev; Eo *touch_dev; + Eo *seat_dev; int window_id; } Ecore_Wl2_Input_Devices; @@ -92,6 +93,18 @@ _ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, int window_id) return NULL; } +static Eo * +_ecore_wl2_seat_dev_get(Ecore_Wl2_Input *input, int window_id) +{ + Ecore_Wl2_Input_Devices *devices; + + devices = _ecore_wl2_devices_get(input, window_id); + if (devices) + return efl_ref(devices->seat_dev); + + return NULL; +} + static void _input_event_cb_free(void *data, void *event) { @@ -389,7 +402,9 @@ _ecore_wl2_input_focus_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window) ev->timestamp = input->timestamp; ev->window = window->id; - ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, NULL, NULL); + ev->dev = _ecore_wl2_seat_dev_get(input, window->id); + ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, _input_event_cb_free, + ev->dev); } static void @@ -402,7 +417,9 @@ _ecore_wl2_input_focus_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window ev->timestamp = input->timestamp; ev->window = window->id; - ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, NULL, NULL); + ev->dev = _ecore_wl2_seat_dev_get(input, window->id); + ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, _input_event_cb_free, + ev->dev); } static int @@ -1331,6 +1348,8 @@ _ecore_wl2_input_cursor_update(void *data) static void _ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices) { + if (devices->seat_dev) + efl_unref(devices->seat_dev); if (devices->pointer_dev) efl_unref(devices->pointer_dev); if (devices->keyboard_dev) @@ -1378,6 +1397,8 @@ _ecore_evas_wl_common_cb_device_event(void *data, int type, void *event) devices->keyboard_dev = efl_ref(ev->dev); else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH) devices->touch_dev = efl_ref(ev->dev); + else if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT) + devices->seat_dev = efl_ref(ev->dev); return ECORE_CALLBACK_PASS_ON; } diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo index 2a5ea1fa11..91eb4135df 100644 --- a/src/lib/evas/canvas/evas_canvas.eo +++ b/src/lib/evas/canvas/evas_canvas.eo @@ -136,7 +136,7 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) See also \@ref evas_object_focus_set, \@ref evas_object_focus_get, \@ref evas_object_key_grab, - \@ref evas_object_key_ungrab, @.seat_focus_get, + \@ref evas_object_key_ungrab, @.seat_focus.get, @.focused_objects.get, @Efl.Canvas.Object.seat_focus_check, @Efl.Canvas.Object.seat_focus_add, @Efl.Canvas.Object.seat_focus_del. @@ -165,14 +165,17 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) Efl.Input.Device and the data is an Efl.Canvas.Object or $null on error.]] } } - seat_focus_get { + @property seat_focus { [[Return the focused object by a given seat. @since 1.19]] - params { - @in seat: Efl.Input.Device;[[The seat to fetch the focused - object or $null for the default seat.]] + get {} + keys { + seat: Efl.Input.Device;[[The seat to fetch the focused + object or $null for the default seat.]] } - return: Efl.Canvas.Object; [[The object that has the focus or $null if - the seat has no focused object.]] + values { + return: Efl.Canvas.Object; [[The object that has the focus or $null if + the seat has no focused object.]] + } } @property object_top { get { @@ -265,10 +268,20 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) } @property focus_state { get { - [[Get the focus state known by the given evas.]] + [[Get the focus state for the default seat.]] return: bool; [[$true if focused, $false otherwise]] } } + @property seat_focus_state { + [[Get the focus state by a given seat.]] + get {} + keys { + seat: Efl.Input.Device; [[The seat to check the focus state. Use $null for the default seat.]] + } + values { + return: bool; [[$true if the seat has the canvas focus, $false otherwise.]] + } + } @property changed { get { [[Get the changed marker for the canvas. @@ -599,7 +612,7 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) ]] } focus_out { - [[Inform to the evas that it lost the focus.]] + [[Inform to the evas that it lost the focus from the default seat.]] } norender { [[Update the canvas internal objects but not triggering immediate @@ -942,7 +955,21 @@ class Evas.Canvas (Efl.Object, Efl.Canvas, Efl.Animator, Efl.Input.Interface) } } focus_in { - [[Inform to the evas that it got the focus.]] + [[Inform to the evas that it got the focus from the default seat.]] + } + seat_focus_in { + [[Inform to the evas that it got the focus from a given seat. @since 1.19]] + legacy: null; + params { + @in seat: Efl.Input.Device; [[The seat or $null for the default seat.]] + } + } + seat_focus_out { + [[Inform to the evas that it lost the focus from a given seat. @since 1.19]] + legacy: null; + params { + @in seat: Efl.Input.Device; [[The seat or $null for the default seat.]] + } } obscured_rectangle_add { [[Add an "obscured region" to an Evas canvas. diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c index 5bccd61272..0a55fa88c2 100644 --- a/src/lib/evas/canvas/evas_events.c +++ b/src/lib/evas/canvas/evas_events.c @@ -3531,19 +3531,20 @@ _evas_canvas_event_key_cb(void *data, const Efl_Event *event) static void _evas_canvas_event_focus_cb(void *data, const Efl_Event *event) { + Efl_Input_Device *seat = efl_input_device_get(event->info); Evas_Public_Data *e = data; if (event->desc == EFL_EVENT_FOCUS_IN) { - if (e->focus) return; - e->focus = 1; + if (eina_list_data_find(e->focused_by, seat)) return; + e->focused_by = eina_list_append(e->focused_by, seat); evas_event_callback_call(e->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, event->info); } else { - if (!e->focus) return; - e->focus = 0; + if (!eina_list_data_find(e->focused_by, seat)) return; + e->focused_by = eina_list_remove(e->focused_by, seat); evas_event_callback_call(e->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, event->info); } diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index 3dc7b612be..22f4fa357a 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -376,6 +376,7 @@ _evas_canvas_efl_object_destructor(Eo *eo_e, Evas_Public_Data *e) free(touch_point); _evas_device_cleanup(eo_e); + e->focused_by = eina_list_free(e->focused_by); eina_lock_free(&(e->lock_objects)); eina_spinlock_free(&(e->render.lock)); @@ -538,7 +539,8 @@ _evas_canvas_data_attach_get(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) } static void -_evas_canvas_focus_inout_dispatch(Eo *eo_e, Evas_Public_Data *e, Eina_Bool in) +_evas_canvas_focus_inout_dispatch(Eo *eo_e, Efl_Input_Device *seat, + Eina_Bool in) { Efl_Input_Focus_Data *ev_data; Efl_Input_Focus *evt; @@ -546,7 +548,7 @@ _evas_canvas_focus_inout_dispatch(Eo *eo_e, Evas_Public_Data *e, Eina_Bool in) evt = efl_input_instance_get(EFL_INPUT_FOCUS_CLASS, eo_e, (void **) &ev_data); if (!evt) return; - ev_data->device = efl_ref(e->default_seat); + ev_data->device = efl_ref(seat); ev_data->timestamp = time(NULL); efl_event_callback_call(eo_e, in ? EFL_EVENT_FOCUS_IN : EFL_EVENT_FOCUS_OUT, @@ -554,22 +556,48 @@ _evas_canvas_focus_inout_dispatch(Eo *eo_e, Evas_Public_Data *e, Eina_Bool in) efl_del(evt); } +EOLIAN static void +_evas_canvas_seat_focus_in(Eo *eo_e, Evas_Public_Data *e, + Efl_Input_Device *seat) +{ + if (!seat) seat = e->default_seat; + if (!seat || efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_CLASS_SEAT) return; + _evas_canvas_focus_inout_dispatch(eo_e, seat, EINA_TRUE); +} + +EOLIAN static void +_evas_canvas_seat_focus_out(Eo *eo_e, Evas_Public_Data *e, + Efl_Input_Device *seat) +{ + if (!seat) seat = e->default_seat; + if (!seat || efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_CLASS_SEAT) return; + _evas_canvas_focus_inout_dispatch(eo_e, seat, EINA_FALSE); +} + EOLIAN static void _evas_canvas_focus_in(Eo *eo_e, Evas_Public_Data *e) { - _evas_canvas_focus_inout_dispatch(eo_e, e, EINA_TRUE); + _evas_canvas_seat_focus_in(eo_e, e, NULL); } EOLIAN static void _evas_canvas_focus_out(Eo *eo_e, Evas_Public_Data *e) { - _evas_canvas_focus_inout_dispatch(eo_e, e, EINA_FALSE); + _evas_canvas_seat_focus_out(eo_e, e, NULL); } EOLIAN static Eina_Bool -_evas_canvas_focus_state_get(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) +_evas_canvas_seat_focus_state_get(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, + Efl_Input_Device *seat) { - return e->focus; + if (!seat) seat = e->default_seat; + return eina_list_data_find(e->focused_by, seat) ? EINA_TRUE : EINA_FALSE; +} + +EOLIAN static Eina_Bool +_evas_canvas_focus_state_get(Eo *eo_e, Evas_Public_Data *e) +{ + return _evas_canvas_seat_focus_state_get(eo_e, e, NULL); } EOLIAN static Eina_Bool diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 9d5b2e045d..f6a011b46b 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -903,6 +903,7 @@ struct _Evas_Public_Data int smart_calc_count; Eina_Hash *focused_objects; //Key - seat; value - the focused object + Eina_List *focused_by; //Which seat has the canvas focus void *attach_data; Evas_Modifier modifiers; Evas_Lock locks; @@ -926,7 +927,6 @@ struct _Evas_Public_Data unsigned char delete_me : 1; unsigned char invalidate : 1; unsigned char cleanup : 1; - unsigned char focus : 1; Eina_Bool is_frozen : 1; Eina_Bool rendering : 1; Eina_Bool render2 : 1; diff --git a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c index 1bfb0850e9..a2afc3db4e 100644 --- a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c +++ b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c @@ -186,10 +186,7 @@ _ecore_evas_cocoa_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, ee = _ecore_evas_cocoa_match(e->cocoa_window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -202,10 +199,7 @@ _ecore_evas_cocoa_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, ee = _ecore_evas_cocoa_match(e->cocoa_window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = EINA_FALSE; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -676,6 +670,11 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; static Ecore_Cocoa_Window * diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c index d0f730a0f5..917f1defb7 100644 --- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c +++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c @@ -793,6 +793,9 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func = _drm_animator_unregister, // animator_unregister _drm_evas_changed, // evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set }; static Ecore_Evas * diff --git a/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c b/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c index 785f9cd0f4..3b364d8a52 100644 --- a/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c +++ b/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c @@ -750,8 +750,11 @@ _ecore_evas_extn_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj E Ecore_Evas *ee = data; Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data; Extn *extn; + Evas_Device *dev; - ee->prop.focused = EINA_TRUE; + dev = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_SEAT); + if (ecore_evas_focus_device_get(ee, dev)) return; + ee->prop.focused_by = eina_list_append(ee->prop.focused_by, dev); extn = bdata->data; if (!extn) return; if (!extn->ipc.server) return; @@ -765,7 +768,8 @@ _ecore_evas_extn_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data; Extn *extn; - ee->prop.focused = EINA_FALSE; + ee->prop.focused_by = eina_list_remove(ee->prop.focused_by, + evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_SEAT)); extn = bdata->data; if (!extn) return; if (!extn->ipc.server) return; @@ -916,6 +920,11 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; static Eina_Bool @@ -1199,7 +1208,6 @@ ecore_evas_extn_plug_new_internal(Ecore_Evas *ee_target) ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_FALSE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_FALSE; @@ -1660,20 +1668,10 @@ _ipc_client_data(void *data, int type EINA_UNUSED, void *event) } break; case OP_FOCUS: - if (!ee->prop.focused) - { - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - } + if (!ecore_evas_focus_device_get(ee, NULL)) _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); break; case OP_UNFOCUS: - if (ee->prop.focused) - { - ee->prop.focused = EINA_FALSE; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - } + if (ecore_evas_focus_device_get(ee, NULL)) _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); break; case OP_EV_MOUSE_IN: if (ee->events_block) break; @@ -2125,7 +2123,6 @@ ecore_evas_extn_socket_new_internal(int w, int h) ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_FALSE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_FALSE; diff --git a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c index 558f82f752..f5d84bd2fc 100644 --- a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c +++ b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c @@ -416,12 +416,10 @@ _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED) static void _ecore_evas_show(Ecore_Evas *ee) { - if (ee->prop.focused) return; + if (ecore_evas_focus_device_get(ee, NULL)) return; ee->prop.withdrawn = EINA_FALSE; if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); } static void @@ -429,12 +427,7 @@ _ecore_evas_hide(Ecore_Evas *ee) { ee->prop.withdrawn = EINA_TRUE; if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - if (ee->prop.focused) - { - ee->prop.focused = EINA_FALSE; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - } + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); } static void @@ -644,6 +637,11 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; EAPI Ecore_Evas * @@ -692,7 +690,6 @@ ecore_evas_fb_new_internal(const char *disp_name, int rotation, int w, int h) ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_FALSE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_TRUE; diff --git a/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c b/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c index 7938dce2e5..fc8c6ce801 100644 --- a/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c +++ b/src/modules/ecore_evas/engines/psl1ght/ecore_evas_psl1ght.c @@ -67,10 +67,7 @@ _ecore_evas_psl1ght_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -83,10 +80,7 @@ _ecore_evas_psl1ght_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSE if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - evas_focus_out(ee->evas); - ee->prop.focused = EINA_FALSE; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); return ECORE_CALLBACK_PASS_ON; } @@ -313,10 +307,8 @@ _ecore_evas_show(Ecore_Evas *ee) { ee->prop.withdrawn = EINA_FALSE; if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - if (ee->prop.focused) return; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + if (ecore_evas_focus_device_get(ee, NULL)) return; + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); } static void @@ -466,6 +458,11 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; EAPI Ecore_Evas * @@ -496,7 +493,6 @@ ecore_evas_psl1ght_new_internal(const char *name, int w, int h) ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_TRUE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_TRUE; @@ -558,6 +554,7 @@ ecore_evas_psl1ght_new_internal(const char *name, int w, int h) if (getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH")) ecore_evas_cursor_set(ee, getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH"), EVAS_LAYER_MAX, 0, 0); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); return ee; diff --git a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c index 2382fdac44..440185e1db 100644 --- a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c +++ b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c @@ -103,12 +103,9 @@ _ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, vo Ecore_Evas *ee; ee = _ecore_evas_sdl_match(ev->windowID); - - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + if (!ee) return ECORE_CALLBACK_PASS_ON; + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -122,9 +119,7 @@ _ecore_evas_sdl_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, v if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - ee->prop.focused = EINA_FALSE; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); return ECORE_CALLBACK_PASS_ON; } @@ -411,8 +406,8 @@ _ecore_evas_show(Ecore_Evas *ee) { ee->prop.withdrawn = EINA_FALSE; if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - if (ee->prop.focused) return; - ee->prop.focused = EINA_TRUE; + if (ecore_evas_focus_device_get(ee, NULL)) return; + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); } @@ -555,6 +550,11 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; static Ecore_Evas* @@ -599,7 +599,6 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu ee->prop.max.w = 0; ee->prop.max.h = 0; ee->prop.layer = 0; - ee->prop.focused = EINA_TRUE; ee->prop.borderless = EINA_TRUE; ee->prop.override = EINA_TRUE; ee->prop.maximized = EINA_TRUE; @@ -725,6 +724,7 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu ee->engine.func->fn_render = _ecore_evas_sdl_render; _ecore_evas_register(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); ecore_evas_sdl_count++; return ee; diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index 232d96b0cb..0bea2c4ccb 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -85,6 +85,11 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; #define _smart_frame_type "ecore_evas_wl_frame" @@ -160,13 +165,12 @@ _ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, ee = ecore_event_window_match(ev->window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->in) return ECORE_CALLBACK_PASS_ON; + if (_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON; - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + _ecore_evas_mouse_inout_set(ee, ev->dev, EINA_TRUE, EINA_FALSE); ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - ee->in = EINA_TRUE; return ECORE_CALLBACK_PASS_ON; } @@ -182,16 +186,13 @@ _ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, ee = ecore_event_window_match(ev->window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (!_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON; - if (ee->in) - { - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); - if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - ee->in = EINA_FALSE; - } + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); + evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); + _ecore_evas_mouse_inout_set(ee, ev->dev, EINA_FALSE, EINA_FALSE); + if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); return ECORE_CALLBACK_PASS_ON; } @@ -207,10 +208,7 @@ _ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, ee = ecore_event_window_match(ev->window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->prop.focused) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, ev->dev, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -226,10 +224,7 @@ _ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, ee = ecore_event_window_match(ev->window); if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (!ee->prop.focused) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = EINA_FALSE; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_focus_device_set(ee, ev->dev, EINA_FALSE); return ECORE_CALLBACK_PASS_ON; } diff --git a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c index 1187d5dba2..27b416089e 100644 --- a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c +++ b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c @@ -190,7 +190,7 @@ _ecore_evas_win32_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, v if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */ if ((Ecore_Window)e->window != ee->prop.window) return 1; - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_TRUE, EINA_FALSE); /* FIXME to do */ /* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */ evas_event_feed_mouse_in(ee->evas, e->timestamp, NULL); @@ -215,11 +215,11 @@ _ecore_evas_win32_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, /* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->timestamp); - if (ee->in) + if (_ecore_evas_mouse_in_check(ee, NULL)) { if (evas_event_down_count_get(ee->evas) > 0) return ECORE_CALLBACK_PASS_ON; evas_event_feed_mouse_out(ee->evas, e->timestamp, NULL); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_FALSE, EINA_FALSE); if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); } @@ -237,9 +237,7 @@ _ecore_evas_win32_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UN if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -254,9 +252,7 @@ _ecore_evas_win32_event_window_focus_out(void *data EINA_UNUSED, int type EINA_U if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = EINA_FALSE; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); return ECORE_CALLBACK_PASS_ON; } @@ -958,7 +954,7 @@ _ecore_evas_win32_override_set(Ecore_Evas *ee, Eina_Bool on) /* FIXME: use borderless_set for now */ ecore_win32_window_borderless_set(window, on); if (ee->should_be_visible) ecore_win32_window_show(window); - if (ee->prop.focused) ecore_win32_window_focus(window); + if (ecore_evas_focus_device_get(ee, NULL)) ecore_win32_window_focus(window); ee->prop.override = on; } @@ -1077,7 +1073,7 @@ _ecore_evas_win32_alpha_set(Ecore_Evas *ee, int alpha) if (ee->prop.borderless) ecore_win32_window_borderless_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.borderless); if (ee->visible) ecore_win32_window_show((struct _Ecore_Win32_Window *)ee->prop.window); - if (ee->prop.focused) ecore_win32_window_focus((struct _Ecore_Win32_Window *)ee->prop.window); + if (ecore_evas_focus_device_get(ee, NULL)) ecore_win32_window_focus((struct _Ecore_Win32_Window *)ee->prop.window); if (ee->prop.title) { ecore_win32_window_title_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.title); @@ -1206,6 +1202,11 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; #endif /* BUILD_ECORE_EVAS_WIN32 */ diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 2a71070e07..e1eb9f7029 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -1314,9 +1314,8 @@ _fake_out(void *data) _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time); _feed_cancel_out(e, (e->mode == ECORE_X_EVENT_MODE_GRAB)); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_FALSE, EINA_TRUE); if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - ee->in = EINA_FALSE; return EINA_FALSE; } @@ -1385,7 +1384,7 @@ _ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void } /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */ - if (!ee->in) + if (!_ecore_evas_mouse_in_check(ee, NULL)) { Ecore_Event_Mouse_IO io = { .event_window = (Ecore_Window) e->win, /* not event_win! */ @@ -1396,9 +1395,8 @@ _ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void .y = e->y }; - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_TRUE, EINA_FALSE); ecore_event_evas_mouse_in(NULL, ECORE_EVENT_MOUSE_IN, &io); - ee->in = EINA_TRUE; } return ECORE_CALLBACK_PASS_ON; } @@ -1472,7 +1470,7 @@ _ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void // if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; // printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n", // ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas)); - if (ee->in) + if (_ecore_evas_mouse_in_check(ee, NULL)) { if ((evas_event_down_count_get(ee->evas) > 0) && (!((e->mode == ECORE_X_EVENT_MODE_GRAB) && @@ -1480,10 +1478,9 @@ _ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void return ECORE_CALLBACK_PASS_ON; ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers); _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_FALSE, EINA_FALSE); _feed_cancel_out(e, (e->mode == ECORE_X_EVENT_MODE_GRAB)); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - ee->in = EINA_FALSE; } return ECORE_CALLBACK_PASS_ON; } @@ -1500,9 +1497,7 @@ _ecore_evas_x_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; //xx// filtering with these doesnt help //xx// if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = EINA_TRUE; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_TRUE); return ECORE_CALLBACK_PASS_ON; } @@ -1521,9 +1516,7 @@ _ecore_evas_x_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSE // if (ee->prop.fullscreen) // ecore_x_window_focus(ee->prop.window); - evas_focus_out(ee->evas); - ee->prop.focused = EINA_FALSE; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_focus_device_set(ee, NULL, EINA_FALSE); return ECORE_CALLBACK_PASS_ON; } @@ -1795,7 +1788,7 @@ _ecore_evas_x_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, vo ee = ecore_event_window_match(e->win); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->in) + if (_ecore_evas_mouse_in_check(ee, NULL)) { Ecore_X_Event_Mouse_Out out = { .event_win = e->event_win, @@ -1806,9 +1799,8 @@ _ecore_evas_x_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, vo .y = 0, }; _feed_cancel_out(&out, EINA_TRUE); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + _ecore_evas_mouse_inout_set(ee, NULL, EINA_FALSE, EINA_FALSE); if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - ee->in = EINA_FALSE; } if (ee->prop.override) { @@ -2721,7 +2713,7 @@ _alpha_do(Ecore_Evas *ee, int alpha) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); if (ee->visible || ee->should_be_visible) ecore_x_window_show(ee->prop.window); - if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); + if (ecore_evas_focus_device_get(ee, NULL)) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { ecore_x_icccm_title_set(ee->prop.window, ee->prop.title); @@ -2877,7 +2869,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless); if (ee->visible || ee->should_be_visible) ecore_x_window_show(ee->prop.window); - if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); + if (ecore_evas_focus_device_get(ee, NULL)) ecore_x_window_focus(ee->prop.window); if (ee->prop.title) { ecore_x_icccm_title_set(ee->prop.window, ee->prop.title); @@ -3359,7 +3351,7 @@ _ecore_evas_x_override_set(Ecore_Evas *ee, Eina_Bool on) if (ee->should_be_visible) ecore_x_window_hide(ee->prop.window); ecore_x_window_override_set(ee->prop.window, on); if (ee->should_be_visible) ecore_x_window_show(ee->prop.window); - if (ee->prop.focused) ecore_x_window_focus(ee->prop.window); + if (ecore_evas_focus_device_get(ee, NULL)) ecore_x_window_focus(ee->prop.window); ee->prop.override = on; } @@ -3788,6 +3780,11 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func = NULL, // fn_animator_unregister NULL, // fn_evas_changed + NULL, //fn_focus_device_set + NULL, //fn_callback_focus_device_in_set + NULL, //fn_callback_focus_device_out_set + NULL, //fn_callback_device_mouse_in_set + NULL, //fn_callback_device_mouse_out_set }; /* diff --git a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c index def9593c9e..8f78f40bde 100644 --- a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c +++ b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c @@ -101,6 +101,10 @@ typedef struct _Ecore_Evas_Vnc_Server_Client_Data { #define VNC_SAMPLES_PER_PIXEL (3) #define VNC_BYTES_PER_PIXEL (4) + +static void _ecore_evas_vnc_server_ecore_event_generic_free(void *user_data, + void *func_data); + static void _ecore_evas_vnc_server_update_clients(rfbScreenInfoPtr vnc_screen) { @@ -151,16 +155,34 @@ _ecore_evas_vnc_server_socket_listen_activity(void *data, return ECORE_CALLBACK_RENEW; } +static void +_ecore_evas_vnc_server_mouse_inout_emit(Ecore_Evas_Vnc_Server *server, + Evas_Device *dev, int event_type) +{ + Ecore_Event_Mouse_IO *io = calloc(1, sizeof(Ecore_Event_Mouse_IO)); + EINA_SAFETY_ON_NULL_RETURN(io); + io->timestamp = time(NULL); + io->dev = efl_ref(dev); + io->event_window = io->window = server->ee->prop.window; + ecore_event_add(event_type, io, + _ecore_evas_vnc_server_ecore_event_generic_free, dev); +} + static void _ecore_evas_vnc_server_client_gone(rfbClientRec *client) { - Ecore_Evas_Vnc_Server_Client_Data *cdata = client->clientData; Ecore_Evas_Vnc_Server *server = client->screen->screenData; + Ecore_Evas_Vnc_Server_Client_Data *cdata = client->clientData; DBG("VNC client on seat '%s' gone", evas_device_name_get(cdata->seat)); if (server->disc_cb) server->disc_cb(server->cb_data, server->ee, client->host); + _ecore_evas_vnc_server_mouse_inout_emit(server, cdata->mouse, + ECORE_EVENT_MOUSE_OUT); + _ecore_evas_mouse_inout_set(server->ee, cdata->mouse, EINA_FALSE, + EINA_FALSE); + ecore_evas_focus_device_set(server->ee, cdata->seat, EINA_FALSE); ecore_main_fd_handler_del(cdata->handler); evas_device_del(cdata->keyboard); evas_device_del(cdata->mouse); @@ -240,7 +262,11 @@ _ecore_evas_vnc_server_client_connection_new(rfbClientRec *client) DBG("New VNC client on seat '%u'", _available_seat); _available_seat++; - + _ecore_evas_vnc_server_mouse_inout_emit(server, cdata->mouse, + ECORE_EVENT_MOUSE_IN); + _ecore_evas_mouse_inout_set(server->ee, cdata->mouse, EINA_TRUE, + EINA_FALSE); + ecore_evas_focus_device_set(server->ee, cdata->seat, EINA_TRUE); return RFB_CLIENT_ACCEPT; err_mouse: