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
This commit is contained in:
Mike Blumenkrantz 2014-12-07 20:14:34 -05:00
parent 6f024d3abf
commit 0d2001013f
3 changed files with 30 additions and 14 deletions

View File

@ -604,7 +604,7 @@ _e_comp_shapes_update_comp_client_shape_comp_helper(E_Client *ec, Eina_Tiler *tb
INF("COMP EC: %p", ec); INF("COMP EC: %p", ec);
#endif #endif
if (ec->shape_input_rects || ec->shape_rects) if (ec->shaped || ec->shaped_input)
{ {
int num, tot; int num, tot;
int l, r, t, b; int l, r, t, b;

View File

@ -169,7 +169,6 @@ _e_comp_object_event_add(Evas_Object *obj)
static inline Eina_Bool static inline Eina_Bool
_e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num) _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 (num > 1) return EINA_TRUE;
if ((rects[0].x == 0) && (rects[0].y == 0) && if ((rects[0].x == 0) && (rects[0].y == 0) &&
((int)rects[0].w == w) && ((int)rects[0].h == h)) ((int)rects[0].w == w) && ((int)rects[0].h == h))
@ -3069,9 +3068,11 @@ e_comp_object_shape_apply(Evas_Object *obj)
API_ENTRY; API_ENTRY;
if (!cw->ec) return; //NYI 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) if (cw->native)
{ {
@ -3083,11 +3084,11 @@ e_comp_object_shape_apply(Evas_Object *obj)
//INF("SHAPE RENDER %p", cw->ec); //INF("SHAPE RENDER %p", cw->ec);
if (cw->ec->shape_rects) evas_object_image_native_surface_set(cw->obj, NULL); if (cw->ec->shaped) evas_object_image_native_surface_set(cw->obj, NULL);
evas_object_image_alpha_set(cw->obj, !!cw->ec->shape_rects); evas_object_image_alpha_set(cw->obj, !!cw->ec->shaped);
EINA_LIST_FOREACH(cw->obj_mirror, l, o) 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); 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); evas_object_image_data_set(cw->obj, pix);
return; return;
} }
if (cw->ec->shape_rects) if (cw->ec->shaped)
{ {
unsigned char *spix, *sp; 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, "E_Client", cw->ec);
evas_object_data_set(o, "comp_mirror", cw); 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); evas_object_image_size_set(o, w, h);
if (cw->ec->shaped) if (cw->ec->shaped)

View File

@ -3559,7 +3559,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec)
ec->changes.shape = 0; ec->changes.shape = 0;
rects = ecore_x_window_shape_rectangles_get(win, &num); rects = ecore_x_window_shape_rectangles_get(win, &num);
if (rects) if (rects && num)
{ {
int cw = 0, ch = 0; int cw = 0, ch = 0;
@ -3622,16 +3622,21 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec)
free(rects); free(rects);
if (ec->shape_changed) if (ec->shape_changed)
e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW); e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW);
evas_object_pass_events_set(ec->frame, 0);
} }
else 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)) if (ec->shaped && ec->comp_data->reparented && (!ec->bordername))
{ {
ec->border.changed = 1; ec->border.changed = 1;
EC_CHANGED(ec); EC_CHANGED(ec);
} }
ec->shaped = 0; evas_object_pass_events_set(ec->frame, 1);
} }
if (ec->shaped != pshaped) 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; ec->changes.shape_input = 0;
rects = ecore_x_window_shape_input_rectangles_get(win, &num); rects = ecore_x_window_shape_input_rectangles_get(win, &num);
if (rects) if (rects && num)
{ {
int cw = 0, ch = 0; 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 = (Eina_Rectangle*)rects;
ec->shape_input_rects_num = num; ec->shape_input_rects_num = num;
} }
evas_object_pass_events_set(ec->frame, 0);
} }
else 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)) if (changed || (pshaped != ec->shaped_input))
{ {
ec->need_shape_merge = 1; ec->need_shape_merge = 1;