e_service_taskbar: support auto_placement request
[platform/upstream/enlightenment.git] / src / bin / services / e_service_taskbar.c
1 #include "e.h"
2 #include "services/e_service_taskbar.h"
3
4 #include <wayland-server.h>
5 #include <tzsh_server.h>
6
7 static void _e_service_taskbar_update(E_Service_Taskbar *taskbar_service);
8
9 /* private data for taskbar */
10 static E_Service_Taskbar   *_taskbar_service = NULL;
11
12 /* event handler */
13 static E_Client_Hook       *_taskbar_del_hook = NULL;
14
15 EINTERN E_Client *
16 e_service_taskbar_client_get(void)
17 {
18    if (!_taskbar_service) return NULL;
19    return _taskbar_service->ec;
20 }
21
22 static void
23 _taskbar_client_unset(void)
24 {
25    E_FREE_LIST(_taskbar_service->events, ecore_event_handler_del);
26    E_FREE_FUNC(_taskbar_del_hook, e_client_hook_del);
27    E_FREE(_taskbar_service);
28 }
29
30 static void
31 _taskbar_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
32 {
33    if (!ec) return;
34    if (!_taskbar_service) return;
35    if (ec != _taskbar_service->ec) return;
36
37    ELOGF("TASKBAR","Del Client", ec);
38
39    e_zone_obstacle_remove(_taskbar_service->zone, ec);
40    _taskbar_client_unset();
41 }
42
43 static Eina_Bool
44 _taskbar_cb_client_zone_set(void *data, int type EINA_UNUSED, void *event)
45 {
46    E_Service_Taskbar *taskbar_service;
47    E_Event_Client_Zone_Set *ev;
48
49    taskbar_service = data;
50    ev = event;
51
52    if (taskbar_service->ec != ev->ec)
53      goto end;
54
55    if (taskbar_service->zone == ev->zone)
56      goto end;
57
58    ELOGF("TASKBAR", "Change Zone | taskbar_service %p old(%p) new(%p)",
59          taskbar_service->ec, taskbar_service, taskbar_service->zone, ev->zone);
60
61    taskbar_service->zone = ev->zone;
62    _e_service_taskbar_update(taskbar_service);
63
64 end:
65    return ECORE_CALLBACK_PASS_ON;
66 }
67
68 EINTERN Eina_Bool
69 e_service_taskbar_client_set(E_Client *ec)
70 {
71    E_Layer layer;
72    E_Service_Taskbar *taskbar_service;
73
74    if (!ec) return EINA_FALSE;
75    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
76
77    if (_taskbar_service)
78      {
79         ELOGF("TASKBAR", "Taskbar is already registered. registered(%p)", ec, _taskbar_service->ec);
80         return EINA_FALSE;
81      }
82
83    taskbar_service = E_NEW(E_Service_Taskbar, 1);
84    EINA_SAFETY_ON_NULL_RETURN_VAL(taskbar_service, EINA_FALSE);
85
86    ELOGF("TASKBAR","Set Client", ec);
87
88    taskbar_service->ec = ec;
89    taskbar_service->zone = e_comp_zone_find_by_ec(ec);
90    taskbar_service->x = ec->x;
91    taskbar_service->y = ec->y;
92    taskbar_service->w = ec->w;
93    taskbar_service->h = ec->h;
94
95    _taskbar_service = taskbar_service;
96
97    _taskbar_del_hook =
98       e_client_hook_add(E_CLIENT_HOOK_DEL, _taskbar_hook_client_del, NULL);
99    E_LIST_HANDLER_APPEND(taskbar_service->events, E_EVENT_CLIENT_ZONE_SET, _taskbar_cb_client_zone_set, taskbar_service);
100
101    // set taskbar layer
102    if (e_config->use_desk_area)
103      layer = e_client_desk_area_original_layer_get(ec);
104    else
105      layer = e_client_layer_get(ec);
106
107    if (E_POLICY_TASKBAR_LAYER != layer)
108      {
109         e_client_layer_set(ec, E_POLICY_TASKBAR_LAYER);
110      }
111
112    // set skip iconify
113    ec->exp_iconify.skip_iconify = 1;
114
115    // set skip focus
116    ec->icccm.accepts_focus = ec->icccm.take_focus = 0;
117
118    e_zone_obstacle_add(taskbar_service->zone, ec,
119                        &(Eina_Rectangle){_taskbar_service->x, _taskbar_service->y, _taskbar_service->w, _taskbar_service->h},
120                        0);
121
122    return EINA_TRUE;
123 }
124
125 static void
126 _e_service_taskbar_update(E_Service_Taskbar *taskbar_service)
127 {
128    Eina_Bool vertical;
129    E_Client *ec;
130
131    if (!taskbar_service->ec) return;
132    if (!taskbar_service->zone) return;
133
134    ec = taskbar_service->ec;
135
136    if (taskbar_service->place_type == 0)
137      {
138         taskbar_service->x = 0;
139         taskbar_service->y = taskbar_service->zone->h - taskbar_service->h;
140         vertical = EINA_FALSE;
141      }
142    else if (taskbar_service->place_type == 1)
143      {
144         taskbar_service->x = 0;
145         taskbar_service->y = 0;
146         vertical = EINA_FALSE;
147      }
148    else if (taskbar_service->place_type == 2)
149      {
150         taskbar_service->x = 0;
151         taskbar_service->y = 0;
152         vertical = EINA_TRUE;
153      }
154    else
155      {
156         taskbar_service->x = taskbar_service->zone->w - taskbar_service->w;
157         taskbar_service->y = 0;
158         vertical = EINA_TRUE;
159      }
160
161    if (taskbar_service->auto_placement == EINA_TRUE)
162      e_client_util_move_without_frame(ec, taskbar_service->x, taskbar_service->y);
163
164    e_zone_obstacle_update(taskbar_service->zone, ec,
165                           &(Eina_Rectangle){taskbar_service->x, taskbar_service->y, taskbar_service->w, taskbar_service->h},
166                           vertical);
167 }
168
169 EINTERN Eina_Bool
170 e_service_taskbar_place_type_set(E_Client *ec, int type)
171 {
172    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
173    EINA_SAFETY_ON_NULL_RETURN_VAL(_taskbar_service, EINA_FALSE);
174
175    ELOGF("TASKBAR", "Set PLACE_TYPE... type:%d", ec, type);
176
177    if (ec != _taskbar_service->ec)
178      {
179         ELOGF("TASKBAR", "ERROR... Taskbar ec is not matched...regisered(%p)..", ec, _taskbar_service->ec);
180         return EINA_FALSE;
181      }
182
183    if (type == _taskbar_service->place_type)
184      return EINA_TRUE;
185
186    _taskbar_service->place_type = type;
187
188    _e_service_taskbar_update(_taskbar_service);
189    return EINA_TRUE;
190 }
191
192 EINTERN Eina_Bool
193 e_service_taskbar_size_set(E_Client *ec, unsigned int w, unsigned int h)
194 {
195    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
196    EINA_SAFETY_ON_NULL_RETURN_VAL(_taskbar_service, EINA_FALSE);
197
198    ELOGF("TASKBAR", "Set SIZE... size:%dx%d)", ec, w, h);
199
200    if (ec != _taskbar_service->ec)
201      {
202         ELOGF("TASKBAR", "ERROR... Taskbar ec is not matched...regisered(%p)..", ec, _taskbar_service->ec);
203         return EINA_FALSE;
204      }
205
206    if (w == 0)
207      _taskbar_service->w = ec->w;
208    else
209      _taskbar_service->w = w;
210
211    if (h == 0)
212      _taskbar_service->h = ec->h;
213    else
214      _taskbar_service->h = h;
215
216    _e_service_taskbar_update(_taskbar_service);
217    return EINA_TRUE;
218 }
219
220 EINTERN Eina_Bool
221 e_service_taskbar_auto_placement_set(E_Client *ec, Eina_Bool set)
222 {
223    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
224    EINA_SAFETY_ON_NULL_RETURN_VAL(_taskbar_service, EINA_FALSE);
225
226    ELOGF("TASKBAR", "Set Auto Placement to %d", ec, set);
227
228    if (ec != _taskbar_service->ec)
229      {
230         ELOGF("TASKBAR", "ERROR... Taskbar ec is not matched...regisered(%p)..", ec, _taskbar_service->ec);
231         return EINA_FALSE;
232      }
233
234    if (set == _taskbar_service->auto_placement)
235      return EINA_TRUE;
236
237    _taskbar_service->auto_placement = set;
238    _e_service_taskbar_update(_taskbar_service);
239
240    return EINA_TRUE;
241 }