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;
157 /* set this window to be a dock window. This needs to be done after show
158 * as E will sometimes reset the window type */
159 ecore_x_netwm_window_type_set(iwin->win->evas_win, ECORE_X_WINDOW_TYPE_DOCK);
161 /* tell conformant apps our position and size */
162 ecore_x_e_illume_indicator_geometry_set(zone->black_win, zone->x, zone->y,
168 /* local function prototypes */
170 _e_mod_ind_win_cb_free(Ind_Win *iwin)
172 Ecore_Event_Handler *hdl;
174 /* delete the handlers */
175 EINA_LIST_FREE(iwin->hdls, hdl)
176 ecore_event_handler_del(hdl);
178 /* delete the menu */
181 e_menu_post_deactivate_callback_set(iwin->menu, NULL, NULL);
182 e_object_del(E_OBJECT(iwin->menu));
186 /* delete the gadget container */
187 if (iwin->gadcon) e_object_del(E_OBJECT(iwin->gadcon));
190 /* delete the objects */
191 if (iwin->o_base) evas_object_del(iwin->o_base);
193 if (iwin->o_event) evas_object_del(iwin->o_event);
194 iwin->o_event = NULL;
196 /* tell conformant apps our position and size */
197 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 0, 0, 0, 0);
199 if (iwin->popup) e_object_del(E_OBJECT(iwin->popup));
202 /* delete the window */
203 if (iwin->win) e_object_del(E_OBJECT(iwin->win));
206 /* free the allocated object */
211 _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event)
214 Ecore_X_Event_Window_Property *ev;
219 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
220 if (ev->win != iwin->win->container->manager->root)
221 return ECORE_CALLBACK_PASS_ON;
222 if (ev->atom != ATM_ENLIGHTENMENT_SCALE) return ECORE_CALLBACK_PASS_ON;
224 h = (il_ind_cfg->height * e_scale);
226 /* set minimum size of this window */
227 e_win_size_min_set(iwin->win, iwin->zone->w, h);
228 ecore_evas_size_min_set(iwin->popup->ecore_evas, iwin->zone->w, h);
230 /* NB: Not sure why, but we need to tell this border to fetch icccm
231 * size position hints now :( (NOTE: This was not needed a few days ago)
232 * If we do not do this, than indicator does not change w/ scale anymore */
233 iwin->win->border->client.icccm.fetch.size_pos_hints = 1;
235 /* resize this window */
236 e_win_resize(iwin->win, iwin->zone->w, h);
237 e_popup_resize(iwin->popup, iwin->zone->w, h);
239 /* tell conformant apps our position and size */
240 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win,
241 iwin->win->x, iwin->win->y,
244 return ECORE_CALLBACK_PASS_ON;
248 _e_mod_ind_win_cb_zone_resize(void *data, int type __UNUSED__, void *event)
251 E_Event_Zone_Move_Resize *ev;
255 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
256 if (ev->zone != iwin->zone) return ECORE_CALLBACK_PASS_ON;
258 h = (il_ind_cfg->height * e_scale);
260 /* set minimum size of this window to match zone size */
261 e_win_size_min_set(iwin->win, ev->zone->w, h);
262 ecore_evas_size_min_set(iwin->popup->ecore_evas, ev->zone->w, h);
264 return ECORE_CALLBACK_PASS_ON;
268 _e_mod_ind_win_cb_resize(E_Win *win)
272 if (!(iwin = win->data)) return;
273 if (iwin->popup) e_popup_resize(iwin->popup, win->w, win->h);
274 if (iwin->o_event) evas_object_resize(iwin->o_event, win->w, win->h);
275 if (iwin->o_base) evas_object_resize(iwin->o_base, win->w, win->h);
276 if (iwin->gadcon->o_container)
277 edje_extern_object_min_size_set(iwin->gadcon->o_container,
282 _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
285 Evas_Event_Mouse_Down *ev;
288 if (!(iwin = data)) return;
291 iwin->mouse_down = 1;
293 /* make sure we can drag */
294 if (iwin->win->border->client.illume.drag.locked) return;
296 iwin->drag.start = 1;
298 iwin->drag.y = ev->output.y;
299 iwin->drag.by = iwin->win->border->y;
301 else if (ev->button == 3)
305 /* create our popup menu */
306 iwin->menu = e_menu_new();
307 e_menu_post_deactivate_callback_set(iwin->menu,
308 _e_mod_ind_win_cb_menu_post, iwin);
310 /* append items to our menu */
311 _e_mod_ind_win_cb_menu_append(iwin, iwin->menu);
314 e_gadcon_canvas_zone_geometry_get(iwin->gadcon, &x, &y, NULL, NULL);
315 e_menu_activate_mouse(iwin->menu, iwin->zone, x + ev->output.x,
316 y + ev->output.y, 1, 1,
317 E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
322 _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
325 Evas_Event_Mouse_Up *ev;
328 if (!(iwin = data)) return;
330 if (ev->button != 1) return;
332 /* if we are not dragging, send message to toggle quickpanel state */
333 if ((!iwin->drag.dnd) && (iwin->mouse_down == 1))
337 xwin = iwin->win->border->zone->black_win;
338 ecore_x_e_illume_quickpanel_state_toggle(xwin);
340 else if (iwin->drag.dnd)
344 bd = iwin->win->border;
346 /* reset mouse pointer */
348 e_pointer_type_pop(bd->pointer, bd, "move");
350 /* tell edj we are done moving */
351 edje_object_signal_emit(iwin->o_base, "e,action,move,stop", "e");
353 /* send message that we are done dragging */
354 ecore_x_e_illume_drag_end_send(bd->client.win);
356 /* update quickpanel position if needed */
357 if (bd->y != iwin->drag.by)
358 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
360 /* tell conformant apps our position and size */
361 ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win,
365 iwin->drag.start = 0;
369 iwin->mouse_down = 0;
373 _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
376 Evas_Event_Mouse_Move *ev;
380 if (!(iwin = data)) return;
381 bd = iwin->win->border;
382 if (iwin->drag.start)
385 iwin->drag.start = 0;
387 /* change mouse pointer to indicate we are dragging */
388 if (iwin->win->border->pointer)
389 e_pointer_type_push(iwin->win->border->pointer,
390 iwin->win->border, "move");
392 /* tell edj we are going to start moving */
393 edje_object_signal_emit(iwin->o_base, "e,action,move,start", "e");
395 /* tell quickpanel to hide because we are going to drag */
396 ecore_x_e_illume_quickpanel_state_send(bd->zone->black_win,
397 ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
399 /* send message that we are going to start dragging */
400 ecore_x_e_illume_drag_start_send(bd->client.win);
403 /* make sure we are dragging */
408 /* get current mouse position */
409 py = ev->cur.output.y;
411 /* do moves in 'chunks' of screen size */
412 dy = ((bd->zone->h - bd->h) / 8);
414 /* are we moving up or down ? */
415 if (ev->cur.output.y > ev->prev.output.y)
418 if ((py - iwin->drag.y) < dy) return;
420 else if (ev->cur.output.y < ev->prev.output.y)
423 if ((iwin->drag.y - py) < dy) return;
427 if (py > iwin->drag.y)
429 else if (py < iwin->drag.y)
433 /* make sure we don't drag off the screen */
434 if (ny < iwin->zone->y)
436 else if ((ny + bd->h) > (iwin->zone->y + iwin->zone->h))
439 /* move the border if we need to */
445 e_popup_move(iwin->popup, iwin->popup->x, ny);
451 _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
455 if (!(iwin = data)) return;
456 if (gc != iwin->gadcon) return;
457 if (h < iwin->win->h) h = iwin->win->h;
458 edje_extern_object_min_size_set(iwin->gadcon->o_container, w, h);
462 _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
468 _e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__)
474 _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn)
478 if (!(iwin = data)) return;
479 _e_mod_ind_win_cb_menu_append(iwin, mn);
483 _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn)
489 snprintf(buff, sizeof(buff),
490 "%s/e-module-illume-indicator.edj", _ind_mod_dir);
493 mi = e_menu_item_new(mn);
494 e_menu_item_label_set(mi, _("Illume Indicator"));
495 e_menu_item_icon_edje_set(mi, buff, "icon");
496 e_menu_pre_activate_callback_set(subm, _e_mod_ind_win_cb_menu_pre, iwin);
497 e_menu_item_submenu_set(mi, subm);
501 _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn)
506 if (!(iwin = data)) return;
507 e_menu_pre_activate_callback_set(mn, NULL, NULL);
509 mi = e_menu_item_new(mn);
510 e_menu_item_label_set(mi, _("Set Contents"));
511 e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
512 e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_contents, iwin);
514 mi = e_menu_item_new(mn);
515 if (iwin->gadcon->editing)
516 e_menu_item_label_set(mi, _("End Move/Resize Items"));
518 e_menu_item_label_set(mi, _("Begin Move/Resize Items"));
520 e_util_menu_item_theme_icon_set(mi, "transform-scale");
521 e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_edit, iwin);
525 _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__)
529 if (!(iwin = data)) return;
530 if (!iwin->menu) return;
531 e_object_del(E_OBJECT(iwin->menu));
536 _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__)
540 if (!(iwin = data)) return;
541 if (!iwin->gadcon->config_dialog)
542 e_int_gadcon_config_shelf(iwin->gadcon);
545 e_win_show(iwin->gadcon->config_dialog->dia->win);
546 e_win_raise(iwin->gadcon->config_dialog->dia->win);
551 _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__)
555 if (!(iwin = data)) return;
556 if (iwin->gadcon->editing)
557 e_gadcon_edit_end(iwin->gadcon);
559 e_gadcon_edit_begin(iwin->gadcon);
563 _e_mod_ind_win_cb_border_hide(void *data, int type __UNUSED__, void *event)
566 E_Event_Border_Hide *ev;
568 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
570 if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
571 e_popup_hide(iwin->popup);
572 return ECORE_CALLBACK_PASS_ON;
576 _e_mod_ind_win_cb_border_show(void *data, int type __UNUSED__, void *event)
579 E_Event_Border_Show *ev;
581 if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
583 if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
584 e_popup_show(iwin->popup);
585 return ECORE_CALLBACK_PASS_ON;