}
}
-/**
- * @note
- * Every user event (mouse) on the buffer will be passed via this event callback
- */
-static int event_handler_cb(widget_buffer_h handler, struct widget_buffer_event_data *event_info, void *data)
+static inline int processing_events(vwin_info_t info, widget_buffer_event_data_t event_info, double timestamp)
{
- vwin_info_t info = data;
Elm_Access_Action_Info action_info;
Elm_Access_Action_Type action_type;
- int ret = 0;
Evas_Object *parent_elm;
KeySym *key_symbol;
unsigned int flags = 0;
- double timestamp;
-
- if (!info || info->state != VWIN_INFO_CREATED || !info->handle) {
- /* Just ignore this event */
- return 0;
- }
-
- if (WIDGET_CONF_USE_GETTIMEOFDAY) {
- if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
- struct timeval tv;
-
- if (gettimeofday(&tv, NULL) < 0) {
- ErrPrint("gettimeofday: %d\n", errno);
- } else {
- timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
- timestamp -= event_info->timestamp;
-
- if (timestamp > WIDGET_CONF_EVENT_FILTER) {
- DbgPrint("Dropped %lf\n", timestamp);
- return 0;
- }
- }
- }
-
- /**
- * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
- * Evas only use the monotic time for animating objects
- */
- timestamp = ecore_time_get() * 1000.0f;
- } else {
- if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
- timestamp = ecore_time_get();
-
- timestamp -= event_info->timestamp;
- if (timestamp > WIDGET_CONF_EVENT_FILTER) {
- DbgPrint("Dropped %lf\n", timestamp);
- return 0;
- }
- }
-
- timestamp = event_info->timestamp * 1000.0f;
- }
-
+ int ret = 0;
/**
* @note
* Feed up events
break;
}
- return ret;
+}
+
+static Eina_Bool pended_event_consumer_cb(void *data)
+{
+ vwin_info_t info = data;
+ widget_buffer_event_data_t event_info;
+
+ event_info = eina_list_nth(info->pended_events_list, 0);
+ if (!event_info) {
+ info->pended_events_consumer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ DbgPrint("Consuming delayed events\n");
+ (void)processing_events(info, event_info, event_info->timestamp);
+
+ info->pended_events_list = eina_list_remove(info->pended_events_list, event_info);
+ free(event_info);
+ return ECORE_CALLBACK_RENEW;
+}
+
+/**
+ * @note
+ * Every user event (mouse) on the buffer will be passed via this event callback
+ */
+static int event_handler_cb(widget_buffer_h handler, widget_buffer_event_data_t event_info, void *data)
+{
+ vwin_info_t info = data;
+ double timestamp;
+
+ /**
+ * @note
+ * If the feeds event is accessibility or key event,
+ * "return 0" will confusing the viewer,
+ * because it will waiting result of event processing to do handles state properly.
+ */
+
+ if (!info || info->state != VWIN_INFO_CREATED || !info->handle || info->deleted) {
+ /* Just ignore this event */
+ return 0;
+ }
+
+ if (event_info->type == WIDGET_BUFFER_EVENT_FRAME_SKIP_CLEARED) {
+ /**
+ * Increase the count_of_rendering only if it meets conditions.
+ * Or do not increase it to prevent from overflow problem.
+ * If we trying to increase the count_of_rendering variable, it could be overflowed.
+ * These conditions will prevents count_of_rendering from overflow issue.
+ */
+ if (info->pended_events_list && !info->pended_events_consumer) {
+ info->pended_events_consumer = ecore_timer_add(0.0001f, pended_event_consumer_cb, info);
+ if (info->pended_events_consumer) {
+ ErrPrint("Failed to create a pended event consumer\n");
+ }
+ }
+
+ return;
+ }
+
+ if (WIDGET_CONF_USE_GETTIMEOFDAY) {
+ if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) < 0) {
+ ErrPrint("gettimeofday: %d\n", errno);
+ } else {
+ timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+ timestamp -= event_info->timestamp;
+
+ if (timestamp > WIDGET_CONF_EVENT_FILTER) {
+ DbgPrint("Dropped %lf\n", timestamp);
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
+ * Evas only use the monotic time for animating objects
+ */
+ timestamp = ecore_time_get() * 1000.0f;
+ } else {
+ if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
+ timestamp = ecore_time_get();
+
+ timestamp -= event_info->timestamp;
+ if (timestamp > WIDGET_CONF_EVENT_FILTER) {
+ DbgPrint("Dropped %lf\n", timestamp);
+ return 0;
+ }
+ }
+
+ timestamp = event_info->timestamp * 1000.0f;
+ }
+
+ if ((info->w <= 1 && info->h <= 1) || widget_provider_buffer_frame_skip(info->handle) > 0 || info->pended_events_list) {
+ widget_buffer_event_data_t _ev_info;
+ _ev_info = malloc(sizeof(*_ev_info));
+ if (_ev_info) {
+ memcpy(_ev_info, event_info, sizeof(*_ev_info));
+ info->pended_events_list = eina_list_append(info->pended_events_list, _ev_info);
+ _ev_info->timestamp = timestamp;
+ /**
+ * @note
+ * Push events to pending list,.
+ * Consuming it first.
+ */
+ DbgPrint("Canvas is not prepared. pending the events (%dx%d)\n", info->w, info->h);
+ return 0;
+ } else {
+ ErrPrint("malloc: %d\n", errno);
+ }
+ }
+
+ return processing_events(info, event_info, timestamp);
}
static void pre_render_cb(void *data, Evas *e, void *event_info)
return;
}
+ if (info->pended_events_consumer) {
+ widget_buffer_event_data_t event_info;
+
+ DbgPrint("Clearing pended event consumer\n");
+ ecore_timer_del(info->pended_events_consumer);
+ info->pended_events_consumer = NULL;
+
+ EINA_LIST_FREE(info->pended_events_list, event_info) {
+ free(event_info);
+ }
+ }
+
widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
if (info->e) {