e_comp: calculate and send touch cancel when visibility is changed during touch 72/187972/2
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 30 Aug 2018 05:21:09 +0000 (14:21 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 30 Aug 2018 05:36:04 +0000 (14:36 +0900)
Change-Id: Ib5f1da04ce99004a4436b6430b48de0d0be36e38

src/bin/e_client.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h

index f617a3c91e142bc46f76be89dd7063fb5b82d9c8..6833beb2dbec9a5d11c87e00e9ab3ab121c43423 100644 (file)
@@ -2976,6 +2976,29 @@ e_client_transient_child_top_get(E_Client *ec, Eina_Bool consider_focus)
 #endif
 #define EC_IS_NOT_VISIBLE if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
 
+static Eina_Bool
+_e_client_visibility_touched_check(E_Client *ec)
+{
+   Eina_Bool res = EINA_FALSE;
+   int x, y, w, h;
+   int tx, ty;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, res);
+
+   tx = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x);
+   ty = wl_fixed_to_int(e_comp->wl_comp_data->ptr.y);
+
+   e_client_geometry_get(ec, &x, &y, &w, &h);
+
+   if ((tx >= x) && (tx <= x + w) &&
+       (ty >= y) && (ty <= y + h))
+     {
+        res = EINA_TRUE;
+     }
+
+   return res;
+}
+
 static void
 _e_client_visibility_zone_calculate(E_Zone *zone, Eina_Bool check_focus)
 {
@@ -3007,6 +3030,9 @@ _e_client_visibility_zone_calculate(E_Zone *zone, Eina_Bool check_focus)
    Eina_Bool ec_frame_visible = EINA_FALSE;
    int calc_skip_type = 0;
 
+   Eina_Bool touched_win_changed = EINA_FALSE;
+   E_Client *touched_ec;
+
    if (!e_config->calc_vis_without_effect)
      {
         if (e_comp->animating) return;
@@ -3212,6 +3238,7 @@ _e_client_visibility_zone_calculate(E_Zone *zone, Eina_Bool check_focus)
 
    if (changed_list)
      {
+        touched_ec = e_comp_wl->ptr.ec ? e_comp_wl->ptr.ec : e_comp_wl->touch.faked_ec;
         EINA_LIST_FOREACH(changed_list, l, ec)
           {
              if (ec->visibility.changed)
@@ -3219,8 +3246,19 @@ _e_client_visibility_zone_calculate(E_Zone *zone, Eina_Bool check_focus)
 
              _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY, ec);
 
+             if (ec == touched_ec)
+               touched_win_changed = EINA_TRUE;
+
              if (ec->visibility.obscured == E_VISIBILITY_UNOBSCURED)
                {
+                  if (e_comp_wl->touch.pressed && !touched_win_changed && !e_policy_client_is_keyboard_sub(ec))
+                    {
+                       if (_e_client_visibility_touched_check(ec))
+                         {
+                            touched_win_changed = EINA_TRUE;
+                            e_comp_wl_touch_cancel();
+                         }
+                    }
                   if (!find_top_vis_ec)
                     {
                        find_top_vis_ec = EINA_TRUE;
index 35da2ede1ab2e3f0b9f4e5bd370fcf1618a5d407..520feb254cadceb5f526b825cf884a3580fdc672 100644 (file)
@@ -585,13 +585,15 @@ _e_comp_wl_send_touch_cancel(E_Client *ec)
 static void
 _e_comp_wl_touch_cancel(void)
 {
-   if (!e_comp_wl->ptr.ec)
-     return;
+   E_Client *ec;
+
+   ec = e_comp_wl->ptr.ec ? e_comp_wl->ptr.ec : e_comp_wl->touch.faked_ec;
+   if (!ec) return;
 
    if (!need_send_released)
      return;
 
-   _e_comp_wl_send_touch_cancel(e_comp_wl->ptr.ec);
+   _e_comp_wl_send_touch_cancel(ec);
 
    need_send_released = EINA_FALSE;
    need_send_motion = EINA_FALSE;
@@ -606,9 +608,6 @@ _e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EIN
    if (e_object_is_del(E_OBJECT(ec))) return;
    if (ec->comp_data->sub.restacking) return;
 
-   if (ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED)
-     _e_comp_wl_touch_cancel();
-
    e_comp_wl_subsurface_stack_update(ec);
 }
 
@@ -1245,6 +1244,9 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
 
    if (dev &&  (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
      {
+        if (!e_comp_wl->touch.pressed)
+          e_comp_wl->touch.faked_ec = ec;
+
         if (dev_name)
           _e_comp_wl_device_renew_axis(dev_name, evas_device_class_get(dev),
                                         ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
@@ -1309,11 +1311,15 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
 
    if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
      {
+        e_comp_wl->touch.pressed &= ~(1 << 0);
+
+        if (!e_comp_wl->touch.pressed && e_comp_wl->touch.faked_ec)
+          e_comp_wl->touch.faked_ec = NULL;
+
         if (dev_name)
           _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
                                         ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
         _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_FALSE);
-        e_comp_wl->touch.pressed &= ~(1 << 0);
      }
    else
      e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
@@ -1424,6 +1430,10 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
    flags = evas_event_default_flags_get(evas);
    if (flags & EVAS_EVENT_FLAG_ON_HOLD) return;
 
+   e_comp_wl->touch.pressed &= ~(1 << ev->device);
+   if (!e_comp_wl->touch.pressed && e_comp_wl->touch.faked_ec)
+     e_comp_wl->touch.faked_ec = NULL;
+
    dev = ev->dev;
    if (dev && (dev_name = evas_device_description_get(dev)))
      {
@@ -1433,7 +1443,6 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
      }
 
    _e_comp_wl_send_touch(ec, ev->device, 0, 0, ev->timestamp, EINA_FALSE);
-   e_comp_wl->touch.pressed &= ~(1 << ev->device);
 }
 
 static void
index 7afb8afcc9f16be5bb9dfa2c668bb6b1cc0c3f72..1e69ab05591a8a1522b7cc2707e8ad5e52186c16 100644 (file)
@@ -274,6 +274,7 @@ struct _E_Comp_Wl_Data
         Eina_Bool enabled : 1;
         unsigned int num_devices;
         unsigned int pressed;
+        E_Client *faked_ec;
      } touch;
 
    struct