diff --git a/src/bin/e_border.c b/src/bin/e_border.c index cfe0422b4..342bb71b1 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -647,7 +647,7 @@ e_border_move(E_Border *bd, int x, int y) ev = calloc(1, sizeof(E_Event_Border_Move)); ev->border = bd; e_object_ref(E_OBJECT(bd)); - e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event"); + e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event"); ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL); } @@ -1877,6 +1877,8 @@ _e_border_free(E_Border *bd) _e_border_move_end(bd); /* TODO: Other states to end before dying? */ + IF_FREE(bd->shape_rects); + bd->shape_rects_num = 0; if (bd->dangling_ref_check) { ecore_timer_del(bd->dangling_ref_check); @@ -4353,18 +4355,53 @@ _e_border_eval(E_Border *bd) if (bd->need_shape_export) { - Ecore_X_Rectangle *rects; + Ecore_X_Rectangle *rects, *orects; int num; rects = ecore_x_window_shape_rectangles_get(bd->win, &num); if (rects) { - if (bd->client.shaped) - e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0); + int changed; + + changed = 1; + if ((num == bd->shape_rects_num) && (bd->shape_rects)) + { + int i; + + orects = bd->shape_rects; + for (i = 0; i < num; i++) + { + if ((orects[i].x != rects[i].x) || + (orects[i].y != rects[i].y) || + (orects[i].width != rects[i].width) || + (orects[i].height != rects[i].height)) + { + changed = 1; + break; + } + } + changed = 0; + } + if (changed) + { + if (bd->client.shaped) + e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0); + else + e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h); + IF_FREE(bd->shape_rects); + bd->shape_rects = rects; + bd->shape_rects_num = num; + e_container_shape_rects_set(bd->shape, rects, num); + } else - e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h); - e_container_shape_rects_set(bd->shape, rects, num); - free(rects); + free(rects); + } + else + { + IF_FREE(bd->shape_rects); + bd->shape_rects = NULL; + bd->shape_rects_num = 0; + e_container_shape_rects_set(bd->shape, NULL, 0); } bd->need_shape_export = 0; } diff --git a/src/bin/e_border.h b/src/bin/e_border.h index 81ec2b7c7..478e718a0 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -324,6 +324,8 @@ struct _E_Border Ecore_Timer *raise_timer; Ecore_Timer *ping_timer; Ecore_Timer *kill_timer; + int shape_rects_num; + Ecore_X_Rectangle *shape_rects; Ecore_Timer *dangling_ref_check; }; diff --git a/src/bin/e_container.c b/src/bin/e_container.c index 1d61b6fa8..ee4046f7c 100644 --- a/src/bin/e_container.c +++ b/src/bin/e_container.c @@ -465,30 +465,10 @@ e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int { Evas_List *l; int i; - int changed = 1; E_Rect *r; E_OBJECT_CHECK(es); E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE); - - if (num == evas_list_count(es->shape)) - { - for (i = 0, l = es->shape; (i < num) && (l); i++, l = l->next) - { - r = l->data; - if ((r->x != rects[i].x) || (r->y != rects[i].y) || - (r->w != rects[i].width) || (r->h != rects[i].height)) - { - changed = 1; - break; - } - } - changed = 0; - } - if (!changed) - { - return; - } if (es->shape) { for (l = es->shape; l; l = l->next) diff --git a/src/bin/e_dnd.c b/src/bin/e_dnd.c index 70d2c2503..f8d13b4c7 100644 --- a/src/bin/e_dnd.c +++ b/src/bin/e_dnd.c @@ -23,11 +23,14 @@ static int _e_dnd_cb_event_dnd_selection(void *data, int type, void *event); /* local subsystem globals */ -typedef struct _XDnd { - int x, y; - char *type; - void *data; -} XDnd; +typedef struct _XDnd XDnd; + +struct _XDnd +{ + int x, y; + char *type; + void *data; +}; static Evas_List *_event_handlers = NULL; static Evas_List *_drop_handlers = NULL; @@ -495,14 +498,49 @@ e_drag_idler_before(void) drag = l->data; if (drag->need_shape_export) { - Ecore_X_Rectangle *rects; + Ecore_X_Rectangle *rects, *orects; int num; rects = ecore_x_window_shape_rectangles_get(drag->evas_win, &num); if (rects) { - e_container_shape_rects_set(drag->shape, rects, num); - free(rects); + int changed; + + changed = 1; + if ((num == drag->shape_rects_num) && (drag->shape_rects)) + { + int i; + + orects = drag->shape_rects; + for (i = 0; i < num; i++) + { + if ((orects[i].x != rects[i].x) || + (orects[i].y != rects[i].y) || + (orects[i].width != rects[i].width) || + (orects[i].height != rects[i].height)) + { + changed = 1; + break; + } + } + changed = 0; + } + if (changed) + { + IF_FREE(drag->shape_rects); + drag->shape_rects = rects; + drag->shape_rects_num = num; + e_container_shape_rects_set(drag->shape, rects, num); + } + else + free(rects); + } + else + { + IF_FREE(drag->shape_rects); + drag->shape_rects = NULL; + drag->shape_rects_num = 0; + e_container_shape_rects_set(drag->shape, NULL, 0); } drag->need_shape_export = 0; if (drag->visible) @@ -518,6 +556,8 @@ _e_drag_free(E_Drag *drag) { _drag_list = evas_list_remove(_drag_list, drag); + IF_FREE(drag->shape_rects); + drag->shape_rects_num = 0; e_object_unref(E_OBJECT(drag->container)); e_container_shape_hide(drag->shape); e_object_del(E_OBJECT(drag->shape)); diff --git a/src/bin/e_dnd.h b/src/bin/e_dnd.h index 31c9172bf..563b20891 100644 --- a/src/bin/e_dnd.h +++ b/src/bin/e_dnd.h @@ -36,6 +36,9 @@ struct _E_Drag int x, y, w, h; int dx, dy; + int shape_rects_num; + Ecore_X_Rectangle *shape_rects; + unsigned int layer; unsigned char visible : 1; unsigned char need_shape_export : 1; diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index 97a69c4f2..1b3f4c5af 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -770,14 +770,49 @@ e_menu_idler_before(void) m = l->data; if (m->need_shape_export) { - Ecore_X_Rectangle *rects; + Ecore_X_Rectangle *rects, *orects; int num; rects = ecore_x_window_shape_rectangles_get(m->evas_win, &num); if (rects) { - e_container_shape_rects_set(m->shape, rects, num); - free(rects); + int changed; + + changed = 1; + if ((num == m->shape_rects_num) && (m->shape_rects)) + { + int i; + + orects = m->shape_rects; + for (i = 0; i < num; i++) + { + if ((orects[i].x != rects[i].x) || + (orects[i].y != rects[i].y) || + (orects[i].width != rects[i].width) || + (orects[i].height != rects[i].height)) + { + changed = 1; + break; + } + } + changed = 0; + } + if (changed) + { + IF_FREE(m->shape_rects); + m->shape_rects = rects; + m->shape_rects_num = num; + e_container_shape_rects_set(m->shape, rects, num); + } + else + free(rects); + } + else + { + IF_FREE(m->shape_rects); + m->shape_rects = NULL; + m->shape_rects_num = 0; + e_container_shape_rects_set(m->shape, NULL, 0); } m->need_shape_export = 0; if (m->cur.visible) @@ -814,6 +849,8 @@ _e_menu_free(E_Menu *m) Evas_List *l, *tmp; _e_menu_unrealize(m); + IF_FREE(m->shape_rects); + m->shape_rects_num = 0; for (l = m->items; l;) { tmp = l; diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index 0596f7f51..dfb373fdb 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -55,7 +55,9 @@ struct _E_Menu Evas_Object *container_object; Evas_Coord container_x, container_y, container_w, container_h; E_Container_Shape *shape; - + int shape_rects_num; + Ecore_X_Rectangle *shape_rects; + struct { void *data; void (*func) (void *data, E_Menu *m); diff --git a/src/bin/e_popup.c b/src/bin/e_popup.c index 809d15ac1..fbfe1f8ad 100644 --- a/src/bin/e_popup.c +++ b/src/bin/e_popup.c @@ -173,19 +173,54 @@ e_popup_idler_before(void) pop = l->data; if (pop->need_shape_export) { - Ecore_X_Rectangle *rects; + Ecore_X_Rectangle *rects, *orects; int num; rects = ecore_x_window_shape_rectangles_get(pop->evas_win, &num); if (rects) { - e_container_shape_rects_set(pop->shape, rects, num); - free(rects); + int changed; + + changed = 1; + if ((num == pop->shape_rects_num) && (pop->shape_rects)) + { + int i; + + orects = pop->shape_rects; + for (i = 0; i < num; i++) + { + if ((orects[i].x != rects[i].x) || + (orects[i].y != rects[i].y) || + (orects[i].width != rects[i].width) || + (orects[i].height != rects[i].height)) + { + changed = 1; + break; + } + } + changed = 0; + } + if (changed) + { + IF_FREE(pop->shape_rects); + pop->shape_rects = rects; + pop->shape_rects_num = num; + e_container_shape_rects_set(pop->shape, rects, num); + } + else + free(rects); + } + else + { + IF_FREE(pop->shape_rects); + pop->shape_rects = NULL; + pop->shape_rects_num = 0; + e_container_shape_rects_set(pop->shape, NULL, 0); } pop->need_shape_export = 0; - if (pop->visible) - e_container_shape_show(pop->shape); } + if (pop->visible) + e_container_shape_show(pop->shape); } } @@ -194,6 +229,8 @@ e_popup_idler_before(void) static void _e_popup_free(E_Popup *pop) { + IF_FREE(pop->shape_rects); + pop->shape_rects_num = 0; e_container_shape_hide(pop->shape); e_object_del(E_OBJECT(pop->shape)); e_canvas_del(pop->ecore_evas); diff --git a/src/bin/e_popup.h b/src/bin/e_popup.h index bc6bbd3dc..3bcb7757b 100644 --- a/src/bin/e_popup.h +++ b/src/bin/e_popup.h @@ -26,6 +26,8 @@ struct _E_Popup Ecore_X_Window evas_win; E_Container_Shape *shape; E_Zone *zone; + int shape_rects_num; + Ecore_X_Rectangle *shape_rects; }; EAPI int e_popup_init(void);