1 #include "e.h"
2 
3 #define INITS
4 #define ACT_GO(name)                                      \
5   {                                                       \
6      act = e_action_add(#name);                           \
7      if (act) act->func.go = _e_actions_act_##name##_go;  \
8   }
9 #define ACT_FN_GO(act, use) \
10   static void _e_actions_act_##act##_go(E_Object * obj EINA_UNUSED, const char *params use)
11 
12 #define ACT_GO_MOUSE(name)                                            \
13   {                                                                   \
14      act = e_action_add(#name);                                       \
15      if (act) act->func.go_mouse = _e_actions_act_##name##_go_mouse;  \
16   }
17 #define ACT_FN_GO_MOUSE(act, use) \
18   static Eina_Bool _e_actions_act_##act##_go_mouse(E_Object * obj EINA_UNUSED, const char *params use, E_Binding_Event_Mouse_Button * ev EINA_UNUSED)
19 
20 #define ACT_GO_WHEEL(name)                                            \
21   {                                                                   \
22      act = e_action_add(#name);                                       \
23      if (act) act->func.go_wheel = _e_actions_act_##name##_go_wheel;  \
24   }
25 #define ACT_FN_GO_WHEEL(act, use) \
26   static Eina_Bool _e_actions_act_##act##_go_wheel(E_Object * obj EINA_UNUSED, const char *params use, E_Binding_Event_Wheel * ev EINA_UNUSED)
27 
28 #define ACT_GO_EDGE(name)                                           \
29   {                                                                 \
30      act = e_action_add(#name);                                     \
31      if (act) act->func.go_edge = _e_actions_act_##name##_go_edge;  \
32   }
33 #define ACT_FN_GO_EDGE(act, use) \
34   static void _e_actions_act_##act##_go_edge(E_Object * obj EINA_UNUSED, const char *params use, E_Event_Zone_Edge * ev EINA_UNUSED)
35 
36 #define ACT_GO_SIGNAL(name)                                             \
37   {                                                                     \
38      act = e_action_add(#name);                                         \
39      if (act) act->func.go_signal = _e_actions_act_##name##_go_signal;  \
40   }
41 #define ACT_FN_GO_SIGNAL(act, use) \
42   static void _e_actions_act_##act##_go_signal(E_Object * obj EINA_UNUSED, const char *params use, const char *sig, const char *src)
43 
44 #define ACT_GO_KEY(name)                                          \
45   {                                                               \
46      act = e_action_add(#name);                                   \
47      if (act) act->func.go_key = _e_actions_act_##name##_go_key;  \
48   }
49 #define ACT_FN_GO_KEY(act, use1, use2) \
50   static void _e_actions_act_##act##_go_key(E_Object * obj EINA_UNUSED, const char *params use1, Ecore_Event_Key * ev use2)
51 
52 #define ACT_END(name)                                       \
53   {                                                         \
54      act = e_action_add(#name);                             \
55      if (act) act->func.end = _e_actions_act_##name##_end;  \
56   }
57 #define ACT_FN_END(act, use) \
58   static void _e_actions_act_##act##_end(E_Object * obj EINA_UNUSED, const char *params use)
59 
60 #define ACT_END_MOUSE(name)                                             \
61   {                                                                     \
62      act = e_action_add(#name);                                         \
63      if (act) act->func.end_mouse = _e_actions_act_##name##_end_mouse;  \
64   }
65 #define ACT_FN_END_MOUSE(act, use) \
66   static Eina_Bool _e_actions_act_##act##_end_mouse(E_Object * obj EINA_UNUSED, const char *params use, E_Binding_Event_Mouse_Button * ev EINA_UNUSED)
67 
68 #define ACT_END_KEY(name)                                           \
69   {                                                                 \
70      act = e_action_add(#name);                                     \
71      if (act) act->func.end_key = _e_actions_act_##name##_end_key;  \
72   }
73 #define ACT_FN_END_KEY(act, use) \
74   static void _e_actions_act_##act##_end_key(E_Object * obj EINA_UNUSED, const char *params use, Ecore_Event_Key * ev EINA_UNUSED)
75 
76 #define ACT_GO_ACPI(name)                                           \
77   {                                                                 \
78      act = e_action_add(#name);                                     \
79      if (act) act->func.go_acpi = _e_actions_act_##name##_go_acpi;  \
80   }
81 #define ACT_FN_GO_ACPI(act, use) \
82   static void _e_actions_act_##act##_go_acpi(E_Object * obj EINA_UNUSED, const char *params use, E_Event_Acpi * ev EINA_UNUSED)
83 
84 /* local functions forward declarations (window_jump_to needs the definition of exec) */
85 ACT_FN_GO(exec, );
86 
87 /* local subsystem functions */
88 static void       _e_action_free(E_Action *act);
89 static E_Maximize _e_actions_maximize_parse(const char *maximize);
90 static int        _action_groups_sort_cb(const void *d1, const void *d2);
91 
92 /* to save writing this in N places - the sections are defined here */
93 /***************************************************************************/
ACT_FN_GO(window_move,EINA_UNUSED)94 ACT_FN_GO(window_move, EINA_UNUSED)
95 {
96    if ((!obj) || (obj->type != E_CLIENT_TYPE))
97      obj = E_OBJECT(e_client_focused_get());
98    if (!obj) return;
99    if (obj->type != E_CLIENT_TYPE) return;
100    if (!((E_Client *)(void *)obj)->lock_user_location)
101      e_client_act_move_begin((E_Client *)(void *)obj, NULL);
102 }
103 
ACT_FN_GO_MOUSE(window_move,EINA_UNUSED)104 ACT_FN_GO_MOUSE(window_move, EINA_UNUSED)
105 {
106    if ((!obj) || (obj->type != E_CLIENT_TYPE))
107      obj = E_OBJECT(e_client_focused_get());
108    if (!obj) return EINA_FALSE;
109    if (obj->type != E_CLIENT_TYPE) return EINA_FALSE;
110    e_client_act_move_begin((E_Client *)(void *)obj, ev);
111    return EINA_TRUE;
112 }
113 
114 ACT_FN_GO_SIGNAL(window_move, )
115 {
116    if ((!obj) || (obj->type != E_CLIENT_TYPE))
117      obj = E_OBJECT(e_client_focused_get());
118    if (!obj) return;
119    if (obj->type != E_CLIENT_TYPE) return;
120    if (!((E_Client *)(void *)obj)->lock_user_location)
121      {
122         if ((params) && (!strcmp(params, "end")))
123           e_client_signal_move_end((E_Client *)(void *)obj, sig, src);
124         else
125           {
126              if (!((E_Client *)(void *)obj)->moving)
127                e_client_signal_move_begin((E_Client *)(void *)obj, sig, src);
128           }
129      }
130 }
131 
ACT_FN_END(window_move,EINA_UNUSED)132 ACT_FN_END(window_move, EINA_UNUSED)
133 {
134    if ((!obj) || (obj->type != E_CLIENT_TYPE))
135      obj = E_OBJECT(e_client_focused_get());
136    if (!obj) return;
137    if (obj->type != E_CLIENT_TYPE) return;
138    e_client_act_move_end((E_Client *)(void *)obj, NULL);
139 }
140 
ACT_FN_END_MOUSE(window_move,EINA_UNUSED)141 ACT_FN_END_MOUSE(window_move, EINA_UNUSED)
142 {
143    if ((!obj) || (obj->type != E_CLIENT_TYPE))
144      obj = E_OBJECT(e_client_focused_get());
145    if (!obj) return EINA_FALSE;
146    if (obj->type != E_CLIENT_TYPE) return EINA_FALSE;
147    e_client_act_move_end((E_Client *)(void *)obj, ev);
148    return EINA_TRUE;
149 }
150 
ACT_FN_GO_KEY(window_move,EINA_UNUSED,EINA_UNUSED)151 ACT_FN_GO_KEY(window_move, EINA_UNUSED, EINA_UNUSED)
152 {
153    if ((!obj) || (obj->type != E_CLIENT_TYPE))
154      obj = E_OBJECT(e_client_focused_get());
155    if (!obj) return;
156    if (!((E_Client *)(void *)obj)->lock_user_location)
157      e_client_act_move_keyboard((E_Client *)(void *)obj);
158 }
159 
160 /***************************************************************************/
ACT_FN_GO(window_resize,EINA_UNUSED)161 ACT_FN_GO(window_resize, EINA_UNUSED)
162 {
163    if ((!obj) || (obj->type != E_CLIENT_TYPE))
164      obj = E_OBJECT(e_client_focused_get());
165    if (!obj) return;
166    if (!((E_Client *)(void *)obj)->lock_user_size)
167      e_client_act_resize_begin((E_Client *)(void *)obj, NULL);
168 }
169 
ACT_FN_GO_MOUSE(window_resize,EINA_UNUSED)170 ACT_FN_GO_MOUSE(window_resize, EINA_UNUSED)
171 {
172    if ((!obj) || (obj->type != E_CLIENT_TYPE))
173      obj = E_OBJECT(e_client_focused_get());
174    if (!obj) return EINA_FALSE;
175    if (obj->type != E_CLIENT_TYPE) return EINA_FALSE;
176    if (!((E_Client *)(void *)obj)->lock_user_size)
177      e_client_act_resize_begin((E_Client *)(void *)obj, ev);
178    return EINA_TRUE;
179 }
180 
181 ACT_FN_GO_SIGNAL(window_resize, )
182 {
183    if ((!obj) || (obj->type != E_CLIENT_TYPE))
184      obj = E_OBJECT(e_client_focused_get());
185    if (!obj) return;
186    if (obj->type != E_CLIENT_TYPE) return;
187    if (!((E_Client *)(void *)obj)->lock_user_size)
188      {
189         if ((params) && (!strcmp(params, "end")))
190           e_client_signal_resize_end((E_Client *)(void *)obj, params, sig, src);
191         else
192           {
193              if (!params) params = "";
194              if (e_client_util_resizing_get((E_Client *)(void *)obj))
195                e_client_signal_resize_end((E_Client *)(void *)obj, params, sig, src);
196              else
197                e_client_signal_resize_begin((E_Client *)(void *)obj, params, sig, src);
198           }
199      }
200 }
201 
ACT_FN_END(window_resize,EINA_UNUSED)202 ACT_FN_END(window_resize, EINA_UNUSED)
203 {
204    if ((!obj) || (obj->type != E_CLIENT_TYPE))
205      obj = E_OBJECT(e_client_focused_get());
206    if (!obj) return;
207    if (obj->type != E_CLIENT_TYPE) return;
208    e_client_act_resize_end((E_Client *)(void *)obj, NULL);
209 }
210 
ACT_FN_END_MOUSE(window_resize,EINA_UNUSED)211 ACT_FN_END_MOUSE(window_resize, EINA_UNUSED)
212 {
213    if ((!obj) || (obj->type != E_CLIENT_TYPE))
214      obj = E_OBJECT(e_client_focused_get());
215    if (!obj) return EINA_FALSE;
216    if (obj->type != E_CLIENT_TYPE) return EINA_FALSE;
217    e_client_act_resize_end((E_Client *)(void *)obj, ev);
218    return EINA_TRUE;
219 }
220 
ACT_FN_GO_KEY(window_resize,EINA_UNUSED,EINA_UNUSED)221 ACT_FN_GO_KEY(window_resize, EINA_UNUSED, EINA_UNUSED)
222 {
223    if ((!obj) || (obj->type != E_CLIENT_TYPE))
224      obj = E_OBJECT(e_client_focused_get());
225    if (!obj) return;
226    if (obj->type != E_CLIENT_TYPE)
227      {
228         obj = E_OBJECT(e_client_focused_get());
229         if (!obj) return;
230      }
231    if (!((E_Client *)(void *)obj)->lock_user_size)
232      e_client_act_resize_keyboard((E_Client *)(void *)obj);
233 }
234 
235 /***************************************************************************/
ACT_FN_GO(window_menu,EINA_UNUSED)236 ACT_FN_GO(window_menu, EINA_UNUSED)
237 {
238    if ((!obj) || (obj->type != E_CLIENT_TYPE))
239      obj = E_OBJECT(e_client_focused_get());
240    if (!obj) return;
241    e_client_act_menu_begin((E_Client *)(void *)obj, NULL, 0);
242 }
243 
ACT_FN_GO_MOUSE(window_menu,EINA_UNUSED)244 ACT_FN_GO_MOUSE(window_menu, EINA_UNUSED)
245 {
246    if ((!obj) || (obj->type != E_CLIENT_TYPE))
247      obj = E_OBJECT(e_client_focused_get());
248    if (!obj) return EINA_FALSE;
249    if (obj->type != E_CLIENT_TYPE)
250      {
251         obj = E_OBJECT(e_client_focused_get());
252         if (!obj) return EINA_FALSE;
253      }
254    e_client_act_menu_begin((E_Client *)(void *)obj, ev, 0);
255    return EINA_TRUE;
256 }
257 
ACT_FN_GO_KEY(window_menu,EINA_UNUSED,EINA_UNUSED)258 ACT_FN_GO_KEY(window_menu, EINA_UNUSED, EINA_UNUSED)
259 {
260    if ((!obj) || (obj->type != E_CLIENT_TYPE))
261      obj = E_OBJECT(e_client_focused_get());
262    if (!obj) return;
263    if (obj->type != E_CLIENT_TYPE)
264      {
265         obj = E_OBJECT(e_client_focused_get());
266         if (!obj) return;
267      }
268    e_client_act_menu_begin((E_Client *)(void *)obj, NULL, 1);
269 }
270 
271 /***************************************************************************/
ACT_FN_GO(window_raise,EINA_UNUSED)272 ACT_FN_GO(window_raise, EINA_UNUSED)
273 {
274    if ((!obj) || (obj->type != E_CLIENT_TYPE))
275      obj = E_OBJECT(e_client_focused_get());
276    if (!obj) return;
277    if (!((E_Client *)(void *)obj)->lock_user_stacking)
278      evas_object_raise(((E_Client *)(void *)obj)->frame);
279 }
280 
281 /***************************************************************************/
ACT_FN_GO(window_lower,EINA_UNUSED)282 ACT_FN_GO(window_lower, EINA_UNUSED)
283 {
284    if ((!obj) || (obj->type != E_CLIENT_TYPE))
285      obj = E_OBJECT(e_client_focused_get());
286    if (!obj) return;
287    if (!((E_Client *)(void *)obj)->lock_user_stacking)
288      evas_object_lower(((E_Client *)(void *)obj)->frame);
289 }
290 
291 /***************************************************************************/
ACT_FN_GO(window_close,EINA_UNUSED)292 ACT_FN_GO(window_close, EINA_UNUSED)
293 {
294    if ((!obj) || (obj->type != E_CLIENT_TYPE))
295      obj = E_OBJECT(e_client_focused_get());
296    if (!obj) return;
297    if (!((E_Client *)(void *)obj)->lock_close)
298      e_client_act_close_begin((E_Client *)(void *)obj);
299 }
300 
301 /***************************************************************************/
302 static E_Dialog *kill_dialog = NULL;
303 
304 static void
_e_actions_cb_kill_dialog_ok(void * data,E_Dialog * dia)305 _e_actions_cb_kill_dialog_ok(void *data, E_Dialog *dia)
306 {
307    E_Object *obj;
308 
309    obj = data;
310    if (dia)
311      {
312         e_object_del(E_OBJECT(kill_dialog));
313         kill_dialog = NULL;
314      }
315    if ((!((E_Client *)(void *)obj)->lock_close) && (!((E_Client *)(void *)obj)->internal))
316      e_client_act_kill_begin((E_Client *)(void *)obj);
317 }
318 
319 static void
_e_actions_cb_kill_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)320 _e_actions_cb_kill_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
321 {
322    e_object_del(E_OBJECT(kill_dialog));
323    kill_dialog = NULL;
324 }
325 
326 static void
_e_actions_cb_kill_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)327 _e_actions_cb_kill_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
328 {
329    _e_actions_cb_kill_dialog_cancel(NULL, data);
330 }
331 
ACT_FN_GO(window_kill,EINA_UNUSED)332 ACT_FN_GO(window_kill, EINA_UNUSED)
333 {
334    E_Client *ec;
335    char dialog_text[1024];
336 
337    if ((!obj) || (obj->type != E_CLIENT_TYPE))
338      obj = E_OBJECT(e_client_focused_get());
339    if (!obj) return;
340    ec = (E_Client *)(void *)obj;
341    if ((ec->lock_close) || (ec->internal)) return;
342 
343    if (kill_dialog) e_object_del(E_OBJECT(kill_dialog));
344 
345    if (e_config->cnfmdlg_disabled)
346      {
347         _e_actions_cb_kill_dialog_ok(obj, NULL);
348         return;
349      }
350 
351    snprintf(dialog_text, sizeof(dialog_text),
352             _("You are about to kill %s.<ps/><ps/>"
353               "Please keep in mind that all data from this window<ps/>"
354               "which has not yet been saved will be lost!<ps/><ps/>"
355               "Are you sure you want to kill this window?"),
356             ec->icccm.name);
357 
358    kill_dialog = e_dialog_new(NULL,
359                               "E", "_kill_dialog");
360    if (!kill_dialog) return;
361    evas_object_event_callback_add(kill_dialog->win, EVAS_CALLBACK_DEL,
362                              _e_actions_cb_kill_dialog_delete, kill_dialog);
363    e_dialog_title_set(kill_dialog,
364                       _("Are you sure you want to kill this window?"));
365    e_dialog_text_set(kill_dialog, _(dialog_text));
366    e_dialog_icon_set(kill_dialog, "application-exit", 64);
367    e_dialog_button_add(kill_dialog, _("Kill"), NULL,
368                        _e_actions_cb_kill_dialog_ok, obj);
369    e_dialog_button_add(kill_dialog, _("No"), NULL,
370                        _e_actions_cb_kill_dialog_cancel, NULL);
371    e_dialog_button_focus_num(kill_dialog, 1);
372    elm_win_center(kill_dialog->win, 1, 1);
373    e_dialog_show(kill_dialog);
374 }
375 
376 /***************************************************************************/
ACT_FN_GO(window_sticky_toggle,EINA_UNUSED)377 ACT_FN_GO(window_sticky_toggle, EINA_UNUSED)
378 {
379    if ((!obj) || (obj->type != E_CLIENT_TYPE))
380      obj = E_OBJECT(e_client_focused_get());
381    if (!obj) return;
382    if (!((E_Client *)(void *)obj)->lock_user_sticky)
383      {
384         E_Client *ec;
385 
386         ec = (E_Client *)(void *)obj;
387         if (ec->sticky) e_client_unstick(ec);
388         else e_client_stick(ec);
389      }
390 }
391 
392 /***************************************************************************/
393 ACT_FN_GO(window_sticky, )
394 {
395    if ((!obj) || (obj->type != E_CLIENT_TYPE))
396      obj = E_OBJECT(e_client_focused_get());
397    if (!obj) return;
398    if (!((E_Client *)(void *)obj)->lock_user_sticky)
399      {
400         E_Client *ec;
401 
402         ec = (E_Client *)(void *)obj;
403         if (params)
404           {
405              if (atoi(params) == 1)
406                e_client_stick(ec);
407              else if (atoi(params) == 0)
408                e_client_unstick(ec);
409           }
410      }
411 }
412 
413 /***************************************************************************/
ACT_FN_GO(window_iconic_toggle,EINA_UNUSED)414 ACT_FN_GO(window_iconic_toggle, EINA_UNUSED)
415 {
416    E_Client *ec;
417 
418    if ((!obj) || (obj->type != E_CLIENT_TYPE))
419      obj = E_OBJECT(e_client_focused_get());
420    if (!obj) return;
421    ec = (E_Client *)(void *)obj;
422 
423    if ((!ec->lock_user_iconify) && (!ec->fullscreen) &&
424        ((ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
425         (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN)))
426      {
427         if (ec->iconic) e_client_uniconify(ec);
428         else e_client_iconify(ec);
429      }
430 }
431 
432 /***************************************************************************/
433 ACT_FN_GO(window_iconic, )
434 {
435    if ((!obj) || (obj->type != E_CLIENT_TYPE))
436      obj = E_OBJECT(e_client_focused_get());
437    if (!obj) return;
438    if (!((E_Client *)(void *)obj)->lock_user_iconify)
439      {
440         E_Client *ec;
441 
442         ec = (E_Client *)(void *)obj;
443         if (params)
444           {
445              if (atoi(params) == 1)
446                e_client_iconify(ec);
447              else if (atoi(params) == 0)
448                e_client_uniconify(ec);
449           }
450      }
451 }
452 
453 /***************************************************************************/
454 ACT_FN_GO(window_fullscreen_toggle, )
455 {
456    if ((!obj) || (obj->type != E_CLIENT_TYPE))
457      obj = E_OBJECT(e_client_focused_get());
458    if (!obj) return;
459    if (!((E_Client *)(void *)obj)->lock_user_fullscreen)
460      {
461         E_Client *ec;
462 
463         ec = (E_Client *)(void *)obj;
464         if (ec->fullscreen)
465           e_client_unfullscreen(ec);
466         else if (!params || *params == '\0')
467           e_client_fullscreen(ec, e_config->fullscreen_policy);
468         else if (!strcmp(params, "resize"))
469           e_client_fullscreen(ec, E_FULLSCREEN_RESIZE);
470         else if (!strcmp(params, "zoom"))
471           e_client_fullscreen(ec, E_FULLSCREEN_ZOOM);
472      }
473 }
474 
475 /***************************************************************************/
476 ACT_FN_GO(window_fullscreen, )
477 {
478    if ((!obj) || (obj->type != E_CLIENT_TYPE))
479      obj = E_OBJECT(e_client_focused_get());
480    if (!obj) return;
481    if (!((E_Client *)(void *)obj)->lock_user_fullscreen)
482      {
483         E_Client *ec;
484 
485         ec = (E_Client *)(void *)obj;
486         if (params)
487           {
488              int v;
489              char buf[32];
490 
491              buf[0] = 0;
492              if (sscanf(params, "%i %20s", &v, buf) == 2)
493                {
494                   if (v == 1)
495                     {
496                        if (*buf == '\0')
497                          e_client_fullscreen(ec, e_config->fullscreen_policy);
498                        else if (!strcmp(buf, "resize"))
499                          e_client_fullscreen(ec, E_FULLSCREEN_RESIZE);
500                        else if (!strcmp(buf, "zoom"))
501                          e_client_fullscreen(ec, E_FULLSCREEN_ZOOM);
502                     }
503                   else if (v == 0)
504                     e_client_unfullscreen(ec);
505                }
506           }
507      }
508 }
509 
510 /***************************************************************************/
511 ACT_FN_GO(window_maximized_toggle, )
512 {
513    E_Client *ec;
514    Eina_Bool resize = EINA_FALSE;
515 
516    if ((!obj) || (obj->type != E_CLIENT_TYPE))
517      obj = E_OBJECT(e_client_focused_get());
518    if (!obj) return;
519    ec = (E_Client *)(void *)obj;
520 
521    /* internal dialog which is resizable */
522    if (ec->internal && (ec->netwm.type == E_WINDOW_TYPE_DIALOG))
523      resize = (ec->icccm.max_w != ec->icccm.min_w);
524    if ((!ec->lock_user_maximize) && (!ec->fullscreen) &&
525        (resize || (ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
526         (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN)))
527      {
528         if ((ec->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
529           {
530              if (!params)
531                e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
532              else
533                {
534                   E_Maximize max;
535 
536                   max = _e_actions_maximize_parse(params);
537                   max &= E_MAXIMIZE_DIRECTION;
538                   if (max == E_MAXIMIZE_VERTICAL)
539                     {
540                        if (ec->maximized & E_MAXIMIZE_VERTICAL)
541                          e_client_unmaximize(ec, E_MAXIMIZE_VERTICAL);
542                        else
543                          goto maximize;
544                     }
545                   else if (max == E_MAXIMIZE_HORIZONTAL)
546                     {
547                        if (ec->maximized & E_MAXIMIZE_HORIZONTAL)
548                          e_client_unmaximize(ec, E_MAXIMIZE_HORIZONTAL);
549                        else
550                          goto maximize;
551                     }
552                   else if (max == E_MAXIMIZE_LEFT)
553                     {
554                        if (ec->maximized & E_MAXIMIZE_LEFT)
555                          e_client_unmaximize(ec, E_MAXIMIZE_LEFT);
556                        else
557                          goto maximize;
558                     }
559                   else if (max == E_MAXIMIZE_RIGHT)
560                     {
561                        if (ec->maximized & E_MAXIMIZE_RIGHT)
562                          e_client_unmaximize(ec, E_MAXIMIZE_RIGHT);
563                        else
564                          goto maximize;
565                     }
566                   else
567                     e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
568                }
569           }
570         else
571           {
572 maximize:
573              e_client_maximize(ec, _e_actions_maximize_parse(params));
574           }
575      }
576 }
577 /***************************************************************************/
578 ACT_FN_GO(window_maximized, )
579 {
580    if ((!obj) || (obj->type != E_CLIENT_TYPE))
581      obj = E_OBJECT(e_client_focused_get());
582    if (!obj) return;
583    if (!((E_Client *)(void *)obj)->lock_user_maximize)
584      {
585         E_Client *ec;
586 
587         ec = (E_Client *)(void *)obj;
588         if (params)
589           {
590              E_Maximize max;
591              int v, ret;
592              char s1[32], s2[32];
593 
594              max = (e_config->maximize_policy & E_MAXIMIZE_DIRECTION);
595              ret = sscanf(params, "%i %20s %20s", &v, s1, s2);
596              if (ret == 3)
597                {
598                   if (!strcmp(s2, "horizontal"))
599                     max = E_MAXIMIZE_HORIZONTAL;
600                   else if (!strcmp(s2, "vertical"))
601                     max = E_MAXIMIZE_VERTICAL;
602                   else if (!strcmp(s2, "left"))
603                     max = E_MAXIMIZE_LEFT;
604                   else if (!strcmp(s2, "right"))
605                     max = E_MAXIMIZE_RIGHT;
606                   else
607                     max = E_MAXIMIZE_BOTH;
608                }
609              if (ret > 1)
610                {
611                   if (v == 1)
612                     {
613                        if (!strcmp(s1, "fullscreen"))
614                          e_client_maximize(ec, E_MAXIMIZE_FULLSCREEN | max);
615                        else if (!strcmp(s1, "smart"))
616                          e_client_maximize(ec, E_MAXIMIZE_SMART | max);
617                        else if (!strcmp(s1, "expand"))
618                          e_client_maximize(ec, E_MAXIMIZE_EXPAND | max);
619                        else if (!strcmp(s1, "fill"))
620                          e_client_maximize(ec, E_MAXIMIZE_FILL | max);
621                        else
622                          e_client_maximize(ec, (e_config->maximize_policy & E_MAXIMIZE_TYPE) | max);
623                     }
624                   else if (v == 0)
625                     e_client_unmaximize(ec, max);
626                }
627           }
628      }
629 }
630 
631 /***************************************************************************/
632 ACT_FN_GO(window_shaded_toggle, )
633 {
634    if ((!obj) || (obj->type != E_CLIENT_TYPE))
635      obj = E_OBJECT(e_client_focused_get());
636    if (!obj) return;
637    if (!((E_Client *)(void *)obj)->lock_user_shade)
638      {
639         E_Client *ec;
640 
641         ec = (E_Client *)(void *)obj;
642         if (ec->shaded)
643           {
644              if (!params)
645                e_client_unshade(ec, E_DIRECTION_UP);
646              else
647                {
648                   if (!strcmp(params, "up"))
649                     e_client_unshade(ec, E_DIRECTION_UP);
650                   else if (!strcmp(params, "down"))
651                     e_client_unshade(ec, E_DIRECTION_DOWN);
652                   else if (!strcmp(params, "left"))
653                     e_client_unshade(ec, E_DIRECTION_LEFT);
654                   else if (!strcmp(params, "right"))
655                     e_client_unshade(ec, E_DIRECTION_RIGHT);
656                   else
657                     e_client_unshade(ec, E_DIRECTION_UP);
658                }
659           }
660         else
661           {
662              if (!params)
663                e_client_shade(ec, E_DIRECTION_UP);
664              else
665                {
666                   if (!strcmp(params, "up"))
667                     e_client_shade(ec, E_DIRECTION_UP);
668                   else if (!strcmp(params, "down"))
669                     e_client_shade(ec, E_DIRECTION_DOWN);
670                   else if (!strcmp(params, "left"))
671                     e_client_shade(ec, E_DIRECTION_LEFT);
672                   else if (!strcmp(params, "right"))
673                     e_client_shade(ec, E_DIRECTION_RIGHT);
674                   else
675                     e_client_shade(ec, E_DIRECTION_UP);
676                }
677           }
678      }
679 }
680 
681 /***************************************************************************/
682 ACT_FN_GO(window_shaded, )
683 {
684    if ((!obj) || (obj->type != E_CLIENT_TYPE))
685      obj = E_OBJECT(e_client_focused_get());
686    if (!obj) return;
687    if (!((E_Client *)(void *)obj)->lock_user_shade)
688      {
689         E_Client *ec;
690 
691         ec = (E_Client *)(void *)obj;
692         if (!e_comp_object_frame_allowed(ec->frame)) return;
693         if (params)
694           {
695              int v;
696              char buf[32];
697 
698              if (sscanf(params, "%i %20s", &v, buf) == 2)
699                {
700                   if (v == 1)
701                     {
702                        if (!strcmp(buf, "up"))
703                          e_client_shade(ec, E_DIRECTION_UP);
704                        else if (!strcmp(buf, "down"))
705                          e_client_shade(ec, E_DIRECTION_DOWN);
706                        else if (!strcmp(buf, "left"))
707                          e_client_shade(ec, E_DIRECTION_LEFT);
708                        else if (!strcmp(buf, "right"))
709                          e_client_shade(ec, E_DIRECTION_RIGHT);
710                     }
711                   else if (v == 0)
712                     {
713                        if (!strcmp(buf, "up"))
714                          e_client_unshade(ec, E_DIRECTION_UP);
715                        else if (!strcmp(buf, "down"))
716                          e_client_unshade(ec, E_DIRECTION_DOWN);
717                        else if (!strcmp(buf, "left"))
718                          e_client_unshade(ec, E_DIRECTION_LEFT);
719                        else if (!strcmp(buf, "right"))
720                          e_client_unshade(ec, E_DIRECTION_RIGHT);
721                     }
722                }
723           }
724      }
725 }
726 
727 /***************************************************************************/
ACT_FN_GO(window_borderless_toggle,EINA_UNUSED)728 ACT_FN_GO(window_borderless_toggle, EINA_UNUSED)
729 {
730    if ((!obj) || (obj->type != E_CLIENT_TYPE))
731      obj = E_OBJECT(e_client_focused_get());
732    if (!obj) return;
733    if (!((E_Client *)(void *)obj)->lock_border)
734      {
735         E_Client *ec;
736 
737         ec = (E_Client *)(void *)obj;
738         if (!e_comp_object_frame_allowed(ec->frame)) return;
739         ec->borderless = !ec->borderless;
740 
741         ec->border.changed = 1;
742         EC_CHANGED(ec);
743      }
744 }
745 
746 /***************************************************************************/
ACT_FN_GO(window_border_set,EINA_UNUSED)747 ACT_FN_GO(window_border_set, EINA_UNUSED)
748 {
749    if ((!obj) || (obj->type != E_CLIENT_TYPE))
750      obj = E_OBJECT(e_client_focused_get());
751    if (!obj) return;
752    if (!((E_Client *)(void *)obj)->lock_border)
753      {
754         E_Client *ec;
755 
756         ec = (E_Client *)(void *)obj;
757         if (!e_comp_object_frame_allowed(ec->frame)) return;
758         if (ec && params)
759           {
760              eina_stringshare_replace(&ec->bordername, params);
761              ec->border.changed = 1;
762              EC_CHANGED(ec);
763           }
764      }
765 }
766 
767 /***************************************************************************/
ACT_FN_GO(window_border_cycle,EINA_UNUSED)768 ACT_FN_GO(window_border_cycle, EINA_UNUSED)
769 {
770    if ((!obj) || (obj->type != E_CLIENT_TYPE))
771      obj = E_OBJECT(e_client_focused_get());
772    if (!obj) return;
773    if (!((E_Client *)(void *)obj)->lock_border)
774      {
775         E_Client *ec;
776 
777         ec = (E_Client *)(void *)obj;
778         if (!e_comp_object_frame_allowed(ec->frame)) return;
779         if (ec && params)
780           {
781              const char *space;
782 
783              while (*params == ' ')
784                params++;
785 
786              if (ec->bordername)
787                {
788                   const char *bdname = params;
789 
790                   while ((space = strchr(bdname, ' ')))
791                     {
792                        if (strncmp(ec->bordername, bdname, space - bdname) == 0)
793                          {
794                             bdname = space + 1;
795                             while (*bdname == ' ')
796                               bdname++;
797                             space = strchr(bdname, ' ');
798                             if (space)
799                               eina_stringshare_replace_length(
800                                 &ec->bordername,
801                                 bdname, space - bdname);
802                             else
803                               eina_stringshare_replace(&ec->bordername, bdname);
804                             ec->border.changed = 1;
805                             EC_CHANGED(ec);
806                             return;
807                          }
808                        bdname = space + 1;
809                        while (*bdname == ' ')
810                          bdname++;
811                     }
812                }
813 
814              space = strchr(params, ' ');
815              if (space)
816                eina_stringshare_replace_length(&ec->bordername,
817                                                params, space - params);
818              else
819                eina_stringshare_replace(&ec->bordername, params);
820              ec->border.changed = 1;
821              EC_CHANGED(ec);
822           }
823      }
824 }
825 
826 /***************************************************************************/
ACT_FN_GO(window_pinned_toggle,EINA_UNUSED)827 ACT_FN_GO(window_pinned_toggle, EINA_UNUSED)
828 {
829    if ((!obj) || (obj->type != E_CLIENT_TYPE))
830      obj = E_OBJECT(e_client_focused_get());
831    if (!obj) return;
832    if (!((E_Client *)(void *)obj)->lock_border)
833      {
834         E_Client *ec;
835 
836         ec = (E_Client *)(void *)obj;
837         if ((ec->netwm.state.stacking == E_STACKING_BELOW) &&
838             (ec->user_skip_winlist) && (ec->borderless))
839           e_client_pinned_set(ec, 0);
840         else
841           e_client_pinned_set(ec, 1);
842      }
843 }
844 
845 /***************************************************************************/
846 ACT_FN_GO(window_move_by, )
847 {
848    if ((!obj) || (obj->type != E_CLIENT_TYPE))
849      obj = E_OBJECT(e_client_focused_get());
850    if (!obj) return;
851    if (obj->type != E_CLIENT_TYPE)
852      {
853         obj = E_OBJECT(e_client_focused_get());
854         if (!obj) return;
855      }
856    if (params)
857      {
858         int dx, dy;
859 
860         if (sscanf(params, "%i %i", &dx, &dy) == 2)
861           {
862              E_Client *ec;
863 
864              ec = (E_Client *)(void *)obj;
865              evas_object_move(ec->frame, ec->x + dx, ec->y + dy);
866 
867              if (!e_client_focus_policy_click(ec))
868                e_client_pointer_warp_to_center_now(ec);
869           }
870      }
871 }
872 
873 /***************************************************************************/
874 ACT_FN_GO(window_move_to, )
875 {
876    if ((!obj) || (obj->type != E_CLIENT_TYPE))
877      obj = E_OBJECT(e_client_focused_get());
878    if (!obj) return;
879    if (params)
880      {
881         E_Client *ec;
882         int x, y, zx, zy, zw, zh;
883         char cx, cy;
884 
885         ec = (E_Client *)(void *)obj;
886         e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
887 
888         if (sscanf(params, "%c%i %c%i", &cx, &x, &cy, &y) == 4)
889           {
890              x += zx;
891              y += zy;
892           }
893         else if (sscanf(params, "* %c%i", &cy, &y) == 2)
894           {
895              /* Updated y, keep x. */
896              y += zy;
897              x = ec->x;
898              cx = 0;
899           }
900         else if (sscanf(params, "%c%i *", &cx, &x) == 2)
901           {
902              /* Updated x, keep y. */
903              x += zx;
904              y = ec->y;
905              cy = 0;
906           }
907         else return;
908 
909         if (cx == '-') x = zw - ec->w - x + 2 * zx;  /* compensate x with zx */
910         if (cy == '-') y = zh - ec->h - y + 2 * zy;  /* compensate y with zy */
911 
912         if ((x != ec->x) || (y != ec->y))
913           {
914              evas_object_move(ec->frame, x, y);
915 
916              if (!e_client_focus_policy_click(ec))
917                e_client_pointer_warp_to_center_now(ec);
918           }
919      }
920 }
921 
922 
923 /***************************************************************************/
924 ACT_FN_GO(window_quick_tile_to_quadrant, )
925 {
926    E_Client *ec;
927    int x, y, zx, zy, zw, zh;
928 
929    if ((!obj) || (obj->type != E_CLIENT_TYPE))
930       obj = E_OBJECT(e_client_focused_get());
931    if (!obj) return;
932 
933    ec = (E_Client *)(void *)obj;
934    if((ec->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
935       e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
936    e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
937 
938    if (params)
939      {
940         if (strcmp(params, "upper_left") == 0)
941           {
942              x = zx;
943              y = zy;
944           }
945         else if (strcmp(params, "upper_right") == 0)
946           {
947              x = zx + (zw / 2);
948              y = zy;
949           }
950         else if (strcmp(params, "lower_left") == 0)
951           {
952              x = zx;
953              y = zy + (zh / 2);
954           }
955         else if (strcmp(params, "lower_right") == 0)
956           {
957              x = zx + (zw / 2);
958              y = zy + (zh / 2);
959           }
960         else
961           return;
962 
963         evas_object_geometry_set(ec->frame, x, y, zw / 2, zh / 2);
964      }
965 }
966 
967 
968 /***************************************************************************/
ACT_FN_GO(window_move_to_center,EINA_UNUSED)969 ACT_FN_GO(window_move_to_center, EINA_UNUSED)
970 {
971    E_Client *ec;
972 
973    if ((!obj) || (obj->type != E_CLIENT_TYPE))
974      obj = E_OBJECT(e_client_focused_get());
975    if (!obj) return;
976 
977    ec = (E_Client *)(void *)obj;
978    e_comp_object_util_center(ec->frame);
979 
980    if (!e_client_focus_policy_click(ec))
981      e_client_pointer_warp_to_center_now(ec);
982 }
983 
984 /***************************************************************************/
985 ACT_FN_GO(window_resize_by, )
986 {
987    if ((!obj) || (obj->type != E_CLIENT_TYPE))
988      obj = E_OBJECT(e_client_focused_get());
989    if (!obj) return;
990 
991    if (params)
992      {
993         int dw, dh;
994 
995         if (sscanf(params, "%i %i", &dw, &dh) == 2)
996           {
997              E_Client *ec;
998 
999              ec = (E_Client *)(void *)obj;
1000 
1001              dw += ec->w;
1002              dh += ec->h;
1003              e_client_resize_limit(ec, &dw, &dh);
1004              evas_object_resize(ec->frame, dw, dh);
1005 
1006              if (!e_client_focus_policy_click(ec))
1007                e_client_pointer_warp_to_center_now(ec);
1008           }
1009      }
1010 }
1011 
1012 /***************************************************************************/
1013 ACT_FN_GO(window_push, )
1014 {
1015    if ((!obj) || (obj->type != E_CLIENT_TYPE))
1016      obj = E_OBJECT(e_client_focused_get());
1017    if (!obj) return;
1018 
1019    if (params)
1020      {
1021         E_Client *ec, *cur;
1022         E_Desk *desk_current;
1023         int hdir, vdir;
1024         int x, y, zx, zy, zw, zh;
1025 
1026         if (strcmp(params, "left") == 0)
1027           {
1028              hdir = -1;
1029              vdir = 0;
1030           }
1031         else if (strcmp(params, "right") == 0)
1032           {
1033              hdir = +1;
1034              vdir = 0;
1035           }
1036         else if (strcmp(params, "up") == 0)
1037           {
1038              hdir = 0;
1039              vdir = -1;
1040           }
1041         else if (strcmp(params, "down") == 0)
1042           {
1043              hdir = 0;
1044              vdir = +1;
1045           }
1046         else if (strcmp(params, "up-left") == 0)
1047           {
1048              hdir = -1;
1049              vdir = -1;
1050           }
1051         else if (strcmp(params, "up-right") == 0)
1052           {
1053              hdir = +1;
1054              vdir = -1;
1055           }
1056         else if (strcmp(params, "down-left") == 0)
1057           {
1058              hdir = -1;
1059              vdir = +1;
1060           }
1061         else if (strcmp(params, "down-right") == 0)
1062           {
1063              hdir = +1;
1064              vdir = +1;
1065           }
1066         else
1067           return;
1068 
1069         ec = (E_Client *)(void *)obj;
1070         e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
1071 
1072         if (hdir < 0) x = zx;
1073         else if (hdir > 0)
1074           x = zx + zw - ec->w;
1075         else x = ec->x;
1076 
1077         if (vdir < 0) y = zy;
1078         else if (vdir > 0)
1079           y = zy + zh - ec->h;
1080         else y = ec->y;
1081 
1082         desk_current = e_desk_current_get(ec->zone);
1083 
E_CLIENT_FOREACH(cur)1084         E_CLIENT_FOREACH(cur)
1085           {
1086              if (((cur->desk == desk_current) || (cur->sticky)) && (ec != cur) && (!cur->iconic))
1087                {
1088                   if ((hdir < 0)
1089                       && (cur->x + cur->w < ec->x)
1090                       && (E_SPANS_COMMON(ec->y, ec->h, cur->y, cur->h)))
1091                     x = MAX(x, cur->x + cur->w);
1092                   else if ((hdir > 0)
1093                            && (cur->x > ec->x + ec->w)
1094                            && (E_SPANS_COMMON(ec->y, ec->h, cur->y, cur->h)))
1095                     x = MIN(x, zx + cur->x - ec->w);
1096 
1097                   if ((vdir < 0)
1098                       && (cur->y + cur->h < ec->y)
1099                       && (E_SPANS_COMMON(ec->x, ec->w, cur->x, cur->w)))
1100                     y = MAX(y, cur->y + cur->h);
1101                   else if ((vdir > 0)
1102                            && (cur->y > ec->y + ec->h)
1103                            && (E_SPANS_COMMON(ec->x, ec->w, cur->x, cur->w)))
1104                     y = MIN(y, zy + cur->y - ec->h);
1105                }
1106           }
1107 
1108         if ((x != ec->x) || (y != ec->y))
1109           {
1110              evas_object_move(ec->frame, x, y);
1111              if (!e_client_focus_policy_click(ec))
1112                e_client_pointer_warp_to_center_now(ec);
1113           }
1114      }
1115 }
1116 
1117 /*
1118  * These actions jump to a window with the given name. It uses the last focused
1119  * window it finds (going through e_client_focus_stack_get), so the name should
1120  * be unique, if you want to jump to a specific window.
1121  *
1122  */
1123 static int
window_jump_to(const char * params)1124 window_jump_to(const char *params)
1125 {
1126    Eina_List *l, *ll;
1127    E_Zone *current_zone;
1128    E_Client *ec;
1129 
1130    if (!params) return 0;
1131 
1132    /* Go through the list of all windows (that's what the focus stack is used for) */
1133    l = e_client_focus_stack_get();
1134    /* If we can start at the second window, we start there in order to cycle.
1135     * If not, there is only one window, so let's use it */
1136    if (eina_list_next(l))
1137      l = l->next;
1138    EINA_LIST_FOREACH(l, ll, ec)
1139      {
1140         if (!ec->icccm.name) continue;
1141         if (strcasecmp(ec->icccm.name, params)) continue;
1142         /* Jump to the screen the window is on if it isn't on the current screen but
1143          * only if we don't have to warp the pointer anyway */
1144         current_zone = e_zone_current_get();
1145 
1146         /* Change the virtual desktop if the window isn't on the current virtual desktop */
1147         e_desk_show(ec->desk);
1148 
1149         /* A minimized window won't be focusable for key input, un-minimize it */
1150         if (!ec->lock_user_iconify)
1151           e_client_uniconify(ec);
1152 
1153 
1154         evas_object_raise(ec->frame);
1155         if (ec->zone != current_zone)
1156           {
1157              if (!e_client_focus_policy_click(ec))
1158                e_client_pointer_warp_to_center_now(ec);
1159           }
1160         evas_object_focus_set(ec->frame, 1);
1161         return 1;
1162      }
1163    return 0;
1164 }
1165 
1166 ACT_FN_GO(window_jump_to, )
1167 {
1168    window_jump_to(params);
1169 }
1170 
1171 ACT_FN_GO(window_jump_to_or_start, )
1172 {
1173    char *window_name, *start_name;
1174    if (!params) return;
1175 
1176    window_name = strdup(params);
1177    start_name = window_name;
1178    start_name = strchr(window_name, ' ');
1179    if (start_name)
1180      {
1181         start_name[0] = 0;
1182         start_name++;
1183      }
1184    else
1185      {
1186         /* The user just specified one parameter, just call window_jump_to */
1187         window_jump_to(window_name);
1188         free(window_name);
1189         return;
1190      }
1191 
1192    /* If we cannot jump to the specified window... */
1193    if (!window_jump_to(window_name))
1194      {
1195         /* ...start application by calling "exec" action */
1196         _e_actions_act_exec_go(obj, start_name);
1197      }
1198    free(window_name);
1199 }
1200 
1201 /***************************************************************************/
ACT_FN_GO(window_drag_icon,EINA_UNUSED)1202 ACT_FN_GO(window_drag_icon, EINA_UNUSED)
1203 {
1204    if ((!obj) || (obj->type != E_CLIENT_TYPE))
1205      obj = E_OBJECT(e_client_focused_get());
1206    if (!obj) return;
1207    {
1208       E_Client *ec;
1209 
1210       ec = (E_Client *)(void *)obj;
1211       ec->drag.start = 1;
1212       ec->drag.x = -1;
1213       ec->drag.y = -1;
1214    }
1215 }
1216 
1217 /***************************************************************************/
1218 ACT_FN_GO(window_desk_move_by, )
1219 {
1220    E_Client *ec;
1221    int x, y;
1222 
1223    if (!params) return;
1224    if ((!obj) || (obj->type != E_CLIENT_TYPE))
1225      obj = E_OBJECT(e_client_focused_get());
1226    if (!obj)
1227      obj = E_OBJECT(e_client_action_get());
1228    if (!obj) return;
1229 
1230    ec = (E_Client *)(void *)obj;
1231    if ((!ec->zone) || (!ec->desk)) return;
1232    if (sscanf(params, "%d %d", &x, &y) == 2)
1233      {
1234         E_Desk *desk;
1235         int dx, dy;
1236         int to_x = 0, to_y = 0;
1237 
1238         e_desk_xy_get(ec->desk, &dx, &dy);
1239 
1240         to_x = dx + x;
1241         to_y = dy + y;
1242         while (!(desk = e_desk_at_xy_get(ec->zone, to_x, to_y)))
1243           {
1244              /* here we are out of our desktop range */
1245              while (to_x >= ec->zone->desk_x_count)
1246                {
1247                   to_x -= ec->zone->desk_x_count;
1248                   to_y++;
1249                }
1250              while (to_x < 0)
1251                {
1252                   to_x += ec->zone->desk_x_count;
1253                   to_y--;
1254                }
1255 
1256              while (to_y >= ec->zone->desk_y_count)
1257                to_y -= ec->zone->desk_y_count;
1258              while (to_y < 0)
1259                to_y += ec->zone->desk_y_count;
1260           }
1261 
1262         if (desk)
1263           {
1264              /* send the border to the required desktop. */
1265              e_client_desk_set(ec, desk);
1266              /* switch desktop. Quite useful from the interface point of view. */
1267              e_zone_desk_flip_by(ec->zone, to_x - dx, to_y - dy);
1268              if (!ec->lock_user_stacking)
1269                evas_object_raise(ec->frame);
1270           }
1271      }
1272 }
1273 
1274 /***************************************************************************/
1275 ACT_FN_GO(window_zone_move_by, )
1276 {
1277    E_Client *ec;
1278    E_Zone *zone;
1279    E_Maximize max;
1280    int move;
1281    char *end;
1282    E_Fullscreen fs;
1283    Eina_Bool fullscreen;
1284 
1285    if (!params) return;
1286    if ((!obj) || (obj->type != E_CLIENT_TYPE))
1287      obj = E_OBJECT(e_client_focused_get());
1288    if (!obj)
1289      obj = E_OBJECT(e_client_action_get());
1290    if (!obj) return;
1291 
1292    ec = (E_Client *)(void *)obj;
1293    /* bad */
1294    if (!ec->zone) return;
1295    /* only one screen */
1296    if (eina_list_count(e_comp->zones) < 2) return;
1297    errno = 0;
1298    move = strtol(params, &end, 10);
1299    if ((!end) || end[0] || errno) return;
1300    move += ec->zone->num;
1301    if (move < 0)
1302      move = eina_list_count(e_comp->zones) - 1;
1303    else if ((unsigned int)move >= eina_list_count(e_comp->zones))
1304      move = 0;
1305    zone = e_comp_zone_number_get(move);
1306    if (!zone) return;
1307    if (ec->zone == zone) return;
1308    max = ec->maximized;
1309    fs = ec->fullscreen_policy;
1310    fullscreen = ec->fullscreen;
1311    if (ec->maximized) e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
1312    if (fullscreen) e_client_unfullscreen(ec);
1313    e_client_zone_set(ec, zone);
1314    if (max) e_client_maximize(ec, max);
1315    if (fullscreen) e_client_fullscreen(ec, fs);
1316    e_client_focus_set_with_pointer(ec);
1317 }
1318 
1319 /***************************************************************************/
1320 ACT_FN_GO(window_desk_move_to, )
1321 {
1322    E_Client *ec;
1323    int x, y;
1324 
1325    if (!params) return;
1326    if ((!obj) || (obj->type != E_CLIENT_TYPE))
1327      obj = E_OBJECT(e_client_focused_get());
1328    if (!obj)
1329      obj = E_OBJECT(e_client_action_get());
1330    if (!obj) return;
1331 
1332    ec = (E_Client *)(void *)obj;
1333    if ((!ec->zone) || (!ec->desk)) return;
1334    if (sscanf(params, "%d %d", &x, &y) == 2)
1335      {
1336         E_Desk *desk;
1337         E_Desk *old_desk = ec->desk;
1338         Eina_Bool was_focused = e_client_stack_focused_get(ec);
1339 
1340         desk = e_desk_at_xy_get(ec->zone, x, y);
1341         if ((desk) && (desk != old_desk))
1342           {
1343              e_client_desk_set(ec, desk);
1344              if (was_focused)
1345                e_desk_last_focused_focus(old_desk);
1346           }
1347      }
1348 }
1349 
1350 /***************************************************************************/
1351 static E_Zone *
_e_actions_zone_get(E_Object * obj)1352 _e_actions_zone_get(E_Object *obj)
1353 {
1354    if (obj)
1355      {
1356         if (obj->type == (int)E_COMP_TYPE)
1357           return e_zone_current_get();
1358         else if (obj->type == (int)E_ZONE_TYPE)
1359           return (void *)obj;
1360         else if (obj->type == (int)E_CLIENT_TYPE)
1361           return ((E_Client *)(void *)obj)->zone;
1362         else if (obj->type == (int)E_SHELF_TYPE)
1363           return ((E_Shelf *)(void *)obj)->zone;
1364         else if (e_obj_is_win(obj))
1365           return e_win_client_get((void*)obj)->zone;
1366      }
1367    return e_zone_current_get();
1368 }
1369 
1370 ACT_FN_GO(desk_flip_by, )
1371 {
1372    E_Zone *zone;
1373 
1374    zone = _e_actions_zone_get(obj);
1375    if (zone)
1376      {
1377         if (params)
1378           {
1379              int dx = 0, dy = 0;
1380 
1381              if (sscanf(params, "%i %i", &dx, &dy) == 2)
1382                e_zone_desk_flip_by(zone, dx, dy);
1383           }
1384      }
1385 }
1386 
1387 /***************************************************************************/
1388 ACT_FN_GO(desk_flip_to, )
1389 {
1390    E_Zone *zone;
1391 
1392    zone = _e_actions_zone_get(obj);
1393    if (zone)
1394      {
1395         if (params)
1396           {
1397              int dx = 0, dy = 0;
1398 
1399              if (sscanf(params, "%i %i", &dx, &dy) == 2)
1400                e_zone_desk_flip_to(zone, dx, dy);
1401           }
1402      }
1403 }
1404 
1405 /***************************************************************************/
ACT_FN_GO(desk_flip_prev,EINA_UNUSED)1406 ACT_FN_GO(desk_flip_prev, EINA_UNUSED)
1407 {
1408    E_Zone *zone;
1409 
1410    zone = _e_actions_zone_get(obj);
1411    if (!zone) return;
1412    e_zone_desk_flip_to(zone, zone->desk_x_prev, zone->desk_y_prev);
1413 }
1414 
1415 /***************************************************************************/
1416 #define ACT_FLIP_LEFT(zone)       ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0))
1417 #define ACT_FLIP_RIGHT(zone)      ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || (((zone)->desk_x_current + 1) < (zone)->desk_x_count))
1418 #define ACT_FLIP_UP(zone)         ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0))
1419 #define ACT_FLIP_DOWN(zone)       ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || (((zone)->desk_y_current + 1) < (zone)->desk_y_count))
1420 #define ACT_FLIP_UP_LEFT(zone)    ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || (((zone)->desk_x_current > 0) && ((zone)->desk_y_current > 0)))
1421 #define ACT_FLIP_UP_RIGHT(zone)   ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || ((((zone)->desk_x_current + 1) < (zone)->desk_x_count) && ((zone)->desk_y_current > 0)))
1422 #define ACT_FLIP_DOWN_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || ((((zone)->desk_x_current + 1) < (zone)->desk_x_count) && (((zone)->desk_y_current + 1) < (zone)->desk_y_count)))
1423 #define ACT_FLIP_DOWN_LEFT(zone)  ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || (((zone)->desk_x_current > 0) && (((zone)->desk_y_current + 1) < (zone)->desk_y_count)))
1424 
1425 ACT_FN_GO_EDGE(desk_flip_in_direction, )
1426 {
1427    E_Zone *zone;
1428    E_Desk *current = NULL;
1429    E_Event_Pointer_Warp *wev;
1430    int x, y, offset = 25;
1431 
1432    if (!ev) return;  // with flip on _e_zone_cb_edge_timer we don't have ev!!!
1433    if (e_client_action_get() && e_client_util_resizing_get(e_client_action_get())) return;
1434    zone = _e_actions_zone_get(obj);
1435    if (!zone) return;
1436    wev = E_NEW(E_Event_Pointer_Warp, 1);
1437    if (!wev) return;
1438    ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
1439    wev->prev.x = x;
1440    wev->prev.y = y;
1441    if (params)
1442      {
1443         if (sscanf(params, "%i", &offset) != 1)
1444           offset = 25;
1445      }
1446    switch (ev->edge)
1447      {
1448       case E_ZONE_EDGE_LEFT:
1449         if (ACT_FLIP_LEFT(zone))
1450           {
1451              e_zone_desk_flip_by(zone, -1, 0);
1452              ecore_evas_pointer_warp(e_comp->ee, zone->x + zone->w - offset, y);
1453              wev->curr.y = y;
1454              wev->curr.x = zone->w - offset;
1455           }
1456         break;
1457 
1458       case E_ZONE_EDGE_RIGHT:
1459         if (ACT_FLIP_RIGHT(zone))
1460           {
1461              e_zone_desk_flip_by(zone, 1, 0);
1462              ecore_evas_pointer_warp(e_comp->ee, zone->x + offset, y);
1463              wev->curr.y = y;
1464              wev->curr.x = offset;
1465           }
1466         break;
1467 
1468       case E_ZONE_EDGE_TOP:
1469         if (ACT_FLIP_UP(zone))
1470           {
1471              e_zone_desk_flip_by(zone, 0, -1);
1472              ecore_evas_pointer_warp(e_comp->ee, x, zone->y + zone->h - offset);
1473              wev->curr.x = x;
1474              wev->curr.y = zone->h - offset;
1475           }
1476         break;
1477 
1478       case E_ZONE_EDGE_BOTTOM:
1479         if (ACT_FLIP_DOWN(zone))
1480           {
1481              e_zone_desk_flip_by(zone, 0, 1);
1482              ecore_evas_pointer_warp(e_comp->ee, x, zone->y + offset);
1483              wev->curr.x = x;
1484              wev->curr.y = offset;
1485           }
1486         break;
1487 
1488       case E_ZONE_EDGE_TOP_LEFT:
1489         if (ACT_FLIP_UP_LEFT(zone))
1490           {
1491              e_zone_desk_flip_by(zone, -1, -1);
1492              ecore_evas_pointer_warp(e_comp->ee, zone->x + zone->w - offset, zone->y + zone->h - offset);
1493              wev->curr.x = zone->w - offset;
1494              wev->curr.y = zone->h - offset;
1495           }
1496         break;
1497 
1498       case E_ZONE_EDGE_TOP_RIGHT:
1499         if (ACT_FLIP_UP_RIGHT(zone))
1500           {
1501              e_zone_desk_flip_by(zone, 1, -1);
1502              ecore_evas_pointer_warp(e_comp->ee, zone->x + offset, zone->y + zone->h - offset);
1503              wev->curr.x = offset;
1504              wev->curr.y = zone->h - offset;
1505           }
1506         break;
1507 
1508       case E_ZONE_EDGE_BOTTOM_LEFT:
1509         if (ACT_FLIP_DOWN_LEFT(zone))
1510           {
1511              e_zone_desk_flip_by(zone, -1, 1);
1512              ecore_evas_pointer_warp(e_comp->ee, zone->x + zone->w - offset, zone->y + offset);
1513              wev->curr.y = offset;
1514              wev->curr.x = zone->w - offset;
1515           }
1516         break;
1517 
1518       case E_ZONE_EDGE_BOTTOM_RIGHT:
1519         if (ACT_FLIP_DOWN_RIGHT(zone))
1520           {
1521              e_zone_desk_flip_by(zone, 1, 1);
1522              ecore_evas_pointer_warp(e_comp->ee, zone->x + offset, zone->y + offset);
1523              wev->curr.y = offset;
1524              wev->curr.x = offset;
1525           }
1526         break;
1527 
1528       default:
1529         break;
1530      }
1531 
1532    current = e_desk_current_get(zone);
1533    if (current)
1534      ecore_event_add(E_EVENT_POINTER_WARP, wev, NULL, NULL);
1535    else
1536      free(wev);
1537 }
1538 
1539 /***************************************************************************/
1540 ACT_FN_GO(desk_linear_flip_by, )
1541 {
1542    E_Zone *zone;
1543 
1544    zone = _e_actions_zone_get(obj);
1545    if (zone)
1546      {
1547         if (params)
1548           {
1549              int dx = 0;
1550 
1551              if (sscanf(params, "%i", &dx) == 1)
1552                e_zone_desk_linear_flip_by(zone, dx);
1553           }
1554      }
1555 }
1556 
1557 /***************************************************************************/
1558 ACT_FN_GO(desk_linear_flip_to, )
1559 {
1560    E_Zone *zone;
1561 
1562    zone = _e_actions_zone_get(obj);
1563    if (zone)
1564      {
1565         if (params)
1566           {
1567              int dx = 0;
1568 
1569              if (sscanf(params, "%i", &dx) == 1)
1570                e_zone_desk_linear_flip_to(zone, dx);
1571           }
1572      }
1573 }
1574 
1575 #define DESK_ACTION_ALL(zone, act) \
1576    do { \
1577      E_Zone *zone; \
1578      const Eina_List *lz; \
1579      \
1580      EINA_LIST_FOREACH(e_comp->zones, lz, zone) { \
1581         { \
1582            zone->desk_flip_sync = 1; \
1583            act; \
1584         } \
1585      } \
1586    } while (0)
1587 
1588 /***************************************************************************/
1589 ACT_FN_GO(desk_linear_flip_to_screen, )
1590 {
1591    if (params)
1592      {
1593         int dx = 0, ds = 0;
1594 
1595         if (sscanf(params, "%i %i", &dx, &ds) == 2)
1596           {
1597              int current_screen = 0;
1598 
1599              DESK_ACTION_ALL(zone,
1600                              if (current_screen == ds)
1601                                {
1602                                   e_zone_desk_linear_flip_to(zone, dx);
1603                                   break;
1604                                }
1605                              else current_screen++;
1606                             );
1607           }
1608      }
1609 }
1610 
1611 /***************************************************************************/
1612 ACT_FN_GO(desk_flip_by_all, )
1613 {
1614    if (params)
1615      {
1616         int dx = 0, dy = 0;
1617 
1618         if (sscanf(params, "%i %i", &dx, &dy) == 2)
1619           {
1620              DESK_ACTION_ALL(zone, e_zone_desk_flip_by(zone, dx, dy));
1621           }
1622      }
1623 }
1624 
1625 /***************************************************************************/
1626 ACT_FN_GO(desk_flip_to_all, )
1627 {
1628    if (params)
1629      {
1630         int dx = 0, dy = 0;
1631 
1632         if (sscanf(params, "%i %i", &dx, &dy) == 2)
1633           {
1634              DESK_ACTION_ALL(zone, e_zone_desk_flip_to(zone, dx, dy));
1635           }
1636      }
1637 }
1638 
1639 /***************************************************************************/
1640 ACT_FN_GO(desk_linear_flip_by_all, )
1641 {
1642    if (params)
1643      {
1644         int dx = 0;
1645 
1646         if (sscanf(params, "%i", &dx) == 1)
1647           {
1648              DESK_ACTION_ALL(zone, e_zone_desk_linear_flip_by(zone, dx));
1649           }
1650      }
1651 }
1652 
1653 /***************************************************************************/
1654 ACT_FN_GO(desk_linear_flip_to_all, )
1655 {
1656    if (params)
1657      {
1658         int dx = 0;
1659 
1660         if (sscanf(params, "%i", &dx) == 1)
1661           {
1662              DESK_ACTION_ALL(zone, e_zone_desk_linear_flip_to(zone, dx));
1663           }
1664      }
1665 }
1666 
1667 /***************************************************************************/
1668 ACT_FN_GO(screen_send_to, )
1669 {
1670    E_Zone *zone, *zone2;
1671    int scr;
1672 
1673    zone = _e_actions_zone_get(obj);
1674    if (!zone) zone = e_zone_current_get();
1675    if (!zone) return;
1676    if (!params) return;
1677 
1678    errno = 0;
1679    scr = strtol(params, NULL, 10);
1680    if (errno) return;
1681 
1682    if (scr != -1)
1683      scr = scr % eina_list_count(e_comp->zones);
1684    if (scr < 0) scr += eina_list_count(e_comp->zones);
1685    zone2 = e_comp_zone_number_get(scr);
1686    if ((zone2) && (zone != zone2))
1687      {
1688         ecore_evas_pointer_warp(e_comp->ee,
1689                                 zone2->x + (zone2->w / 2),
1690                                 zone2->y + (zone2->h / 2));
1691         e_desk_last_focused_focus(e_desk_current_get(zone2));
1692      }
1693 }
1694 
1695 ACT_FN_GO(screen_send_by, )
1696 {
1697    E_Zone *zone, *zone2;
1698    int scr = 0;
1699 
1700    zone = _e_actions_zone_get(obj);
1701    if (!zone) zone = e_zone_current_get();
1702    if (!zone) return;
1703    if (!params) return;
1704 
1705    errno = 0;
1706    scr = strtol(params, NULL, 10);
1707    if (errno) return;
1708    scr += zone->num;
1709    if (scr != -1)
1710      scr = scr % eina_list_count(e_comp->zones);
1711    if (scr < 0) scr += eina_list_count(e_comp->zones);
1712    zone2 = e_comp_zone_number_get(scr);
1713    if ((zone2) && (zone != zone2))
1714      {
1715         ecore_evas_pointer_warp(e_comp->ee,
1716                              zone2->x + (zone2->w / 2),
1717                              zone2->y + (zone2->h / 2));
1718         e_desk_last_focused_focus(e_desk_current_get(zone2));
1719      }
1720 }
1721 
1722 #define ZONE_DESK_ACTION(con_num, zone_num, zone, act)                    \
1723   E_Zone * zone;                                                          \
1724   if ((con_num < 0) || (zone_num < 0)) {                                  \
1725        Eina_List *l;                                           \
1726        if ((con_num >= 0) && (zone_num < 0)) /* con=1 zone=all */ {       \
1727             EINA_LIST_FOREACH(e_comp->zones, l, zone) {                     \
1728                  act;                                                     \
1729               } }                                                         \
1730        else if ((con_num < 0) && (zone_num >= 0)) /* c=all zone=1 */ {  \
1731               zone = e_comp_zone_number_get(zone_num);  \
1732               if (zone)                                           \
1733                 act;                                              \
1734                     }                                                  \
1735        else if ((con_num < 0) && (zone_num < 0)) /* c=all zone=all */ { \
1736               EINA_LIST_FOREACH(e_comp->zones, lll, zone) {         \
1737                    act;                                           \
1738                 } } }                                         \
1739   else {                                                                  \
1740        zone = e_comp_zone_number_get(zone_num);        \
1741        if (zone) act;                                                     \
1742     }
1743 
1744 /***************************************************************************/
1745 #if 0
1746 ACT_FN_GO(zone_desk_flip_by, )
1747 {
1748    if (params)
1749      {
1750         int con_num = 0, zone_num = 0;
1751         int dx = 0, dy = 0;
1752 
1753         if (sscanf(params, "%i %i %i %i", &con_num, &zone_num, &dx, &dy) == 4)
1754           ZONE_DESK_ACTION(con_num, zone_num, zone,
1755                            e_zone_desk_flip_by(zone, dx, dy));
1756      }
1757 }
1758 #endif
1759 
1760 /***************************************************************************/
1761 #if 0
1762 ACT_FN_GO(zone_desk_flip_to, )
1763 {
1764    if (params)
1765      {
1766         int con_num = 0, zone_num = 0;
1767         int dx = 0, dy = 0;
1768 
1769         if (sscanf(params, "%i %i %i %i", &con_num, &zone_num, &dx, &dy) == 4)
1770           ZONE_DESK_ACTION(con_num, zone_num, zone,
1771                            e_zone_desk_flip_to(zone, dx, dy));
1772      }
1773 }
1774 #endif
1775 
1776 /***************************************************************************/
1777 #if 0
1778 ACT_FN_GO(zone_desk_linear_flip_by, )
1779 {
1780    if (params)
1781      {
1782         int con_num = 0, zone_num = 0;
1783         int dx = 0;
1784 
1785         if (sscanf(params, "%i %i %i", &con_num, &zone_num, &dx) == 3)
1786           ZONE_DESK_ACTION(con_num, zone_num, zone,
1787                            e_zone_desk_linear_flip_by(zone, dx));
1788      }
1789 }
1790 #endif
1791 
1792 /***************************************************************************/
1793 #if 0
1794 ACT_FN_GO(zone_desk_linear_flip_to, )
1795 {
1796    if (params)
1797      {
1798         int con_num = 0, zone_num = 0;
1799         int dx = 0;
1800 
1801         if (sscanf(params, "%i %i %i", &con_num, &zone_num, &dx) == 3)
1802           ZONE_DESK_ACTION(con_num, zone_num, zone,
1803                            e_zone_desk_linear_flip_to(zone, dx));
1804      }
1805 }
1806 #endif
1807 
1808 /***************************************************************************/
1809 static void
_e_actions_cb_menu_end(void * data EINA_UNUSED,E_Menu * m)1810 _e_actions_cb_menu_end(void *data EINA_UNUSED, E_Menu *m)
1811 {
1812    e_object_del(E_OBJECT(m));
1813 }
1814 
1815 static E_Menu *
_e_actions_menu_find(const char * name)1816 _e_actions_menu_find(const char *name)
1817 {
1818    if (!strcmp(name, "main"))
1819      return e_int_menus_main_new();
1820    else if (!strcmp(name, "favorites"))
1821      return e_int_menus_favorite_apps_new();
1822    else if (!strcmp(name, "all"))
1823      return e_int_menus_all_apps_new();
1824    else if (!strcmp(name, "clients"))
1825      return e_int_menus_clients_new();
1826    else if (!strcmp(name, "lost_clients"))
1827      return e_int_menus_lost_clients_new();
1828    else if (!strcmp(name, "configuration"))
1829      return e_int_menus_config_new();
1830    return NULL;
1831 }
1832 
1833 ACT_FN_GO(menu_show, )
1834 {
1835    E_Zone *zone;
1836 
1837    /* menu is active - abort */
1838    if (e_comp_util_kbd_grabbed() || e_comp_util_mouse_grabbed()) return;
1839    zone = _e_actions_zone_get(obj);
1840    if (zone)
1841      {
1842         if (params)
1843           {
1844              E_Menu *m = NULL;
1845 
1846              m = _e_actions_menu_find(params);
1847              if (m)
1848                {
1849                   int x, y;
1850 
1851                   /* FIXME: this is a bit of a hack... setting m->c - bad hack */
1852                   m->zone = zone;
1853                   ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
1854                   e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
1855                   e_menu_activate_mouse(m, zone, x, y, 1, 1,
1856                                         E_MENU_POP_DIRECTION_AUTO, 0);
1857                }
1858           }
1859      }
1860 }
1861 
1862 ACT_FN_GO_MOUSE(menu_show, )
1863 {
1864    E_Zone *zone;
1865    E_Menu *m = NULL;
1866    int x, y;
1867 
1868    /* menu is active - abort */
1869    if (e_comp_util_kbd_grabbed() || e_comp_util_mouse_grabbed()) return EINA_TRUE;
1870    zone = _e_actions_zone_get(obj);
1871    if (!zone) return EINA_TRUE;
1872    if (!params) return EINA_TRUE;
1873    m = _e_actions_menu_find(params);
1874    if (!m) return EINA_TRUE;
1875    /* FIXME: this is a bit of a hack... setting m->zone - bad hack */
1876    m->zone = zone;
1877    x = ev->canvas.x;
1878    y = ev->canvas.y;
1879    e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
1880    e_menu_activate_mouse(m, zone, x, y, 1, 1,
1881                          E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
1882    return EINA_TRUE;
1883 }
1884 
1885 ACT_FN_GO_KEY(menu_show, , EINA_UNUSED)
1886 {
1887    E_Zone *zone;
1888 
1889    /* menu is active - abort */
1890    if (e_comp_util_kbd_grabbed() || e_comp_util_mouse_grabbed()) return;
1891    zone = _e_actions_zone_get(obj);
1892    if (zone)
1893      {
1894         if (params)
1895           {
1896              E_Menu *m = NULL;
1897 
1898              m = _e_actions_menu_find(params);
1899              if (m)
1900                {
1901                   int x, y;
1902 
1903                   /* FIXME: this is a bit of a hack... setting m->con - bad hack */
1904                   m->zone = zone;
1905                   ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
1906                   e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
1907                   e_menu_activate_key(m, zone, x, y, 1, 1,
1908                                       E_MENU_POP_DIRECTION_DOWN);
1909                }
1910           }
1911      }
1912 }
1913 
1914 ACT_FN_GO(menu_show_object,)
1915 {
1916    E_Zone *zone;
1917 
1918    /* menu is active - abort */
1919    if (e_comp_util_kbd_grabbed() || e_comp_util_mouse_grabbed()) return;
1920    zone = _e_actions_zone_get(obj);
1921    if (zone)
1922      {
1923         if (params)
1924           {
1925              E_Menu *m = NULL;
1926 
1927              m = _e_actions_menu_find(params);
1928              if (m)
1929                {
1930                   int x, y, w, h;
1931                   Eina_List *l, *ll;
1932                   Evas_Object *o;
1933 
1934                   ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
1935                   l = evas_objects_at_xy_get(e_comp->evas, x, y, 0, 0);
EINA_LIST_REVERSE_FOREACH(l,ll,o)1936                   EINA_LIST_REVERSE_FOREACH(l, ll, o)
1937                     {
1938                        if (evas_object_repeat_events_get(o) && ll->prev) continue;
1939                        evas_object_geometry_get(o, &x, &y, &w, &h);
1940                        m->zone = e_comp_object_util_zone_get(o);
1941                        e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
1942                        e_menu_activate_mouse(m, zone, x, y, w, h,
1943                                              E_MENU_POP_DIRECTION_AUTO, 0);
1944                        break;
1945                     }
1946                   eina_list_free(l);
1947                }
1948           }
1949      }
1950 }
1951 
1952 /***************************************************************************/
1953 ACT_FN_GO(exec, )
1954 {
1955    E_Zone *zone;
1956    static double lock;
1957    double test;
1958 
1959    /* prevent exec actions from occurring too frequently */
1960    test = ecore_loop_time_get();
1961    if (test - lock < 0.05)
1962      {
1963         lock = test;
1964         return;
1965      }
1966    lock = ecore_loop_time_get();
1967    zone = _e_actions_zone_get(obj);
1968    if (zone)
1969      {
1970         if (params)
1971           e_exec(zone, NULL, params, NULL, "action/exec");
1972      }
1973 }
1974 
1975 /***************************************************************************/
1976 ACT_FN_GO(app, )
1977 {
1978    E_Zone *zone;
1979 
1980    zone = _e_actions_zone_get(obj);
1981    if (zone)
1982      {
1983         if (params)
1984           {
1985              Efreet_Desktop *desktop = NULL;
1986              char *p, *p2;
1987              size_t plen;
1988 
1989              plen = strlen(params);
1990              p2 = memcpy(alloca(plen + 1), params, plen + 1);
1991              p = strchr(p2, ':');
1992              if (p)
1993                {
1994                   *p++ = 0;
1995                   if (*p == ' ')
1996                     {
1997                        E_Dialog *dia;
1998                        char dialog_text[1024];
1999 
2000                        dia = e_dialog_new(NULL, "E", "_e_action_act_app_go_syntax_error");
2001                        if (!dia) return;
2002 
2003                        snprintf(dialog_text, sizeof(dialog_text),
2004                                 "%s<ps/><ps/>"
2005                                 "Check syntax. You should not put a whitespace right after colon in action params.<ps/>"
2006                                 "syntax: [file:file.desktop|name:App Name|generic:Generic Name|exe:exename]<ps/><ps/>"
2007                                 "exe:terminology (O)<ps/>"
2008                                 "exe: terminology (X)", params);
2009 
2010                        e_dialog_title_set(dia, _("Action Params Syntax Error"));
2011                        e_dialog_text_set(dia, _(dialog_text));
2012                        e_dialog_icon_set(dia, "dialog-error", 64);
2013                        e_dialog_button_add(dia, _("Close"), NULL, NULL, NULL);
2014                        e_dialog_button_focus_num(dia, 0);
2015                        elm_win_center(dia->win, 1, 1);
2016                        e_dialog_show(dia);
2017 
2018                        return;
2019                     }
2020                   if (!strcmp(p2, "file"))
2021                     desktop = efreet_util_desktop_file_id_find(p);
2022                   else if (!strcmp(p2, "name"))
2023                     desktop = efreet_util_desktop_name_find(p);
2024                   else if (!strcmp(p2, "generic"))
2025                     desktop = efreet_util_desktop_generic_name_find(p);
2026                   else if (!strcmp(p2, "exe"))
2027                     desktop = efreet_util_desktop_exec_find(p);
2028                   if (desktop)
2029                     {
2030                        e_exec(zone, desktop, NULL, NULL, "action/app");
2031                        efreet_desktop_free(desktop);
2032                     }
2033                }
2034           }
2035      }
2036 }
2037 
2038 /***************************************************************************/
ACT_FN_GO(app_new_instance,EINA_UNUSED)2039 ACT_FN_GO(app_new_instance, EINA_UNUSED)
2040 {
2041    E_Client *ec;
2042    E_Zone *zone;
2043 
2044    zone = _e_actions_zone_get(obj);
2045    if (!zone)
2046      zone = e_zone_current_get();
2047 
2048    if (!obj) obj = E_OBJECT(e_client_focused_get());
2049    if ((!obj) || (!zone)) return;
2050    if (obj->type != E_CLIENT_TYPE)
2051      {
2052         obj = E_OBJECT(e_client_focused_get());
2053         if (!obj) return;
2054      }
2055    ec = (E_Client *)(void *)obj;
2056 
2057    if (ec->desktop)
2058      e_exec(zone, ec->desktop, NULL, NULL, "action/app");
2059 }
2060 
2061 /***************************************************************************/
ACT_FN_GO(desk_deskshow_toggle,EINA_UNUSED)2062 ACT_FN_GO(desk_deskshow_toggle, EINA_UNUSED)
2063 {
2064    E_Zone *zone;
2065 
2066    zone = _e_actions_zone_get(obj);
2067    if (!zone) zone = e_zone_current_get();
2068    if (zone) e_desk_deskshow(zone);
2069 }
2070 
ACT_FN_GO(cleanup_windows,EINA_UNUSED)2071 ACT_FN_GO(cleanup_windows, EINA_UNUSED)
2072 {
2073    E_Zone *zone;
2074 
2075    zone = _e_actions_zone_get(obj);
2076    if (!zone) zone = e_zone_current_get();
2077    if (zone) e_place_zone_region_smart_cleanup(zone);
2078 }
2079 
2080 /***************************************************************************/
2081 static E_Dialog *exit_dialog = NULL;
2082 
2083 static void
_e_actions_cb_exit_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2084 _e_actions_cb_exit_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2085 {
2086    if (dia)
2087      {
2088         e_object_del(E_OBJECT(exit_dialog));
2089         exit_dialog = NULL;
2090      }
2091    e_sys_action_do(E_SYS_EXIT, NULL);
2092 }
2093 
2094 static void
_e_actions_cb_exit_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2095 _e_actions_cb_exit_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2096 {
2097    e_object_del(E_OBJECT(exit_dialog));
2098    exit_dialog = NULL;
2099 }
2100 
2101 static void
_e_actions_cb_exit_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2102 _e_actions_cb_exit_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2103 {
2104    _e_actions_cb_exit_dialog_cancel(NULL, data);
2105 }
2106 
2107 ACT_FN_GO(exit, )
2108 {
2109    if ((params) && (!strcmp(params, "now")))
2110      {
2111         e_sys_action_do(E_SYS_EXIT, NULL);
2112         return;
2113      }
2114    if (exit_dialog) e_object_del(E_OBJECT(exit_dialog));
2115 
2116    if (e_config->cnfmdlg_disabled)
2117      {
2118         _e_actions_cb_exit_dialog_ok(NULL, NULL);
2119         return;
2120      }
2121 
2122    exit_dialog = e_dialog_new(NULL, "E", "_exit_dialog");
2123    if (!exit_dialog) return;
2124    evas_object_event_callback_add(exit_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_exit_dialog_delete, exit_dialog);
2125    e_dialog_title_set(exit_dialog, _("Exit"));
2126    e_dialog_text_set(exit_dialog, _("Are you sure you want to exit Enlightenment?"));
2127    e_dialog_icon_set(exit_dialog, "application-exit", 64);
2128    e_dialog_button_add(exit_dialog, _("Yes"), NULL,
2129                        _e_actions_cb_exit_dialog_ok, NULL);
2130    e_dialog_button_add(exit_dialog, _("No"), NULL,
2131                        _e_actions_cb_exit_dialog_cancel, NULL);
2132    e_dialog_button_focus_num(exit_dialog, 1);
2133    elm_win_center(exit_dialog->win, 1, 1);
2134    e_dialog_show(exit_dialog);
2135 }
2136 
2137 /***************************************************************************/
ACT_FN_GO(restart,EINA_UNUSED)2138 ACT_FN_GO(restart, EINA_UNUSED)
2139 {
2140    e_sys_action_do(E_SYS_RESTART, NULL);
2141 }
2142 
2143 /***************************************************************************/
ACT_FN_GO(exit_now,EINA_UNUSED)2144 ACT_FN_GO(exit_now, EINA_UNUSED)
2145 {
2146    e_sys_action_do(E_SYS_EXIT_NOW, NULL);
2147 }
2148 
2149 /***************************************************************************/
ACT_FN_GO(halt_now,EINA_UNUSED)2150 ACT_FN_GO(halt_now, EINA_UNUSED)
2151 {
2152    e_sys_action_do(E_SYS_HALT_NOW, NULL);
2153 }
2154 
2155 /***************************************************************************/
ACT_FN_GO(mode_presentation_toggle,EINA_UNUSED)2156 ACT_FN_GO(mode_presentation_toggle, EINA_UNUSED)
2157 {
2158    e_config->mode.presentation = !e_config->mode.presentation;
2159    e_config_mode_changed();
2160    e_config_save_queue();
2161 }
2162 
2163 /***************************************************************************/
ACT_FN_GO(mode_offline_toggle,EINA_UNUSED)2164 ACT_FN_GO(mode_offline_toggle, EINA_UNUSED)
2165 {
2166    e_config->mode.offline = !e_config->mode.offline;
2167    e_config_mode_changed();
2168    e_config_save_queue();
2169 }
2170 
2171 /***************************************************************************/
2172 static E_Dialog *logout_dialog = NULL;
2173 
2174 static void
_e_actions_cb_logout_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2175 _e_actions_cb_logout_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2176 {
2177    if (dia)
2178      {
2179         e_object_del(E_OBJECT(logout_dialog));
2180         logout_dialog = NULL;
2181      }
2182    e_sys_action_do(E_SYS_LOGOUT, NULL);
2183 }
2184 
2185 static void
_e_actions_cb_logout_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2186 _e_actions_cb_logout_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2187 {
2188    e_object_del(E_OBJECT(logout_dialog));
2189    logout_dialog = NULL;
2190 }
2191 
2192 static void
_e_actions_cb_logout_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2193 _e_actions_cb_logout_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2194 {
2195    _e_actions_cb_logout_dialog_cancel(NULL, data);
2196 }
2197 
2198 ACT_FN_GO(logout, )
2199 {
2200    if ((params) && (!strcmp(params, "now")))
2201      {
2202         e_sys_action_do(E_SYS_LOGOUT, NULL);
2203         return;
2204      }
2205    if (logout_dialog) e_object_del(E_OBJECT(logout_dialog));
2206 
2207    if (e_config->cnfmdlg_disabled)
2208      {
2209         _e_actions_cb_logout_dialog_ok(NULL, NULL);
2210         return;
2211      }
2212 
2213    logout_dialog = e_dialog_new(NULL, "E", "_logout_dialog");
2214    if (!logout_dialog) return;
2215    evas_object_event_callback_add(logout_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_logout_dialog_delete, logout_dialog);
2216    e_dialog_title_set(logout_dialog, _("Logout"));
2217    e_dialog_text_set(logout_dialog, _("Are you sure you want to logout?"));
2218    e_dialog_icon_set(logout_dialog, "system-log-out", 64);
2219    e_dialog_button_add(logout_dialog, _("Yes"), NULL,
2220                        _e_actions_cb_logout_dialog_ok, NULL);
2221    e_dialog_button_add(logout_dialog, _("No"), NULL,
2222                        _e_actions_cb_logout_dialog_cancel, NULL);
2223    e_dialog_button_focus_num(logout_dialog, 1);
2224    elm_win_center(logout_dialog->win, 1, 1);
2225    e_dialog_show(logout_dialog);
2226 }
2227 
2228 /***************************************************************************/
2229 static E_Dialog *halt_dialog = NULL;
2230 
2231 static void
_e_actions_cb_halt_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2232 _e_actions_cb_halt_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2233 {
2234    if (dia)
2235      {
2236         e_object_del(E_OBJECT(halt_dialog));
2237         halt_dialog = NULL;
2238      }
2239    e_sys_action_do(E_SYS_HALT, NULL);
2240 }
2241 
2242 static void
_e_actions_cb_halt_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2243 _e_actions_cb_halt_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2244 {
2245    e_object_del(E_OBJECT(halt_dialog));
2246    halt_dialog = NULL;
2247 }
2248 
2249 static void
_e_actions_cb_halt_dialog_delete(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2250 _e_actions_cb_halt_dialog_delete(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2251 {
2252    if (!halt_dialog) return;
2253    e_object_del(E_OBJECT(halt_dialog));
2254    halt_dialog = NULL;
2255 }
2256 
2257 ACT_FN_GO(halt, )
2258 {
2259    if ((params) && (!strcmp(params, "now")))
2260      {
2261         e_sys_action_do(E_SYS_HALT, NULL);
2262         return;
2263      }
2264    if (halt_dialog) e_object_del(E_OBJECT(halt_dialog));
2265 
2266    if (e_config->cnfmdlg_disabled)
2267      {
2268         _e_actions_cb_halt_dialog_ok(NULL, NULL);
2269         return;
2270      }
2271 
2272    halt_dialog = e_dialog_new(NULL, "E", "_halt_dialog");
2273    if (!halt_dialog) return;
2274    evas_object_event_callback_add(halt_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_halt_dialog_delete, halt_dialog);
2275    e_dialog_title_set(halt_dialog, _("Power off"));
2276    e_dialog_text_set(halt_dialog,
2277                      _("Are you sure you want to power off your computer?"));
2278    e_dialog_icon_set(halt_dialog, "system-shutdown", 64);
2279    e_dialog_button_add(halt_dialog, _("Yes"), NULL,
2280                        _e_actions_cb_halt_dialog_ok, NULL);
2281    e_dialog_button_add(halt_dialog, _("No"), NULL,
2282                        _e_actions_cb_halt_dialog_cancel, NULL);
2283    e_dialog_button_focus_num(halt_dialog, 1);
2284    elm_win_center(halt_dialog->win, 1, 1);
2285    e_dialog_show(halt_dialog);
2286 }
2287 
2288 /***************************************************************************/
2289 static E_Dialog *reboot_dialog = NULL;
2290 
2291 static void
_e_actions_cb_reboot_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2292 _e_actions_cb_reboot_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2293 {
2294    if (dia)
2295      {
2296         e_object_del(E_OBJECT(reboot_dialog));
2297         reboot_dialog = NULL;
2298      }
2299    e_sys_action_do(E_SYS_REBOOT, NULL);
2300 }
2301 
2302 static void
_e_actions_cb_reboot_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2303 _e_actions_cb_reboot_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2304 {
2305    e_object_del(E_OBJECT(reboot_dialog));
2306    reboot_dialog = NULL;
2307 }
2308 
2309 static void
_e_actions_cb_reboot_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2310 _e_actions_cb_reboot_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2311 {
2312    _e_actions_cb_reboot_dialog_cancel(NULL, data);
2313 }
2314 
2315 ACT_FN_GO(reboot, )
2316 {
2317    if ((params) && (!strcmp(params, "now")))
2318      {
2319         e_sys_action_do(E_SYS_REBOOT, NULL);
2320         return;
2321      }
2322    if (reboot_dialog) e_object_del(E_OBJECT(reboot_dialog));
2323 
2324    if (e_config->cnfmdlg_disabled)
2325      {
2326         _e_actions_cb_reboot_dialog_ok(NULL, NULL);
2327         return;
2328      }
2329 
2330    reboot_dialog = e_dialog_new(NULL, "E", "_reboot_dialog");
2331    if (!reboot_dialog) return;
2332    evas_object_event_callback_add(reboot_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_reboot_dialog_delete, reboot_dialog);
2333    e_dialog_title_set(reboot_dialog, _("Reboot"));
2334    e_dialog_text_set(reboot_dialog, _("Are you sure you want to reboot your computer?"));
2335    e_dialog_icon_set(reboot_dialog, "system-restart", 64);
2336    e_dialog_button_add(reboot_dialog, _("Yes"), NULL,
2337                        _e_actions_cb_reboot_dialog_ok, NULL);
2338    e_dialog_button_add(reboot_dialog, _("No"), NULL,
2339                        _e_actions_cb_reboot_dialog_cancel, NULL);
2340    e_dialog_button_focus_num(reboot_dialog, 1);
2341    elm_win_center(reboot_dialog->win, 1, 1);
2342    e_dialog_show(reboot_dialog);
2343 }
2344 
2345 /***************************************************************************/
2346 static E_Dialog *suspend_dialog = NULL;
2347 
2348 static void
_e_actions_cb_suspend_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2349 _e_actions_cb_suspend_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2350 {
2351    if (dia)
2352      {
2353         e_object_del(E_OBJECT(suspend_dialog));
2354         suspend_dialog = NULL;
2355      }
2356    e_sys_action_do(E_SYS_SUSPEND, NULL);
2357 }
2358 
2359 static void
_e_actions_cb_suspend_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2360 _e_actions_cb_suspend_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2361 {
2362    e_object_del(E_OBJECT(suspend_dialog));
2363    suspend_dialog = NULL;
2364 }
2365 
2366 static void
_e_actions_cb_suspend_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2367 _e_actions_cb_suspend_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2368 {
2369    _e_actions_cb_suspend_dialog_cancel(NULL, data);
2370 }
2371 
ACT_FN_GO(suspend_now,EINA_UNUSED)2372 ACT_FN_GO(suspend_now, EINA_UNUSED)
2373 {
2374    e_sys_action_do(E_SYS_SUSPEND, NULL);
2375 }
2376 
2377 ACT_FN_GO(suspend, )
2378 {
2379    if ((params) && (!strcmp(params, "now")))
2380      {
2381         e_sys_action_do(E_SYS_SUSPEND, NULL);
2382         return;
2383      }
2384    if (suspend_dialog) e_object_del(E_OBJECT(suspend_dialog));
2385 
2386    if (e_config->cnfmdlg_disabled)
2387      {
2388         _e_actions_cb_suspend_dialog_ok(NULL, NULL);
2389         return;
2390      }
2391 
2392    suspend_dialog = e_dialog_new(NULL, "E", "_suspend_dialog");
2393    if (!suspend_dialog) return;
2394    evas_object_event_callback_add(suspend_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_suspend_dialog_delete, suspend_dialog);
2395    e_dialog_title_set(suspend_dialog, _("Suspend"));
2396    e_dialog_text_set(suspend_dialog, _("Are you sure you want to suspend your computer?"));
2397    e_dialog_icon_set(suspend_dialog, "system-suspend", 64);
2398    e_dialog_button_add(suspend_dialog, _("Yes"), NULL,
2399                        _e_actions_cb_suspend_dialog_ok, NULL);
2400    e_dialog_button_add(suspend_dialog, _("No"), NULL,
2401                        _e_actions_cb_suspend_dialog_cancel, NULL);
2402    e_dialog_button_focus_num(suspend_dialog, 1);
2403    elm_win_center(suspend_dialog->win, 1, 1);
2404    e_dialog_show(suspend_dialog);
2405 }
2406 
2407 static Eina_Bool
_have_lid_and_external_screens_on(void)2408 _have_lid_and_external_screens_on(void)
2409 {
2410    Eina_List *l;
2411    E_Randr2_Screen *s;
2412    int lids = 0;
2413    int ext_screens = 0;
2414 
2415    EINA_LIST_FOREACH(e_randr2->screens, l, s)
2416      {
2417         if (s->info.is_lid) lids++;
2418         else if ((s->config.enabled) &&
2419                  (s->config.geom.w > 0) &&
2420                  (s->config.geom.h > 0))
2421           ext_screens++;
2422      }
2423    if ((lids > 0) && (ext_screens > 0)) return EINA_TRUE;
2424    return EINA_FALSE;
2425 }
2426 
2427 static Eina_Bool
_should_suspend_if_plugged_in(void)2428 _should_suspend_if_plugged_in(void)
2429 {
2430    if ((e_config->screensaver_suspend_on_ac) ||
2431        (e_powersave_mode_get() > E_POWERSAVE_MODE_LOW))
2432      return EINA_TRUE;
2433    return EINA_FALSE;
2434 }
2435 
ACT_FN_GO(suspend_smart,EINA_UNUSED)2436 ACT_FN_GO(suspend_smart, EINA_UNUSED)
2437 {
2438    if (!_have_lid_and_external_screens_on())
2439      {
2440         if (_should_suspend_if_plugged_in())
2441           e_sys_action_do(E_SYS_SUSPEND, NULL);
2442         else
2443           e_powersave_defer_suspend();
2444      }
2445 }
2446 
2447 /***************************************************************************/
2448 static E_Dialog *hibernate_dialog = NULL;
2449 
2450 static void
_e_actions_cb_hibernate_dialog_ok(void * data EINA_UNUSED,E_Dialog * dia)2451 _e_actions_cb_hibernate_dialog_ok(void *data EINA_UNUSED, E_Dialog *dia)
2452 {
2453    if (dia)
2454      {
2455         e_object_del(E_OBJECT(hibernate_dialog));
2456         hibernate_dialog = NULL;
2457      }
2458    e_sys_action_do(E_SYS_HIBERNATE, NULL);
2459 }
2460 
2461 static void
_e_actions_cb_hibernate_dialog_cancel(void * data EINA_UNUSED,E_Dialog * dia EINA_UNUSED)2462 _e_actions_cb_hibernate_dialog_cancel(void *data EINA_UNUSED, E_Dialog *dia EINA_UNUSED)
2463 {
2464    e_object_del(E_OBJECT(hibernate_dialog));
2465    hibernate_dialog = NULL;
2466 }
2467 
2468 static void
_e_actions_cb_hibernate_dialog_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)2469 _e_actions_cb_hibernate_dialog_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2470 {
2471    _e_actions_cb_hibernate_dialog_cancel(NULL, data);
2472 }
2473 
ACT_FN_GO(hibernate_now,EINA_UNUSED)2474 ACT_FN_GO(hibernate_now, EINA_UNUSED)
2475 {
2476    e_sys_action_do(E_SYS_HIBERNATE, NULL);
2477 }
2478 
2479 ACT_FN_GO(hibernate, )
2480 {
2481    if ((params) && (!strcmp(params, "now")))
2482      {
2483         e_sys_action_do(E_SYS_HIBERNATE, NULL);
2484         return;
2485      }
2486    if (hibernate_dialog) e_object_del(E_OBJECT(hibernate_dialog));
2487 
2488    if (e_config->cnfmdlg_disabled)
2489      {
2490         _e_actions_cb_hibernate_dialog_ok(NULL, NULL);
2491         return;
2492      }
2493 
2494    hibernate_dialog = e_dialog_new(NULL, "E", "_hibernate_dialog");
2495    if (!hibernate_dialog) return;
2496    evas_object_event_callback_add(hibernate_dialog->win, EVAS_CALLBACK_DEL, _e_actions_cb_hibernate_dialog_delete, hibernate_dialog);
2497    e_dialog_title_set(hibernate_dialog, _("Hibernate"));
2498    e_dialog_text_set(hibernate_dialog, _("Are you sure you want to hibernate your computer?"));
2499    e_dialog_icon_set(hibernate_dialog, "system-suspend-hibernate", 64);
2500    e_dialog_button_add(hibernate_dialog, _("Yes"), NULL,
2501                        _e_actions_cb_hibernate_dialog_ok, NULL);
2502    e_dialog_button_add(hibernate_dialog, _("No"), NULL,
2503                        _e_actions_cb_hibernate_dialog_cancel, NULL);
2504    e_dialog_button_focus_num(hibernate_dialog, 1);
2505    elm_win_center(hibernate_dialog->win, 1, 1);
2506    e_dialog_show(hibernate_dialog);
2507 }
2508 
ACT_FN_GO(hibernate_smart,EINA_UNUSED)2509 ACT_FN_GO(hibernate_smart, EINA_UNUSED)
2510 {
2511    if (!_have_lid_and_external_screens_on())
2512      {
2513         if (_should_suspend_if_plugged_in())
2514           e_sys_action_do(E_SYS_HIBERNATE, NULL);
2515         else
2516           e_powersave_defer_hibernate();
2517      }
2518 }
2519 
2520 /***************************************************************************/
2521 ACT_FN_GO(pointer_resize_push, )
2522 {
2523    if (!obj) return;
2524    if (obj->type == E_CLIENT_TYPE)
2525      {
2526         E_Client *ec;
2527 
2528         ec = (E_Client *)(void *)obj;
2529         if ((ec->lock_user_size) || (ec->shaded) || (ec->shading) ||
2530             (ec->fullscreen) || ((ec->maximized) && (!e_config->allow_manip)))
2531           return;
2532         e_pointer_type_push(e_comp->pointer, ec, params);
2533      }
2534 }
2535 
2536 /***************************************************************************/
2537 ACT_FN_GO(pointer_resize_pop, )
2538 {
2539    if (!obj) return;
2540    if (obj->type == E_CLIENT_TYPE)
2541      {
2542         E_Client *ec;
2543 
2544         ec = (E_Client *)(void *)obj;
2545         if ((ec->lock_user_size) || (ec->shaded) || (ec->shading) ||
2546             (ec->fullscreen) || ((ec->maximized) && (!e_config->allow_manip)))
2547           return;
2548         e_pointer_type_pop(e_comp->pointer, ec, params);
2549      }
2550 }
2551 
2552 /***************************************************************************/
ACT_FN_GO(desk_lock,EINA_UNUSED)2553 ACT_FN_GO(desk_lock, EINA_UNUSED)
2554 {
2555 /*  E_Zone *zone;
2556 
2557    zone = _e_actions_zone_get(obj);
2558    if (zone)*/
2559    e_desklock_show_manual(EINA_FALSE);
2560 }
2561 
2562 /***************************************************************************/
2563 ACT_FN_GO(shelf_show, )
2564 {
2565    Eina_List *l;
2566    E_Shelf *es;
2567 
2568    if (params)
2569      {
2570         for (; *params != '\0'; params++)
2571           if (!isspace(*params))
2572             break;
2573         if (*params == '\0')
2574           params = NULL;
2575      }
2576 
EINA_LIST_FOREACH(e_shelf_list (),l,es)2577    EINA_LIST_FOREACH(e_shelf_list(), l, es)
2578      {
2579         if ((!params) || (params && (fnmatch(params, es->name, 0) == 0)))
2580           {
2581              e_shelf_toggle(es, 1);
2582              e_shelf_toggle(es, 0);
2583           }
2584      }
2585 }
2586 /***************************************************************************/
2587 #define ACT_SHELF_SHOW(params, es)                                  \
2588   if ((!params) || (params && (fnmatch(params, es->name, 0) == 0))) \
2589     {                                                               \
2590        e_shelf_toggle(es, 1);                                       \
2591        e_shelf_toggle(es, 0);                                       \
2592     }
2593 
2594 ACT_FN_GO_EDGE(shelf_show, )
2595 {
2596    Eina_List *l;
2597    E_Shelf *es;
2598 
2599    if (params)
2600      {
2601         for (; *params != '\0'; params++)
2602           {
2603              if (!isspace(*params))
2604                break;
2605           }
2606         if (*params == '\0')
2607           params = NULL;
2608      }
2609 
EINA_LIST_FOREACH(e_shelf_list (),l,es)2610    EINA_LIST_FOREACH(e_shelf_list(), l, es)
2611      {
2612         switch (ev->edge)
2613           {
2614            case E_ZONE_EDGE_LEFT:
2615              if ((es->gadcon->orient == E_GADCON_ORIENT_LEFT ||
2616                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_LT ||
2617                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_LB) &&
2618                  (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
2619                ACT_SHELF_SHOW(params, es);
2620              break;
2621 
2622            case E_ZONE_EDGE_RIGHT:
2623              if ((es->gadcon->orient == E_GADCON_ORIENT_RIGHT ||
2624                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_RT ||
2625                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_RB) &&
2626                  (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
2627                ACT_SHELF_SHOW(params, es);
2628              break;
2629 
2630            case E_ZONE_EDGE_TOP:
2631              if ((es->gadcon->orient == E_GADCON_ORIENT_TOP ||
2632                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_TL ||
2633                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_TR) &&
2634                  (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
2635                ACT_SHELF_SHOW(params, es);
2636              break;
2637 
2638            case E_ZONE_EDGE_BOTTOM:
2639              if ((es->gadcon->orient == E_GADCON_ORIENT_BOTTOM ||
2640                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_BL ||
2641                   es->gadcon->orient == E_GADCON_ORIENT_CORNER_BR) &&
2642                  (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
2643                ACT_SHELF_SHOW(params, es);
2644              break;
2645 
2646            default:
2647              break;
2648           }
2649      }
2650 }
2651 #undef ACT_SHELF_SHOW
2652 
2653 /***************************************************************************/
2654 typedef struct _Delayed_Action Delayed_Action;
2655 
2656 struct _Delayed_Action
2657 {
2658    int          mouse, button;
2659    const char  *key;
2660    E_Object    *obj;
2661    Ecore_Timer *timer;
2662    struct
2663    {
2664       const char *action, *params;
2665    } def, delayed;
2666 };
2667 
2668 static Eina_List *_delayed_actions = NULL;
2669 
2670 static void
_delayed_action_free(Delayed_Action * da)2671 _delayed_action_free(Delayed_Action *da)
2672 {
2673    if (da->obj) e_object_unref(da->obj);
2674    if (da->key) eina_stringshare_del(da->key);
2675    if (da->timer) ecore_timer_del(da->timer);
2676    if (da->def.action) eina_stringshare_del(da->def.action);
2677    if (da->def.params) eina_stringshare_del(da->def.params);
2678    if (da->delayed.action) eina_stringshare_del(da->delayed.action);
2679    if (da->delayed.params) eina_stringshare_del(da->delayed.params);
2680    free(da);
2681 }
2682 
2683 static Eina_Bool
_delayed_action_cb_timer(void * data)2684 _delayed_action_cb_timer(void *data)
2685 {
2686    Delayed_Action *da;
2687    E_Action *act;
2688 
2689    da = data;
2690    da->timer = NULL;
2691    if (da->delayed.action)
2692      {
2693         act = e_action_find(da->delayed.action);
2694         if (act)
2695           {
2696              if (act->func.go) act->func.go(da->obj, da->delayed.params);
2697           }
2698      }
2699    _delayed_actions = eina_list_remove(_delayed_actions, da);
2700    _delayed_action_free(da);
2701    return ECORE_CALLBACK_CANCEL;
2702 }
2703 
2704 static void
_delayed_action_do(Delayed_Action * da)2705 _delayed_action_do(Delayed_Action *da)
2706 {
2707    E_Action *act;
2708 
2709    if (da->def.action)
2710      {
2711         act = e_action_find(da->def.action);
2712         if (act)
2713           {
2714              if (act->func.go) act->func.go(da->obj, da->def.params);
2715           }
2716      }
2717 }
2718 
2719 static void
_delayed_action_list_parse_action(const char * str,double * delay,const char ** action,const char ** params)2720 _delayed_action_list_parse_action(const char *str, double *delay, const char **action, const char **params)
2721 {
2722    char fbuf[16];
2723    char buf[1024];
2724    const char *p;
2725 
2726    buf[0] = 0;
2727    if (sscanf(str, "%10s %1000s", fbuf, buf) != 2) return;
2728    *action = eina_stringshare_add(buf);
2729    *delay = atof(fbuf);
2730    p = strchr(str, ' ');
2731    if (p)
2732      {
2733         p++;
2734         p = strchr(p, ' ');
2735         if (p)
2736           {
2737              p++;
2738              *params = eina_stringshare_add(p);
2739           }
2740      }
2741 }
2742 
2743 static void
_delayed_action_list_parse(Delayed_Action * da,const char * params)2744 _delayed_action_list_parse(Delayed_Action *da, const char *params)
2745 {
2746    double delay = 2.0;
2747    const char *p, *a1start = NULL, *a1stop = NULL;
2748    const char *a2start = NULL, *a2stop = NULL;
2749 
2750    // FORMAT: "[0.0 default_action param1 param2] [x.x action2 param1 param2]"
2751    p = params;
2752    while (*p)
2753      {
2754         if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1start = p + 1; break; }
2755         p++;
2756      }
2757    while (*p)
2758      {
2759         if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1stop = p; break; }
2760         p++;
2761      }
2762    while (*p)
2763      {
2764         if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2start = p + 1; break; }
2765         p++;
2766      }
2767    while (*p)
2768      {
2769         if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2stop = p; break; }
2770         p++;
2771      }
2772    if ((a1start) && (a2start) && (a1stop) && (a2stop))
2773      {
2774         char *a1, *a2;
2775 
2776         a1 = alloca(a1stop - a1start + 1);
2777         eina_strlcpy(a1, a1start, a1stop - a1start + 1);
2778         _delayed_action_list_parse_action(a1, &delay, &da->def.action, &da->def.params);
2779 
2780         a2 = alloca(a1stop - a1start + 1);
2781         eina_strlcpy(a2, a2start, a2stop - a2start + 1);
2782         _delayed_action_list_parse_action(a2, &delay, &da->delayed.action, &da->delayed.params);
2783      }
2784    da->timer = ecore_timer_loop_add(delay, _delayed_action_cb_timer, da);
2785 }
2786 
2787 static void
_delayed_action_key_add(E_Object * obj,const char * params,Ecore_Event_Key * ev)2788 _delayed_action_key_add(E_Object *obj, const char *params, Ecore_Event_Key *ev)
2789 {
2790    Delayed_Action *da;
2791 
2792    da = E_NEW(Delayed_Action, 1);
2793    if (!da) return;
2794    if (obj)
2795      {
2796         da->obj = obj;
2797         e_object_ref(da->obj);
2798      }
2799    da->mouse = 0;
2800    da->key = eina_stringshare_add(ev->key);
2801    if (params) _delayed_action_list_parse(da, params);
2802    _delayed_actions = eina_list_append(_delayed_actions, da);
2803 }
2804 
2805 static void
_delayed_action_key_del(E_Object * obj,const char * params EINA_UNUSED,Ecore_Event_Key * ev)2806 _delayed_action_key_del(E_Object *obj, const char *params EINA_UNUSED, Ecore_Event_Key *ev)
2807 {
2808    Eina_List *l;
2809    Delayed_Action *da;
2810 
2811    EINA_LIST_FOREACH(_delayed_actions, l, da)
2812      {
2813         if ((da->obj == obj) && (!da->mouse) &&
2814             (!strcmp(da->key, ev->key)))
2815           {
2816              _delayed_action_do(da);
2817              _delayed_action_free(da);
2818              _delayed_actions = eina_list_remove_list(_delayed_actions, l);
2819              return;
2820           }
2821      }
2822 }
2823 
2824 static void
_delayed_action_mouse_add(E_Object * obj,const char * params,E_Binding_Event_Mouse_Button * ev)2825 _delayed_action_mouse_add(E_Object *obj, const char *params, E_Binding_Event_Mouse_Button *ev)
2826 {
2827    Delayed_Action *da;
2828 
2829    da = E_NEW(Delayed_Action, 1);
2830    if (!da) return;
2831    if (obj)
2832      {
2833         da->obj = obj;
2834         e_object_ref(da->obj);
2835      }
2836    da->mouse = 1;
2837    da->button = ev->button;
2838    if (params) _delayed_action_list_parse(da, params);
2839    _delayed_actions = eina_list_append(_delayed_actions, da);
2840 }
2841 
2842 static void
_delayed_action_mouse_del(E_Object * obj,const char * params EINA_UNUSED,E_Binding_Event_Mouse_Button * ev)2843 _delayed_action_mouse_del(E_Object *obj, const char *params EINA_UNUSED, E_Binding_Event_Mouse_Button *ev)
2844 {
2845    Eina_List *l;
2846    Delayed_Action *da;
2847 
2848    EINA_LIST_FOREACH(_delayed_actions, l, da)
2849      {
2850         if ((da->obj == obj) && (da->mouse) &&
2851             ((int)ev->button == da->button))
2852           {
2853              _delayed_action_do(da);
2854              _delayed_action_free(da);
2855              _delayed_actions = eina_list_remove_list(_delayed_actions, l);
2856              return;
2857           }
2858      }
2859 }
2860 
2861 // obj , params  , ev
2862 ACT_FN_GO_KEY(delayed_action, , )
2863 {
2864    _delayed_action_key_add(obj, params, ev);
2865 }
2866 
2867 ACT_FN_GO_MOUSE(delayed_action, )
2868 {
2869    _delayed_action_mouse_add(obj, params, ev);
2870    return EINA_TRUE;
2871 }
2872 
2873 ACT_FN_END_KEY(delayed_action, )
2874 {
2875    _delayed_action_key_del(obj, params, ev);
2876 }
2877 
2878 ACT_FN_END_MOUSE(delayed_action, )
2879 {
2880    _delayed_action_mouse_del(obj, params, ev);
2881    return EINA_TRUE;
2882 }
2883 
ACT_FN_GO(dim_screen,EINA_UNUSED)2884 ACT_FN_GO(dim_screen, EINA_UNUSED)
2885 {
2886    E_Zone *zone = _e_actions_zone_get(obj);
2887    e_backlight_mode_set(zone, E_BACKLIGHT_MODE_DIM);
2888 }
2889 
ACT_FN_GO(undim_screen,EINA_UNUSED)2890 ACT_FN_GO(undim_screen, EINA_UNUSED)
2891 {
2892    E_Zone *zone = _e_actions_zone_get(obj);
2893    e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
2894 }
2895 
2896 ACT_FN_GO(backlight_set, )
2897 {
2898    E_Zone *zone = _e_actions_zone_get(obj);
2899    int v;
2900    if (params)
2901      v = atoi(params);
2902    else
2903      {
2904         v = e_backlight_level_get(zone) * 100.0;
2905         if (v == 0) v = 100;
2906         else v = 0;
2907      }
2908    e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
2909    e_backlight_level_set(zone, ((double)v / 100.0), -1.0);
2910    e_config->backlight.normal = e_backlight_level_get(zone);
2911    e_config_save_queue();
2912 }
2913 
2914 ACT_FN_GO(backlight_adjust, )
2915 {
2916    E_Zone *zone = _e_actions_zone_get(obj);
2917    int v;
2918    if (!params) return;
2919    v = atoi(params);
2920    e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
2921    e_backlight_level_set(zone, e_backlight_level_get(zone) + ((double)v / 100.0), -1.0);
2922    e_config->backlight.normal = e_backlight_level_get(zone);
2923    e_config_save_queue();
2924 }
2925 
2926 ACT_FN_GO(kbd_layout, )
2927 {
2928    unsigned int x;
2929 
2930    if (!params) return;
2931    errno = 0;
2932    x = strtoul(params, NULL, 10);
2933    if (errno || (x > eina_list_count(e_config->xkb.used_layouts) - 1)) return;
2934    e_xkb_layout_set(eina_list_nth(e_config->xkb.used_layouts, x));
2935 }
2936 
ACT_FN_GO(kbd_layout_next,EINA_UNUSED)2937 ACT_FN_GO(kbd_layout_next, EINA_UNUSED)
2938 {
2939    e_xkb_layout_next();
2940 }
2941 
ACT_FN_GO(kbd_layout_prev,EINA_UNUSED)2942 ACT_FN_GO(kbd_layout_prev, EINA_UNUSED)
2943 {
2944    e_xkb_layout_prev();
2945 }
2946 
2947 #ifdef HAVE_WAYLAND
2948 ACT_FN_GO_MOUSE(mouse_to_key, )
2949 {
2950    const char *p, *nextp, *key = NULL;
2951    const char *mods[] =
2952    {
2953       "shift",
2954       "ctrl",
2955       "alt",
2956       "win",
2957       "altgr",
2958       NULL
2959    };
2960    int modifiers = 0, mod = 0;
2961 
2962    if ((!params) || (!params[0]) || (params[0] == '+')) return EINA_TRUE;
2963    for (p = params; p; p = nextp)
2964      {
2965         const char **m;
2966 
2967         nextp = strchr(p + 1, '+');
2968         if (!nextp) break;
2969         for (m = mods; *m; m++)
2970           {
2971              if (strncmp(p, *m, nextp - p)) continue;
2972              modifiers |= 1 << (m - mods);
2973              break;
2974           }
2975         key = nextp;
2976      }
2977    if (key)
2978      key++;
2979    else
2980      key = params;
2981    if (!key[0]) return EINA_TRUE;
2982 
2983    mod |= (ECORE_EVENT_MODIFIER_SHIFT * !!(modifiers & E_BINDING_MODIFIER_SHIFT));
2984    mod |= (ECORE_EVENT_MODIFIER_CTRL * !!(modifiers & E_BINDING_MODIFIER_CTRL));
2985    mod |= (ECORE_EVENT_MODIFIER_ALT * !!(modifiers & E_BINDING_MODIFIER_ALT));
2986    mod |= (ECORE_EVENT_MODIFIER_WIN * !!(modifiers & E_BINDING_MODIFIER_WIN));
2987    mod |= (ECORE_EVENT_MODIFIER_ALTGR * !!(modifiers & E_BINDING_MODIFIER_ALTGR));
2988    e_comp_wl_input_keyboard_event_generate(key, mod, 0);
2989    e_comp_wl_input_keyboard_event_generate(key, mod, 1);
2990    return EINA_TRUE;
2991 }
2992 #endif
2993 
2994 ACT_FN_GO(module_enable, )
2995 {
2996    E_Module *m;
2997 
2998    if (!params) return;
2999    m = e_module_find(params);
3000    if (!m)
3001      {
3002         m = e_module_new(params);
3003         if (!m) return;
3004      }
3005    e_module_enable(m);
3006 }
3007 
3008 ACT_FN_GO(module_disable, )
3009 {
3010    E_Module *m;
3011 
3012    if (!params) return;
3013    m = e_module_find(params);
3014    if (!m) return;
3015    e_module_disable(m);
3016 }
3017 
3018 ACT_FN_GO(module_toggle, )
3019 {
3020    E_Module *m;
3021 
3022    fprintf(stderr, "toggle\n");
3023    if (!params) return;
3024    fprintf(stderr, "'%s'\n", params);
3025    m = e_module_find(params);
3026    fprintf(stderr, "m = %p\n", m);
3027    if (!m)
3028      {
3029         m = e_module_new(params);
3030         if (!m) return;
3031      }
3032    fprintf(stderr, "currently %i\n", e_module_enabled_get(m));
3033    if (e_module_enabled_get(m)) e_module_disable(m);
3034    else e_module_enable(m);
3035 }
3036 
ACT_FN_GO(screen_redo,EINA_UNUSED)3037 ACT_FN_GO(screen_redo, EINA_UNUSED)
3038 {
3039    printf("REDOOOOOOOOOOOOOOOOOOOOOOOOOOO\n");
3040 #ifndef HAVE_WAYLAND_ONLY
3041    e_randr2_screeninfo_update();
3042    e_randr2_config_apply();
3043 #endif
3044 }
3045 
3046 /***************************************************************************/
3047 static Eina_Bool
_skip_win(E_Client * ec,E_Zone * zone,E_Desk * desk)3048 _skip_win(E_Client *ec, E_Zone *zone, E_Desk *desk)
3049 {
3050    if ((!ec->icccm.accepts_focus) && (!ec->icccm.take_focus)) return EINA_TRUE;
3051    if (ec->netwm.state.skip_taskbar) return EINA_TRUE;
3052    if (ec->user_skip_winlist) return EINA_TRUE;
3053    if (ec->iconic) return EINA_TRUE;
3054    if (ec->zone != zone) return EINA_TRUE;
3055    if (!((ec->sticky) || (ec->desk == desk))) return EINA_TRUE;
3056    return EINA_FALSE;
3057 }
3058 
3059 static int
_point_line_dist(int x,int y,int lx1,int ly1,int lx2,int ly2)3060 _point_line_dist(int x, int y, int lx1, int ly1, int lx2, int ly2)
3061 {
3062    int xx, yy, dx, dy;
3063    int a = x - lx1;
3064    int b = y - ly1;
3065    int c = lx2 - lx1;
3066    int d = ly2 - ly1;
3067    int dot = (a * c) + (b * d);
3068    int len_sq = (c * c) + (d * d);
3069    double dist, param = -1.0;
3070 
3071    // if line is 0 length
3072    if (len_sq) param = (double)dot / len_sq;
3073 
3074    if (param < 0)
3075      {
3076         xx = lx1;
3077         yy = ly1;
3078      }
3079    else if (param > 1)
3080      {
3081         xx = lx2;
3082         yy = ly2;
3083      }
3084    else
3085      {
3086         xx = lx1 + lround(param * c);
3087         yy = ly1 + lround(param * d);
3088      }
3089 
3090    dx = x - xx;
3091    dy = y - yy;
3092    dist = sqrt((dx * dx) + (dy * dy));
3093    return lround(dist);
3094 }
3095 
ACT_FN_GO(window_focus,EINA_UNUSED)3096 ACT_FN_GO(window_focus, EINA_UNUSED)
3097 {
3098    E_Zone *zone = e_zone_current_get();
3099    E_Desk *desk = e_desk_current_get(zone);
3100    E_Client *ec, *ec_orig,
3101      *ec_prev = NULL, *ec_last = NULL, *ec_first = NULL, *ec_next = NULL;
3102    Eina_List *l;
3103    int distance = INT_MAX, cx, cy, dir = -1, found = 0;
3104 
3105    if (!params) return;
3106    ec_orig = e_client_focused_get();
3107    if (!ec_orig)
3108      {
3109         // XXX: just pick any window to focus
3110         EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
3111           {
3112              if (_skip_win(ec, zone, desk)) continue;
3113              e_client_focus_set_with_pointer(ec);
3114              return;
3115           }
3116         return;
3117      }
3118 
3119    if      (!strcmp(params, "next"))  dir = -1;
3120    else if (!strcmp(params, "prev"))  dir = -2;
3121    else if (!strcmp(params, "up"))    dir =  0;
3122    else if (!strcmp(params, "down"))  dir =  1;
3123    else if (!strcmp(params, "left"))  dir =  2;
3124    else if (!strcmp(params, "right")) dir =  3;
3125    else
3126      {
3127         e_util_dialog_show(_("Error: window_focus action"),
3128                            _("Invalid parameter: %s"), params);
3129         return;
3130      }
3131    if (dir < 0)
3132      {
3133         EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
3134           {
3135              if (_skip_win(ec, zone, desk)) continue;
3136 
3137              if (ec == ec_orig)              found = 1;
3138              else if (!found)                ec_prev = ec;
3139              else if ((found) && (!ec_next)) ec_next = ec;
3140 
3141              if (!ec_first)                  ec_first = ec;
3142              ec_last = ec;
3143           }
3144         if (dir == -1) /* next */
3145           {
3146              if (ec_next) e_client_focus_set_with_pointer(ec_next);
3147              else if (ec_first) e_client_focus_set_with_pointer(ec_first);
3148           }
3149         else if (dir == -2)
3150           {
3151              if (ec_prev) e_client_focus_set_with_pointer(ec_prev);
3152              else if (ec_last) e_client_focus_set_with_pointer(ec_last);
3153           }
3154         return;
3155      }
3156 
3157    cx = ec_orig->x + (ec_orig->w / 2);
3158    cy = ec_orig->y + (ec_orig->h / 2);
3159 
3160    EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
3161      {
3162         int a = 0, d = 0;
3163 
3164         if (ec == ec_orig) continue;
3165         if (_skip_win(ec, zone, desk)) continue;
3166 
3167         switch (dir)
3168           {
3169            case 0: /* up */
3170              d = _point_line_dist(cx, cy,
3171                                   ec->x,         ec->y + ec->h,
3172                                   ec->x + ec->w, ec->y + ec->h);
3173              if (d >= distance) continue;
3174              d = _point_line_dist(cx, cy,
3175                                   ec->x,         ec->y + (ec->h / 2),
3176                                   ec->x + ec->w, ec->y + (ec->h / 2));
3177              if (d >= distance) continue;
3178              if (cy <= (ec->y + (ec->h / 2))) continue;
3179              a = abs(cx - (ec->x + (ec->w / 2)));
3180              d += (a * a) / d;
3181              if (d >= distance) continue;
3182              break;
3183            case 1: /* down */
3184              d = _point_line_dist(cx, cy,
3185                                   ec->x,         ec->y,
3186                                   ec->x + ec->w, ec->y);
3187              if (d >= distance) continue;
3188              d = _point_line_dist(cx, cy,
3189                                   ec->x,         ec->y + (ec->h / 2),
3190                                   ec->x + ec->w, ec->y + (ec->h / 2));
3191              if (d >= distance) continue;
3192              if (cy >= (ec->y + (ec->h / 2))) continue;
3193              a = abs(cx - (ec->x + (ec->w / 2)));
3194              d += (a * a) / d;
3195              if (d >= distance) continue;
3196              break;
3197            case 2: /* left */
3198              d = _point_line_dist(cx, cy,
3199                                   ec->x + ec->w, ec->y,
3200                                   ec->x + ec->w, ec->y + ec->h);
3201              if (d >= distance) continue;
3202              d = _point_line_dist(cx, cy,
3203                                   ec->x + (ec->w / 2), ec->y,
3204                                   ec->x + (ec->w / 2), ec->y + ec->h);
3205              if (d >= distance) continue;
3206              if (cx <= (ec->x + (ec->w / 2))) continue;
3207              a = abs(cy - (ec->y + (ec->h / 2)));
3208              d += (a * a) / d;
3209              if (d >= distance) continue;
3210              break;
3211            case 3: /* right */
3212              d = _point_line_dist(cx, cy,
3213                                   ec->x, ec->y,
3214                                   ec->x, ec->y + ec->h);
3215              if (d >= distance) continue;
3216              d = _point_line_dist(cx, cy,
3217                                   ec->x + (ec->w / 2), ec->y,
3218                                   ec->x + (ec->w / 2), ec->y + ec->h);
3219              if (d >= distance) continue;
3220              if (cx >= (ec->x + (ec->w / 2))) continue;
3221              a = abs(cy - (ec->y + (ec->h / 2)));
3222              d += (a * a) / d;
3223              if (d >= distance) continue;
3224              break;
3225           }
3226         ec_next = ec;
3227         distance = d;
3228      }
3229 
3230    if (ec_next) e_client_focus_set_with_pointer(ec_next);
3231 }
3232 
3233 /* local subsystem globals */
3234 static Eina_Hash *actions = NULL;
3235 static Eina_List *action_list = NULL;
3236 static Eina_List *action_names = NULL;
3237 static Eina_List *action_groups = NULL;
3238 
3239 static void
_e_actions_post_init(void * d EINA_UNUSED)3240 _e_actions_post_init(void *d EINA_UNUSED)
3241 {
3242 #ifdef HAVE_WAYLAND
3243    E_Action *act;
3244 
3245    /* wayland-specific actions */
3246    if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
3247      {
3248         /* mouse -> key */
3249         /* "key" here is the platform-specific key name;
3250          * /usr/share/X11/xkb/keycodes/evdev is probably what your system is using
3251          */
3252         ACT_GO_MOUSE(mouse_to_key);
3253         e_action_predef_name_set(N_("Mouse Remapping"),
3254                                  N_("Mouse to key"), "mouse_to_key",
3255                                  NULL, "[AD02] [ctrl+shift+alt+win+altgr+AD02]", 1);
3256      }
3257 #endif
3258 }
3259 
3260 /* externally accessible functions */
3261 
3262 EINTERN int
e_actions_init(void)3263 e_actions_init(void)
3264 {
3265    E_Action *act;
3266 
3267    actions = eina_hash_string_superfast_new(NULL);
3268    ACT_GO(window_move);
3269    e_action_predef_name_set(N_("Window : Actions"), N_("Move"),
3270                             "window_move", NULL, NULL, 0);
3271 
3272    ACT_GO_MOUSE(window_move);
3273    ACT_GO_SIGNAL(window_move);
3274    ACT_END(window_move);
3275    ACT_END_MOUSE(window_move);
3276    ACT_GO_KEY(window_move);
3277 
3278    /* window_resize */
3279    ACT_GO(window_resize);
3280    e_action_predef_name_set(N_("Window : Actions"), N_("Resize"),
3281                             "window_resize", NULL, NULL, 0);
3282 
3283    ACT_GO_MOUSE(window_resize);
3284    ACT_GO_SIGNAL(window_resize);
3285    ACT_END(window_resize);
3286    ACT_END_MOUSE(window_resize);
3287    ACT_GO_KEY(window_resize);
3288 
3289    /* window_menu */
3290    ACT_GO(window_menu);
3291    e_action_predef_name_set(N_("Menu"), N_("Window Menu"),
3292                             "window_menu", NULL, NULL, 0);
3293 
3294    ACT_GO_MOUSE(window_menu);
3295    ACT_GO_KEY(window_menu);
3296 
3297    /* window_raise */
3298    ACT_GO(window_raise);
3299    e_action_predef_name_set(N_("Window : Actions"), N_("Raise"),
3300                             "window_raise", NULL, NULL, 0);
3301 
3302    /* window_lower */
3303    ACT_GO(window_lower);
3304    e_action_predef_name_set(N_("Window : Actions"), N_("Lower"),
3305                             "window_lower", NULL, NULL, 0);
3306 
3307    /* window_close */
3308    ACT_GO(window_close);
3309    e_action_predef_name_set(N_("Window : Actions"), N_("Close"),
3310                             "window_close", NULL, NULL, 0);
3311 
3312    /* window_kill */
3313    ACT_GO(window_kill);
3314    e_action_predef_name_set(N_("Window : Actions"), N_("Kill"),
3315                             "window_kill", NULL, NULL, 0);
3316 
3317    /* window_sticky_toggle */
3318    ACT_GO(window_sticky_toggle);
3319    e_action_predef_name_set(N_("Window : State"), N_("Sticky Mode Toggle"),
3320                             "window_sticky_toggle", NULL, NULL, 0);
3321 
3322    ACT_GO(window_sticky);
3323    e_action_predef_name_set(N_("Window : State"), N_("Sticky Mode Enable"),
3324                             "window_sticky", NULL, NULL, 0);
3325 
3326    /* window_iconic_toggle */
3327    ACT_GO(window_iconic_toggle);
3328    e_action_predef_name_set(N_("Window : State"), N_("Iconic Mode Toggle"),
3329                             "window_iconic_toggle", NULL, NULL, 0);
3330 
3331    ACT_GO(window_iconic);
3332    e_action_predef_name_set(N_("Window : State"), N_("Iconic Mode Enable"),
3333                             "window_iconic", NULL, NULL, 0);
3334 
3335    /* window_fullscreen_toggle */
3336    ACT_GO(window_fullscreen_toggle);
3337    e_action_predef_name_set(N_("Window : State"), N_("Fullscreen Mode Toggle"),
3338                             "window_fullscreen_toggle", NULL, NULL, 0);
3339 
3340    ACT_GO(window_fullscreen);
3341    e_action_predef_name_set(N_("Window : State"), N_("Fullscreen Mode Enable"),
3342                             "window_fullscreen", NULL, NULL, 0);
3343 
3344    /* window_maximized_toggle */
3345    ACT_GO(window_maximized_toggle);
3346    e_action_predef_name_set(N_("Window : State"), N_("Maximize"),
3347                             "window_maximized_toggle", NULL, NULL, 0);
3348    e_action_predef_name_set(N_("Window : State"), N_("Maximize Vertically"),
3349                             "window_maximized_toggle", "default vertical",
3350                             NULL, 0);
3351    e_action_predef_name_set(N_("Window : State"), N_("Maximize Horizontally"),
3352                             "window_maximized_toggle", "default horizontal",
3353                             NULL, 0);
3354    e_action_predef_name_set(N_("Window : State"), N_("Maximize Left"),
3355                             "window_maximized_toggle", "default left",
3356                             NULL, 0);
3357    e_action_predef_name_set(N_("Window : State"), N_("Maximize Right"),
3358                             "window_maximized_toggle", "default right",
3359                             NULL, 0);
3360    e_action_predef_name_set(N_("Window : State"), N_("Maximize Fullscreen"),
3361                             "window_maximized_toggle", "fullscreen", NULL, 0);
3362    e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Smart\""),
3363                             "window_maximized_toggle", "smart", NULL, 0);
3364    e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Expand\""),
3365                             "window_maximized_toggle", "expand", NULL, 0);
3366    e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Fill\""),
3367                             "window_maximized_toggle", "fill", NULL, 0);
3368 
3369    ACT_GO(window_maximized);
3370 
3371    /* window_shaded_toggle */
3372    ACT_GO(window_shaded_toggle);
3373    e_action_predef_name_set(N_("Window : State"), N_("Shade Up Mode Toggle"),
3374                             "window_shaded_toggle", "up", NULL, 0);
3375    e_action_predef_name_set(N_("Window : State"), N_("Shade Down Mode Toggle"),
3376                             "window_shaded_toggle", "down", NULL, 0);
3377    e_action_predef_name_set(N_("Window : State"), N_("Shade Left Mode Toggle"),
3378                             "window_shaded_toggle", "left", NULL, 0);
3379    e_action_predef_name_set(N_("Window : State"), N_("Shade Right Mode Toggle"),
3380                             "window_shaded_toggle", "right", NULL, 0);
3381    e_action_predef_name_set(N_("Window : State"), N_("Shade Mode Toggle"),
3382                             "window_shaded_toggle", NULL, NULL, 0);
3383 
3384    ACT_GO(window_shaded);
3385    e_action_predef_name_set(N_("Window : State"), N_("Set Shaded State"),
3386                             "window_shaded", NULL, _("syntax: \"(0|1) (up|down|left|right)\""), 1);
3387 
3388    /* window_borderless_toggle */
3389    ACT_GO(window_borderless_toggle);
3390    e_action_predef_name_set(N_("Window : State"), N_("Toggle Borderless State"),
3391                             "window_borderless_toggle", NULL, NULL, 0);
3392 
3393    /* window_border_set */
3394    ACT_GO(window_border_set);
3395    e_action_predef_name_set(N_("Window : State"), N_("Set Border"),
3396                             "window_border_set", NULL,
3397                             "syntax: BorderName, example: pixel", 1);
3398 
3399    /* window_border_cycle */
3400    ACT_GO(window_border_cycle);
3401    e_action_predef_name_set(N_("Window : State"), N_("Cycle between Borders"),
3402                             "window_border_cycle", NULL,
3403                             "syntax: BorderNames, example: default pixel", 1);
3404 
3405    /* window_pinned_toggle */
3406    ACT_GO(window_pinned_toggle);
3407    e_action_predef_name_set(N_("Window : State"), N_("Toggle Pinned State"),
3408                             "window_pinned_toggle", NULL, NULL, 0);
3409 
3410    /* desk_flip_by */
3411    ACT_GO(desk_flip_by);
3412    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Left"),
3413                             "desk_flip_by", "-1 0", NULL, 0);
3414    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Right"),
3415                             "desk_flip_by", "1 0", NULL, 0);
3416    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Up"),
3417                             "desk_flip_by", "0 -1", NULL, 0);
3418    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Down"),
3419                             "desk_flip_by", "0 1", NULL, 0);
3420    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop By..."),
3421                             "desk_flip_by", NULL,
3422                             "syntax: X-offset Y-offset, example: -1 0", 1);
3423 
3424    /* desk_flip_prev */
3425    ACT_GO(desk_flip_prev);
3426    e_action_predef_name_set(N_("Desktop"), N_("Flip To Previous Desktop"),
3427                             "desk_flip_prev", NULL, NULL, 0);
3428 
3429    /* desk_deskshow_toggle */
3430    ACT_GO(desk_deskshow_toggle);
3431    e_action_predef_name_set(N_("Desktop"), N_("Show The Desktop"),
3432                             "desk_deskshow_toggle", NULL, NULL, 0);
3433 
3434    /* shelf_show */
3435    ACT_GO(shelf_show);
3436    ACT_GO_EDGE(shelf_show);
3437    e_action_predef_name_set(N_("Desktop"), N_("Show The Shelf"), "shelf_show",
3438                             NULL, "shelf name glob: Shelf-* ", 1);
3439 
3440    /* desk_linear_flip_to */
3441    ACT_GO(desk_flip_to);
3442    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop To..."),
3443                             "desk_flip_to", NULL,
3444                             "syntax: X Y, example: 1 2", 1);
3445    /* desk_linear_flip_to_screen */
3446    ACT_GO(desk_linear_flip_to_screen);
3447    e_action_predef_name_set(N_("Desktop"), N_("Switch Desktop To... On Screen..."),
3448                             "desk_linear_flip_to_screen", NULL,
3449                             "syntax: D S, example: 0 1", 1);
3450 
3451    /* desk_linear_flip_by */
3452    ACT_GO(desk_linear_flip_by);
3453    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Linearly..."),
3454                             "desk_linear_flip_by",
3455                             NULL, "syntax: N-offset, example: -2", 1);
3456 
3457    /* desk_linear_flip_to */
3458    ACT_GO(desk_linear_flip_to);
3459    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 0"),
3460                             "desk_linear_flip_to", "0", NULL, 0);
3461    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 1"),
3462                             "desk_linear_flip_to", "1", NULL, 0);
3463    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 2"),
3464                             "desk_linear_flip_to", "2", NULL, 0);
3465    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 3"),
3466                             "desk_linear_flip_to", "3", NULL, 0);
3467    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 4"),
3468                             "desk_linear_flip_to", "4", NULL, 0);
3469    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 5"),
3470                             "desk_linear_flip_to", "5", NULL, 0);
3471    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 6"),
3472                             "desk_linear_flip_to", "6", NULL, 0);
3473    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 7"),
3474                             "desk_linear_flip_to", "7", NULL, 0);
3475    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 8"),
3476                             "desk_linear_flip_to", "8", NULL, 0);
3477    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 9"),
3478                             "desk_linear_flip_to", "9", NULL, 0);
3479    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 10"),
3480                             "desk_linear_flip_to", "10", NULL, 0);
3481    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 11"),
3482                             "desk_linear_flip_to", "11", NULL, 0);
3483    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop..."),
3484                             "desk_linear_flip_to", NULL,
3485                             "syntax: N, example: 1", 1);
3486 
3487    /* desk_flip_by_all */
3488    ACT_GO(desk_flip_by_all);
3489    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Left (All Screens)"),
3490                             "desk_flip_by_all", "-1 0", NULL, 0);
3491    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Right (All Screens)"),
3492                             "desk_flip_by_all", "1 0", NULL, 0);
3493    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Up (All Screens)"),
3494                             "desk_flip_by_all", "0 -1", NULL, 0);
3495    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Down (All Screens)"),
3496                             "desk_flip_by_all", "0 1", NULL, 0);
3497    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop By... (All Screens)"),
3498                             "desk_flip_by_all", NULL,
3499                             "syntax: X-offset Y-offset, example: -1 0", 1);
3500 
3501    /* desk_flip_to_all */
3502    ACT_GO(desk_flip_to_all);
3503    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop To... (All Screens)"),
3504                             "desk_flip_to_all", NULL,
3505                             "syntax: X Y, example: 1 2", 1);
3506 
3507    /* desk_linear_flip_by_all */
3508    ACT_GO(desk_linear_flip_by_all);
3509    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Linearly... (All Screens)"),
3510                             "desk_linear_flip_by_all",
3511                             NULL, "syntax: N-offset, example: -2", 1);
3512 
3513    /* desk_flip_in_direction */
3514    ACT_GO_EDGE(desk_flip_in_direction);
3515    e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop In Direction..."),
3516                             "desk_flip_in_direction", NULL, "syntax: N-pixel-offset, example: 25", 1);
3517 
3518    /* desk_linear_flip_to_all */
3519    ACT_GO(desk_linear_flip_to_all);
3520    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 0 (All Screens)"),
3521                             "desk_linear_flip_to_all", "0", NULL, 0);
3522    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 1 (All Screens)"),
3523                             "desk_linear_flip_to_all", "1", NULL, 0);
3524    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 2 (All Screens)"),
3525                             "desk_linear_flip_to_all", "2", NULL, 0);
3526    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 3 (All Screens)"),
3527                             "desk_linear_flip_to_all", "3", NULL, 0);
3528    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 4 (All Screens)"),
3529                             "desk_linear_flip_to_all", "4", NULL, 0);
3530    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 5 (All Screens)"),
3531                             "desk_linear_flip_to_all", "5", NULL, 0);
3532    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 6 (All Screens)"),
3533                             "desk_linear_flip_to_all", "6", NULL, 0);
3534    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 7 (All Screens)"),
3535                             "desk_linear_flip_to_all", "7", NULL, 0);
3536    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 8 (All Screens)"),
3537                             "desk_linear_flip_to_all", "8", NULL, 0);
3538    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 9 (All Screens)"),
3539                             "desk_linear_flip_to_all", "9", NULL, 0);
3540    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 10 (All Screens)"),
3541                             "desk_linear_flip_to_all", "10", NULL, 0);
3542    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 11 (All Screens)"),
3543                             "desk_linear_flip_to_all", "11", NULL, 0);
3544    e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop... (All Screens)"),
3545                             "desk_linear_flip_to_all", NULL,
3546                             "syntax: N, example: 1", 1);
3547 
3548    /* window_jump_to */
3549    ACT_GO(window_jump_to);
3550    e_action_predef_name_set(N_("Window : List"), N_("Jump to window..."),
3551                             "window_jump_to", NULL, "syntax: icccm window name, example: urxvt-mutt", 1);
3552 
3553    ACT_GO(window_jump_to_or_start);
3554    e_action_predef_name_set(N_("Window : List"), N_("Jump to window... or start..."),
3555                             "window_jump_to_or_start", NULL, "syntax: icccm_window_name application", 1);
3556 
3557    /* screen_send_to */
3558    ACT_GO(screen_send_to);
3559    e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen 0"),
3560                             "screen_send_to", "0", NULL, 0);
3561    e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen 1"),
3562                             "screen_send_to", "1", NULL, 0);
3563    e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen..."),
3564                             "screen_send_to", NULL,
3565                             "syntax: N, example: 0", 1);
3566 
3567    /* screen_send_by */
3568    ACT_GO(screen_send_by);
3569    e_action_predef_name_set(N_("Screen"), N_("Send Mouse Forward 1 Screen"),
3570                             "screen_send_by", "1", NULL, 0);
3571    e_action_predef_name_set(N_("Screen"), N_("Send Mouse Back 1 Screen"),
3572                             "screen_send_by", "-1", NULL, 0);
3573    e_action_predef_name_set(N_("Screen"), N_("Send Mouse Forward/Back Screens..."),
3574                             "screen_send_by", NULL,
3575                             "syntax: N-offset, example: -2", 1);
3576 
3577    ACT_GO(dim_screen);
3578    e_action_predef_name_set(N_("Screen"), N_("Dim"), "dim_screen",
3579                             NULL, NULL, 0);
3580    ACT_GO(undim_screen);
3581    e_action_predef_name_set(N_("Screen"), N_("Undim"), "undim_screen",
3582                             NULL, NULL, 0);
3583    ACT_GO(backlight_set);
3584    e_action_predef_name_set(N_("Screen"), N_("Backlight Set"), "backlight_set",
3585                             NULL, "syntax: brightness(0 - 100), example: 50", 1);
3586    e_action_predef_name_set(N_("Screen"), N_("Backlight Min"), "backlight_set",
3587                             "0", NULL, 0);
3588    e_action_predef_name_set(N_("Screen"), N_("Backlight Mid"), "backlight_set",
3589                             "50", NULL, 0);
3590    e_action_predef_name_set(N_("Screen"), N_("Backlight Max"), "backlight_set",
3591                             "100", NULL, 0);
3592    ACT_GO(backlight_adjust);
3593    e_action_predef_name_set(N_("Screen"), N_("Backlight Adjust"), "backlight_adjust",
3594                             NULL, "syntax: brightness(-100 - 100), example: -20", 1);
3595    e_action_predef_name_set(N_("Screen"), N_("Backlight Up"), "backlight_adjust",
3596                             "10", NULL, 0);
3597    e_action_predef_name_set(N_("Screen"), N_("Backlight Down"), "backlight_adjust",
3598                             "-10", NULL, 0);
3599 
3600    /* screen setup */
3601    ACT_GO(screen_redo);
3602    e_action_predef_name_set(N_("Screen"),
3603                             N_("Update and re-apply screen setup"),
3604                             "screen_redo", NULL, NULL, 0);
3605 
3606    /* window_move_to_center */
3607    ACT_GO(window_move_to_center);
3608    e_action_predef_name_set(N_("Window : Actions"), N_("Move To Center"),
3609                             "window_move_to_center", NULL, NULL, 0);
3610 
3611    /* window_quick_tile_upper_left */
3612    ACT_GO(window_quick_tile_to_quadrant);
3613    e_action_predef_name_set(N_("Window : Actions"), N_("Move/resize to upper-left quadrant"),
3614                             "window_quick_tile_to_quadrant", "upper_left", NULL, 0);
3615 
3616    /* window_quick_tile_upper_right */
3617    ACT_GO(window_quick_tile_to_quadrant);
3618    e_action_predef_name_set(N_("Window : Actions"), N_("Move/resize to upper-right quadrant"),
3619                             "window_quick_tile_to_quadrant", "upper_right", NULL, 0);
3620 
3621    /* window_quick_tile_lower_left */
3622    ACT_GO(window_quick_tile_to_quadrant);
3623    e_action_predef_name_set(N_("Window : Actions"), N_("Move/resize to lower-left quadrant"),
3624                             "window_quick_tile_to_quadrant", "lower_left", NULL, 0);
3625 
3626    /* window_quick_tile_lower_right */
3627    ACT_GO(window_quick_tile_to_quadrant);
3628    e_action_predef_name_set(N_("Window : Actions"), N_("Move/resize to lower-right quadrant"),
3629                             "window_quick_tile_to_quadrant", "lower_right", NULL, 0);
3630 
3631    /* window_move_to */
3632    ACT_GO(window_move_to);
3633    e_action_predef_name_set(N_("Window : Actions"), N_("Move To Coordinates..."),
3634                             "window_move_to", NULL,
3635                             "syntax: [+,-]X [+,-]Y or * [+,-]Y or [+,-]X *, example: -1 +1", 1);
3636    /* window_move_by */
3637    ACT_GO(window_move_by);
3638    e_action_predef_name_set(N_("Window : Actions"), N_("Move By Coordinate Offset..."),
3639                             "window_move_by", NULL,
3640                             "syntax: X-offset Y-offset, example: -1 0", 1);
3641 
3642    /* window_resize_by */
3643    ACT_GO(window_resize_by);
3644    e_action_predef_name_set(N_("Window : Actions"), N_("Resize By..."),
3645                             "window_resize_by", NULL,
3646                             "syntax: W H, example: 100 150", 1);
3647 
3648    /* window_push */
3649    ACT_GO(window_push);
3650    e_action_predef_name_set(N_("Window : Actions"), N_("Push in Direction..."),
3651                             "window_push", NULL,
3652                             "syntax: direction, example: up, down, left, right, up-left, up-right, down-left, down-right", 1);
3653 
3654    /* window_drag_icon */
3655    ACT_GO(window_drag_icon);
3656    e_action_predef_name_set(N_("Window : Actions"), N_("Drag Icon..."),
3657                             "window_drag_icon", NULL, NULL, 0);
3658 
3659    /* window_desk_move_by */
3660    ACT_GO(window_desk_move_by);
3661    e_action_predef_name_set(N_("Window : Moving"), N_("To Next Desktop"),
3662                             "window_desk_move_by", "1 0", NULL, 0);
3663    e_action_predef_name_set(N_("Window : Moving"), N_("To Previous Desktop"),
3664                             "window_desk_move_by", "-1 0", NULL, 0);
3665    e_action_predef_name_set(N_("Window : Moving"), N_("By Desktop #..."),
3666                             "window_desk_move_by", NULL,
3667                             "syntax: X-offset Y-offset, example: -2 2", 1);
3668 
3669    /* window_desk_move_to */
3670    ACT_GO(window_desk_move_to);
3671    e_action_predef_name_set(N_("Window : Moving"), N_("To Desktop..."),
3672                             "window_desk_move_to", NULL,
3673                             "syntax: X Y, example: 0 1", 1);
3674 
3675    /* window_zone_move_by */
3676    ACT_GO(window_zone_move_by);
3677    e_action_predef_name_set(N_("Window : Moving"), N_("To Next Screen"),
3678                             "window_zone_move_by", "1", NULL, 0);
3679    e_action_predef_name_set(N_("Window : Moving"), N_("To Previous Screen"),
3680                             "window_zone_move_by", "-1", NULL, 0);
3681 
3682    /* Move window focus somewhere */
3683    ACT_GO(window_focus);
3684    e_action_predef_name_set(N_("Window : Focus"),
3685                             N_("Focus next window"),
3686                             "window_focus", "next", NULL, 0);
3687    e_action_predef_name_set(N_("Window : Focus"),
3688                             N_("Focus previous window"),
3689                             "window_focus", "prev", NULL, 0);
3690    e_action_predef_name_set(N_("Window : Focus"),
3691                             N_("Focus window above"),
3692                             "window_focus", "up", NULL, 0);
3693    e_action_predef_name_set(N_("Window : Focus"),
3694                             N_("Focus window below"),
3695                             "window_focus", "down", NULL, 0);
3696    e_action_predef_name_set(N_("Window : Focus"),
3697                             N_("Focus window left"),
3698                             "window_focus", "left", NULL, 0);
3699    e_action_predef_name_set(N_("Window : Focus"),
3700                             N_("Focus window right"),
3701                             "window_focus", "right", NULL, 0);
3702 
3703    /* menu_show */
3704    ACT_GO(menu_show);
3705    e_action_predef_name_set(N_("Menu"), N_("Show Main Menu"),
3706                             "menu_show", "main", NULL, 0);
3707    e_action_predef_name_set(N_("Menu"), N_("Show Favorites Menu"), "menu_show",
3708                             "favorites", NULL, 0);
3709    e_action_predef_name_set(N_("Menu"), N_("Show All Applications Menu"),
3710                             "menu_show", "all", NULL, 0);
3711    e_action_predef_name_set(N_("Menu"), N_("Show Clients Menu"), "menu_show",
3712                             "clients", NULL, 0);
3713    e_action_predef_name_set(N_("Menu"), N_("Show Menu..."), "menu_show", NULL,
3714                             "syntax: MenuName, example: MyMenu", 1);
3715    ACT_GO_MOUSE(menu_show);
3716    ACT_GO_KEY(menu_show);
3717 
3718    /* internal: for showing a menu from an object */
3719    ACT_GO(menu_show_object);
3720 
3721    /* exec */
3722    ACT_GO(exec);
3723    e_action_predef_name_set(N_("Launch"), N_("Command"), "exec", NULL,
3724                             "syntax: CommandName, example: /usr/bin/xmms", 1);
3725 
3726    /* app */
3727    ACT_GO(app);
3728    e_action_predef_name_set(N_("Launch"), N_("Application"), "app", NULL,
3729                             "syntax: [file:file.desktop|name:App Name|generic:Generic Name|exe:exename], example: file:terminology.desktop | file:/path/to/terminology.desktop | name:Terminology | generic:Terminal Emulator | exe:xterm", 1);
3730 
3731    /* new instance of focused app */
3732    ACT_GO(app_new_instance);
3733    e_action_predef_name_set(N_("Launch"), N_("New Instance of Focused App"), "app_new_instance", NULL,
3734                             NULL, 0);
3735 
3736    ACT_GO(restart);
3737    e_action_predef_name_set(N_("Enlightenment"), N_("Restart"), "restart",
3738                             NULL, NULL, 0);
3739 
3740    ACT_GO(exit);
3741    e_action_predef_name_set(N_("Enlightenment"), N_("Exit"), "exit",
3742                             NULL, NULL, 0);
3743 
3744    ACT_GO(exit_now);
3745    e_action_predef_name_set(N_("Enlightenment"), N_("Exit Now"),
3746                             "exit_now", NULL, NULL, 0);
3747 
3748    ACT_GO(mode_presentation_toggle);
3749    e_action_predef_name_set(N_("Enlightenment : Mode"),
3750                             N_("Presentation Mode Toggle"),
3751                             "mode_presentation_toggle", NULL, NULL, 0);
3752 
3753    ACT_GO(mode_offline_toggle);
3754    e_action_predef_name_set(N_("Enlightenment : Mode"),
3755                             N_("Offline Mode Toggle"),
3756                             "mode_offline_toggle", NULL, NULL, 0);
3757    /* modules */
3758    ACT_GO(module_enable);
3759    e_action_predef_name_set(N_("Enlightenment : Module"),
3760                             N_("Enable the named module"),
3761                             "module_enable", NULL, NULL, 1);
3762    ACT_GO(module_disable);
3763    e_action_predef_name_set(N_("Enlightenment : Module"),
3764                             N_("Disable the named module"),
3765                             "module_disable", NULL, NULL, 1);
3766    ACT_GO(module_toggle);
3767    e_action_predef_name_set(N_("Enlightenment : Module"),
3768                             N_("Toggle the named module"),
3769                             "module_toggle", NULL, NULL, 1);
3770 
3771    ACT_GO(logout);
3772    e_action_predef_name_set(N_("System"), N_("Log Out"), "logout",
3773                             NULL, NULL, 0);
3774 
3775    ACT_GO(halt_now);
3776    e_action_predef_name_set(N_("System"), N_("Power Off Now"),
3777                             "halt_now", NULL, NULL, 0);
3778 
3779    ACT_GO(halt);
3780    e_action_predef_name_set(N_("System"), N_("Power Off"), "halt",
3781                             NULL, NULL, 0);
3782 
3783    ACT_GO(reboot);
3784    e_action_predef_name_set(N_("System"), N_("Reboot"), "reboot",
3785                             NULL, NULL, 0);
3786 
3787    ACT_GO(suspend_now);
3788    e_action_predef_name_set(N_("System"), N_("Suspend Now"), "suspend_now",
3789                             NULL, NULL, 0);
3790 
3791    ACT_GO(suspend);
3792    e_action_predef_name_set(N_("System"), N_("Suspend"), "suspend",
3793                             NULL, NULL, 0);
3794 
3795    ACT_GO(suspend_smart);
3796    e_action_predef_name_set(N_("System"), N_("Suspend Intelligently"), "suspend_smart",
3797                             NULL, NULL, 0);
3798 
3799    ACT_GO(hibernate);
3800    e_action_predef_name_set(N_("System"), N_("Hibernate"), "hibernate",
3801                             NULL, NULL, 0);
3802 
3803    ACT_GO(hibernate_now);
3804    e_action_predef_name_set(N_("System"), N_("Hibernate Now"), "hibernate_now",
3805                             NULL, NULL, 0);
3806 
3807    ACT_GO(hibernate_smart);
3808    e_action_predef_name_set(N_("System"), N_("Hibernate Intelligently"), "hibernate_smart",
3809                             NULL, NULL, 0);
3810 
3811    ACT_GO(pointer_resize_push);
3812    ACT_GO(pointer_resize_pop);
3813 
3814    /* desk_lock */
3815    ACT_GO(desk_lock);
3816    e_action_predef_name_set(N_("Desktop"), N_("Lock"), "desk_lock",
3817                             NULL, NULL, 0);
3818 
3819    /* cleanup_windows */
3820    ACT_GO(cleanup_windows);
3821    e_action_predef_name_set(N_("Desktop"), N_("Cleanup Windows"),
3822                             "cleanup_windows", NULL, NULL, 0);
3823 
3824    /* delayed_action */
3825    ACT_GO_KEY(delayed_action);
3826    e_action_predef_name_set(N_("Generic : Actions"), N_("Delayed Action"),
3827                             "delayed_action", NULL, "[0.0 exec xterm] [0.3 exec xev]", 1);
3828    ACT_GO_MOUSE(delayed_action);
3829    ACT_END_KEY(delayed_action);
3830    ACT_END_MOUSE(delayed_action);
3831 
3832    /* xkb */
3833    ACT_GO(kbd_layout);
3834    e_action_predef_name_set(N_("Keyboard Layouts"),
3835                             N_("Use keyboard layout"), "kbd_layout",
3836                             NULL, "syntax: Keyboard-layout-name, example: us", 1);
3837    ACT_GO(kbd_layout_next);
3838    e_action_predef_name_set(N_("Keyboard Layouts"),
3839                             N_("Next keyboard layout"), "kbd_layout_next",
3840                             NULL, NULL, 0);
3841    ACT_GO(kbd_layout_prev);
3842    e_action_predef_name_set(N_("Keyboard Layouts"),
3843                             N_("Previous keyboard layout"), "kbd_layout_prev",
3844                             NULL, NULL, 0);
3845 
3846    ecore_job_add(_e_actions_post_init, NULL);
3847 
3848    return 1;
3849 }
3850 
3851 EINTERN int
e_actions_shutdown(void)3852 e_actions_shutdown(void)
3853 {
3854    Eina_List *tlist = NULL, *l;
3855    E_Action *act;
3856 
3857    e_action_predef_name_all_del();
3858 
3859    EINA_LIST_FOREACH(action_list, l, act)
3860      tlist = eina_list_append(tlist, act);
3861    EINA_LIST_FREE(tlist, act)
3862      e_object_del(E_OBJECT(act));
3863 
3864    action_names = eina_list_free(action_names);
3865    eina_hash_free(actions);
3866    actions = NULL;
3867 
3868    return 1;
3869 }
3870 
3871 E_API Eina_List *
e_action_name_list(void)3872 e_action_name_list(void)
3873 {
3874    return action_names;
3875 }
3876 
3877 E_API E_Action *
e_action_add(const char * name)3878 e_action_add(const char *name)
3879 {
3880    E_Action *act;
3881 
3882    act = e_action_find(name);
3883    if (!act)
3884      {
3885         act = E_OBJECT_ALLOC(E_Action, E_ACTION_TYPE, _e_action_free);
3886         if (!act) return NULL;
3887         act->name = name;
3888         eina_hash_direct_add(actions, act->name, act);
3889         action_names = eina_list_append(action_names, name);
3890         action_list = eina_list_append(action_list, act);
3891      }
3892    return act;
3893 }
3894 
3895 E_API void
e_action_del(const char * name)3896 e_action_del(const char *name)
3897 {
3898    E_Action *act;
3899 
3900    act = eina_hash_find(actions, name);
3901    if (act) _e_action_free(act);
3902 }
3903 
3904 E_API E_Action *
e_action_find(const char * name)3905 e_action_find(const char *name)
3906 {
3907    E_Action *act;
3908 
3909    act = eina_hash_find(actions, name);
3910    return act;
3911 }
3912 
3913 E_API const char *
e_action_predef_label_get(const char * action,const char * params)3914 e_action_predef_label_get(const char *action, const char *params)
3915 {
3916    E_Action_Group *actg = NULL;
3917    E_Action_Description *actd = NULL;
3918    Eina_List *l, *l2;
3919 
3920    EINA_LIST_FOREACH(action_groups, l, actg)
3921      {
3922         EINA_LIST_FOREACH(actg->acts, l2, actd)
3923           {
3924              if (!strcmp(actd->act_cmd, action))
3925                {
3926                   if ((params) && (actd->act_params))
3927                     {
3928                        if (!strcmp(params, actd->act_params))
3929                          return actd->act_name;
3930                     }
3931                   else return actd->act_name;
3932                }
3933           }
3934      }
3935    if (params) return e_action_predef_label_get(action, NULL);
3936    return NULL;
3937 }
3938 
3939 E_API void
e_action_predef_name_set(const char * act_grp,const char * act_name,const char * act_cmd,const char * act_params,const char * param_example,int editable)3940 e_action_predef_name_set(const char *act_grp, const char *act_name, const char *act_cmd, const char *act_params, const char *param_example, int editable)
3941 {
3942    E_Action_Group *actg = NULL;
3943    E_Action_Description *actd = NULL;
3944    Eina_List *l;
3945 
3946    if ((!act_grp) || (!act_name)) return;
3947 
3948    EINA_LIST_FOREACH(action_groups, l, actg)
3949      {
3950         if (!strcmp(actg->act_grp, act_grp)) break;
3951         actg = NULL;
3952      }
3953 
3954    if (!actg)
3955      {
3956         actg = E_NEW(E_Action_Group, 1);
3957         if (!actg) return;
3958 
3959         actg->act_grp = eina_stringshare_add(act_grp);
3960         action_groups = eina_list_append(action_groups, actg);
3961         action_groups =
3962           eina_list_sort(action_groups, -1, _action_groups_sort_cb);
3963      }
3964 
3965    EINA_LIST_FOREACH(actg->acts, l, actd)
3966      {
3967         if (!strcmp(actd->act_name, act_name)) break;
3968         actd = NULL;
3969      }
3970 
3971    if (actd) return;
3972 
3973    actd = E_NEW(E_Action_Description, 1);
3974    if (!actd) return;
3975 
3976    actd->act_name = eina_stringshare_add(act_name);
3977    actd->act_cmd = !act_cmd ? NULL : eina_stringshare_add(act_cmd);
3978    actd->act_params = !act_params ? NULL : eina_stringshare_add(act_params);
3979    actd->param_example = !param_example ? NULL : eina_stringshare_add(param_example);
3980    actd->editable = editable;
3981 
3982    actg->acts = eina_list_append(actg->acts, actd);
3983 }
3984 
3985 E_API void
e_action_predef_name_del(const char * act_grp,const char * act_name)3986 e_action_predef_name_del(const char *act_grp, const char *act_name)
3987 {
3988    E_Action_Group *actg = NULL;
3989    E_Action_Description *actd = NULL;
3990    Eina_List *l;
3991 
3992    EINA_LIST_FOREACH(action_groups, l, actg)
3993      {
3994         if (!strcmp(actg->act_grp, act_grp)) break;
3995         actg = NULL;
3996      }
3997 
3998    if (!actg) return;
3999 
4000    EINA_LIST_FOREACH(actg->acts, l, actd)
4001      {
4002         if (!strcmp(actd->act_name, act_name))
4003           {
4004              actg->acts = eina_list_remove(actg->acts, actd);
4005 
4006              if (actd->act_name) eina_stringshare_del(actd->act_name);
4007              if (actd->act_cmd) eina_stringshare_del(actd->act_cmd);
4008              if (actd->act_params) eina_stringshare_del(actd->act_params);
4009              if (actd->param_example) eina_stringshare_del(actd->param_example);
4010 
4011              E_FREE(actd);
4012 
4013              if (!eina_list_count(actg->acts))
4014                {
4015                   action_groups = eina_list_remove(action_groups, actg);
4016                   if (actg->act_grp) eina_stringshare_del(actg->act_grp);
4017                   E_FREE(actg);
4018                }
4019              break;
4020           }
4021      }
4022 }
4023 
4024 E_API void
e_action_predef_name_all_del(void)4025 e_action_predef_name_all_del(void)
4026 {
4027    E_Action_Group *actg = NULL;
4028    E_Action_Description *actd = NULL;
4029 
4030    EINA_LIST_FREE(action_groups, actg)
4031      {
4032         EINA_LIST_FREE(actg->acts, actd)
4033           {
4034              if (actd->act_name) eina_stringshare_del(actd->act_name);
4035              if (actd->act_cmd) eina_stringshare_del(actd->act_cmd);
4036              if (actd->act_params) eina_stringshare_del(actd->act_params);
4037              if (actd->param_example) eina_stringshare_del(actd->param_example);
4038 
4039              E_FREE(actd);
4040           }
4041         if (actg->act_grp) eina_stringshare_del(actg->act_grp);
4042         E_FREE(actg);
4043      }
4044    action_groups = NULL;
4045 }
4046 
4047 E_API Eina_List *
e_action_groups_get(void)4048 e_action_groups_get(void)
4049 {
4050    return action_groups;
4051 }
4052 
4053 /* local subsystem functions */
4054 
4055 static void
_e_action_free(E_Action * act)4056 _e_action_free(E_Action *act)
4057 {
4058    eina_hash_del(actions, act->name, act);
4059    action_names = eina_list_remove(action_names, act->name);
4060    action_list = eina_list_remove(action_list, act);
4061    free(act);
4062 }
4063 
4064 static E_Maximize
_e_actions_maximize_parse(const char * params)4065 _e_actions_maximize_parse(const char *params)
4066 {
4067    E_Maximize max = 0;
4068    int ret;
4069    char s1[32], s2[32];
4070 
4071    if (!params) return e_config->maximize_policy;
4072    ret = sscanf(params, "%20s %20s", s1, s2);
4073    if (ret == 2)
4074      {
4075         if (!strcmp(s2, "horizontal"))
4076           max = E_MAXIMIZE_HORIZONTAL;
4077         else if (!strcmp(s2, "vertical"))
4078           max = E_MAXIMIZE_VERTICAL;
4079         else if (!strcmp(s2, "left"))
4080           max = E_MAXIMIZE_LEFT;
4081         else if (!strcmp(s2, "right"))
4082           max = E_MAXIMIZE_RIGHT;
4083         else
4084           max = E_MAXIMIZE_BOTH;
4085      }
4086    if (ret >= 1)
4087      {
4088         if (!strcmp(s1, "fullscreen"))
4089           max |= E_MAXIMIZE_FULLSCREEN;
4090         else if (!strcmp(s1, "smart"))
4091           max |= E_MAXIMIZE_SMART;
4092         else if (!strcmp(s1, "expand"))
4093           max |= E_MAXIMIZE_EXPAND;
4094         else if (!strcmp(s1, "fill"))
4095           max |= E_MAXIMIZE_FILL;
4096         else
4097           max |= (e_config->maximize_policy & E_MAXIMIZE_TYPE);
4098      }
4099    else
4100      max = e_config->maximize_policy;
4101    return max;
4102 }
4103 
4104 static int
_action_groups_sort_cb(const void * d1,const void * d2)4105 _action_groups_sort_cb(const void *d1, const void *d2)
4106 {
4107    const E_Action_Group *g1, *g2;
4108 
4109    if (!(g1 = d1)) return 1;
4110    if (!(g2 = d2)) return -1;
4111    return strcmp(g1->act_grp, g2->act_grp);
4112 }
4113 
4114