1 #include "e.h"
2 #include "e_mod_main.h"
3 
4 /* gadcon requirements */
5 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
6 static void             _gc_shutdown(E_Gadcon_Client *gcc);
7 static void             _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED);
8 static const char      *_gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED);
9 static Evas_Object     *_gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas);
10 static const char      *_gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED);
11 
12 /* and actually define the gadcon class that this module provides (just 1) */
13 static const E_Gadcon_Client_Class _gadcon_class =
14 {
15    GADCON_CLIENT_CLASS_VERSION,
16    "pager",
17    {
18       _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
19       e_gadcon_site_is_not_toolbar
20    },
21    E_GADCON_CLIENT_STYLE_INSET
22 };
23 
24 /* actual module specifics */
25 typedef struct _Instance    Instance;
26 typedef struct _Pager       Pager;
27 typedef struct _Pager_Desk  Pager_Desk;
28 typedef struct _Pager_Win   Pager_Win;
29 typedef struct _Pager_Popup Pager_Popup;
30 
31 struct _Instance
32 {
33    E_Gadcon_Client *gcc;
34    Evas_Object     *o_pager; /* table */
35    Pager           *pager;
36 };
37 
38 struct _Pager
39 {
40    Instance       *inst;
41    E_Drop_Handler *drop_handler;
42    Pager_Popup    *popup;
43    Evas_Object    *o_table;
44    E_Zone         *zone;
45    int             xnum, ynum;
46    Eina_List      *desks;
47    Pager_Desk     *active_pd;
48    struct {
49       int zone_num, desk_x, desk_y;
50    } menu;
51    unsigned char   dragging E_BITFIELD;
52    unsigned char   just_dragged E_BITFIELD;
53    Evas_Coord      dnd_x, dnd_y;
54    Pager_Desk     *active_drop_pd;
55    E_Client       *active_drag_client;
56    Ecore_Job      *recalc;
57    Eina_Bool       invert E_BITFIELD;
58 };
59 
60 struct _Pager_Desk
61 {
62    Pager       *pager;
63    E_Desk      *desk;
64    Eina_List   *wins;
65    Evas_Object *o_desk;
66    Evas_Object *o_layout;
67    int          xpos, ypos, urgent;
68    int          current E_BITFIELD;
69    struct
70    {
71       Pager        *from_pager;
72       unsigned char in_pager E_BITFIELD;
73       unsigned char start E_BITFIELD;
74       int           x, y, dx, dy, button;
75    } drag;
76 };
77 
78 struct _Pager_Win
79 {
80    E_Client     *client;
81    Pager_Desk   *desk;
82    Evas_Object  *o_window;
83    Evas_Object  *o_mirror;
84    unsigned char skip_winlist E_BITFIELD;
85    struct
86    {
87       Pager        *from_pager;
88       unsigned char start E_BITFIELD;
89       unsigned char in_pager E_BITFIELD;
90       unsigned char desktop  E_BITFIELD;
91       int           x, y, dx, dy, button;
92    } drag;
93 };
94 
95 struct _Pager_Popup
96 {
97    Evas_Object  *popup;
98    Evas_Object  *o_bg;
99    Pager        *pager;
100    Ecore_Timer  *timer;
101    unsigned char urgent E_BITFIELD;
102 };
103 
104 static void             _pager_cb_mirror_add(Pager_Desk *pd, Evas_Object *obj, Evas_Object *mirror);
105 
106 static void             _pager_cb_obj_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
107 static void             _pager_cb_obj_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
108 static void             _pager_cb_obj_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
109 static void             _button_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
110 static void             _pager_inst_cb_menu_configure(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED);
111 static void             _pager_inst_cb_menu_virtual_desktops_dialog(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED);
112 static void             _pager_inst_cb_menu_virtual_desktop_dialog(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED);
113 static void             _pager_instance_drop_zone_recalc(Instance *inst);
114 static Eina_Bool        _pager_cb_event_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
115 static Eina_Bool        _pager_cb_event_desk_name_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
116 static Eina_Bool        _pager_cb_event_compositor_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
117 static void             _pager_window_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
118 static void             _pager_window_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
119 static void             _pager_window_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
120 static void             _pager_window_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
121 static void            *_pager_window_cb_drag_convert(E_Drag *drag, const char *type);
122 static void             _pager_window_cb_drag_finished(E_Drag *drag, int dropped);
123 static void             _pager_drop_cb_enter(void *data, const char *type EINA_UNUSED, void *event_info);
124 static void             _pager_drop_cb_move(void *data, const char *type EINA_UNUSED, void *event_info);
125 static void             _pager_drop_cb_leave(void *data, const char *type EINA_UNUSED, void *event_info EINA_UNUSED);
126 static void             _pager_drop_cb_drop(void *data, const char *type, void *event_info);
127 static void             _pager_inst_cb_scroll(void *data);
128 static void             _pager_update_drop_position(Pager *p, Evas_Coord x, Evas_Coord y);
129 static void             _pager_desk_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
130 static void             _pager_desk_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
131 static void             _pager_desk_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
132 static void             _pager_desk_cb_drag_finished(E_Drag *drag, int dropped);
133 static void             _pager_desk_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info);
134 static Eina_Bool        _pager_popup_cb_timeout(void *data);
135 static Pager           *_pager_new(Evas *evas, E_Zone *zone, E_Gadcon *gc, Instance *inst);
136 static void             _pager_free(Pager *p);
137 static void             _pager_fill(Pager *p, E_Gadcon *gc);
138 static void             _pager_empty(Pager *p);
139 static Pager_Desk      *_pager_desk_new(Pager *p, E_Desk *desk, int xpos, int ypos, Eina_Bool invert);
140 static void             _pager_desk_free(Pager_Desk *pd);
141 static Pager_Desk      *_pager_desk_at_coord(Pager *p, Evas_Coord x, Evas_Coord y);
142 static void             _pager_desk_select(Pager_Desk *pd);
143 static Pager_Desk      *_pager_desk_find(Pager *p, E_Desk *desk);
144 static void             _pager_desk_switch(Pager_Desk *pd1, Pager_Desk *pd2);
145 static Pager_Win       *_pager_window_new(Pager_Desk *pd, Evas_Object *mirror, E_Client *client);
146 static void             _pager_window_free(Pager_Win *pw);
147 static Pager_Popup     *_pager_popup_new(E_Zone *zone, int keyaction);
148 static void             _pager_popup_free(Pager_Popup *pp);
149 static Pager_Popup     *_pager_popup_find(E_Zone *zone);
150 
151 /* functions for pager popup on key actions */
152 static int              _pager_popup_show(void);
153 static void             _pager_popup_hide(int switch_desk);
154 static Eina_Bool        _pager_popup_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
155 static void             _pager_popup_desk_switch(int x, int y);
156 static void             _pager_popup_modifiers_set(int mod);
157 static Eina_Bool        _pager_popup_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
158 static Eina_Bool        _pager_popup_cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
159 static void             _pager_popup_cb_action_show(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED, Ecore_Event_Key *ev EINA_UNUSED);
160 static void             _pager_popup_cb_action_switch(E_Object *obj EINA_UNUSED, const char *params, Ecore_Event_Key *ev);
161 
162 /* variables for pager popup on key actions */
163 static E_Action *act_popup_show = NULL;
164 static E_Action *act_popup_switch = NULL;
165 static Ecore_Window input_window = 0;
166 static Eina_List *handlers = NULL;
167 static Pager_Popup *act_popup = NULL; /* active popup */
168 static int hold_count = 0;
169 static int hold_mod = 0;
170 static E_Desk *current_desk = NULL;
171 static Eina_List *pagers = NULL;
172 static double _pager_start_time = 0.0;
173 
174 EINTERN E_Module *module;
175 EINTERN E_Config_Dialog *config_dialog;
176 EINTERN Eina_List *instances, *shandlers;
177 
178 static Pager_Win *
_pager_desk_window_find(Pager_Desk * pd,E_Client * client)179 _pager_desk_window_find(Pager_Desk *pd, E_Client *client)
180 {
181    Eina_List *l;
182    Pager_Win *pw;
183 
184    EINA_LIST_FOREACH(pd->wins, l, pw)
185      if (pw->client == client) return pw;
186 
187    return NULL;
188 }
189 
190 static Pager_Win *
_pager_window_find(Pager * p,E_Client * client)191 _pager_window_find(Pager *p, E_Client *client)
192 {
193    Eina_List *l;
194    Pager_Desk *pd;
195 
196    EINA_LIST_FOREACH(p->desks, l, pd)
197      {
198         Pager_Win *pw;
199 
200         pw = _pager_desk_window_find(pd, client);
201         if (pw) return pw;
202      }
203    return NULL;
204 }
205 
206 static E_Gadcon_Client *
_gc_init(E_Gadcon * gc,const char * name,const char * id,const char * style)207 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
208 {
209    Pager *p;
210    Evas_Object *o;
211    E_Gadcon_Client *gcc;
212    Instance *inst;
213    Evas_Coord x, y, w, h;
214    const char *drop[] =
215    {
216       "enlightenment/pager_win", "enlightenment/border",
217       "enlightenment/vdesktop"
218    };
219 
220    inst = E_NEW(Instance, 1);
221 
222    p = _pager_new(gc->evas, gc->zone, gc, inst);
223    o = p->o_table;
224    gcc = e_gadcon_client_new(gc, name, id, style, o);
225    gcc->data = inst;
226 
227    inst->gcc = gcc;
228    inst->o_pager = o;
229 
230    evas_object_geometry_get(o, &x, &y, &w, &h);
231    p->drop_handler =
232      e_drop_handler_add(E_OBJECT(inst->gcc), NULL, p,
233                         _pager_drop_cb_enter, _pager_drop_cb_move,
234                         _pager_drop_cb_leave, _pager_drop_cb_drop,
235                         drop, 3, x, y, w, h);
236    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE,
237                                   _pager_cb_obj_moveresize, inst);
238    evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
239                                   _pager_cb_obj_moveresize, inst);
240    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
241                                   _button_cb_mouse_down, inst);
242    evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW,
243                                   _pager_cb_obj_show, inst);
244    evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE,
245                                   _pager_cb_obj_hide, inst);
246    instances = eina_list_append(instances, inst);
247    return gcc;
248 }
249 
250 static void
_gc_shutdown(E_Gadcon_Client * gcc)251 _gc_shutdown(E_Gadcon_Client *gcc)
252 {
253    Instance *inst;
254 
255    inst = gcc->data;
256    if (pager_config)
257      instances = eina_list_remove(instances, inst);
258    e_drop_handler_del(inst->pager->drop_handler);
259    _pager_free(inst->pager);
260    free(inst);
261 }
262 
263 static void
_aspect(E_Gadcon_Client * gcc)264 _aspect(E_Gadcon_Client *gcc)
265 {
266    Instance *inst;
267    int aspect_w, aspect_h;
268    double aspect_ratio;
269 
270    inst = gcc->data;
271    if (inst->pager->invert)
272      {
273         aspect_w = inst->pager->ynum * inst->pager->zone->w;
274         aspect_h = inst->pager->xnum * inst->pager->zone->h;
275      }
276    else
277      {
278         aspect_w = inst->pager->xnum * inst->pager->zone->w;
279         aspect_h = inst->pager->ynum * inst->pager->zone->h;
280      }
281 
282    e_gadcon_client_aspect_set(gcc, aspect_w, aspect_h);
283    aspect_ratio = (double)aspect_w / (double)aspect_h;
284 
285    if (aspect_ratio > 1.0)
286      e_gadcon_client_min_size_set(gcc, 4 * aspect_ratio, 4);
287    else
288      e_gadcon_client_min_size_set(gcc, 4, 4 * aspect_ratio);
289 }
290 
291 static void
_gc_orient(E_Gadcon_Client * gcc,E_Gadcon_Orient orient EINA_UNUSED)292 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED)
293 {
294    _aspect(gcc);
295 }
296 
297 static const char *
_gc_label(const E_Gadcon_Client_Class * client_class EINA_UNUSED)298 _gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
299 {
300    return _("Pager");
301 }
302 
303 static Evas_Object *
_gc_icon(const E_Gadcon_Client_Class * client_class EINA_UNUSED,Evas * evas)304 _gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas)
305 {
306    Evas_Object *o;
307    char buf[PATH_MAX];
308 
309    o = edje_object_add(evas);
310    snprintf(buf, sizeof(buf), "%s/e-module-pager.edj",
311             e_module_dir_get(module));
312    edje_object_file_set(o, buf, "icon");
313    return o;
314 }
315 
316 static const char *
_gc_id_new(const E_Gadcon_Client_Class * client_class)317 _gc_id_new(const E_Gadcon_Client_Class *client_class)
318 {
319    static char buf[4096];
320 
321    snprintf(buf, sizeof(buf), "%s.%d", client_class->name,
322             eina_list_count(instances) + 1);
323    return buf;
324 }
325 
326 static void
_pager_recalc(void * data)327 _pager_recalc(void *data)
328 {
329    Pager *p = data;
330    Pager_Desk *pd;
331    Evas_Coord mw = 0, mh = 0;
332    int w, h, zw, zh, w2, h2;
333 
334    p->recalc = NULL;
335    zw = p->zone->w; zh = p->zone->h;
336    pd = eina_list_data_get(p->desks);
337    if (!pd) return;
338 
339    edje_object_size_min_calc(pd->o_desk, &mw, &mh);
340    evas_object_geometry_get(pd->o_desk, NULL, NULL, &w, &h);
341    w -= mw; h -= mh;
342    w2 = w; h2 = (zh * w) / zw;
343    if (h2 > h)
344      {
345         h2 = h; w2 = (zw * h) / zh;
346      }
347    w = w2; h = h2;
348    w += mw; h += mh;
349    if ((p->inst) && (p->inst->gcc))
350      {
351         if (p->invert)
352           e_gadcon_client_aspect_set(p->inst->gcc, p->ynum * w, p->xnum * h);
353         else
354           e_gadcon_client_aspect_set(p->inst->gcc, p->xnum * w, p->ynum * h);
355         _aspect(p->inst->gcc);
356      }
357 }
358 
359 static void
_pager_resize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)360 _pager_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
361 {
362    Pager *p = data;
363 
364    if (!p->recalc)
365      p->recalc = ecore_job_add(_pager_recalc, p);
366 }
367 
368 static Pager *
_pager_new(Evas * evas,E_Zone * zone,E_Gadcon * gc,Instance * inst)369 _pager_new(Evas *evas, E_Zone *zone, E_Gadcon *gc, Instance *inst)
370 {
371    Pager *p;
372 
373    p = E_NEW(Pager, 1);
374    p->inst = inst;
375    if (inst) inst->pager = p;
376    p->o_table = elm_table_add(e_win_evas_win_get(evas));
377    evas_object_event_callback_add(p->o_table, EVAS_CALLBACK_RESIZE,
378                                   _pager_resize, p);
379    elm_table_homogeneous_set(p->o_table, 1);
380    p->zone = zone;
381    _pager_fill(p, gc);
382    pagers = eina_list_append(pagers, p);
383    return p;
384 }
385 
386 static void
_pager_free(Pager * p)387 _pager_free(Pager *p)
388 {
389    _pager_empty(p);
390    evas_object_del(p->o_table);
391    ecore_job_del(p->recalc);
392    pagers = eina_list_remove(pagers, p);
393    free(p);
394 }
395 
396 static void
_pager_fill(Pager * p,E_Gadcon * gc)397 _pager_fill(Pager *p, E_Gadcon *gc)
398 {
399    int x, y;
400 
401    if (gc)
402      {
403         switch (gc->orient)
404           {
405 
406              case E_GADCON_ORIENT_TOP:
407              case E_GADCON_ORIENT_BOTTOM:
408              case E_GADCON_ORIENT_CORNER_TL:
409              case E_GADCON_ORIENT_CORNER_TR:
410              case E_GADCON_ORIENT_CORNER_BL:
411              case E_GADCON_ORIENT_CORNER_BR:
412              case E_GADCON_ORIENT_HORIZ:
413              case E_GADCON_ORIENT_FLOAT:
414                p->invert = EINA_FALSE;
415                break;
416              case E_GADCON_ORIENT_VERT:
417              case E_GADCON_ORIENT_LEFT:
418              case E_GADCON_ORIENT_RIGHT:
419              case E_GADCON_ORIENT_CORNER_LT:
420              case E_GADCON_ORIENT_CORNER_RT:
421              case E_GADCON_ORIENT_CORNER_LB:
422              case E_GADCON_ORIENT_CORNER_RB:
423              default:
424                p->invert = EINA_TRUE;
425           }
426      }
427    e_zone_desk_count_get(p->zone, &(p->xnum), &(p->ynum));
428    if (p->ynum != 1) p->invert = EINA_FALSE;
429    for (x = 0; x < p->xnum; x++)
430      {
431         for (y = 0; y < p->ynum; y++)
432           {
433              Pager_Desk *pd;
434              E_Desk *desk;
435 
436              desk = e_desk_at_xy_get(p->zone, x, y);
437              if (desk)
438                {
439                   pd = _pager_desk_new(p, desk, x, y, p->invert);
440                   if (pd)
441                     {
442                        p->desks = eina_list_append(p->desks, pd);
443                        if (desk == e_desk_current_get(desk->zone))
444                          _pager_desk_select(pd);
445                     }
446                }
447           }
448      }
449 }
450 
451 static void
_pager_empty(Pager * p)452 _pager_empty(Pager *p)
453 {
454    p->active_pd = NULL;
455    E_FREE_LIST(p->desks, _pager_desk_free);
456 }
457 
458 static Pager_Desk *
_pager_desk_new(Pager * p,E_Desk * desk,int xpos,int ypos,Eina_Bool invert)459 _pager_desk_new(Pager *p, E_Desk *desk, int xpos, int ypos, Eina_Bool invert)
460 {
461    Pager_Desk *pd;
462    Evas_Object *o, *evo;
463    E_Client *ec;
464    Eina_List *l;
465    int w, h;
466    Evas *e;
467 
468    if (!desk) return NULL;
469    pd = E_NEW(Pager_Desk, 1);
470    if (!pd) return NULL;
471 
472    pd->xpos = xpos;
473    pd->ypos = ypos;
474    pd->urgent = 0;
475    pd->desk = desk;
476    e_object_ref(E_OBJECT(desk));
477    pd->pager = p;
478 
479    e = evas_object_evas_get(p->o_table);
480    o = edje_object_add(e);
481    pd->o_desk = o;
482    e_theme_edje_object_set(o, "base/theme/modules/pager",
483                            "e/modules/pager16/desk");
484    edje_object_part_text_set(o, "e.text.label", desk->name);
485    if (pager_config->show_desk_names)
486      edje_object_signal_emit(o, "e,name,show", "e");
487 
488    edje_object_size_min_calc(o, &w, &h);
489    evas_object_size_hint_min_set(o, w, h);
490    E_EXPAND(o);
491    E_FILL(o);
492    if (invert)
493      elm_table_pack(p->o_table, o, ypos, xpos, 1, 1);
494    else
495      elm_table_pack(p->o_table, o, xpos, ypos, 1, 1);
496 
497    evo = (Evas_Object *)edje_object_part_object_get(o, "e.eventarea");
498    if (!evo) evo = o;
499 
500    evas_object_event_callback_add(evo, EVAS_CALLBACK_MOUSE_DOWN,
501                                   _pager_desk_cb_mouse_down, pd);
502    evas_object_event_callback_add(evo, EVAS_CALLBACK_MOUSE_UP,
503                                   _pager_desk_cb_mouse_up, pd);
504    evas_object_event_callback_add(evo, EVAS_CALLBACK_MOUSE_MOVE,
505                                   _pager_desk_cb_mouse_move, pd);
506    evas_object_event_callback_add(evo, EVAS_CALLBACK_MOUSE_WHEEL,
507                                   _pager_desk_cb_mouse_wheel, pd);
508    evas_object_show(o);
509 
510    pd->o_layout = e_deskmirror_add(desk, 1, 0);
511    evas_object_smart_callback_add(pd->o_layout, "mirror_add", (Evas_Smart_Cb)_pager_cb_mirror_add, pd);
512 
513    l = e_deskmirror_mirror_list(pd->o_layout);
514    EINA_LIST_FREE(l, o)
515      {
516         ec = evas_object_data_get(o, "E_Client");
517         if (ec)
518           {
519              Pager_Win *pw;
520 
521              pw = _pager_window_new(pd, o, ec);
522              if (pw) pd->wins = eina_list_append(pd->wins, pw);
523           }
524      }
525    edje_object_part_swallow(pd->o_desk, "e.swallow.content", pd->o_layout);
526    evas_object_show(pd->o_layout);
527 
528    return pd;
529 }
530 
531 static void
_pager_desk_free(Pager_Desk * pd)532 _pager_desk_free(Pager_Desk *pd)
533 {
534    Pager_Win *w;
535 
536    evas_object_del(pd->o_desk);
537    evas_object_del(pd->o_layout);
538    EINA_LIST_FREE(pd->wins, w)
539      _pager_window_free(w);
540    e_object_unref(E_OBJECT(pd->desk));
541    free(pd);
542 }
543 
544 static Pager_Desk *
_pager_desk_at_coord(Pager * p,Evas_Coord x,Evas_Coord y)545 _pager_desk_at_coord(Pager *p, Evas_Coord x, Evas_Coord y)
546 {
547    Eina_List *l;
548    Pager_Desk *pd;
549 
550    EINA_LIST_FOREACH(p->desks, l, pd)
551      {
552         Evas_Coord dx, dy, dw, dh;
553 
554         evas_object_geometry_get(pd->o_desk, &dx, &dy, &dw, &dh);
555         if (E_INSIDE(x, y, dx, dy, dw, dh)) return pd;
556      }
557    return NULL;
558 }
559 
560 static void
_pager_desk_select(Pager_Desk * pd)561 _pager_desk_select(Pager_Desk *pd)
562 {
563    if (pd->current) return;
564    if (pd->pager->active_pd)
565      {
566         pd->pager->active_pd->current = 0;
567         edje_object_signal_emit(pd->pager->active_pd->o_desk, "e,state,unselected", "e");
568      }
569    pd->current = 1;
570    evas_object_raise(pd->o_desk);
571    edje_object_signal_emit(pd->o_desk, "e,state,selected", "e");
572    pd->pager->active_pd = pd;
573 }
574 
575 static Pager_Desk *
_pager_desk_find(Pager * p,E_Desk * desk)576 _pager_desk_find(Pager *p, E_Desk *desk)
577 {
578    Eina_List *l;
579    Pager_Desk *pd;
580 
581    EINA_LIST_FOREACH(p->desks, l, pd)
582      if (pd->desk == desk) return pd;
583 
584    return NULL;
585 }
586 
587 static void
_pager_desk_switch(Pager_Desk * pd1,Pager_Desk * pd2)588 _pager_desk_switch(Pager_Desk *pd1, Pager_Desk *pd2)
589 {
590    int c;
591    E_Zone *zone1, *zone2;
592    E_Desk *desk1, *desk2;
593    Pager_Win *pw;
594    Eina_List *l;
595 
596    if ((!pd1) || (!pd2) || (!pd1->desk) || (!pd2->desk)) return;
597    if (pd1 == pd2) return;
598 
599    desk1 = pd1->desk;
600    desk2 = pd2->desk;
601    zone1 = pd1->desk->zone;
602    zone2 = pd2->desk->zone;
603 
604    /* Move opened windows from on desk to the other */
605    EINA_LIST_FOREACH(pd1->wins, l, pw)
606      {
607         if ((!pw) || (!pw->client) || (pw->client->iconic)) continue;
608         pw->client->hidden = 0;
609         e_client_desk_set(pw->client, desk2);
610      }
611    EINA_LIST_FOREACH(pd2->wins, l, pw)
612      {
613         if ((!pw) || (!pw->client) || (pw->client->iconic)) continue;
614         pw->client->hidden = 0;
615         e_client_desk_set(pw->client, desk1);
616      }
617    e_deskmirror_update_force(pd1->o_layout);
618    e_deskmirror_update_force(pd2->o_layout);
619 
620    /* Modify desktop names in the config */
621    for (l = e_config->desktop_names, c = 0; l && c < 2; l = l->next)
622      {
623         E_Config_Desktop_Name *tmp_dn;
624 
625         tmp_dn = l->data;
626         if (!tmp_dn) continue;
627         if ((tmp_dn->desk_x == desk1->x) &&
628             (tmp_dn->desk_y == desk1->y) &&
629             (tmp_dn->zone == (int)desk1->zone->num))
630           {
631              tmp_dn->desk_x = desk2->x;
632              tmp_dn->desk_y = desk2->y;
633              tmp_dn->zone = desk2->zone->num;
634              c++;
635           }
636         else if ((tmp_dn->desk_x == desk2->x) &&
637                  (tmp_dn->desk_y == desk2->y) &&
638                  (tmp_dn->zone == (int)desk2->zone->num))
639           {
640              tmp_dn->desk_x = desk1->x;
641              tmp_dn->desk_y = desk1->y;
642              tmp_dn->zone = desk1->zone->num;
643              c++;
644           }
645      }
646    if (c > 0) e_config_save();
647    e_desk_name_update();
648 
649    /* Modify desktop backgrounds in the config */
650    for (l = e_config->desktop_backgrounds, c = 0; l && c < 2; l = l->next)
651      {
652         E_Config_Desktop_Background *tmp_db;
653 
654         tmp_db = l->data;
655         if (!tmp_db) continue;
656         if ((tmp_db->desk_x == desk1->x) &&
657             (tmp_db->desk_y == desk1->y) &&
658             (tmp_db->zone == (int)desk1->zone->num))
659           {
660              tmp_db->desk_x = desk2->x;
661              tmp_db->desk_y = desk2->y;
662              tmp_db->zone = desk2->zone->num;
663              c++;
664           }
665         else if ((tmp_db->desk_x == desk2->x) &&
666                  (tmp_db->desk_y == desk2->y) &&
667                  (tmp_db->zone == (int)desk2->zone->num))
668           {
669              tmp_db->desk_x = desk1->x;
670              tmp_db->desk_y = desk1->y;
671              tmp_db->zone = desk1->zone->num;
672              c++;
673           }
674      }
675    if (c > 0) e_config_save();
676 
677    /* If the current desktop has been switched, force to update of the screen */
678    if (desk2 == e_desk_current_get(zone2))
679      {
680         desk2->visible = 0;
681         e_desk_show(desk2);
682      }
683    if (desk1 == e_desk_current_get(zone1))
684      {
685         desk1->visible = 0;
686         e_desk_show(desk1);
687      }
688 }
689 
690 static Pager_Win *
_pager_window_new(Pager_Desk * pd,Evas_Object * mirror,E_Client * client)691 _pager_window_new(Pager_Desk *pd, Evas_Object *mirror, E_Client *client)
692 {
693    Pager_Win *pw;
694    //Evas_Object *o;
695    //int visible;
696 
697    if (!client) return NULL;
698    pw = E_NEW(Pager_Win, 1);
699    if (!pw) return NULL;
700 
701    pw->client = client;
702    pw->o_mirror = mirror;
703 
704    //visible = evas_object_visible_get(mirror);
705    //pw->skip_winlist = client->netwm.state.skip_pager;
706    pw->desk = pd;
707 
708    //o = edje_object_add(evas_object_evas_get(pd->pager->o_table));
709    //pw->o_window = o;
710    //e_theme_edje_object_set(o, "base/theme/modules/pager",
711                            //"e/modules/pager16/window");
712    //if (visible) evas_object_show(o);
713 
714 
715    evas_object_event_callback_add(mirror, EVAS_CALLBACK_MOUSE_DOWN,
716                                   _pager_window_cb_mouse_down, pw);
717    evas_object_event_callback_add(mirror, EVAS_CALLBACK_MOUSE_UP,
718                                   _pager_window_cb_mouse_up, pw);
719    evas_object_event_callback_add(mirror, EVAS_CALLBACK_MOUSE_MOVE,
720                                   _pager_window_cb_mouse_move, pw);
721    evas_object_event_callback_add(mirror, EVAS_CALLBACK_DEL,
722                                   _pager_window_cb_del, pw);
723 
724    if (client->urgent)
725      {
726         if (!(client->iconic))
727           edje_object_signal_emit(pd->o_desk, "e,state,urgent", "e");
728         //edje_object_signal_emit(pw->o_window, "e,state,urgent", "e");
729      }
730 
731    //evas_object_show(o);
732    return pw;
733 }
734 
735 static void
_pager_window_free(Pager_Win * pw)736 _pager_window_free(Pager_Win *pw)
737 {
738    if ((pw->drag.from_pager) && (pw->desk->pager->dragging))
739      pw->desk->pager->dragging = 0;
740    if (pw->o_mirror)
741      evas_object_event_callback_del_full(pw->o_mirror, EVAS_CALLBACK_DEL,
742                                     _pager_window_cb_del, pw);
743    if (pw->o_window) evas_object_del(pw->o_window);
744    free(pw);
745 }
746 
747 static void
_pager_popup_cb_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)748 _pager_popup_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
749 {
750    Pager_Popup *pp = data;
751    E_FREE_FUNC(pp->timer, ecore_timer_del);
752    _pager_free(pp->pager);
753    free(pp);
754 }
755 
756 static Pager_Popup *
_pager_popup_new(E_Zone * zone,int keyaction)757 _pager_popup_new(E_Zone *zone, int keyaction)
758 {
759    Pager_Popup *pp;
760    Evas_Coord w, h, zx, zy, zw, zh;
761    int x, y, height, width;
762    E_Desk *desk;
763    Pager_Desk *pd;
764 
765    pp = E_NEW(Pager_Popup, 1);
766    if (!pp) return NULL;
767 
768    /* Show popup */
769 
770    pp->pager = _pager_new(e_comp->evas, zone, NULL, NULL);
771 
772    pp->pager->popup = pp;
773    pp->urgent = 0;
774 
775    e_zone_desk_count_get(zone, &x, &y);
776 
777    if (keyaction)
778      height = pager_config->popup_act_height;
779    else
780      height = pager_config->popup_height;
781 
782    pd = eina_list_data_get(pp->pager->desks);
783    if (!pd)
784      {
785         height *= y;
786         width = height * (zone->w * x) / (zone->h * y);
787      }
788    else
789      {
790         Evas_Coord mw = 0, mh = 0;
791 
792         edje_object_size_min_calc(pd->o_desk, &mw, &mh);
793         height -= mh;
794         width = (height * zone->w) / zone->h;
795         height *= y;
796         height += (y * mh);
797         width *= x;
798         width += (x * mw);
799      }
800 
801    evas_object_move(pp->pager->o_table, 0, 0);
802    evas_object_resize(pp->pager->o_table, width, height);
803 
804    pp->o_bg = edje_object_add(e_comp->evas);
805    evas_object_name_set(pp->o_bg, "pager_popup");
806    e_theme_edje_object_set(pp->o_bg, "base/theme/modules/pager",
807                            "e/modules/pager16/popup");
808    desk = e_desk_current_get(zone);
809    if (desk)
810      edje_object_part_text_set(pp->o_bg, "e.text.label", desk->name);
811 
812    evas_object_size_hint_min_set(pp->pager->o_table, width, height);
813    edje_object_part_swallow(pp->o_bg, "e.swallow.content", pp->pager->o_table);
814    edje_object_size_min_calc(pp->o_bg, &w, &h);
815 
816    pp->popup = e_comp_object_util_add(pp->o_bg, E_COMP_OBJECT_TYPE_POPUP);
817    evas_object_layer_set(pp->popup, E_LAYER_CLIENT_POPUP);
818    evas_object_pass_events_set(pp->popup, 1);
819    e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
820    evas_object_geometry_set(pp->popup, zx, zy, w, h);
821    e_comp_object_util_center(pp->popup);
822    evas_object_event_callback_add(pp->popup, EVAS_CALLBACK_DEL, _pager_popup_cb_del, pp);
823    evas_object_show(pp->popup);
824 
825    pp->timer = NULL;
826 
827    return pp;
828 }
829 
830 static void
_pager_popup_free(Pager_Popup * pp)831 _pager_popup_free(Pager_Popup *pp)
832 {
833    E_FREE_FUNC(pp->timer, ecore_timer_del);
834    evas_object_hide(pp->popup);
835    evas_object_del(pp->popup);
836 }
837 
838 static Pager_Popup *
_pager_popup_find(E_Zone * zone)839 _pager_popup_find(E_Zone *zone)
840 {
841    Eina_List *l;
842    Pager *p;
843 
844    EINA_LIST_FOREACH(pagers, l, p)
845      if ((p->popup) && (p->zone == zone))
846        return p->popup;
847 
848    return NULL;
849 }
850 
851 static void
_pager_cb_obj_hide(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)852 _pager_cb_obj_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
853 {
854     Instance *inst = data;
855     Eina_List *l;
856     Pager_Desk *pd;
857 
858     EINA_LIST_FOREACH(inst->pager->desks, l, pd)
859        edje_object_signal_emit(pd->o_desk, "e,state,hidden", "e");
860 }
861 
862 static void
_pager_cb_obj_show(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)863 _pager_cb_obj_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
864 {
865     Instance *inst = data;
866     Eina_List *l;
867     Pager_Desk *pd;
868 
869     EINA_LIST_FOREACH(inst->pager->desks, l, pd)
870        edje_object_signal_emit(pd->o_desk, "e,state,visible", "e");
871 }
872 
873 static void
_pager_cb_obj_moveresize(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)874 _pager_cb_obj_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
875 {
876    Instance *inst;
877 
878    inst = data;
879    _pager_instance_drop_zone_recalc(inst);
880 }
881 
882 static void
_button_cb_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)883 _button_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
884 {
885    Instance *inst;
886    Evas_Event_Mouse_Down *ev;
887    E_Menu *m;
888    E_Menu_Item *mi;
889    int cx, cy;
890    Pager_Desk *pd;
891 
892    inst = data;
893    ev = event_info;
894    if (ev->button != 3) return;
895    if (inst->gcc->menu) return;
896 
897    m = e_menu_new();
898    mi = e_menu_item_new(m);
899    e_menu_item_label_set(mi, _("Settings"));
900    e_util_menu_item_theme_icon_set(mi, "configure");
901    e_menu_item_callback_set(mi, _pager_inst_cb_menu_configure, NULL);
902 
903    m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
904 
905    mi = e_menu_item_new_relative(m, NULL);
906    e_menu_item_separator_set(mi, 1);
907 
908    if (e_configure_registry_exists("screen/virtual_desktops"))
909      {
910         mi = e_menu_item_new_relative(m, NULL);
911         e_menu_item_label_set(mi, _("All desktop settings"));
912         e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
913         e_menu_item_callback_set(mi, _pager_inst_cb_menu_virtual_desktops_dialog, inst);
914      }
915    if (e_configure_registry_exists("internal/desk"))
916      {
917         pd = _pager_desk_at_coord(inst->pager, ev->canvas.x, ev->canvas.y);
918         inst->pager->menu.zone_num = inst->pager->zone->num;
919         inst->pager->menu.desk_x = pd->desk->x;
920         inst->pager->menu.desk_y = pd->desk->y;
921         mi = e_menu_item_new_relative(m, NULL);
922         e_menu_item_label_set(mi, _("This desktop name and wallpaper settings"));
923         e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
924         e_menu_item_callback_set(mi, _pager_inst_cb_menu_virtual_desktop_dialog, inst);
925      }
926 
927    e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &cx, &cy,
928                                      NULL, NULL);
929    e_menu_activate_mouse(m, e_zone_current_get(),
930                          cx + ev->output.x, cy + ev->output.y, 1, 1,
931                          E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
932    evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
933                             EVAS_BUTTON_NONE, ev->timestamp, NULL);
934 }
935 
936 static void
_pager_inst_cb_menu_configure(void * data EINA_UNUSED,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)937 _pager_inst_cb_menu_configure(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
938 {
939    if (!pager_config) return;
940    if (config_dialog) return;
941    /* FIXME: pass zone config item */
942    _config_pager_module(NULL);
943 }
944 
945 static E_Config_Dialog *
_pager_config_dialog(Evas_Object * parent EINA_UNUSED,const char * params EINA_UNUSED)946 _pager_config_dialog(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED)
947 {
948    if (!pager_config) return NULL;
949    if (config_dialog) return NULL;
950    /* FIXME: pass zone config item */
951    _config_pager_module(NULL);
952    return config_dialog;
953 }
954 
955 static void
_pager_inst_cb_menu_virtual_desktops_dialog(void * data EINA_UNUSED,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)956 _pager_inst_cb_menu_virtual_desktops_dialog(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
957 {
958    e_configure_registry_call("screen/virtual_desktops", NULL, NULL);
959 }
960 
961 static void
_pager_inst_cb_menu_virtual_desktop_dialog(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)962 _pager_inst_cb_menu_virtual_desktop_dialog(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
963 {
964    Instance *inst = data;
965    char buf[256];
966 
967    snprintf(buf, sizeof(buf), "%i %i %i", inst->pager->menu.zone_num,
968             inst->pager->menu.desk_x, inst->pager->menu.desk_y);
969    e_configure_registry_call("internal/desk", NULL, buf);
970 }
971 
972 static void
_pager_instance_drop_zone_recalc(Instance * inst)973 _pager_instance_drop_zone_recalc(Instance *inst)
974 {
975    Evas_Coord x, y, w, h;
976 
977    e_gadcon_client_viewport_geometry_get(inst->gcc, &x, &y, &w, &h);
978    e_drop_handler_geometry_set(inst->pager->drop_handler, x, y, w, h);
979 }
980 
981 EINTERN void
_pager_cb_config_updated(void)982 _pager_cb_config_updated(void)
983 {
984    Pager *p;
985    Pager_Desk *pd;
986    Eina_List *l, *ll;
987    if (!pager_config) return;
988    EINA_LIST_FOREACH(pagers, l, p)
989      EINA_LIST_FOREACH(p->desks, ll, pd)
990        {
991           if (pd->current)
992             edje_object_signal_emit(pd->o_desk, "e,state,selected", "e");
993           else
994             edje_object_signal_emit(pd->o_desk, "e,state,unselected", "e");
995           if (pager_config->show_desk_names)
996             edje_object_signal_emit(pd->o_desk, "e,name,show", "e");
997           else
998             edje_object_signal_emit(pd->o_desk, "e,name,hide", "e");
999        }
1000 }
1001 
1002 static void
_pager_cb_mirror_add(Pager_Desk * pd,Evas_Object * obj EINA_UNUSED,Evas_Object * mirror)1003 _pager_cb_mirror_add(Pager_Desk *pd, Evas_Object *obj EINA_UNUSED, Evas_Object *mirror)
1004 {
1005    Pager_Win *pw;
1006 
1007    pw = _pager_window_new(pd, mirror, evas_object_data_get(mirror, "E_Client"));
1008    if (pw) pd->wins = eina_list_append(pd->wins, pw);
1009 }
1010 
1011 static Eina_Bool
_pager_cb_event_zone_desk_count_set(void * data EINA_UNUSED,int type EINA_UNUSED,E_Event_Zone_Desk_Count_Set * ev)1012 _pager_cb_event_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Zone_Desk_Count_Set *ev)
1013 {
1014    Eina_List *l;
1015    Pager *p;
1016 
1017    EINA_LIST_FOREACH(pagers, l, p)
1018      {
1019         if ((ev->zone->desk_x_count == p->xnum) &&
1020             (ev->zone->desk_y_count == p->ynum)) continue;
1021         _pager_empty(p);
1022         _pager_fill(p, p->inst ? p->inst->gcc->gadcon : NULL);
1023         if (p->inst) _gc_orient(p->inst->gcc, p->inst->gcc->gadcon->orient);
1024      }
1025 
1026    return ECORE_CALLBACK_PASS_ON;
1027 }
1028 
1029 static Eina_Bool
_pager_cb_event_desk_show(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)1030 _pager_cb_event_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1031 {
1032    E_Event_Desk_Show *ev = event;
1033    Eina_List *l;
1034    Pager *p;
1035    Pager_Popup *pp;
1036    Pager_Desk *pd;
1037 
1038    if (!eina_list_count(pagers)) return ECORE_CALLBACK_PASS_ON;
1039 
1040    EINA_LIST_FOREACH(pagers, l, p)
1041      {
1042         if (p->zone != ev->desk->zone) continue;
1043         pd = _pager_desk_find(p, ev->desk);
1044         if (pd) _pager_desk_select(pd);
1045 
1046         if (p->popup)
1047           edje_object_part_text_set(p->popup->o_bg, "e.text.label", ev->desk->name);
1048      }
1049 
1050    if ((pager_config->popup) && (!act_popup) &&
1051        ((ecore_time_get() - _pager_start_time) > 0.5)) //. not at start
1052      {
1053         if ((pp = _pager_popup_find(ev->desk->zone)))
1054           evas_object_show(pp->popup);
1055         else
1056           pp = _pager_popup_new(ev->desk->zone, 0);
1057         if (pp->timer)
1058           ecore_timer_loop_reset(pp->timer);
1059         else
1060           pp->timer = ecore_timer_add(pager_config->popup_speed,
1061                                       _pager_popup_cb_timeout, pp);
1062      }
1063 
1064    return ECORE_CALLBACK_PASS_ON;
1065 }
1066 
1067 static Eina_Bool
_pager_cb_event_desk_name_change(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)1068 _pager_cb_event_desk_name_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1069 {
1070    E_Event_Desk_Name_Change *ev = event;
1071    Eina_List *l;
1072    Pager *p;
1073 
1074    EINA_LIST_FOREACH(pagers, l, p)
1075      {
1076         Pager_Desk *pd;
1077 
1078         if (p->zone != ev->desk->zone) continue;
1079         pd = _pager_desk_find(p, ev->desk);
1080         if (pager_config->show_desk_names)
1081           {
1082              if (pd)
1083                edje_object_part_text_set(pd->o_desk, "e.text.label",
1084                                          ev->desk->name);
1085           }
1086         else
1087           {
1088              if (pd)
1089                edje_object_part_text_set(pd->o_desk, "e.text.label", "");
1090           }
1091      }
1092 
1093    return ECORE_CALLBACK_PASS_ON;
1094 }
1095 
1096 static Eina_Bool
_pager_cb_event_client_urgent_change(void * data EINA_UNUSED,int type EINA_UNUSED,E_Event_Client_Property * ev)1097 _pager_cb_event_client_urgent_change(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Client_Property *ev)
1098 {
1099    if (!(ev->property & E_CLIENT_PROPERTY_URGENCY)) return ECORE_CALLBACK_RENEW;
1100 
1101    if (!eina_list_count(pagers)) return ECORE_CALLBACK_RENEW;
1102 
1103    if (pager_config->popup_urgent && (!e_client_util_desk_visible(ev->ec, e_desk_current_get(ev->ec->zone))) &&
1104                                       (pager_config->popup_urgent_focus ||
1105                                       (!pager_config->popup_urgent_focus && (!ev->ec->focused) && (!ev->ec->want_focus))))
1106      {
1107         Pager_Popup *pp;
1108 
1109         pp = _pager_popup_find(ev->ec->zone);
1110 
1111         if ((!pp) && (ev->ec->urgent || ev->ec->icccm.urgent) && (!ev->ec->iconic))
1112           {
1113              pp = _pager_popup_new(ev->ec->zone, 0);
1114              if (!pp) return ECORE_CALLBACK_RENEW;
1115 
1116              if (!pager_config->popup_urgent_stick)
1117                pp->timer = ecore_timer_loop_add(pager_config->popup_urgent_speed,
1118                                            _pager_popup_cb_timeout, pp);
1119              pp->urgent = 1;
1120           }
1121      }
1122    return ECORE_CALLBACK_RENEW;
1123 }
1124 
1125 static Eina_Bool
_pager_cb_event_compositor_resize(void * data EINA_UNUSED,int type EINA_UNUSED,void * event EINA_UNUSED)1126 _pager_cb_event_compositor_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1127 {
1128    Eina_List *l;
1129    Pager *p;
1130 
1131    EINA_LIST_FOREACH(pagers, l, p)
1132      {
1133         Eina_List *l2;
1134         Pager_Desk *pd;
1135 
1136         EINA_LIST_FOREACH(p->desks, l2, pd)
1137           e_layout_virtual_size_set(pd->o_layout, pd->desk->zone->w,
1138                                     pd->desk->zone->h);
1139 
1140         if (p->inst) _gc_orient(p->inst->gcc, p->inst->gcc->gadcon->orient);
1141         /* TODO if (p->popup) */
1142      }
1143 
1144    return ECORE_CALLBACK_PASS_ON;
1145 }
1146 
1147 static void
_pager_window_cb_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1148 _pager_window_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1149 {
1150    Pager_Win *pw = data;
1151 
1152    pw->desk->wins = eina_list_remove(pw->desk->wins, pw);
1153    _pager_window_free(data);
1154 }
1155 
1156 static void
_pager_window_cb_mouse_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1157 _pager_window_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1158 {
1159    Pager_Win *pw = data;
1160 
1161    pw->drag.button = 0;
1162 }
1163 
1164 static void
_pager_window_cb_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1165 _pager_window_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1166 {
1167    Evas_Event_Mouse_Down *ev;
1168    Pager_Win *pw;
1169 
1170    ev = event_info;
1171    pw = data;
1172 
1173    if (!pw) return;
1174    pw->desk->pager->active_drag_client = NULL;
1175    if (pw->desk->pager->popup && !act_popup) return;
1176    if (!pw->desk->pager->popup && ev->button == 3) return;
1177    if (e_client_util_ignored_get(pw->client) || e_client_util_is_popup(pw->client)) return;
1178    if (ev->button == (int)pager_config->btn_desk) return;
1179    if ((ev->button == (int)pager_config->btn_drag) ||
1180        (ev->button == (int)pager_config->btn_noplace))
1181      {
1182         Evas_Coord ox, oy;
1183 
1184         evas_object_geometry_get(pw->o_mirror, &ox, &oy, NULL, NULL);
1185         pw->drag.in_pager = 1;
1186         pw->drag.x = ev->canvas.x;
1187         pw->drag.y = ev->canvas.y;
1188         pw->drag.dx = ox - ev->canvas.x;
1189         pw->drag.dy = oy - ev->canvas.y;
1190         pw->drag.start = 1;
1191         pw->drag.button = ev->button;
1192         pw->desk->pager->active_drag_client = pw->client;
1193      }
1194 }
1195 
1196 static void
_pager_window_cb_mouse_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1197 _pager_window_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1198 {
1199    Evas_Event_Mouse_Move *ev;
1200    Pager_Win *pw;
1201    E_Drag *drag;
1202    Evas_Object *o;
1203    Evas_Coord x, y, w, h;
1204    const char *drag_types[] =
1205    { "enlightenment/pager_win", "enlightenment/border" };
1206 
1207    ev = event_info;
1208    pw = data;
1209 
1210    if (!pw) return;
1211    if (pw->client->lock_user_location) return;
1212    if ((pw->desk->pager->popup) && (!act_popup)) return;
1213    if (!pw->drag.button) return;
1214 
1215    /* prevent drag for a few pixels */
1216    if (!pw->drag.start) return;
1217 
1218    if (!is_dragged(pw->drag.x - ev->cur.output.x,
1219                    pw->drag.y - ev->cur.output.y)) return;
1220 
1221    pw->desk->pager->dragging = 1;
1222    pw->drag.start = 0;
1223    e_comp_object_effect_clip(pw->client->frame);
1224    edje_object_signal_emit(pw->desk->o_desk, "e,action,drag,in", "e");
1225    pw->desk->pager->active_drop_pd = pw->desk;
1226 
1227    evas_object_geometry_get(pw->o_mirror, &x, &y, &w, &h);
1228    evas_object_hide(pw->o_mirror);
1229 
1230    drag = e_drag_new(x, y, drag_types, 2, pw->desk->pager, -1,
1231                      _pager_window_cb_drag_convert,
1232                      _pager_window_cb_drag_finished);
1233    drag->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
1234 
1235    evas_object_raise(pw->client->frame);
1236    /* this is independent of the original mirror */
1237    o = e_deskmirror_mirror_copy(pw->o_mirror);
1238    evas_object_show(o);
1239 
1240    e_drag_object_set(drag, o);
1241    e_drag_resize(drag, w, h);
1242    e_drag_show(drag);
1243    e_drag_start(drag, x - pw->drag.dx, y - pw->drag.dy);
1244 }
1245 
1246 static void *
_pager_window_cb_drag_convert(E_Drag * drag,const char * type)1247 _pager_window_cb_drag_convert(E_Drag *drag, const char *type)
1248 {
1249    Pager *p;
1250 
1251    p = drag->data;
1252    if (!strcmp(type, "enlightenment/pager_win")) return _pager_window_find(p, p->active_drag_client);
1253    if (!strcmp(type, "enlightenment/border")) return p->active_drag_client;
1254    return NULL;
1255 }
1256 
1257 static void
_pager_window_cb_drag_finished(E_Drag * drag,int dropped)1258 _pager_window_cb_drag_finished(E_Drag *drag, int dropped)
1259 {
1260    Pager_Win *pw;
1261    Pager *p;
1262 
1263    p = drag->data;
1264    if (!p) return;
1265    pw = _pager_window_find(p, p->active_drag_client);
1266    if (!pw) return;
1267    p->active_drag_client = NULL;
1268    evas_object_show(pw->o_mirror);
1269    if (dropped)
1270      {
1271         /* be helpful */
1272         if (pw->client->desk->visible && (!e_client_focused_get()))
1273           evas_object_focus_set(pw->client->frame, 1);
1274         e_deskmirror_update_force(pw->desk->o_layout);
1275      }
1276    else
1277      {
1278         int dx, dy, x, y, zx, zy, zw, zh;
1279         E_Client *ec = pw->client;
1280 
1281         ec->hidden = !p->active_pd->desk->visible;
1282         e_client_desk_set(ec, p->active_pd->desk);
1283 
1284         dx = (ec->w / 2);
1285         dy = (ec->h / 2);
1286 
1287         evas_pointer_canvas_xy_get(evas_object_evas_get(p->o_table), &x, &y);
1288         e_zone_useful_geometry_get(p->zone, &zx, &zy, &zw, &zh);
1289 
1290         /* offset so that center of window is on mouse, but keep within desk bounds */
1291         if (dx < x)
1292           {
1293              x -= dx;
1294              if ((ec->w < zw) && (x + ec->w > zx + zw))
1295                x -= x + ec->w - (zx + zw);
1296           }
1297         else x = 0;
1298 
1299         if (dy < y)
1300           {
1301              y -= dy;
1302              if ((ec->h < zh) && (y + ec->h > zy + zh))
1303                y -= y + ec->h - (zy + zh);
1304           }
1305         else y = 0;
1306         evas_object_move(ec->frame, x, y);
1307 
1308         if (!(ec->lock_user_stacking)) evas_object_raise(ec->frame);
1309         evas_object_focus_set(ec->frame, 1);
1310         e_deskmirror_update_force(pw->desk->o_layout);
1311      }
1312    if (p->active_drop_pd)
1313      {
1314         edje_object_signal_emit(p->active_drop_pd->o_desk, "e,action,drag,out", "e");
1315         if (!pw->drag.start) p->active_drop_pd->pager->just_dragged = 1;
1316         p->active_drop_pd = NULL;
1317      }
1318    edje_object_signal_emit(pw->desk->o_desk, "e,action,drag,out", "e");
1319    if (!pw->drag.from_pager)
1320      {
1321         if (!pw->drag.start) p->just_dragged = 1;
1322         pw->drag.in_pager = 0;
1323         pw->drag.button = pw->drag.start = 0;
1324         p->dragging = 0;
1325      }
1326    if (pw->drag.from_pager) pw->drag.from_pager->dragging = 0;
1327    pw->drag.from_pager = NULL;
1328    e_comp_object_effect_unclip(pw->client->frame);
1329    if (act_popup)
1330      {
1331         if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1332           e_grabinput_get(input_window, 0, input_window);
1333         else
1334           e_comp_grab_input(1, 1);
1335         if (!hold_count) _pager_popup_hide(1);
1336      }
1337 }
1338 
1339 static void
_pager_inst_cb_scroll(void * data)1340 _pager_inst_cb_scroll(void *data)
1341 {
1342    Pager *p;
1343 
1344    p = data;
1345    _pager_update_drop_position(p, p->dnd_x, p->dnd_y);
1346 }
1347 
1348 static void
_pager_update_drop_position(Pager * p,Evas_Coord x,Evas_Coord y)1349 _pager_update_drop_position(Pager *p, Evas_Coord x, Evas_Coord y)
1350 {
1351    Pager_Desk *pd;
1352    Pager_Win *pw = NULL;
1353    Eina_Bool changed;
1354 
1355    p->dnd_x = x;
1356    p->dnd_y = y;
1357    pd = _pager_desk_at_coord(p, x, y);
1358    changed = (pd != p->active_drop_pd);
1359    if (changed)
1360      {
1361         if (pd)
1362           edje_object_signal_emit(pd->o_desk, "e,action,drag,in", "e");
1363         if (p->active_drop_pd)
1364           edje_object_signal_emit(p->active_drop_pd->o_desk, "e,action,drag,out", "e");
1365         p->active_drop_pd = pd;
1366      }
1367    if (pd)
1368      pw = _pager_desk_window_find(pd, p->active_drag_client);
1369    if (!pw)
1370      pw = _pager_window_find(p, p->active_drag_client);
1371 
1372    if (!pw) return;
1373    if (pd)
1374      {
1375         int zx, zy, zw, zh, vx, vy, offx, offy;
1376         E_Client *ec = pw->client;
1377         E_Desk *old_desk = ec->desk;
1378         Eina_Bool was_focused = e_client_stack_focused_get(ec);
1379         E_Drag *drag = e_drag_current_get();
1380 
1381         pw->drag.in_pager = 1;
1382         //makes drags look weird
1383         //e_zone_useful_geometry_get(pd->desk->zone, &zx, &zy, &zw, &zh);
1384         zx = pd->desk->zone->x, zy = pd->desk->zone->y;
1385         zw = pd->desk->zone->w, zh = pd->desk->zone->h;
1386         e_deskmirror_coord_canvas_to_virtual(pd->o_layout,
1387                                              x, y, &vx, &vy);
1388         ec->hidden = !pd->desk->visible;
1389         e_client_desk_set(ec, pd->desk);
1390         offx = (ec->w / 2);
1391         offy = (ec->h / 2);
1392         if (drag)
1393           {
1394              if (drag->w > 0) offx = ((drag->dx) * ec->w) / drag->w;
1395              if (drag->h > 0) offy = ((drag->dy) * ec->h) / drag->h;
1396           }
1397         x = E_CLAMP(vx + zx - offx, zx, zx + zw - ec->w);
1398         y = E_CLAMP(vy + zy - offy, zy, zy + zh - ec->h);
1399         evas_object_move(ec->frame, x, y);
1400         if (was_focused)
1401           e_desk_last_focused_focus(old_desk);
1402      }
1403    else
1404      {
1405         /* this prevents the desk from switching on drags */
1406         pw->drag.from_pager = pw->desk->pager;
1407         pw->drag.from_pager->dragging = 1;
1408         pw->drag.in_pager = 0;
1409      }
1410 }
1411 
1412 static void
_pager_drop_cb_enter(void * data,const char * type EINA_UNUSED,void * event_info EINA_UNUSED)1413 _pager_drop_cb_enter(void *data, const char *type EINA_UNUSED, void *event_info EINA_UNUSED)
1414 {
1415    Pager *p = data;
1416 
1417    /* FIXME this fixes a segv, but the case is not easy
1418     * reproduceable. this makes no sense either since
1419     * the same 'pager' is passed to e_drop_handler_add
1420     * and it works without this almost all the time.
1421     * so this must be an issue with e_dnd code... i guess */
1422    if (act_popup) p = act_popup->pager;
1423 
1424    if (p->inst)
1425      e_gadcon_client_autoscroll_cb_set(p->inst->gcc, _pager_inst_cb_scroll, p);
1426 }
1427 
1428 static void
_pager_drop_cb_move(void * data,const char * type EINA_UNUSED,void * event_info)1429 _pager_drop_cb_move(void *data, const char *type EINA_UNUSED, void *event_info)
1430 {
1431    E_Event_Dnd_Move *ev;
1432    Pager *p;
1433 
1434    ev = event_info;
1435    p = data;
1436 
1437    if (act_popup) p = act_popup->pager;
1438 
1439    _pager_update_drop_position(p, ev->x, ev->y);
1440 
1441    if (p->inst)
1442      e_gadcon_client_autoscroll_update(p->inst->gcc, ev->x, ev->y);
1443 }
1444 
1445 static void
_pager_drop_cb_leave(void * data,const char * type EINA_UNUSED,void * event_info EINA_UNUSED)1446 _pager_drop_cb_leave(void *data, const char *type EINA_UNUSED, void *event_info EINA_UNUSED)
1447 {
1448    Pager *p = data;
1449 
1450    if (act_popup) p = act_popup->pager;
1451 
1452    if (p->active_drop_pd)
1453      edje_object_signal_emit(p->active_drop_pd->o_desk, "e,action,drag,out", "e");
1454    p->active_drop_pd = NULL;
1455 
1456    if (p->inst) e_gadcon_client_autoscroll_cb_set(p->inst->gcc, NULL, NULL);
1457 }
1458 
1459 static void
_pager_drop_cb_drop(void * data,const char * type,void * event_info)1460 _pager_drop_cb_drop(void *data, const char *type, void *event_info)
1461 {
1462    E_Event_Dnd_Drop *ev;
1463    Pager_Desk *pd;
1464    Pager_Desk *pd2 = NULL;
1465    E_Client *ec = NULL;
1466    Eina_List *l;
1467    Pager_Win *pw = NULL;
1468    Evas_Coord wx, wy, wx2, wy2;
1469    Evas_Coord nx, ny;
1470    Pager *p;
1471 
1472    ev = event_info;
1473    p = data;
1474 
1475    if (act_popup) p = act_popup->pager;
1476 
1477    pd = _pager_desk_at_coord(p, ev->x, ev->y);
1478    if (pd)
1479      {
1480         if (!strcmp(type, "enlightenment/pager_win"))
1481           {
1482              pw = (Pager_Win *)(ev->data);
1483              if (pw)
1484                {
1485                   ec = pw->client;
1486                }
1487           }
1488         else if (!strcmp(type, "enlightenment/border"))
1489           {
1490              ec = ev->data;
1491              e_deskmirror_coord_virtual_to_canvas(pd->o_layout, ec->x, ec->y,
1492                                                   &wx, &wy);
1493              e_deskmirror_coord_virtual_to_canvas(pd->o_layout, ec->x + ec->w,
1494                                                   ec->y + ec->h, &wx2, &wy2);
1495           }
1496         else if (!strcmp(type, "enlightenment/vdesktop"))
1497           {
1498              pd2 = ev->data;
1499              if (!pd2) return;
1500              _pager_desk_switch(pd, pd2);
1501           }
1502         else
1503           return;
1504 
1505         if (ec)
1506           {
1507              E_Maximize max = ec->maximized;
1508              E_Fullscreen fs = ec->fullscreen_policy;
1509              Eina_Bool fullscreen = ec->fullscreen;
1510              E_Desk *old_desk = ec->desk;
1511              Eina_Bool was_focused = e_client_stack_focused_get(ec);
1512 
1513              if (ec->iconic) e_client_uniconify(ec);
1514              if (ec->maximized)
1515                e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
1516              if (fullscreen) e_client_unfullscreen(ec);
1517                ec->hidden = 0;
1518              e_client_desk_set(ec, pd->desk);
1519              if (was_focused)
1520                e_desk_last_focused_focus(old_desk);
1521              evas_object_raise(ec->frame);
1522 
1523              if ((!max) && (!fullscreen))
1524                {
1525                   E_Drag *drag = e_drag_current_get();
1526                   int zx, zy, zw, zh, mx, my, offx, offy;
1527 
1528                   e_deskmirror_coord_canvas_to_virtual(pd->o_layout,
1529                                                        ev->x, ev->y,
1530                                                        &nx, &ny);
1531                   e_zone_useful_geometry_get(pd->desk->zone,
1532                                              &zx, &zy, &zw, &zh);
1533                   offx = (ec->w / 2);
1534                   offy = (ec->h / 2);
1535                   if (drag)
1536                     {
1537                        if (drag->w > 0) offx = ((drag->dx) * ec->w) / drag->w;
1538                        if (drag->h > 0) offy = ((drag->dy) * ec->h) / drag->h;
1539                     }
1540                   mx = E_CLAMP(nx + zx - offx, zx, zx + zw - ec->w);
1541                   my = E_CLAMP(ny + zy - offy, zy, zy + zh - ec->h);
1542                   evas_object_move(ec->frame, mx, my);
1543                }
1544              if (max) e_client_maximize(ec, max);
1545              if (fullscreen) e_client_fullscreen(ec, fs);
1546              e_deskmirror_update_force(pd->o_layout);
1547           }
1548      }
1549 
1550    EINA_LIST_FOREACH(p->desks, l, pd)
1551      {
1552         if (!p->active_drop_pd) break;
1553         if (pd == p->active_drop_pd)
1554           {
1555              edje_object_signal_emit(pd->o_desk, "e,action,drag,out", "e");
1556              p->active_drop_pd = NULL;
1557           }
1558      }
1559 
1560    if (p->inst) e_gadcon_client_autoscroll_cb_set(p->inst->gcc, NULL, NULL);
1561 }
1562 
1563 static void
_pager_desk_cb_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1564 _pager_desk_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1565 {
1566    Evas_Event_Mouse_Down *ev;
1567    Pager_Desk *pd;
1568    Evas_Coord ox, oy;
1569 
1570    ev = event_info;
1571    pd = data;
1572    if (!pd) return;
1573    if ((!pd->pager->popup) && (ev->button == 3)) return;
1574    if (ev->button == (int)pager_config->btn_desk)
1575      {
1576         evas_object_geometry_get(pd->o_desk, &ox, &oy, NULL, NULL);
1577         pd->drag.start = 1;
1578         pd->drag.in_pager = 1;
1579         pd->drag.dx = ox - ev->canvas.x;
1580         pd->drag.dy = oy - ev->canvas.y;
1581         pd->drag.x = ev->canvas.x;
1582         pd->drag.y = ev->canvas.y;
1583         pd->drag.button = ev->button;
1584      }
1585    else
1586      {
1587         pd->drag.dx = pd->drag.dy = pd->drag.x = pd->drag.y = 0;
1588      }
1589    pd->pager->just_dragged = 0;
1590 }
1591 
1592 static void
_pager_desk_cb_mouse_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1593 _pager_desk_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1594 {
1595    Evas_Event_Mouse_Up *ev;
1596    Pager_Desk *pd;
1597    Pager *p;
1598 
1599    ev = event_info;
1600    pd = data;
1601 
1602    if (!pd) return;
1603    p = pd->pager;
1604 
1605    /* FIXME: pd->pager->dragging is 0 when finishing a drag from desk to desk */
1606    if ((ev->button == 1) && (!pd->pager->dragging) &&
1607        (!pd->pager->just_dragged))
1608      {
1609         current_desk = pd->desk;
1610         e_desk_show(pd->desk);
1611         pd->drag.start = 0;
1612         pd->drag.in_pager = 0;
1613         p->active_drop_pd = NULL;
1614      }
1615    else if (ev->button == (int)pager_config->btn_desk)
1616      {
1617         if (pd->pager->dragging) pd->pager->dragging = 0;
1618         pd->drag.start = 0;
1619         pd->drag.in_pager = 0;
1620      }
1621 
1622    if ((p->popup) && (p->popup->urgent)) _pager_popup_free(p->popup);
1623 }
1624 
1625 static void
_pager_desk_cb_mouse_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1626 _pager_desk_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1627 {
1628    Evas_Event_Mouse_Move *ev;
1629    Pager_Desk *pd;
1630    E_Drag *drag;
1631    Evas_Object *o;
1632    Evas_Coord x, y, w, h;
1633    const char *drag_types[] = { "enlightenment/vdesktop" };
1634 
1635    ev = event_info;
1636 
1637    pd = data;
1638    if (!pd) return;
1639    /* prevent drag for a few pixels */
1640    if (pd->drag.start)
1641      {
1642         if (!is_dragged(pd->drag.x - ev->cur.output.x,
1643                         pd->drag.y - ev->cur.output.y)) return;
1644 
1645         if (pd->pager) pd->pager->dragging = 1;
1646         pd->drag.start = 0;
1647      }
1648 
1649    if (pd->drag.in_pager && pd->pager)
1650      {
1651         evas_object_geometry_get(pd->o_desk, &x, &y, &w, &h);
1652         drag = e_drag_new(x, y, drag_types, 1, pd, -1,
1653                           NULL, _pager_desk_cb_drag_finished);
1654         drag->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
1655 
1656         /* redraw the desktop theme above */
1657         o = e_comp_object_util_mirror_add(pd->o_layout);
1658         e_drag_object_set(drag, o);
1659 
1660         e_drag_resize(drag, w, h);
1661         e_drag_start(drag, x - pd->drag.dx, y - pd->drag.dy);
1662 
1663         pd->drag.from_pager = pd->pager;
1664         pd->drag.from_pager->dragging = 1;
1665         pd->drag.in_pager = 0;
1666      }
1667 }
1668 
1669 static void
_pager_desk_cb_drag_finished(E_Drag * drag,int dropped)1670 _pager_desk_cb_drag_finished(E_Drag *drag, int dropped)
1671 {
1672    Pager_Desk *pd;
1673    Pager_Desk *pd2 = NULL;
1674    Eina_List *l;
1675    E_Desk *desk;
1676    E_Zone *zone;
1677    Pager *p;
1678 
1679    pd = drag->data;
1680    if (!pd) return;
1681    if (!dropped)
1682      {
1683         /* wasn't dropped on pager, switch with current desktop */
1684         if (!pd->desk) return;
1685         zone = e_zone_current_get();
1686         desk = e_desk_current_get(zone);
1687         EINA_LIST_FOREACH(pagers, l, p)
1688           {
1689              pd2 = _pager_desk_find(p, desk);
1690              if (pd2) break;
1691           }
1692         _pager_desk_switch(pd, pd2);
1693      }
1694    if (pd->drag.from_pager)
1695      {
1696         pd->drag.from_pager->dragging = 0;
1697         pd->drag.from_pager->just_dragged = 0;
1698      }
1699    if (pd->pager->active_drop_pd)
1700      {
1701         edje_object_signal_emit(pd->pager->active_drop_pd->o_desk, "e,action,drag,out", "e");
1702         pd->pager->active_drop_pd = NULL;
1703      }
1704    pd->drag.from_pager = NULL;
1705 
1706    if (act_popup)
1707      {
1708         if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1709           e_grabinput_get(input_window, 0, input_window);
1710         else
1711           e_comp_grab_input(1, 1);
1712         if (!hold_count) _pager_popup_hide(1);
1713      }
1714 }
1715 
1716 static void
_pager_desk_cb_mouse_wheel(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1717 _pager_desk_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1718 {
1719    Evas_Event_Mouse_Wheel *ev;
1720    Pager_Desk *pd;
1721 
1722    ev = event_info;
1723    pd = data;
1724 
1725    if (pd->pager->popup) return;
1726 
1727    if (pager_config->flip_desk)
1728      e_zone_desk_linear_flip_by(pd->desk->zone, ev->z);
1729 }
1730 
1731 static Eina_Bool
_pager_popup_cb_timeout(void * data)1732 _pager_popup_cb_timeout(void *data)
1733 {
1734    Pager_Popup *pp;
1735 
1736    pp = data;
1737    pp->timer = NULL;
1738    _pager_popup_free(pp);
1739 
1740 #ifndef HAVE_WAYLAND_ONLY
1741    if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1742      {
1743         if (input_window)
1744           {
1745              e_grabinput_release(input_window, input_window);
1746              ecore_x_window_free(input_window);
1747              input_window = 0;
1748           }
1749      }
1750 #endif
1751    if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
1752      {
1753         e_comp_ungrab_input(1, 1);
1754         input_window = 0;
1755      }
1756 
1757    return ECORE_CALLBACK_CANCEL;
1758 }
1759 
1760 /************************************************************************/
1761 /* popup-on-keyaction functions */
1762 static int
_pager_popup_show(void)1763 _pager_popup_show(void)
1764 {
1765    E_Zone *zone;
1766    int x, y, w, h;
1767    Pager_Popup *pp;
1768    //const char *drop[] =
1769    //{
1770       //"enlightenment/pager_win", "enlightenment/border",
1771       //"enlightenment/vdesktop"
1772    //};
1773 
1774    if ((act_popup) || (input_window)) return 0;
1775 
1776    zone = e_zone_current_get();
1777 
1778    pp = _pager_popup_find(zone);
1779    if (pp) _pager_popup_free(pp);
1780 
1781 #ifndef HAVE_WAYLAND_ONLY
1782    if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1783      {
1784         input_window = ecore_x_window_input_new(e_comp->win, 0, 0, 1, 1);
1785         ecore_x_window_show(input_window);
1786         if (!e_grabinput_get(input_window, 0, input_window))
1787           {
1788              ecore_x_window_free(input_window);
1789              input_window = 0;
1790              return 0;
1791           }
1792      }
1793 #endif
1794    if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
1795      {
1796         input_window = e_comp->ee_win;
1797         e_comp_grab_input(1, 1);
1798      }
1799 
1800    handlers = eina_list_append
1801        (handlers, ecore_event_handler_add
1802          (ECORE_EVENT_KEY_DOWN, _pager_popup_cb_key_down, NULL));
1803    handlers = eina_list_append
1804        (handlers, ecore_event_handler_add
1805          (ECORE_EVENT_KEY_UP, _pager_popup_cb_key_up, NULL));
1806    handlers = eina_list_append
1807        (handlers, ecore_event_handler_add
1808          (ECORE_EVENT_MOUSE_WHEEL, _pager_popup_cb_mouse_wheel, NULL));
1809 
1810    act_popup = _pager_popup_new(zone, 1);
1811 
1812    evas_object_geometry_get(act_popup->pager->o_table, &x, &y, &w, &h);
1813 
1814    current_desk = e_desk_current_get(zone);
1815 
1816    return 1;
1817 }
1818 
1819 static void
_pager_popup_hide(int switch_desk)1820 _pager_popup_hide(int switch_desk)
1821 {
1822    hold_count = 0;
1823    hold_mod = 0;
1824    while (handlers)
1825      {
1826         ecore_event_handler_del(handlers->data);
1827         handlers = eina_list_remove_list(handlers, handlers);
1828      }
1829 
1830    act_popup->timer = ecore_timer_loop_add(0.1, _pager_popup_cb_timeout, act_popup);
1831 
1832    if ((switch_desk) && (current_desk)) e_desk_show(current_desk);
1833 
1834    act_popup = NULL;
1835 }
1836 
1837 static void
_pager_popup_modifiers_set(int mod)1838 _pager_popup_modifiers_set(int mod)
1839 {
1840    if (!act_popup) return;
1841    hold_mod = mod;
1842    hold_count = 0;
1843    if (hold_mod & ECORE_EVENT_MODIFIER_SHIFT) hold_count++;
1844    if (hold_mod & ECORE_EVENT_MODIFIER_CTRL) hold_count++;
1845    if (hold_mod & ECORE_EVENT_MODIFIER_ALT) hold_count++;
1846    if (hold_mod & ECORE_EVENT_MODIFIER_WIN) hold_count++;
1847 }
1848 
1849 static void
_pager_popup_desk_switch(int x,int y)1850 _pager_popup_desk_switch(int x, int y)
1851 {
1852    int max_x, max_y, desk_x, desk_y;
1853    Pager_Desk *pd;
1854    Pager_Popup *pp = act_popup;
1855 
1856    e_zone_desk_count_get(pp->pager->zone, &max_x, &max_y);
1857 
1858    desk_x = current_desk->x + x;
1859    desk_y = current_desk->y + y;
1860 
1861    if (desk_x < 0)
1862      desk_x = max_x - 1;
1863    else if (desk_x >= max_x)
1864      desk_x = 0;
1865 
1866    if (desk_y < 0)
1867      desk_y = max_y - 1;
1868    else if (desk_y >= max_y)
1869      desk_y = 0;
1870 
1871    current_desk = e_desk_at_xy_get(pp->pager->zone, desk_x, desk_y);
1872 
1873    pd = _pager_desk_find(pp->pager, current_desk);
1874    if (pd) _pager_desk_select(pd);
1875 
1876    edje_object_part_text_set(pp->o_bg, "e.text.label", current_desk->name);
1877 }
1878 
1879 static void
_pager_popup_cb_action_show(E_Object * obj EINA_UNUSED,const char * params EINA_UNUSED,Ecore_Event_Key * ev EINA_UNUSED)1880 _pager_popup_cb_action_show(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED, Ecore_Event_Key *ev EINA_UNUSED)
1881 {
1882    if (_pager_popup_show())
1883      _pager_popup_modifiers_set(ev->modifiers);
1884 }
1885 
1886 static void
_pager_popup_cb_action_switch(E_Object * obj EINA_UNUSED,const char * params,Ecore_Event_Key * ev)1887 _pager_popup_cb_action_switch(E_Object *obj EINA_UNUSED, const char *params, Ecore_Event_Key *ev)
1888 {
1889    int max_x, max_y, desk_x;
1890    int x = 0, y = 0;
1891 
1892    if (!act_popup)
1893      {
1894         if (_pager_popup_show())
1895           _pager_popup_modifiers_set(ev->modifiers);
1896         else
1897           return;
1898      }
1899 
1900    e_zone_desk_count_get(act_popup->pager->zone, &max_x, &max_y);
1901    desk_x = current_desk->x /* + x <=this is always 0 */;
1902 
1903    if (!strcmp(params, "left"))
1904      x = -1;
1905    else if (!strcmp(params, "right"))
1906      x = 1;
1907    else if (!strcmp(params, "up"))
1908      y = -1;
1909    else if (!strcmp(params, "down"))
1910      y = 1;
1911    else if (!strcmp(params, "next"))
1912      {
1913         x = 1;
1914         if (desk_x == max_x - 1)
1915           y = 1;
1916      }
1917    else if (!strcmp(params, "prev"))
1918      {
1919         x = -1;
1920         if (desk_x == 0)
1921           y = -1;
1922      }
1923 
1924    _pager_popup_desk_switch(x, y);
1925 }
1926 
1927 static Eina_Bool
_pager_popup_cb_mouse_wheel(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)1928 _pager_popup_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1929 {
1930    Ecore_Event_Mouse_Wheel *ev = event;
1931    Pager_Popup *pp = act_popup;
1932    int max_x;
1933 
1934    e_zone_desk_count_get(pp->pager->zone, &max_x, NULL);
1935 
1936    if (current_desk->x + ev->z >= max_x)
1937      _pager_popup_desk_switch(1, 1);
1938    else if (current_desk->x + ev->z < 0)
1939      _pager_popup_desk_switch(-1, -1);
1940    else
1941      _pager_popup_desk_switch(ev->z, 0);
1942 
1943    return ECORE_CALLBACK_PASS_ON;
1944 }
1945 
1946 static Eina_Bool
_pager_popup_cb_key_down(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)1947 _pager_popup_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1948 {
1949    Ecore_Event_Key *ev;
1950 
1951    ev = event;
1952    if (ev->window != input_window) return ECORE_CALLBACK_PASS_ON;
1953    if (!strcmp(ev->key, "Up"))
1954      _pager_popup_desk_switch(0, -1);
1955    else if (!strcmp(ev->key, "Down"))
1956      _pager_popup_desk_switch(0, 1);
1957    else if (!strcmp(ev->key, "Left"))
1958      _pager_popup_desk_switch(-1, 0);
1959    else if (!strcmp(ev->key, "Right"))
1960      _pager_popup_desk_switch(1, 0);
1961    else if (!strcmp(ev->key, "Escape"))
1962      _pager_popup_hide(0);
1963    else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")) ||
1964             (!strcmp(ev->key, "space")))
1965      {
1966         Pager_Popup *pp = act_popup;
1967 
1968         if (pp)
1969           {
1970              E_Desk *desk;
1971 
1972              desk = e_desk_at_xy_get(pp->pager->zone,
1973                                      current_desk->x, current_desk->y);
1974              if (desk) e_desk_show(desk);
1975           }
1976         _pager_popup_hide(0);
1977      }
1978    else
1979      {
1980         E_Config_Binding_Key *binding;
1981         Eina_List *l;
1982 
1983         EINA_LIST_FOREACH(e_bindings->key_bindings, l, binding)
1984           {
1985              E_Binding_Modifier mod = 0;
1986 
1987              if ((binding->action) && (strcmp(binding->action, "pager_switch")))
1988                continue;
1989 
1990              if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1991                mod |= E_BINDING_MODIFIER_SHIFT;
1992              if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1993                mod |= E_BINDING_MODIFIER_CTRL;
1994              if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1995                mod |= E_BINDING_MODIFIER_ALT;
1996              if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1997                mod |= E_BINDING_MODIFIER_WIN;
1998 
1999              if (binding->key && (!strcmp(binding->key, ev->key)) &&
2000                  ((binding->modifiers == mod)))
2001                {
2002                   E_Action *act;
2003 
2004                   act = e_action_find(binding->action);
2005 
2006                   if (act)
2007                     {
2008                        if (act->func.go_key)
2009                          act->func.go_key(NULL, binding->params, ev);
2010                     }
2011                }
2012           }
2013      }
2014    return ECORE_CALLBACK_PASS_ON;
2015 }
2016 
2017 static Eina_Bool
_pager_popup_cb_key_up(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)2018 _pager_popup_cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
2019 {
2020    Ecore_Event_Key *ev;
2021 
2022    ev = event;
2023    if (!(act_popup)) return ECORE_CALLBACK_PASS_ON;
2024 
2025    if (hold_mod)
2026      {
2027         if ((hold_mod & ECORE_EVENT_MODIFIER_SHIFT) &&
2028             (!strcmp(ev->key, "Shift_L"))) hold_count--;
2029         else if ((hold_mod & ECORE_EVENT_MODIFIER_SHIFT) &&
2030                  (!strcmp(ev->key, "Shift_R")))
2031           hold_count--;
2032         else if ((hold_mod & ECORE_EVENT_MODIFIER_CTRL) &&
2033                  (!strcmp(ev->key, "Control_L")))
2034           hold_count--;
2035         else if ((hold_mod & ECORE_EVENT_MODIFIER_CTRL) &&
2036                  (!strcmp(ev->key, "Control_R")))
2037           hold_count--;
2038         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2039                  (!strcmp(ev->key, "Alt_L")))
2040           hold_count--;
2041         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2042                  (!strcmp(ev->key, "Alt_R")))
2043           hold_count--;
2044         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2045                  (!strcmp(ev->key, "Meta_L")))
2046           hold_count--;
2047         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2048                  (!strcmp(ev->key, "Meta_R")))
2049           hold_count--;
2050         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2051                  (!strcmp(ev->key, "Super_L")))
2052           hold_count--;
2053         else if ((hold_mod & ECORE_EVENT_MODIFIER_ALT) &&
2054                  (!strcmp(ev->key, "Super_R")))
2055           hold_count--;
2056         else if ((hold_mod & ECORE_EVENT_MODIFIER_WIN) &&
2057                  (!strcmp(ev->key, "Super_L")))
2058           hold_count--;
2059         else if ((hold_mod & ECORE_EVENT_MODIFIER_WIN) &&
2060                  (!strcmp(ev->key, "Super_R")))
2061           hold_count--;
2062         else if ((hold_mod & ECORE_EVENT_MODIFIER_WIN) &&
2063                  (!strcmp(ev->key, "Mode_switch")))
2064           hold_count--;
2065         else if ((hold_mod & ECORE_EVENT_MODIFIER_WIN) &&
2066                  (!strcmp(ev->key, "Meta_L")))
2067           hold_count--;
2068         else if ((hold_mod & ECORE_EVENT_MODIFIER_WIN) &&
2069                  (!strcmp(ev->key, "Meta_R")))
2070           hold_count--;
2071         if ((hold_count <= 0) && (!act_popup->pager->dragging))
2072           {
2073              _pager_popup_hide(1);
2074              return ECORE_CALLBACK_PASS_ON;
2075           }
2076      }
2077 
2078    return ECORE_CALLBACK_PASS_ON;
2079 }
2080 
2081 /***************************************************************************/
2082 /* module setup */
2083 E_API E_Module_Api e_modapi =
2084 {
2085    E_MODULE_API_VERSION, "Pager"
2086 };
2087 
2088 E_API void *
e_modapi_init(E_Module * m)2089 e_modapi_init(E_Module *m)
2090 {
2091    E_Module *p;
2092 
2093    _pager_start_time = ecore_time_get();
2094    e_modapi_gadget_init(m);
2095    p = e_module_find("pager_plain");
2096    if (p && p->enabled)
2097      {
2098         e_util_dialog_show(_("Error"), _("Pager module cannot be loaded at the same time as Pager Plain!"));
2099         return NULL;
2100      }
2101 
2102    E_LIST_HANDLER_APPEND(shandlers, E_EVENT_ZONE_DESK_COUNT_SET, _pager_cb_event_zone_desk_count_set, NULL);
2103    E_LIST_HANDLER_APPEND(shandlers, E_EVENT_DESK_SHOW, _pager_cb_event_desk_show, NULL);
2104    E_LIST_HANDLER_APPEND(shandlers, E_EVENT_DESK_NAME_CHANGE, _pager_cb_event_desk_name_change, NULL);
2105    E_LIST_HANDLER_APPEND(shandlers, E_EVENT_COMPOSITOR_UPDATE, _pager_cb_event_compositor_resize, NULL);
2106    E_LIST_HANDLER_APPEND(shandlers, E_EVENT_CLIENT_PROPERTY, _pager_cb_event_client_urgent_change, NULL);
2107 
2108    module = m;
2109 
2110    e_gadcon_provider_register(&_gadcon_class);
2111 
2112    e_configure_registry_item_add("extensions/pager", 40, _("Pager"), NULL,
2113                                  "preferences-pager", _pager_config_dialog);
2114 
2115    act_popup_show = e_action_add("pager_show");
2116    if (act_popup_show)
2117      {
2118         act_popup_show->func.go_key = _pager_popup_cb_action_show;
2119         e_action_predef_name_set(N_("Pager"), N_("Show Pager Popup"),
2120                                  "pager_show", "<none>", NULL, 0);
2121      }
2122    act_popup_switch = e_action_add("pager_switch");
2123    if (act_popup_switch)
2124      {
2125         act_popup_switch->func.go_key = _pager_popup_cb_action_switch;
2126         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Right"),
2127                                  "pager_switch", "right", NULL, 0);
2128         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Left"),
2129                                  "pager_switch", "left", NULL, 0);
2130         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Up"),
2131                                  "pager_switch", "up", NULL, 0);
2132         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Down"),
2133                                  "pager_switch", "down", NULL, 0);
2134         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Next"),
2135                                  "pager_switch", "next", NULL, 0);
2136         e_action_predef_name_set(N_("Pager"), N_("Popup Desk Previous"),
2137                                  "pager_switch", "prev", NULL, 0);
2138      }
2139 
2140    return m;
2141 }
2142 
2143 E_API int
e_modapi_shutdown(E_Module * m)2144 e_modapi_shutdown(E_Module *m)
2145 {
2146    e_modapi_gadget_shutdown(m);
2147    e_gadcon_provider_unregister(&_gadcon_class);
2148 
2149    if (config_dialog)
2150      e_object_del(E_OBJECT(config_dialog));
2151    E_FREE_LIST(shandlers, ecore_event_handler_del);
2152 
2153    e_action_del("pager_show");
2154    e_action_del("pager_switch");
2155 
2156    e_action_predef_name_del("Pager", "Popup Desk Right");
2157    e_action_predef_name_del("Pager", "Popup Desk Left");
2158    e_action_predef_name_del("Pager", "Popup Desk Up");
2159    e_action_predef_name_del("Pager", "Popup Desk Down");
2160    e_action_predef_name_del("Pager", "Popup Desk Next");
2161    e_action_predef_name_del("Pager", "Popup Desk Previous");
2162 
2163    return 1;
2164 }
2165 
2166 E_API int
e_modapi_save(E_Module * m)2167 e_modapi_save(E_Module *m)
2168 {
2169    e_modapi_gadget_save(m);
2170    return 1;
2171 }
2172 
2173