2 #include "e_mod_main.h"
3 #include "e_mod_config.h"
4 #include "e_mod_ind_win.h"
6 /* local function prototypes */
7 static void _e_mod_ind_win_cb_free(Ind_Win *iwin);
8 static Eina_Bool _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event);
9 static Eina_Bool _e_mod_ind_win_cb_zone_resize(void *data, int type __UNUSED__, void *event);
10 static void _e_mod_ind_win_cb_resize(E_Win *win);
11 static void _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
12 static void _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
13 static void _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
14 static void _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
15 static void _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__);
16 static Evas_Object *_e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__);
17 static void _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn);
18 static void _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn);
19 static void _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn);
20 static void _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__);
21 static void _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__);
22 static void _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__);
23 static Eina_Bool _e_mod_ind_win_cb_border_hide(void *data, int type __UNUSED__, void *event);
24 static Eina_Bool _e_mod_ind_win_cb_border_show(void *data, int type __UNUSED__, void *event);
27 e_mod_ind_win_new(E_Zone *zone)
30 Ecore_X_Window_State states[2];
33 /* create our new indicator window object */
34 iwin = E_OBJECT_ALLOC(Ind_Win, IND_WIN_TYPE, _e_mod_ind_win_cb_free);
35 if (!iwin) return NULL;
37 h = (il_ind_cfg->height * e_scale);
40 /* create new window */
41 iwin->win = e_win_new(zone->container);
42 iwin->win->data = iwin;
44 /* set some properties on the window */
45 e_win_title_set(iwin->win, _("Illume Indicator"));
46 e_win_name_class_set(iwin->win, "Illume-Indicator", "Illume-Indicator");
47 e_win_no_remember_set(iwin->win, EINA_TRUE);
49 /* hook into window resize so we can resize our objects */
50 e_win_resize_callback_set(iwin->win, _e_mod_ind_win_cb_resize);
52 /* set this window to not show in taskbar or pager */
53 states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
54 states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
55 ecore_x_netwm_window_state_set(iwin->win->evas_win, states, 2);
57 /* set this window to not accept or take focus */
58 ecore_x_icccm_hints_set(iwin->win->evas_win, 0, 0, 0, 0, 0, 0, 0);
60 /* create the popup */
61 iwin->popup = e_popup_new(zone, 0, 0, zone->w, h);
62 e_popup_name_set(iwin->popup, "indicator");
63 e_popup_layer_set(iwin->popup, 200);
65 /* create our event rectangle */
66 iwin->o_event = evas_object_rectangle_add(iwin->win->evas);
67 evas_object_color_set(iwin->o_event, 0, 0, 0, 0);
68 evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_DOWN,
69 _e_mod_ind_win_cb_mouse_down, iwin);
70 evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_UP,
71 _e_mod_ind_win_cb_mouse_up, iwin);
72 evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_MOVE,
73 _e_mod_ind_win_cb_mouse_move, iwin);
74 evas_object_move(iwin->o_event, 0, 0);
75 evas_object_show(iwin->o_event);
77 /* create our base object */
78 iwin->o_base = edje_object_add(iwin->win->evas);
79 if (!e_theme_edje_object_set(iwin->o_base,
80 "base/theme/modules/illume-indicator",
81 "modules/illume-indicator/window"))
85 snprintf(buff, sizeof(buff),
86 "%s/e-module-illume-indicator.edj", _ind_mod_dir);
87 edje_object_file_set(iwin->o_base, buff,
88 "modules/illume-indicator/window");
90 evas_object_move(iwin->o_base, 0, 0);
91 evas_object_show(iwin->o_base);
93 e_popup_edje_bg_object_set(iwin->popup, iwin->o_base);
95 /* create our gadget container */
96 iwin->gadcon = e_gadcon_swallowed_new("illume-indicator", zone->id,
97 iwin->o_base, "e.swallow.content");
98 edje_extern_object_min_size_set(iwin->gadcon->o_container, zone->w, h);
99 e_gadcon_min_size_request_callback_set(iwin->gadcon,
100 _e_mod_ind_win_cb_min_size_request,
102 e_gadcon_size_request_callback_set(iwin->gadcon,
103 _e_mod_ind_win_cb_size_request, iwin);
104 e_gadcon_frame_request_callback_set(iwin->gadcon,
105 _e_mod_ind_win_cb_frame_request, iwin);
106 e_gadcon_orient(iwin->gadcon, E_GADCON_ORIENT_FLOAT);
107 e_gadcon_zone_set(iwin->gadcon, zone);
108 e_gadcon_ecore_evas_set(iwin->gadcon, iwin->win->ecore_evas);
110 e_gadcon_util_menu_attach_func_set(iwin->gadcon,
111 _e_mod_ind_win_cb_menu_items_append,
113 e_gadcon_populate(iwin->gadcon);
115 /* hook into property change so we can adjust w/ e_scale */
117 eina_list_append(iwin->hdls,
118 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
119 _e_mod_ind_win_cb_win_prop, iwin));
121 /* hook into zone resize so we can set minimum window width when zone
124 eina_list_append(iwin->hdls,
125 ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
126 _e_mod_ind_win_cb_zone_resize,
130 eina_list_append(iwin->hdls,
131 ecore_event_handler_add(E_EVENT_BORDER_HIDE,
132 _e_mod_ind_win_cb_border_hide,
136 eina_list_append(iwin->hdls,
137 ecore_event_handler_add(E_EVENT_BORDER_SHOW,
138 _e_mod_ind_win_cb_border_show,
141 /* set minimum size of this window & popup */
142 e_win_size_min_set(iwin->win, zone->w, h);
143 ecore_evas_size_min_set(iwin->popup->ecore_evas, zone->w, h);
145 /* position and resize this window */
146 e_win_move_resize(iwin->win, zone->x, zone->y, zone->w, h);
147 e_popup_move_resize(iwin->popup, zone->x, zone->y, zone->w, h);
149 /* show the window */
150 e_win_show(iwin->win);
151 e_popup_show(iwin->popup);
153 /* set this window on proper zone */
154 e_border_zone_set(iwin->win->border, zone);
155 iwin->win->border->user_skip_winlist = 1;
156 iwin->win->border->lock_focus_in = 1;
157 iwin->win->border->lock_focus_out = 1;
159 /* set this window to be a dock window. This needs to be done after show
160 * as E will sometimes reset the window type */
161 ecore_x_netwm_window_type_set(iwin->win->evas_win, ECORE_X_WINDOW_TYPE_DOCK);
163 /* tell conformant apps our position and size */
164 ecore_x_e_illume_indicator_geometry_set(zone->black_win, zone->x, zone->y,
170 /* local function prototypes */
172 _e_mod_ind_win_cb_free(Ind_Win *iwin)
174 Ecore_Event_Handler *hdl;
176 /* delete the handlers */
177 EINA_LIST_FREE(iwin->hdls, hdl)
178 ecore_event_handler_del(hdl);
180 /* delete the menu */
183 e_menu_post_deactivate_callback_set(iwin->menu, NULL, NULL);
184 e_object_del(E_OBJECT(iwin->menu));
188 /* delete the gadget container */
189 if (iwin->gadcon) e_object_del(E_OBJECT(iwin->gadcon));
192 /* delete the objects */
193 if (iwin->o_base) evas_object_del(iwin->o_base);
195 if (iwin->o_event) evas_object_del(iwin->o_event);
196 iwin->o_event = NULL;
198 /* tell conformant apps our position and size */
199 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 0, 0, 0, 0);
201 if (iwin->popup) e_object_del(E_OBJECT(iwin->popup));
204 /* delete the window */
205 if (iwin->win) e_object_del(E_OBJECT(iwin->win));
208 /* free the allocated object */
213 _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event)
216 Ecore_X_Event_Window_Property *ev;
221 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
222 if (ev->win != iwin->win->container->manager->root)
223 return ECORE_CALLBACK_PASS_ON;
224 if (ev->atom != ATM_ENLIGHTENMENT_SCALE) return ECORE_CALLBACK_PASS_ON;
226 h = (il_ind_cfg->height * e_scale);
228 /* set minimum size of this window */
229 e_win_size_min_set(iwin->win, iwin->zone->w, h);
230 ecore_evas_size_min_set(iwin->popup->ecore_evas, iwin->zone->w, h);
232 /* NB: Not sure why, but we need to tell this border to fetch icccm
233 * size position hints now :( (NOTE: This was not needed a few days ago)
234 * If we do not do this, than indicator does not change w/ scale anymore */
235 iwin->win->border->client.icccm.fetch.size_pos_hints = 1;
237 /* resize this window */
238 e_win_resize(iwin->win, iwin->zone->w, h);
239 e_popup_resize(iwin->popup, iwin->zone->w, h);
241 /* tell conformant apps our position and size */
242 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win,
243 iwin->win->x, iwin->win->y,
246 return ECORE_CALLBACK_PASS_ON;
250 _e_mod_ind_win_cb_zone_resize(void *data, int type __UNUSED__, void *event)
253 E_Event_Zone_Move_Resize *ev;
257 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
258 if (ev->zone != iwin->zone) return ECORE_CALLBACK_PASS_ON;
260 h = (il_ind_cfg->height * e_scale);
262 /* set minimum size of this window to match zone size */
263 e_win_size_min_set(iwin->win, ev->zone->w, h);
264 ecore_evas_size_min_set(iwin->popup->ecore_evas, ev->zone->w, h);
266 return ECORE_CALLBACK_PASS_ON;
270 _e_mod_ind_win_cb_resize(E_Win *win)
274 if (!(iwin = win->data)) return;
275 if (iwin->popup) e_popup_resize(iwin->popup, win->w, win->h);
276 if (iwin->o_event) evas_object_resize(iwin->o_event, win->w, win->h);
277 if (iwin->o_base) evas_object_resize(iwin->o_base, win->w, win->h);
278 if (iwin->gadcon->o_container)
279 edje_extern_object_min_size_set(iwin->gadcon->o_container,
284 _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
287 Evas_Event_Mouse_Down *ev;
290 if (!(iwin = data)) return;
293 iwin->mouse_down = 1;
295 /* make sure we can drag */
296 if (iwin->win->border->client.illume.drag.locked) return;
298 iwin->drag.start = 1;
300 iwin->drag.y = ev->output.y;
301 iwin->drag.by = iwin->win->border->y;
303 else if (ev->button == 3)
307 /* create our popup menu */
308 iwin->menu = e_menu_new();
309 e_menu_post_deactivate_callback_set(iwin->menu,
310 _e_mod_ind_win_cb_menu_post, iwin);
312 /* append items to our menu */
313 _e_mod_ind_win_cb_menu_append(iwin, iwin->menu);
316 e_gadcon_canvas_zone_geometry_get(iwin->gadcon, &x, &y, NULL, NULL);
317 e_menu_activate_mouse(iwin->menu, iwin->zone, x + ev->output.x,
318 y + ev->output.y, 1, 1,
319 E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
324 _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
327 Evas_Event_Mouse_Up *ev;
330 if (!(iwin = data)) return;
332 if (ev->button != 1) return;
334 /* if we are not dragging, send message to toggle quickpanel state */
335 if ((!iwin->drag.dnd) && (iwin->mouse_down == 1))
339 xwin = iwin->win->border->zone->black_win;
340 ecore_x_e_illume_quickpanel_state_toggle(xwin);
342 else if (iwin->drag.dnd)
346 bd = iwin->win->border;
348 /* reset mouse pointer */
350 e_pointer_type_pop(bd->pointer, bd, "move");
352 /* tell edj we are done moving */
353 edje_object_signal_emit(iwin->o_base, "e,action,move,stop", "e");
355 /* send message that we are done dragging */
356 ecore_x_e_illume_drag_end_send(bd->client.win);
358 /* update quickpanel position if needed */
359 if (bd->y != iwin->drag.by)
360 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
362 /* tell conformant apps our position and size */
363 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win,
367 iwin->drag.start = 0;
371 iwin->mouse_down = 0;
375 _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
378 Evas_Event_Mouse_Move *ev;
382 if (!(iwin = data)) return;
383 bd = iwin->win->border;
384 if (iwin->drag.start)
387 iwin->drag.start = 0;
389 /* change mouse pointer to indicate we are dragging */
390 if (iwin->win->border->pointer)
391 e_pointer_type_push(iwin->win->border->pointer,
392 iwin->win->border, "move");
394 /* tell edj we are going to start moving */
395 edje_object_signal_emit(iwin->o_base, "e,action,move,start", "e");
397 /* tell quickpanel to hide because we are going to drag */
398 ecore_x_e_illume_quickpanel_state_send(bd->zone->black_win,
399 ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
401 /* send message that we are going to start dragging */
402 ecore_x_e_illume_drag_start_send(bd->client.win);
405 /* make sure we are dragging */
410 /* get current mouse position */
411 py = ev->cur.output.y;
413 /* do moves in 'chunks' of screen size */
414 dy = ((bd->zone->h - bd->h) / 8);
416 /* are we moving up or down ? */
417 if (ev->cur.output.y > ev->prev.output.y)
420 if ((py - iwin->drag.y) < dy) return;
422 else if (ev->cur.output.y < ev->prev.output.y)
425 if ((iwin->drag.y - py) < dy) return;
429 if (py > iwin->drag.y)
431 else if (py < iwin->drag.y)
435 /* make sure we don't drag off the screen */
436 if (ny < iwin->zone->y)
438 else if ((ny + bd->h) > (iwin->zone->y + iwin->zone->h))
441 /* move the border if we need to */
447 e_popup_move(iwin->popup, iwin->popup->x, ny);
453 _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
457 if (!(iwin = data)) return;
458 if (gc != iwin->gadcon) return;
459 if (h < iwin->win->h) h = iwin->win->h;
460 edje_extern_object_min_size_set(iwin->gadcon->o_container, w, h);
464 _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
470 _e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__)
476 _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn)
480 if (!(iwin = data)) return;
481 _e_mod_ind_win_cb_menu_append(iwin, mn);
485 _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn)
491 snprintf(buff, sizeof(buff),
492 "%s/e-module-illume-indicator.edj", _ind_mod_dir);
495 mi = e_menu_item_new(mn);
496 e_menu_item_label_set(mi, _("Illume Indicator"));
497 e_menu_item_icon_edje_set(mi, buff, "icon");
498 e_menu_pre_activate_callback_set(subm, _e_mod_ind_win_cb_menu_pre, iwin);
499 e_menu_item_submenu_set(mi, subm);
503 _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn)
508 if (!(iwin = data)) return;
509 e_menu_pre_activate_callback_set(mn, NULL, NULL);
511 mi = e_menu_item_new(mn);
512 e_menu_item_label_set(mi, _("Set Contents"));
513 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
514 e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_contents, iwin);
516 mi = e_menu_item_new(mn);
517 if (iwin->gadcon->editing)
518 e_menu_item_label_set(mi, _("End Move/Resize Items"));
520 e_menu_item_label_set(mi, _("Begin Move/Resize Items"));
522 e_util_menu_item_theme_icon_set(mi, "transform-scale");
523 e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_edit, iwin);
527 _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__)
531 if (!(iwin = data)) return;
532 if (!iwin->menu) return;
533 e_object_del(E_OBJECT(iwin->menu));
538 _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__)
542 if (!(iwin = data)) return;
543 if (!iwin->gadcon->config_dialog)
544 e_int_gadcon_config_shelf(iwin->gadcon);
547 e_win_show(iwin->gadcon->config_dialog->dia->win);
548 e_win_raise(iwin->gadcon->config_dialog->dia->win);
553 _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__)
557 if (!(iwin = data)) return;
558 if (iwin->gadcon->editing)
559 e_gadcon_edit_end(iwin->gadcon);
561 e_gadcon_edit_begin(iwin->gadcon);
565 _e_mod_ind_win_cb_border_hide(void *data, int type __UNUSED__, void *event)
568 E_Event_Border_Hide *ev;
570 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
572 if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
573 e_popup_hide(iwin->popup);
574 return ECORE_CALLBACK_PASS_ON;
578 _e_mod_ind_win_cb_border_show(void *data, int type __UNUSED__, void *event)
581 E_Event_Border_Show *ev;
583 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
585 if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
586 e_popup_show(iwin->popup);
587 return ECORE_CALLBACK_PASS_ON;