3 /* local subsystem functions */
4 static void _e_popup_free(E_Popup *pop);
5 static Eina_Bool _e_popup_idle_enterer(void *data);
6 static Eina_Bool _e_popup_cb_window_shape(void *data, int ev_type, void *ev);
8 /* local subsystem globals */
9 static Ecore_Event_Handler *_e_popup_window_shape_handler = NULL;
10 static Eina_List *_e_popup_list = NULL;
11 static Eina_Hash *_e_popup_hash = NULL;
13 /* externally accessible functions */
18 _e_popup_window_shape_handler =
19 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE,
20 _e_popup_cb_window_shape, NULL);
21 if (!_e_popup_hash) _e_popup_hash = eina_hash_string_superfast_new(NULL);
26 e_popup_shutdown(void)
30 eina_hash_free(_e_popup_hash);
33 E_FN_DEL(ecore_event_handler_del, _e_popup_window_shape_handler);
38 e_popup_new(E_Zone *zone, int x, int y, int w, int h)
42 pop = E_OBJECT_ALLOC(E_Popup, E_POPUP_TYPE, _e_popup_free);
43 if (!pop) return NULL;
45 pop->zx = pop->zone->x;
46 pop->zy = pop->zone->y;
51 pop->layer = e_desklock_state_get() ? 200 : 250;
52 pop->ecore_evas = e_canvas_new(pop->zone->container->win,
53 pop->zone->x + pop->x, pop->zone->y + pop->y, pop->w, pop->h, 1, 1,
60 /* avoid excess exposes when shaped - set damage avoid to 1 */
61 // ecore_evas_avoid_damage_set(pop->ecore_evas, 1);
63 e_canvas_add(pop->ecore_evas);
64 pop->shape = e_container_shape_add(pop->zone->container);
65 e_container_shape_move(pop->shape, pop->zone->x + pop->x, pop->zone->y + pop->y);
66 e_container_shape_resize(pop->shape, pop->w, pop->h);
67 pop->evas = ecore_evas_get(pop->ecore_evas);
68 e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer);
69 ecore_x_window_shape_events_select(pop->evas_win, 1);
70 ecore_evas_name_class_set(pop->ecore_evas, "E", "_e_popup_window");
71 ecore_evas_title_set(pop->ecore_evas, "E Popup");
72 e_object_ref(E_OBJECT(pop->zone));
73 pop->zone->popups = eina_list_append(pop->zone->popups, pop);
74 _e_popup_list = eina_list_append(_e_popup_list, pop);
75 eina_hash_add(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
80 e_popup_name_set(E_Popup *pop, const char *name)
82 if (eina_stringshare_replace(&pop->name, name))
83 ecore_evas_name_class_set(pop->ecore_evas, "E", pop->name);
87 e_popup_show(E_Popup *pop)
90 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
91 if (pop->visible) return;
93 if ((pop->shaped) && (!e_config->use_composite))
95 ecore_evas_move(pop->ecore_evas,
96 pop->zone->container->manager->w,
97 pop->zone->container->manager->h);
98 ecore_evas_show(pop->ecore_evas);
99 if (pop->idle_enterer) ecore_idle_enterer_del(pop->idle_enterer);
100 pop->idle_enterer = ecore_idle_enterer_add(_e_popup_idle_enterer, pop);
104 ecore_evas_show(pop->ecore_evas);
105 if (!(pop->shaped && e_config->use_composite))
106 e_container_shape_show(pop->shape);
111 e_popup_hide(E_Popup *pop)
114 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
115 if (!pop->visible) return;
116 if (pop->idle_enterer) ecore_idle_enterer_del(pop->idle_enterer);
117 pop->idle_enterer = NULL;
119 ecore_evas_hide(pop->ecore_evas);
120 e_container_shape_hide(pop->shape);
124 e_popup_move(E_Popup *pop, int x, int y)
127 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
128 if ((pop->x == x) && (pop->y == y) &&
129 (pop->zone->x == pop->zx) && (pop->zone->y == pop->zy)) return;
130 pop->zx = pop->zone->x;
131 pop->zy = pop->zone->y;
134 ecore_evas_move(pop->ecore_evas,
135 pop->zone->x + pop->x,
136 pop->zone->y + pop->y);
137 e_container_shape_move(pop->shape,
138 pop->zone->x + pop->x,
139 pop->zone->y + pop->y);
143 e_popup_resize(E_Popup *pop, int w, int h)
146 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
147 if ((pop->w == w) && (pop->h == h)) return;
150 ecore_evas_resize(pop->ecore_evas, pop->w, pop->h);
151 e_container_shape_resize(pop->shape, pop->w, pop->h);
155 e_popup_move_resize(E_Popup *pop, int x, int y, int w, int h)
158 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
159 if ((pop->x == x) && (pop->y == y) &&
160 (pop->w == w) && (pop->h == h) &&
161 (pop->zone->x == pop->zx) && (pop->zone->y == pop->zy)) return;
162 pop->zx = pop->zone->x;
163 pop->zy = pop->zone->y;
168 ecore_evas_move_resize(pop->ecore_evas,
169 pop->zone->x + pop->x,
170 pop->zone->y + pop->y,
172 e_container_shape_move(pop->shape,
173 pop->zone->x + pop->x,
174 pop->zone->y + pop->y);
175 e_container_shape_resize(pop->shape, pop->w, pop->h);
179 e_popup_ignore_events_set(E_Popup *pop, int ignore)
181 ecore_evas_ignore_events_set(pop->ecore_evas, ignore);
185 e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *o)
187 const char *shape_option;
190 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
191 shape_option = edje_object_data_get(o, "shaped");
194 if (!strcmp(shape_option, "1"))
198 if (e_config->use_composite)
200 ecore_evas_alpha_set(pop->ecore_evas, pop->shaped);
201 eina_hash_del(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
202 pop->evas_win = ecore_evas_software_x11_window_get(pop->ecore_evas);
203 eina_hash_add(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
204 e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer);
207 ecore_evas_shaped_set(pop->ecore_evas, pop->shaped);
212 ecore_evas_alpha_set(pop->ecore_evas, pop->shaped);
213 eina_hash_del(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
214 pop->evas_win = ecore_evas_software_x11_window_get(pop->ecore_evas);
215 eina_hash_add(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
216 e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer);
217 ecore_evas_shaped_set(pop->ecore_evas, pop->shaped);
222 e_popup_layer_set(E_Popup *pop, int layer)
225 E_OBJECT_TYPE_CHECK(pop, E_POPUP_TYPE);
227 e_container_window_raise(pop->zone->container, pop->evas_win, pop->layer);
231 e_popup_idler_before(void)
236 EINA_LIST_FOREACH(_e_popup_list, l, pop)
238 if (pop->need_shape_export)
240 Ecore_X_Rectangle *rects, *orects;
243 rects = ecore_x_window_shape_rectangles_get(pop->evas_win, &num);
249 if ((num == pop->shape_rects_num) && (pop->shape_rects))
253 orects = pop->shape_rects;
255 for (i = 0; i < num; i++)
259 rects[i].width -= rects[i].x;
262 if ((rects[i].x + (int)rects[i].width) > pop->w)
263 rects[i].width = rects[i].width - rects[i].x;
266 rects[i].height -= rects[i].y;
269 if ((rects[i].y + (int)rects[i].height) > pop->h)
270 rects[i].height = rects[i].height - rects[i].y;
272 if ((orects[i].x != rects[i].x) ||
273 (orects[i].y != rects[i].y) ||
274 (orects[i].width != rects[i].width) ||
275 (orects[i].height != rects[i].height))
284 E_FREE(pop->shape_rects);
285 pop->shape_rects = rects;
286 pop->shape_rects_num = num;
287 e_container_shape_rects_set(pop->shape, rects, num);
294 E_FREE(pop->shape_rects);
295 pop->shape_rects = NULL;
296 pop->shape_rects_num = 0;
297 e_container_shape_rects_set(pop->shape, NULL, 0);
299 pop->need_shape_export = 0;
301 if ((pop->visible) && (!pop->idle_enterer) &&
302 (!pop->shaped && e_config->use_composite))
303 e_container_shape_show(pop->shape);
308 e_popup_find_by_window(Ecore_X_Window win)
312 pop = eina_hash_find(_e_popup_hash, e_util_winid_str_get(win));
313 if ((pop) && (pop->evas_win != win))
318 /* local subsystem functions */
321 _e_popup_free(E_Popup *pop)
323 if (pop->idle_enterer) ecore_idle_enterer_del(pop->idle_enterer);
324 pop->idle_enterer = NULL;
325 E_FREE(pop->shape_rects);
326 pop->shape_rects_num = 0;
327 e_container_shape_hide(pop->shape);
328 e_object_del(E_OBJECT(pop->shape));
329 e_canvas_del(pop->ecore_evas);
330 ecore_evas_free(pop->ecore_evas);
331 e_object_unref(E_OBJECT(pop->zone));
332 pop->zone->popups = eina_list_remove(pop->zone->popups, pop);
333 _e_popup_list = eina_list_remove(_e_popup_list, pop);
334 eina_hash_del(_e_popup_hash, e_util_winid_str_get(pop->evas_win), pop);
335 if (pop->name) eina_stringshare_del(pop->name);
340 _e_popup_idle_enterer(void *data)
344 if (!(pop = data)) return ECORE_CALLBACK_CANCEL;
345 ecore_evas_move(pop->ecore_evas,
346 pop->zone->x + pop->x,
347 pop->zone->y + pop->y);
348 e_container_shape_show(pop->shape);
349 pop->idle_enterer = NULL;
350 return ECORE_CALLBACK_CANCEL;
354 _e_popup_cb_window_shape(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
357 Ecore_X_Event_Window_Shape *e;
360 pop = e_popup_find_by_window(e->win);
361 if (pop) pop->need_shape_export = 1;
362 return ECORE_CALLBACK_PASS_ON;