From 0d2001013f0a83fa14a9b490a7055084b71ee106 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Sun, 7 Dec 2014 20:14:34 -0500 Subject: [PATCH] redo shaped client checks to use shape flags instead of rect pointer, fix shapeless clients according to the shape extension protocol, the number of rectangles returned should be checked to determine a client's shape. if 0 is returned, the client has no shape, meaning that it either should not be drawn or should have no input region. this improves behavior with various client window types such as tooltips ref T1820 --- src/bin/e_comp.c | 2 +- src/bin/e_comp_object.c | 17 +++++++++-------- src/bin/e_comp_x.c | 25 ++++++++++++++++++++----- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index 7d8fdd235..db44bfc9f 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -604,7 +604,7 @@ _e_comp_shapes_update_comp_client_shape_comp_helper(E_Client *ec, Eina_Tiler *tb INF("COMP EC: %p", ec); #endif - if (ec->shape_input_rects || ec->shape_rects) + if (ec->shaped || ec->shaped_input) { int num, tot; int l, r, t, b; diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index a552be3c5..942402afb 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -169,7 +169,6 @@ _e_comp_object_event_add(Evas_Object *obj) static inline Eina_Bool _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num) { - if ((!rects) || (num < 1)) return EINA_FALSE; if (num > 1) return EINA_TRUE; if ((rects[0].x == 0) && (rects[0].y == 0) && ((int)rects[0].w == w) && ((int)rects[0].h == h)) @@ -3069,9 +3068,11 @@ e_comp_object_shape_apply(Evas_Object *obj) API_ENTRY; if (!cw->ec) return; //NYI - if (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)) + if (cw->ec->shaped) { - if (!cw->ec->shaped) return; + if ((cw->ec->shape_rects_num >= 1) && + (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num))) + return; } if (cw->native) { @@ -3083,11 +3084,11 @@ e_comp_object_shape_apply(Evas_Object *obj) //INF("SHAPE RENDER %p", cw->ec); - if (cw->ec->shape_rects) evas_object_image_native_surface_set(cw->obj, NULL); - evas_object_image_alpha_set(cw->obj, !!cw->ec->shape_rects); + if (cw->ec->shaped) evas_object_image_native_surface_set(cw->obj, NULL); + evas_object_image_alpha_set(cw->obj, !!cw->ec->shaped); EINA_LIST_FOREACH(cw->obj_mirror, l, o) { - if (cw->ec->shape_rects) evas_object_image_native_surface_set(o, NULL); + if (cw->ec->shaped) evas_object_image_native_surface_set(o, NULL); evas_object_image_alpha_set(o, 1); } @@ -3097,7 +3098,7 @@ e_comp_object_shape_apply(Evas_Object *obj) evas_object_image_data_set(cw->obj, pix); return; } - if (cw->ec->shape_rects) + if (cw->ec->shaped) { unsigned char *spix, *sp; @@ -3422,7 +3423,7 @@ e_comp_object_util_mirror_add(Evas_Object *obj) evas_object_data_set(o, "E_Client", cw->ec); evas_object_data_set(o, "comp_mirror", cw); - evas_object_image_alpha_set(o, cw->ec->argb || (!!cw->ec->shape_rects)); + evas_object_image_alpha_set(o, cw->ec->argb || (!!cw->ec->shaped)); evas_object_image_size_set(o, w, h); if (cw->ec->shaped) diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index e141c5f1b..2383e268b 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -3559,7 +3559,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) ec->changes.shape = 0; rects = ecore_x_window_shape_rectangles_get(win, &num); - if (rects) + if (rects && num) { int cw = 0, ch = 0; @@ -3622,16 +3622,21 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) free(rects); if (ec->shape_changed) e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW); + evas_object_pass_events_set(ec->frame, 0); } else { - // FIXME: no rects i think can mean... totally empty window + ec->shaped = 1; + E_FREE(ec->shape_rects); + E_FREE(ec->shape_input_rects); + ec->shape_input_rects_num = 0; + e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW); if (ec->shaped && ec->comp_data->reparented && (!ec->bordername)) { ec->border.changed = 1; EC_CHANGED(ec); } - ec->shaped = 0; + evas_object_pass_events_set(ec->frame, 1); } if (ec->shaped != pshaped) { @@ -3649,7 +3654,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) ec->changes.shape_input = 0; rects = ecore_x_window_shape_input_rectangles_get(win, &num); - if (rects) + if (rects && num) { int cw = 0, ch = 0; @@ -3689,9 +3694,19 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) ec->shape_input_rects = (Eina_Rectangle*)rects; ec->shape_input_rects_num = num; } + evas_object_pass_events_set(ec->frame, 0); } else - ec->shaped_input = 0; + { + ec->shaped_input = 1; + if (ec->comp_data->reparented) + ecore_x_window_shape_input_rectangles_set(pwin, rects, num); + changed = EINA_TRUE; + evas_object_pass_events_set(ec->frame, 1); + free(ec->shape_input_rects); + ec->shape_input_rects = NULL; + ec->shape_input_rects_num = 0; + } if (changed || (pshaped != ec->shaped_input)) { ec->need_shape_merge = 1;