diff --git a/data/themes/default_border.edc b/data/themes/default_border.edc index 199594913..b5417ec2e 100644 --- a/data/themes/default_border.edc +++ b/data/themes/default_border.edc @@ -232,7 +232,8 @@ images { group { name: "widgets/border/default/border"; data { - // item: "client_inset" "4 4 24 4"; +// this tells e the border is shaped +// item: "shaped" "1"; } parts { part { diff --git a/data/themes/default_menu.edc b/data/themes/default_menu.edc index 7856a48ea..e07938512 100644 --- a/data/themes/default_menu.edc +++ b/data/themes/default_menu.edc @@ -10,6 +10,10 @@ images { } group { name: "widgets/menu/default/background"; + data { +// this tells e the border is shaped +// item: "shaped" "1"; + } parts { part { name: "base"; diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 4f65dacca..0684c5448 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -212,6 +212,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map) bd->w = 1; bd->h = 1; bd->win = ecore_x_window_override_new(bd->container->win, 0, 0, bd->w, bd->h); + ecore_x_window_shape_events_select(bd->win, 1); mwin = e_menu_grab_window_get(); if (!mwin) mwin = e_init_window_get(); if (mwin) @@ -236,6 +237,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map) bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h); bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas); bd->bg_win = ecore_evas_software_x11_window_get(bd->bg_ecore_evas); + ecore_x_window_shape_events_select(bd->bg_win, 1); ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window"); ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame"); bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1); @@ -298,6 +300,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map) bd->w = bd->client.w; bd->h = bd->client.h; bd->changes.size = 1; + bd->changes.shape = 1; printf("##- ON MAP CLIENT 0x%x SIZE %ix%i\n", bd->client.win, bd->client.w, bd->client.h); @@ -1058,6 +1061,36 @@ e_border_find_by_client_window(Ecore_X_Window win) return NULL; } +E_Border * +e_border_find_by_frame_window(Ecore_X_Window win) +{ + Evas_List *l; + + for (l = borders; l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if (bd->bg_win == win) return bd; + } + return NULL; +} + +E_Border * +e_border_find_by_window(Ecore_X_Window win) +{ + Evas_List *l; + + for (l = borders; l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if (bd->win == win) return bd; + } + return NULL; +} + E_Border * e_border_focused_get(void) { @@ -1543,7 +1576,26 @@ _e_border_cb_window_shape(void *data, int ev_type, void *ev) e = ev; bd = e_border_find_by_client_window(e->win); - if (!bd) return 1; + if (bd) + { + bd->changes.shape = 1; + bd->changed = 1; + return 1; + } + bd = e_border_find_by_window(e->win); + if (bd) + { + bd->need_shape_export = 1; + bd->changed = 1; + return 1; + } + bd = e_border_find_by_frame_window(e->win); + if (bd) + { + bd->need_shape_merge = 1; + bd->changed = 1; + return 1; + } return 1; } @@ -2518,6 +2570,39 @@ _e_border_eval(E_Border *bd) bd->client.netwm.fetch.desktop = 0; } + if (bd->changes.shape) + { + Ecore_X_Rectangle *rects; + int num; + + rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num); + if (rects) + { + if ((num == 1) && + (rects[0].x == 0) && + (rects[0].y == 0) && + (rects[0].width == bd->client.w) && + (rects[0].height == bd->client.h)) + { + if (bd->client.shaped) + { + bd->client.shaped = 0; + } + } + else + { + if (!bd->client.shaped) + { + bd->client.shaped = 1; + } + } + free(rects); + } + bd->need_shape_merge = 1; + /* is the client shaped? */ + bd->changes.shape = 0; + } + if (bd->client.border.changed) { Evas_Object *o; @@ -2551,6 +2636,37 @@ _e_border_eval(E_Border *bd) ok = edje_object_file_set(o, path, buf); if (ok) { + const char *shape_option; + + shape_option = edje_object_data_get(o, "shaped"); + if (shape_option) + { + if (!strcmp(shape_option, "1")) + { + if (!bd->shaped) + { + bd->shaped = 1; + ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped); + } + } + else + { + if (bd->shaped) + { + bd->shaped = 0; + ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped); + } + } + } + else + { + if (bd->shaped) + { + bd->shaped = 0; + ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped); + } + } + edje_object_part_text_set(o, "title_text", // "Japanese (hiragana): いろはにほへとちりぬるを"); bd->client.icccm.title); @@ -2926,6 +3042,68 @@ _e_border_eval(E_Border *bd) GRAV_SET(bd, ECORE_X_GRAVITY_NW); bd->changes.reset_gravity = 0; } + + if (bd->need_shape_merge) + { + if ((bd->shaped) || (bd->client.shaped)) + { + Ecore_X_Window twin; + + twin = ecore_x_window_override_new(bd->win, 0, 0, bd->w, bd->h); + if (bd->shaped) + { + ecore_x_window_shape_window_set(twin, bd->bg_win); + } + else + { + Ecore_X_Rectangle rects[4]; + + rects[0].x = 0; + rects[0].y = 0; + rects[0].width = bd->w; + rects[0].height = bd->client_inset.t; + rects[1].x = 0; + rects[1].y = bd->client_inset.t; + rects[1].width = bd->client_inset.l; + rects[1].height = bd->client.h; + rects[2].x = bd->w - bd->client_inset.r; + rects[2].y = bd->client_inset.t; + rects[2].width = bd->client_inset.r; + rects[2].height = bd->client.h; + rects[3].x = 0; + rects[3].y = bd->h - bd->client_inset.b; + rects[3].width = bd->w; + rects[3].height = bd->client_inset.b; + ecore_x_window_shape_rectangles_set(twin, rects, 4); + } + ecore_x_window_shape_window_add_xy(twin, bd->client.win, bd->client_inset.l, bd->client_inset.t); + ecore_x_window_shape_window_set(bd->win, twin); + ecore_x_window_del(twin); + } + else + { + ecore_x_window_shape_mask_set(bd->win, 0); + } + bd->need_shape_merge = 0; + } + + if (bd->need_shape_export) + { + Ecore_X_Rectangle *rects; + 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); + 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); + } + bd->need_shape_export = 0; + } bd->changed = 0; @@ -3705,3 +3883,4 @@ _e_border_reorder_before(E_Border *bd, E_Border *before) borders = evas_list_prepend(borders, bd); } } + diff --git a/src/bin/e_border.h b/src/bin/e_border.h index db73d3788..9ecb7fd97 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -71,7 +71,7 @@ struct _E_Border Evas_List *handlers; struct { - int l, r, t, b; + int l, r, t, b; } client_inset; Ecore_Evas *bg_ecore_evas; @@ -80,88 +80,90 @@ struct _E_Border Evas_Object *bg_object; Evas_Object *icon_object; Ecore_X_Window event_win; - + struct { - Ecore_X_Window shell_win; - Ecore_X_Window win; - - int x, y, w, h; - - struct { - unsigned char changed : 1; - char *name; - } border; - - struct { - char *title; - char *name; - char *class; - char *icon_name; - char *machine; - int min_w, min_h; - int max_w, max_h; - int base_w, base_h; - int step_w, step_h; - int start_x, start_y; - double min_aspect, max_aspect; - Ecore_X_Window_State_Hint initial_state; - Ecore_X_Pixmap icon_pixmap; - Ecore_X_Pixmap icon_mask; - Ecore_X_Window icon_window; - Ecore_X_Window window_group; - Ecore_X_Gravity gravity; - unsigned char take_focus : 1; - unsigned char accepts_focus : 1; - unsigned char urgent : 1; - unsigned char delete_request : 1; - unsigned char withdrawn : 1; - unsigned char iconic : 1; - unsigned char request_pos : 1; - struct { - unsigned int title : 1; - unsigned int name_class : 1; - unsigned int icon_name : 1; - unsigned int machine : 1; - unsigned int hints : 1; - unsigned int size_pos_hints : 1; - unsigned int protocol : 1; - } fetch; - } icccm; - struct { - Ecore_X_MWM_Hint_Func func; - Ecore_X_MWM_Hint_Decor decor; - Ecore_X_MWM_Hint_Input input; - unsigned char exists : 1; - unsigned char borderless : 1; - struct { - unsigned int hints : 1; - } fetch; - } mwm; - struct { - pid_t pid; - int desktop; - struct { - unsigned int pid : 1; - unsigned int desktop : 1; - } fetch; - - /* NetWM Window state */ - struct { - unsigned char modal : 1; - unsigned char maximized_v : 1; - unsigned char maximized_h : 1; - unsigned char skip_taskbar : 1; - unsigned char skip_pager : 1; - unsigned char fullscreen : 1; - unsigned char stacking : 2; /* 0 = None, 1 = Above, 2 = Below */ - } state; - - } netwm; - Ecore_X_Window_Attributes initial_attributes; + Ecore_X_Window shell_win; + Ecore_X_Window win; + + int x, y, w, h; + + struct { + unsigned char changed : 1; + char *name; + } border; + + unsigned char shaped : 1; + + struct { + char *title; + char *name; + char *class; + char *icon_name; + char *machine; + int min_w, min_h; + int max_w, max_h; + int base_w, base_h; + int step_w, step_h; + int start_x, start_y; + double min_aspect, max_aspect; + Ecore_X_Window_State_Hint initial_state; + Ecore_X_Pixmap icon_pixmap; + Ecore_X_Pixmap icon_mask; + Ecore_X_Window icon_window; + Ecore_X_Window window_group; + Ecore_X_Gravity gravity; + unsigned char take_focus : 1; + unsigned char accepts_focus : 1; + unsigned char urgent : 1; + unsigned char delete_request : 1; + unsigned char withdrawn : 1; + unsigned char iconic : 1; + unsigned char request_pos : 1; + struct { + unsigned int title : 1; + unsigned int name_class : 1; + unsigned int icon_name : 1; + unsigned int machine : 1; + unsigned int hints : 1; + unsigned int size_pos_hints : 1; + unsigned int protocol : 1; + } fetch; + } icccm; + struct { + Ecore_X_MWM_Hint_Func func; + Ecore_X_MWM_Hint_Decor decor; + Ecore_X_MWM_Hint_Input input; + unsigned char exists : 1; + unsigned char borderless : 1; + struct { + unsigned int hints : 1; + } fetch; + } mwm; + struct { + pid_t pid; + int desktop; + struct { + unsigned int pid : 1; + unsigned int desktop : 1; + } fetch; + + /* NetWM Window state */ + struct { + unsigned char modal : 1; + unsigned char maximized_v : 1; + unsigned char maximized_h : 1; + unsigned char skip_taskbar : 1; + unsigned char skip_pager : 1; + unsigned char fullscreen : 1; + unsigned char stacking : 2; /* 0 = None, 1 = Above, 2 = Below */ + } state; + + } netwm; + Ecore_X_Window_Attributes initial_attributes; } client; - + E_Container_Shape *shape; - + unsigned char visible : 1; unsigned char moving : 1; unsigned char focused : 1; @@ -172,38 +174,42 @@ struct _E_Border unsigned char maximized : 1; unsigned char iconic : 1; unsigned char sticky : 1; - + unsigned char shaped : 1; + unsigned char need_shape_merge : 1; + unsigned char need_shape_export : 1; + unsigned char changed : 1; - + unsigned char ignore_first_unmap; unsigned char resize_mode; - + struct { - int x, y, w, h; + int x, y, w, h; } saved; struct { - double start; - double val; - int x, y; - E_Direction dir; - Ecore_Animator *anim; + double start; + double val; + int x, y; + E_Direction dir; + Ecore_Animator *anim; } shade; - + Evas_List *stick_desks; E_Menu *border_menu; Evas_List *pending_move_resize; - + struct { - unsigned int visible : 1; - unsigned int pos : 1; - unsigned int size : 1; - unsigned int stack : 1; - unsigned int prop : 1; - unsigned int border : 1; - unsigned int reset_gravity : 1; - unsigned int shading : 1; - unsigned int shaded : 1; + unsigned int visible : 1; + unsigned int pos : 1; + unsigned int size : 1; + unsigned int stack : 1; + unsigned int prop : 1; + unsigned int border : 1; + unsigned int reset_gravity : 1; + unsigned int shading : 1; + unsigned int shaded : 1; + unsigned int shape : 1; } changes; }; @@ -321,6 +327,8 @@ EAPI void e_border_stick(E_Border *bd); EAPI void e_border_unstick(E_Border *bd); EAPI E_Border *e_border_find_by_client_window(Ecore_X_Window win); +EAPI E_Border *e_border_find_by_frame_window(Ecore_X_Window win); +EAPI E_Border *e_border_find_by_window(Ecore_X_Window win); EAPI E_Border *e_border_focused_get(void); EAPI void e_border_idler_before(void); diff --git a/src/bin/e_container.c b/src/bin/e_container.c index 70329c10a..2d2407374 100644 --- a/src/bin/e_container.c +++ b/src/bin/e_container.c @@ -394,8 +394,59 @@ e_container_shape_rects_get(E_Container_Shape *es) return es->shape; } +void +e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int num) +{ + Evas_List *l; + int i; + + E_OBJECT_CHECK(es); + E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE); + + if (es->shape) + { + for (l = es->shape; l; l = l->next) + free(l->data); + evas_list_free(es->shape); + es->shape = NULL; + } + if (rects) + { + for (i = 0; i < num; i++) + { + E_Rect *r; + + r = malloc(sizeof(E_Rect)); + if (r) + { + r->x = rects[i].x; + r->y = rects[i].y; + r->w = rects[i].width; + r->h = rects[i].height; + es->shape = evas_list_append(es->shape, r); + } + } + } + _e_container_shape_change_call(es, E_CONTAINER_SHAPE_RECTS); +} +void +e_container_shape_solid_rect_set(E_Container_Shape *es, int x, int y, int w, int h) +{ + es->solid_rect.x = x; + es->solid_rect.y = y; + es->solid_rect.w = w; + es->solid_rect.h = h; +} +void +e_container_shape_solid_rect_get(E_Container_Shape *es, int *x, int *y, int *w, int *h) +{ + if (x) *x = es->solid_rect.x; + if (y) *y = es->solid_rect.y; + if (w) *w = es->solid_rect.w; + if (h) *h = es->solid_rect.h; +} /* local subsystem functions */ static void diff --git a/src/bin/e_container.h b/src/bin/e_container.h index 7072c6ae9..037c8b453 100644 --- a/src/bin/e_container.h +++ b/src/bin/e_container.h @@ -57,6 +57,9 @@ struct _E_Container_Shape E_Container *con; int x, y, w, h; unsigned char visible : 1; + struct { + int x, y, w, h; + } solid_rect; Evas_List *shape; }; @@ -98,6 +101,9 @@ EAPI E_Container *e_container_shape_container_get(E_Container_Shape *es); EAPI void e_container_shape_change_callback_add(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data); EAPI void e_container_shape_change_callback_del(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data); EAPI Evas_List *e_container_shape_rects_get(E_Container_Shape *es); +EAPI void e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int num); +EAPI void e_container_shape_solid_rect_set(E_Container_Shape *es, int x, int y, int w, int h); +EAPI void e_container_shape_solid_rect_get(E_Container_Shape *es, int *x, int *y, int *w, int *h); extern EAPI int E_EVENT_CONTAINER_RESIZE; diff --git a/src/bin/e_intl.c b/src/bin/e_intl.c index 1f2be6976..bb88d2d2d 100644 --- a/src/bin/e_intl.c +++ b/src/bin/e_intl.c @@ -38,10 +38,7 @@ e_intl_shutdown(void) free(_e_intl_language); _e_intl_language = NULL; while (_e_intl_languages) - { - free(_e_intl_languages->data); - _e_intl_languages = evas_list_remove_list(_e_intl_languages, _e_intl_languages); - } + _e_intl_languages = evas_list_remove_list(_e_intl_languages, _e_intl_languages); return 1; } diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index c637b7fc2..11bbab314 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -65,6 +65,7 @@ static int _e_menu_cb_mouse_up (void *data, int type, void *e static int _e_menu_cb_mouse_move (void *data, int type, void *event); static int _e_menu_cb_mouse_wheel (void *data, int type, void *event); static int _e_menu_cb_scroll_timer (void *data); +static int _e_menu_cb_window_shape (void *data, int ev_type, void *ev); /* local subsystem globals */ static Ecore_X_Window _e_menu_win = 0; @@ -77,23 +78,25 @@ static int _e_menu_y = 0; static Ecore_X_Time _e_menu_time = 0; static int _e_menu_autoscroll_x = 0; static int _e_menu_autoscroll_y = 0; -static Ecore_Event_Handler *_e_menu_key_down_handler = NULL; -static Ecore_Event_Handler *_e_menu_key_up_handler = NULL; -static Ecore_Event_Handler *_e_menu_mouse_down_handler = NULL; -static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL; -static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL; -static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL; +static Ecore_Event_Handler *_e_menu_key_down_handler = NULL; +static Ecore_Event_Handler *_e_menu_key_up_handler = NULL; +static Ecore_Event_Handler *_e_menu_mouse_down_handler = NULL; +static Ecore_Event_Handler *_e_menu_mouse_up_handler = NULL; +static Ecore_Event_Handler *_e_menu_mouse_move_handler = NULL; +static Ecore_Event_Handler *_e_menu_mouse_wheel_handler = NULL; +static Ecore_Event_Handler *_e_menu_window_shape_handler = NULL; /* externally accessible functions */ int e_menu_init(void) { - _e_menu_key_down_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_menu_cb_key_down, NULL); - _e_menu_key_up_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _e_menu_cb_key_up, NULL); - _e_menu_mouse_down_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_menu_cb_mouse_down, NULL); - _e_menu_mouse_up_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _e_menu_cb_mouse_up, NULL); - _e_menu_mouse_move_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _e_menu_cb_mouse_move, NULL); - _e_menu_mouse_wheel_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _e_menu_cb_mouse_wheel, NULL); + _e_menu_key_down_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_menu_cb_key_down, NULL); + _e_menu_key_up_handler = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _e_menu_cb_key_up, NULL); + _e_menu_mouse_down_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _e_menu_cb_mouse_down, NULL); + _e_menu_mouse_up_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _e_menu_cb_mouse_up, NULL); + _e_menu_mouse_move_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _e_menu_cb_mouse_move, NULL); + _e_menu_mouse_wheel_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _e_menu_cb_mouse_wheel, NULL); + _e_menu_window_shape_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_menu_cb_window_shape, NULL); return 1; } @@ -104,9 +107,9 @@ e_menu_shutdown(void) E_FN_DEL(ecore_event_handler_del, _e_menu_key_up_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_down_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_up_handler); - E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_move_handler); E_FN_DEL(ecore_event_handler_del, _e_menu_mouse_wheel_handler); + E_FN_DEL(ecore_event_handler_del, _e_menu_window_shape_handler); while (_e_active_menus) { @@ -611,7 +614,8 @@ e_menu_idler_before(void) m->prev.visible = m->cur.visible; ecore_evas_raise(m->ecore_evas); ecore_evas_show(m->ecore_evas); - e_container_shape_show(m->shape); + if (!m->shaped) + e_container_shape_show(m->shape); } } /* phase 4. de-activate... */ @@ -639,6 +643,28 @@ e_menu_idler_before(void) e_object_unref(E_OBJECT(m)); } } + /* phase 5. shapes... */ + for (l = _e_active_menus; l; l = l->next) + { + E_Menu *m; + + m = l->data; + if (m->need_shape_export) + { + Ecore_X_Rectangle *rects; + 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); + } + m->need_shape_export = 0; + if (m->cur.visible) + e_container_shape_show(m->shape); + } + } /* del refcount to all menus we worked with */ while (tmp) { @@ -981,6 +1007,7 @@ _e_menu_realize(E_Menu *m) { Evas_Object *o; Evas_List *l; + int ok; if (m->realized) return; m->realized = 1; @@ -999,6 +1026,7 @@ _e_menu_realize(E_Menu *m) evas_event_feed_mouse_in(m->evas, NULL); evas_event_feed_mouse_move(m->evas, -1000000, -1000000, NULL); m->evas_win = ecore_evas_software_x11_window_get(m->ecore_evas); + ecore_x_window_shape_events_select(m->evas_win, 1); ecore_evas_name_class_set(m->ecore_evas, "E", "_e_menu_window"); ecore_evas_title_set(m->ecore_evas, "E Menu"); @@ -1008,12 +1036,28 @@ _e_menu_realize(E_Menu *m) evas_object_data_set(o, "e_menu", m); evas_object_move(o, 0, 0); evas_object_resize(o, m->cur.w, m->cur.h); - edje_object_file_set(o, - /* FIXME: "default.edj" needs to come from conf */ - e_path_find(path_themes, "default.edj"), - "widgets/menu/default/background"); + ok = edje_object_file_set(o, + /* FIXME: "default.edj" needs to come from conf */ + e_path_find(path_themes, "default.edj"), + "widgets/menu/default/background"); + if (ok) + { + const char *shape_option; + + shape_option = edje_object_data_get(o, "shaped"); + if (shape_option) + { + if (!strcmp(shape_option, "1")) + { + m->shaped = 1; + } + } + } evas_object_show(o); + if (m->shaped) + ecore_evas_shaped_set(m->ecore_evas, m->shaped); + o = e_box_add(m->evas); m->container_object = o; evas_object_intercept_move_callback_add (o, _e_menu_cb_intercept_container_move, m); @@ -2123,3 +2167,21 @@ _e_menu_cb_scroll_timer(void *data) } return 1; } + +static int +_e_menu_cb_window_shape(void *data, int ev_type, void *ev) +{ + Evas_List *l; + Ecore_X_Event_Window_Shape *e; + + e = ev; + for (l = _e_active_menus; l; l = l->next) + { + E_Menu *m; + + m = l->data; + if (m->evas_win == e->win) + m->need_shape_export = 1; + } + return 1; +} diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index 66ec7184b..7f59c7810 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -68,6 +68,8 @@ struct _E_Menu unsigned char pending_new_submenu : 1; unsigned char have_submenu : 1; unsigned char in_active_list : 1; + unsigned char shaped : 1; + unsigned char need_shape_export : 1; }; struct _E_Menu_Item diff --git a/src/modules/dropshadow/e_mod_main.c b/src/modules/dropshadow/e_mod_main.c index 5f6209a20..05904778c 100644 --- a/src/modules/dropshadow/e_mod_main.c +++ b/src/modules/dropshadow/e_mod_main.c @@ -157,6 +157,7 @@ _ds_init(E_Module *m) E_CONFIG_VAL(D, T, shadow_x, INT); E_CONFIG_VAL(D, T, shadow_y, INT); E_CONFIG_VAL(D, T, blur_size, INT); + E_CONFIG_VAL(D, T, quality, INT); E_CONFIG_VAL(D, T, shadow_darkness, DOUBLE); ds->conf = e_config_domain_load("module.dropshadow", ds->conf_edd); @@ -166,13 +167,15 @@ _ds_init(E_Module *m) ds->conf->shadow_x = 4; ds->conf->shadow_y = 4; ds->conf->blur_size = 10; + ds->conf->quality = 2; ds->conf->shadow_darkness = 0.5; } E_CONFIG_LIMIT(ds->conf->shadow_x, -200, 200); E_CONFIG_LIMIT(ds->conf->shadow_y, -200, 200); E_CONFIG_LIMIT(ds->conf->blur_size, 1, 120); + E_CONFIG_LIMIT(ds->conf->quality, 1, 10); E_CONFIG_LIMIT(ds->conf->shadow_darkness, 0.0, 1.0); - + if (ds->conf->shadow_x >= ds->conf->blur_size) ds->conf->shadow_x = ds->conf->blur_size - 1; if (ds->conf->shadow_y >= ds->conf->blur_size) @@ -222,6 +225,7 @@ _ds_shutdown(Dropshadow *ds) } if (ds->idler_before) e_main_idler_before_del(ds->idler_before); if (ds->table.gauss) free(ds->table.gauss); + if (ds->table.gauss2) free(ds->table.gauss2); _ds_shared_free(ds); free(ds); } @@ -831,12 +835,23 @@ _ds_shadow_recalc(Shadow *sh) Evas_List *l; Shpix *sp; int shw, shh, bsz, shx, shy; + int x1, y1, x2, y2; + int q; + q = sh->ds->conf->quality; if ((!rects) && (sh->toosmall)) sh->square = 1; else sh->square = 0; - + + /* FIXME: find "minimum" center of the shape rects - if any */ + /* idea - take rects, run thru list. for each rect start x + * check all rects with a y > than this one. (will come later + * in the list). keep track of the last y point and id this rect x + * spans this line then advance new y point by rect size if it + * immediately joins it... + + */ shx = sh->ds->conf->shadow_x; shy = sh->ds->conf->shadow_y; shw = sh->w; @@ -849,56 +864,114 @@ _ds_shadow_recalc(Shadow *sh) sh->use_shared = 0; } - sp = _ds_shpix_new(shw + (bsz * 2), shh + (bsz * 2)); + sp = _ds_shpix_new((shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q); if (sp) { + int slx, sly, slw, slh; + if (!rects) { - _ds_shpix_fill(sp, 0, 0, shw + (bsz * 2), bsz, 0); - _ds_shpix_fill(sp, 0, bsz + shh, shw + (bsz * 2), bsz, 0); - _ds_shpix_fill(sp, 0, bsz, bsz, shh, 0); - _ds_shpix_fill(sp, bsz + shw, bsz, bsz, shh, 0); - _ds_shpix_fill(sp, bsz, bsz, shw, shh, 255); + /* FIXME; rounding errors - fix as below in else{} */ + _ds_shpix_fill(sp, 0, 0, (shw + (bsz * 2)) / q, (bsz) / q, 0); + _ds_shpix_fill(sp, 0, (bsz + shh) / q, (shw + (bsz * 2)) / q, (bsz) / q, 0); + _ds_shpix_fill(sp, 0, (bsz) / q, (bsz) / q, (shh) / q, 0); + _ds_shpix_fill(sp, (bsz + shw) / q, (bsz) / q, (bsz) / q, (shh) / q, 0); + _ds_shpix_fill(sp, (bsz) / q, (bsz) / q, (shw) / q, (shh) / q, 255); } else { + _ds_shpix_fill(sp, 0, 0, (shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q, 0); for (l = rects; l; l = l->next) { E_Rect *r; r = l->data; - _ds_shpix_fill(sp, bsz + r->x, bsz + r->y, r->w, r->h, 255); + x1 = (bsz + r->x) / q; + y1 = (bsz + r->y) / q; + x2 = (bsz + r->x + r->w - 1) / q; + y2 = (bsz + r->y + r->h - 1) / q; + _ds_shpix_fill(sp, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1, 255); } } - _ds_shpix_blur(sp, 0, 0, shw + (bsz * 2), shh + (bsz * 2), - sh->ds->table.gauss, bsz); - - _ds_shpix_object_set(sp, sh->object[0], 0, 0, - shw + (bsz * 2), shh + (bsz * 2)); - - evas_object_move(sh->object[0], - sh->x + shx - bsz, - sh->y + shy - bsz); - evas_object_image_border_set(sh->object[0], - 0, 0, 0, 0); - evas_object_resize(sh->object[0], - sh->w + (bsz * 2), - sh->h + (bsz * 2)); - evas_object_image_fill_set(sh->object[0], 0, 0, - sh->w + (bsz * 2), - sh->h + (bsz * 2)); - _ds_object_unset(sh->object[1]); - _ds_object_unset(sh->object[2]); - _ds_object_unset(sh->object[3]); - _ds_shpix_free(sp); - } - - if (evas_object_visible_get(sh->object[0])) - { - evas_object_hide(sh->object[1]); - evas_object_hide(sh->object[2]); - evas_object_hide(sh->object[3]); + e_container_shape_solid_rect_get(sh->shape, &slx, &sly, &slw, &slh); + slx += bsz; + sly += bsz; + slw -= bsz * 2; + slh -= bsz * 2; + slw = (slw - 1 + slx) / q; + slh = (slh - 1 + sly) / q; + slx /= q; + sly /= q; + slw = slw - slx + 1; + slh = slh - sly + 1; + if ((slw > 0) && (slh > 0)) + { + /* FIXME: handle as 4 separate shadow obj's - not 1 */ + _ds_shpix_blur(sp, 0, 0, + (shw + (bsz * 2)) / q, + (shh + (bsz * 2)) / q, + sh->ds->table.gauss2, (bsz) / q); + _ds_shpix_object_set(sp, sh->object[0], 0, 0, + (shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q); + + evas_object_move(sh->object[0], + sh->x + shx - bsz, + sh->y + shy - bsz); + evas_object_image_smooth_scale_set(sh->object[0], 1); + evas_object_image_border_set(sh->object[0], + 0, 0, 0, 0); + evas_object_resize(sh->object[0], + sh->w + (bsz * 2), + sh->h + (bsz * 2)); + evas_object_image_fill_set(sh->object[0], 0, 0, + sh->w + (bsz * 2), + sh->h + (bsz * 2)); + _ds_object_unset(sh->object[1]); + _ds_object_unset(sh->object[2]); + _ds_object_unset(sh->object[3]); + _ds_shpix_free(sp); + + if (evas_object_visible_get(sh->object[0])) + { + evas_object_hide(sh->object[1]); + evas_object_hide(sh->object[2]); + evas_object_hide(sh->object[3]); + } + } + else + { + _ds_shpix_blur(sp, 0, 0, + (shw + (bsz * 2)) / q, + (shh + (bsz * 2)) / q, + sh->ds->table.gauss2, (bsz) / q); + _ds_shpix_object_set(sp, sh->object[0], 0, 0, + (shw + (bsz * 2)) / q, (shh + (bsz * 2)) / q); + + evas_object_move(sh->object[0], + sh->x + shx - bsz, + sh->y + shy - bsz); + evas_object_image_smooth_scale_set(sh->object[0], 1); + evas_object_image_border_set(sh->object[0], + 0, 0, 0, 0); + evas_object_resize(sh->object[0], + sh->w + (bsz * 2), + sh->h + (bsz * 2)); + evas_object_image_fill_set(sh->object[0], 0, 0, + sh->w + (bsz * 2), + sh->h + (bsz * 2)); + _ds_object_unset(sh->object[1]); + _ds_object_unset(sh->object[2]); + _ds_object_unset(sh->object[3]); + _ds_shpix_free(sp); + + if (evas_object_visible_get(sh->object[0])) + { + evas_object_hide(sh->object[1]); + evas_object_hide(sh->object[2]); + evas_object_hide(sh->object[3]); + } + } } } else @@ -965,6 +1038,7 @@ _ds_shadow_recalc(Shadow *sh) _ds_shstore_object_set(sh->ds->shared.shadow[2], sh->object[2]); _ds_shstore_object_set(sh->ds->shared.shadow[3], sh->object[3]); + evas_object_image_smooth_scale_set(sh->object[0], 0); evas_object_move(sh->object[0], sh->x + shx - bsz, sh->y + shy - bsz); @@ -977,6 +1051,7 @@ _ds_shadow_recalc(Shadow *sh) sh->w + (bsz) * 2, bsz - shy); + evas_object_image_smooth_scale_set(sh->object[1], 0); evas_object_move(sh->object[1], sh->x + shx - bsz, sh->y); @@ -989,6 +1064,7 @@ _ds_shadow_recalc(Shadow *sh) bsz - shx, sh->h); + evas_object_image_smooth_scale_set(sh->object[2], 0); evas_object_move(sh->object[2], sh->x + sh->w, sh->y); @@ -1001,6 +1077,7 @@ _ds_shadow_recalc(Shadow *sh) bsz + shx, sh->h); + evas_object_image_smooth_scale_set(sh->object[3], 0); evas_object_move(sh->object[3], sh->x + shx - bsz, sh->y + sh->h); @@ -1100,7 +1177,8 @@ static void _ds_blur_init(Dropshadow *ds) { int i; - + int q; + if (ds->table.gauss) free(ds->table.gauss); ds->table.gauss_size = (ds->conf->blur_size * 2) - 1; ds->table.gauss = calloc(1, ds->table.gauss_size * sizeof(unsigned char)); @@ -1115,6 +1193,22 @@ _ds_blur_init(Dropshadow *ds) ds->table.gauss[ds->conf->blur_size - 1 - i] = _ds_gauss_int(-1.5 + (v * 3.0)) * 255.0; } + + q = ds->conf->quality; + if (ds->table.gauss2) free(ds->table.gauss2); + ds->table.gauss2_size = ((ds->conf->blur_size / q) * 2) - 1; + ds->table.gauss2 = calloc(1, ds->table.gauss2_size * sizeof(unsigned char)); + + ds->table.gauss[(ds->conf->blur_size / q) - 1] = 255; + for (i = 1; i < ((ds->conf->blur_size / q) - 1); i++) + { + double v; + + v = (double)i / ((ds->conf->blur_size / q) - 2); + ds->table.gauss2[(ds->conf->blur_size / q) - 1 + i] = + ds->table.gauss2[(ds->conf->blur_size / q) - 1 - i] = + _ds_gauss_int(-1.5 + (v * 3.0)) * 255.0; + } } static double @@ -1420,7 +1514,6 @@ _ds_shpix_object_set(Shpix *sp, Evas_Object *o, int x, int y, int w, int h) evas_object_image_size_set(o, w, h); evas_object_image_alpha_set(o, 1); - evas_object_image_smooth_scale_set(o, 0); pix2 = evas_object_image_data_get(o, 1); if (pix2) { @@ -1625,7 +1718,6 @@ _ds_shstore_object_set(Shstore *st, Evas_Object *o) evas_object_image_data_set(o, st->pix); evas_object_image_data_update_add(o, 0, 0, st->w, st->h); evas_object_image_alpha_set(o, 1); - evas_object_image_smooth_scale_set(o, 0); } static void diff --git a/src/modules/dropshadow/e_mod_main.h b/src/modules/dropshadow/e_mod_main.h index c8b0c5580..435500085 100644 --- a/src/modules/dropshadow/e_mod_main.h +++ b/src/modules/dropshadow/e_mod_main.h @@ -23,6 +23,7 @@ struct _Config { int shadow_x, shadow_y; int blur_size; + int quality; double shadow_darkness; }; @@ -39,6 +40,8 @@ struct _Dropshadow struct { unsigned char *gauss; int gauss_size; + unsigned char *gauss2; + int gauss2_size; } table; struct {