2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the COPYING file for the original copyright owner and
22 //#define INOUTDEBUG_MOUSE 1
23 //#define INOUTDEBUG_FOCUS 1
25 /* These are compatible with netwm */
35 #define RESIZE_NONE 11
37 /* local subsystem functions */
38 static void _e_border_pri_raise(E_Border *bd);
39 static void _e_border_pri_norm(E_Border *bd);
40 static void _e_border_free(E_Border *bd);
41 static void _e_border_del(E_Border *bd);
43 #ifdef PRINT_LOTS_OF_DEBUG
44 #define E_PRINT_BORDER_INFO(X) \
45 _e_border_print(X, __PRETTY_FUNC__)
47 static void _e_border_print(E_Border *bd,
51 /* FIXME: these likely belong in a separate icccm/client handler */
52 /* and the border needs to become a dumb object that just does what its */
54 static Eina_Bool _e_border_cb_window_show_request(void *data,
57 static Eina_Bool _e_border_cb_window_destroy(void *data,
60 static Eina_Bool _e_border_cb_window_hide(void *data,
63 static Eina_Bool _e_border_cb_window_reparent(void *data,
66 static Eina_Bool _e_border_cb_window_configure_request(void *data,
69 static Eina_Bool _e_border_cb_window_resize_request(void *data,
72 static Eina_Bool _e_border_cb_window_gravity(void *data,
75 static Eina_Bool _e_border_cb_window_stack_request(void *data,
78 static Eina_Bool _e_border_cb_window_property(void *data,
81 static Eina_Bool _e_border_cb_window_colormap(void *data,
84 static Eina_Bool _e_border_cb_window_shape(void *data,
87 static Eina_Bool _e_border_cb_window_focus_in(void *data,
90 static Eina_Bool _e_border_cb_window_focus_out(void *data,
93 static Eina_Bool _e_border_cb_client_message(void *data,
97 static Eina_Bool _e_border_cb_window_state_request(void *data,
100 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
103 static Eina_Bool _e_border_cb_desktop_change(void *data,
106 static Eina_Bool _e_border_cb_sync_alarm(void *data,
109 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
112 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
116 static Eina_Bool _e_border_cb_pointer_warp(void *data,
119 static void _e_border_cb_signal_bind(void *data,
121 const char *emission,
123 static Eina_Bool _e_border_cb_mouse_in(void *data,
126 static Eina_Bool _e_border_cb_mouse_out(void *data,
129 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
132 static Eina_Bool _e_border_cb_mouse_down(void *data,
135 static Eina_Bool _e_border_cb_mouse_up(void *data,
138 static Eina_Bool _e_border_cb_mouse_move(void *data,
141 static Eina_Bool _e_border_cb_grab_replay(void *data,
144 static void _e_border_cb_drag_finished(E_Drag *drag,
146 #ifdef _F_USE_DESK_WINDOW_PROFILE_
147 static Eina_Bool _e_border_cb_desk_window_profile_change(void *data,
151 #ifdef _F_ZONE_WINDOW_ROTATION_
152 static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data,
155 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
156 static void _e_border_rotation_change_request(E_Zone *zone);
157 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
158 static void _e_border_rotation_change_done(void);
159 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
167 static Eina_Bool _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd);
168 static void _e_border_rotation_list_remove(E_Border *bd);
169 static Eina_Bool _e_border_rotation_check(E_Border *bd);
170 static Eina_Bool _e_border_rotation_zone_check(E_Zone *zone);
171 static Eina_Bool _e_border_rotation_border_check(E_Border *bd, int ang);
172 static Eina_Bool _e_border_rotation_zone_vkbd_check(E_Zone *zone);
173 static Eina_Bool _e_border_rotation_vkbd_transient_for_check(E_Border *bd);
174 static Eina_Bool _e_border_rotation_transient_for_check(E_Border *bd, int ang);
175 static Eina_Bool _e_border_cb_window_configure(void *data,
178 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
179 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
180 static void _e_border_vkbd_show(E_Border *bd);
181 static void _e_border_vkbd_hide(E_Border *bd);
183 static void _e_border_move_resize_internal(E_Border *bd,
188 Eina_Bool without_border,
191 static void _e_border_eval(E_Border *bd);
192 static void _e_border_eval0(E_Border *bd);
193 static void _e_border_container_layout_hook(E_Container *con);
195 static void _e_border_moveinfo_gather(E_Border *bd,
197 static void _e_border_resize_handle(E_Border *bd);
199 static Eina_Bool _e_border_shade_animator(void *data);
201 static void _e_border_event_border_add_free(void *data,
203 static void _e_border_event_border_remove_free(void *data,
205 static void _e_border_event_border_zone_set_free(void *data,
207 static void _e_border_event_border_desk_set_free(void *data,
209 static void _e_border_event_border_stack_free(void *data,
211 static void _e_border_event_border_icon_change_free(void *data,
213 static void _e_border_event_border_urgent_change_free(void *data,
215 static void _e_border_event_border_focus_in_free(void *data,
217 static void _e_border_event_border_focus_out_free(void *data,
219 static void _e_border_event_border_resize_free(void *data,
221 static void _e_border_event_border_move_free(void *data,
223 static void _e_border_event_border_show_free(void *data,
225 static void _e_border_event_border_hide_free(void *data,
227 static void _e_border_event_border_iconify_free(void *data,
229 static void _e_border_event_border_uniconify_free(void *data,
231 static void _e_border_event_border_stick_free(void *data,
233 static void _e_border_event_border_unstick_free(void *data,
235 static void _e_border_event_border_property_free(void *data,
237 static void _e_border_event_border_fullscreen_free(void *data,
239 static void _e_border_event_border_unfullscreen_free(void *data,
241 #ifdef _F_ZONE_WINDOW_ROTATION_
242 static void _e_border_event_border_rotation_change_begin_free(void *data,
244 static void _e_border_event_border_rotation_change_cancel_free(void *data,
246 static void _e_border_event_border_rotation_change_end_free(void *data,
248 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
251 static void _e_border_zone_update(E_Border *bd);
253 static int _e_border_resize_begin(E_Border *bd);
254 static int _e_border_resize_end(E_Border *bd);
255 static void _e_border_resize_update(E_Border *bd);
257 static int _e_border_move_begin(E_Border *bd);
258 static int _e_border_move_end(E_Border *bd);
259 static void _e_border_move_update(E_Border *bd);
261 static Eina_Bool _e_border_cb_ping_poller(void *data);
262 static Eina_Bool _e_border_cb_kill_timer(void *data);
264 static void _e_border_pointer_resize_begin(E_Border *bd);
265 static void _e_border_pointer_resize_end(E_Border *bd);
266 static void _e_border_pointer_move_begin(E_Border *bd);
267 static void _e_border_pointer_move_end(E_Border *bd);
269 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
272 static void _e_border_client_move_resize_send(E_Border *bd);
274 static void _e_border_frame_replace(E_Border *bd,
277 static void _e_border_shape_input_rectangle_set(E_Border* bd);
278 static void _e_border_show(E_Border *bd);
279 static void _e_border_hide(E_Border *bd);
282 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
283 static void _e_border_latest_stacked_focus (E_Border* bd);
284 static void _e_border_check_stack (E_Border *bd);
285 static void _e_border_focus_top_stack_set (E_Border* bd);
287 #if _F_BORDER_CLIP_TO_ZONE_
288 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
289 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
290 /* local subsystem globals */
291 static Eina_List *handlers = NULL;
292 static Eina_List *borders = NULL;
293 static Eina_Hash *borders_hash = NULL;
294 static E_Border *focused = NULL;
295 static E_Border *focusing = NULL;
296 static Eina_List *focus_next = NULL;
297 static Ecore_X_Time focus_time = 0;
299 static E_Border *bdresize = NULL;
300 static E_Border *bdmove = NULL;
301 static E_Drag *drag_border = NULL;
303 static int grabbed = 0;
305 static Eina_List *focus_stack = NULL;
306 static Eina_List *raise_stack = NULL;
308 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
309 static int screen_size_index = -1;
311 static int focus_track_frozen = 0;
313 static int warp_to = 0;
314 static int warp_to_x = 0;
315 static int warp_to_y = 0;
316 static int warp_x = 0;
317 static int warp_y = 0;
318 static Ecore_X_Window warp_to_win;
319 static Ecore_Timer *warp_timer = NULL;
321 #ifdef _F_ZONE_WINDOW_ROTATION_
322 typedef struct _E_Border_Rotation E_Border_Rotation;
323 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
325 struct _E_Border_Rotation
329 Eina_Bool wait_prepare_done;
330 Ecore_Timer *prepare_timer;
331 Ecore_Timer *done_timer;
333 Ecore_X_Window vkbd_ctrl_win;
335 E_Border *vkbd_prediction;
337 /* vkbd show/hide preprare */
338 Eina_Bool vkbd_show_prepare_done;
339 Ecore_Timer *vkbd_show_prepare_timer;
340 Ecore_Timer *vkbd_show_timer;
342 Eina_Bool vkbd_hide_prepare_done;
343 Ecore_Timer *vkbd_hide_prepare_timer;
344 Ecore_Timer *vkbd_hide_timer;
350 struct _E_Border_Rotation_Info
355 Eina_Bool win_resize;
358 static E_Border_Rotation rot =
378 EAPI int E_EVENT_BORDER_ADD = 0;
379 EAPI int E_EVENT_BORDER_REMOVE = 0;
380 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
381 EAPI int E_EVENT_BORDER_DESK_SET = 0;
382 EAPI int E_EVENT_BORDER_RESIZE = 0;
383 EAPI int E_EVENT_BORDER_MOVE = 0;
384 EAPI int E_EVENT_BORDER_SHOW = 0;
385 EAPI int E_EVENT_BORDER_HIDE = 0;
386 EAPI int E_EVENT_BORDER_ICONIFY = 0;
387 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
388 EAPI int E_EVENT_BORDER_STICK = 0;
389 EAPI int E_EVENT_BORDER_UNSTICK = 0;
390 EAPI int E_EVENT_BORDER_STACK = 0;
391 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
392 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
393 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
394 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
395 EAPI int E_EVENT_BORDER_PROPERTY = 0;
396 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
397 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
398 #ifdef _F_ZONE_WINDOW_ROTATION_
399 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
400 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
401 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
402 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
405 #define GRAV_SET(bd, grav) \
406 ecore_x_window_gravity_set(bd->bg_win, grav); \
407 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
408 ecore_x_window_gravity_set(bd->client.win, grav);
411 _e_border_sub_borders_new(E_Border *bd)
413 Eina_List *list = NULL, *l;
417 EINA_LIST_FOREACH(bd->transients, l, child)
419 if (!eina_list_data_find(list, child))
420 list = eina_list_append(list, child);
422 bl = e_container_border_list_first(bd->zone->container);
423 while ((child = e_container_border_list_next(bl)))
425 if (e_object_is_del(E_OBJECT(child))) continue;
426 if (child == bd) continue;
428 if ((bd->client.icccm.client_leader) &&
429 (child->client.icccm.client_leader ==
430 bd->client.icccm.client_leader))
432 printf("bd %s in group with %s\n",
433 e_border_name_get(child),
434 e_border_name_get(bd));
435 if (!eina_list_data_find(list, child))
436 list = eina_list_append(list, child);
440 e_container_border_list_free(bl);
444 /* externally accessible functions */
448 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
449 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
450 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
451 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
452 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
453 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
454 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
466 #ifdef _F_ZONE_WINDOW_ROTATION_
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
470 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
472 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
473 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
474 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
475 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
476 #ifdef _F_USE_DESK_WINDOW_PROFILE_
477 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
479 #ifdef _F_ZONE_WINDOW_ROTATION_
480 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
483 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
485 E_EVENT_BORDER_ADD = ecore_event_type_new();
486 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
487 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
488 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
489 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
490 E_EVENT_BORDER_MOVE = ecore_event_type_new();
491 E_EVENT_BORDER_SHOW = ecore_event_type_new();
492 E_EVENT_BORDER_HIDE = ecore_event_type_new();
493 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
494 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
495 E_EVENT_BORDER_STICK = ecore_event_type_new();
496 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
497 E_EVENT_BORDER_STACK = ecore_event_type_new();
498 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
499 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
500 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
501 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
502 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
503 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
504 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
505 #ifdef _F_ZONE_WINDOW_ROTATION_
506 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
507 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
508 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
509 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
518 e_border_shutdown(void)
520 E_FREE_LIST(handlers, ecore_event_handler_del);
522 if (borders_hash) eina_hash_free(borders_hash);
524 e_int_border_menu_hooks_clear();
530 e_border_new(E_Container *con,
536 Ecore_X_Window_Attributes *att;
537 unsigned int managed, desk[2];
540 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
541 if (!bd) return NULL;
542 ecore_x_window_shadow_tree_flush();
543 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
547 /* FIXME: ewww - round trip */
548 bd->client.argb = ecore_x_window_argb_get(win);
550 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
553 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
554 ecore_x_window_shape_events_select(bd->win, 1);
556 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
557 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
559 bd->bg_ecore_evas = e_canvas_new(bd->win,
560 0, 0, bd->w, bd->h, 1, 0,
562 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
563 e_canvas_add(bd->bg_ecore_evas);
564 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
565 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
566 ecore_x_window_shape_events_select(bd->bg_win, 1);
567 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
568 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
570 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
572 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
573 ecore_x_window_container_manage(bd->client.shell_win);
574 if (!internal) ecore_x_window_client_manage(win);
575 /* FIXME: Round trip. XCB */
576 /* fetch needed to avoid grabbing the server as window may vanish */
577 att = &bd->client.initial_attributes;
578 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
580 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
581 e_canvas_del(bd->bg_ecore_evas);
582 ecore_evas_free(bd->bg_ecore_evas);
583 ecore_x_window_free(bd->client.shell_win);
584 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
585 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
586 ecore_x_window_free(bd->win);
591 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
592 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
594 /* FIXME: if first_map is 1 then we should ignore the first hide event
595 * or ensure the window is already hidden and events flushed before we
596 * create a border for it */
599 // printf("##- FIRST MAP\n");
604 // needed to be 1 for internal windw and on restart.
605 // bd->ignore_first_unmap = 2;
608 bd->client.win = win;
609 bd->zone = e_zone_current_get(con);
611 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
613 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
614 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
615 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
616 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
617 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
618 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
620 bd->client.icccm.title = NULL;
621 bd->client.icccm.name = NULL;
622 bd->client.icccm.class = NULL;
623 bd->client.icccm.icon_name = NULL;
624 bd->client.icccm.machine = NULL;
625 bd->client.icccm.min_w = 1;
626 bd->client.icccm.min_h = 1;
627 bd->client.icccm.max_w = 32767;
628 bd->client.icccm.max_h = 32767;
629 bd->client.icccm.base_w = 0;
630 bd->client.icccm.base_h = 0;
631 bd->client.icccm.step_w = -1;
632 bd->client.icccm.step_h = -1;
633 bd->client.icccm.min_aspect = 0.0;
634 bd->client.icccm.max_aspect = 0.0;
635 bd->client.icccm.accepts_focus = 1;
637 bd->client.netwm.pid = 0;
638 bd->client.netwm.name = NULL;
639 bd->client.netwm.icon_name = NULL;
640 bd->client.netwm.desktop = 0;
641 bd->client.netwm.state.modal = 0;
642 bd->client.netwm.state.sticky = 0;
643 bd->client.netwm.state.shaded = 0;
644 bd->client.netwm.state.hidden = 0;
645 bd->client.netwm.state.maximized_v = 0;
646 bd->client.netwm.state.maximized_h = 0;
647 bd->client.netwm.state.skip_taskbar = 0;
648 bd->client.netwm.state.skip_pager = 0;
649 bd->client.netwm.state.fullscreen = 0;
650 bd->client.netwm.state.stacking = E_STACKING_NONE;
651 bd->client.netwm.action.move = 0;
652 bd->client.netwm.action.resize = 0;
653 bd->client.netwm.action.minimize = 0;
654 bd->client.netwm.action.shade = 0;
655 bd->client.netwm.action.stick = 0;
656 bd->client.netwm.action.maximized_h = 0;
657 bd->client.netwm.action.maximized_v = 0;
658 bd->client.netwm.action.fullscreen = 0;
659 bd->client.netwm.action.change_desktop = 0;
660 bd->client.netwm.action.close = 0;
661 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
667 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
668 bd->client.icccm.fetch.command = 1;
671 Eina_Bool video_parent = EINA_FALSE;
672 Eina_Bool video_position = EINA_FALSE;
675 for (i = 0; i < at_num; i++)
677 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
678 bd->client.icccm.fetch.title = 1;
679 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
680 bd->client.icccm.fetch.name_class = 1;
681 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
682 bd->client.icccm.fetch.icon_name = 1;
683 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
684 bd->client.icccm.fetch.machine = 1;
685 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
686 bd->client.icccm.fetch.hints = 1;
687 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
688 bd->client.icccm.fetch.size_pos_hints = 1;
689 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
690 bd->client.icccm.fetch.protocol = 1;
691 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
692 bd->client.mwm.fetch.hints = 1;
693 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
695 bd->client.icccm.fetch.transient_for = 1;
696 bd->client.netwm.fetch.type = 1;
698 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
699 bd->client.icccm.fetch.client_leader = 1;
700 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
701 bd->client.icccm.fetch.window_role = 1;
702 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
703 bd->client.icccm.fetch.state = 1;
705 /* netwm, loop again, netwm will ignore some icccm, so we
706 * have to be sure that netwm is checked after */
707 for (i = 0; i < at_num; i++)
709 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
712 bd->client.icccm.fetch.title = 0;
713 bd->client.netwm.fetch.name = 1;
715 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
718 bd->client.icccm.fetch.icon_name = 0;
719 bd->client.netwm.fetch.icon_name = 1;
721 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
723 bd->client.netwm.fetch.icon = 1;
725 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
727 bd->client.netwm.fetch.user_time = 1;
729 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
731 DBG("ECORE_X_ATOM_NET_WM_STRUT");
732 bd->client.netwm.fetch.strut = 1;
734 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
736 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
737 bd->client.netwm.fetch.strut = 1;
739 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
742 bd->client.mwm.fetch.hints = 0;
744 bd->client.netwm.fetch.type = 1;
746 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
748 bd->client.netwm.fetch.state = 1;
751 /* other misc atoms */
752 for (i = 0; i < at_num; i++)
754 /* loop to check for own atoms */
755 if (atoms[i] == E_ATOM_WINDOW_STATE)
757 bd->client.e.fetch.state = 1;
759 /* loop to check for qtopia atoms */
760 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
761 bd->client.qtopia.fetch.soft_menu = 1;
762 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
763 bd->client.qtopia.fetch.soft_menus = 1;
764 /* loop to check for vkbd atoms */
765 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
766 bd->client.vkbd.fetch.state = 1;
767 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
768 bd->client.vkbd.fetch.vkbd = 1;
769 /* loop to check for illume atoms */
770 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
771 bd->client.illume.conformant.fetch.conformant = 1;
772 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
773 bd->client.illume.quickpanel.fetch.state = 1;
774 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
775 bd->client.illume.quickpanel.fetch.quickpanel = 1;
776 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
777 bd->client.illume.quickpanel.fetch.priority.major = 1;
778 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
779 bd->client.illume.quickpanel.fetch.priority.minor = 1;
780 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
781 bd->client.illume.quickpanel.fetch.zone = 1;
782 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
783 bd->client.illume.drag.fetch.locked = 1;
784 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
785 bd->client.illume.drag.fetch.drag = 1;
786 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
787 bd->client.illume.win_state.fetch.state = 1;
788 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
789 video_parent = EINA_TRUE;
790 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
791 video_position = EINA_TRUE;
792 #ifdef _F_USE_DESK_WINDOW_PROFILE_
793 /* loop to check for window profile list atom */
794 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
795 bd->client.e.fetch.profile_list = 1;
797 #ifdef _F_ZONE_WINDOW_ROTATION_
798 /* loop to check for wm rotation */
799 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
801 if (e_config->wm_win_rotation)
802 bd->client.e.fetch.rot.support = 1;
804 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
805 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
806 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
807 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
809 if (e_config->wm_win_rotation)
810 bd->client.e.fetch.rot.geom_hint = 1;
812 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
814 if (e_config->wm_win_rotation)
815 bd->client.e.fetch.rot.app_set = 1;
817 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
819 if (e_config->wm_win_rotation)
820 bd->client.e.fetch.rot.preferred_rot = 1;
822 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
824 if (e_config->wm_win_rotation)
825 bd->client.e.fetch.rot.available_rots = 1;
828 #ifdef _F_DEICONIFY_APPROVE_
829 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
831 bd->client.e.state.deiconify_approve.support = 1;
835 if (video_position && video_parent)
837 bd->client.e.state.video = 1;
838 bd->client.e.fetch.video_parent = 1;
839 bd->client.e.fetch.video_position = 1;
840 ecore_x_window_lower(bd->win);
841 ecore_x_composite_window_events_disable(bd->win);
842 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
843 fprintf(stderr, "We found a video window \\o/ %x\n", win);
848 bd->client.border.changed = 1;
850 bd->client.w = att->w;
851 bd->client.h = att->h;
853 bd->w = bd->client.w;
854 bd->h = bd->client.h;
856 bd->resize_mode = RESIZE_NONE;
858 bd->saved.layer = bd->layer;
859 bd->changes.icon = 1;
860 bd->changes.size = 1;
861 bd->changes.shape = 1;
862 bd->changes.shape_input = 1;
864 bd->offer_resistance = 1;
866 /* just to friggin make java happy - we're DELAYING the reparent until
869 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
870 bd->need_reparent = 1;
872 ecore_x_window_border_width_set(win, 0);
873 ecore_x_window_show(bd->event_win);
874 ecore_x_window_show(bd->client.shell_win);
875 bd->shape = e_container_shape_add(con);
880 #ifdef _F_ZONE_WINDOW_ROTATION_
881 bd->client.e.state.rot.preferred_rot = -1;
884 // bd->zone = e_zone_current_get(con);
885 bd->desk = e_desk_current_get(bd->zone);
886 e_container_border_add(bd);
887 borders = eina_list_append(borders, bd);
888 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
892 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
893 "optimisations failing due to bizarre client behavior. will\n"
895 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
896 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
899 ELBF(ELBT_BD, 0, bd->client.win,
900 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
901 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
903 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
904 printf("optimisations failing due to bizarre client behavior. will\n");
905 printf("work around.\n");
906 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
907 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
910 ELBF(ELBT_BD, 0, bd->client.win,
911 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
912 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
915 #ifdef _F_ZONE_WINDOW_ROTATION_
916 if ((rot.vkbd) && (rot.vkbd == bd2))
918 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
919 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
920 rot.vkbd_hide_prepare_done);
922 if (rot.vkbd_hide_prepare_timer)
924 ecore_timer_del(rot.vkbd_hide_prepare_timer);
925 rot.vkbd_hide_prepare_timer = NULL;
927 e_object_unref(E_OBJECT(bd2));
930 _e_border_vkbd_hide(rot.vkbd);
932 if (rot.vkbd_ctrl_win)
934 ELB(ELBT_BD, "SET KBD_OFF", 0);
935 ecore_x_e_virtual_keyboard_state_set
936 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
938 rot.vkbd_hide_prepare_done = EINA_FALSE;
940 if (rot.vkbd_hide_timer)
941 ecore_timer_del(rot.vkbd_hide_timer);
942 rot.vkbd_hide_timer = NULL;
944 rot.vkbd_show_prepare_done = EINA_FALSE;
945 if (rot.vkbd_show_prepare_timer)
946 ecore_timer_del(rot.vkbd_show_prepare_timer);
947 rot.vkbd_show_prepare_timer = NULL;
948 if (rot.vkbd_show_timer)
949 ecore_timer_del(rot.vkbd_show_timer);
950 rot.vkbd_show_timer = NULL;
955 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
956 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
957 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
959 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
960 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
961 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
963 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
964 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
965 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
967 unsigned int zgeom[4];
969 zgeom[0] = bd->zone->x;
970 zgeom[1] = bd->zone->y;
971 zgeom[2] = bd->zone->w;
972 zgeom[3] = bd->zone->h;
973 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
975 e_desk_xy_get(bd->desk, &deskx, &desky);
978 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
979 #ifdef _F_USE_DESK_WINDOW_PROFILE_
980 if (strcmp(bd->desk->window_profile,
981 e_config->desktop_default_window_profile) != 0)
983 ecore_x_e_window_profile_set(bd->client.win,
984 bd->desk->window_profile);
988 focus_stack = eina_list_append(focus_stack, bd);
990 bd->pointer = e_pointer_window_new(bd->win, 0);
995 e_border_res_change_geometry_save(E_Border *bd)
998 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1000 if (bd->pre_res_change.valid) return;
1001 bd->pre_res_change.valid = 1;
1002 bd->pre_res_change.x = bd->x;
1003 bd->pre_res_change.y = bd->y;
1004 bd->pre_res_change.w = bd->w;
1005 bd->pre_res_change.h = bd->h;
1006 bd->pre_res_change.saved.x = bd->saved.x;
1007 bd->pre_res_change.saved.y = bd->saved.y;
1008 bd->pre_res_change.saved.w = bd->saved.w;
1009 bd->pre_res_change.saved.h = bd->saved.h;
1013 e_border_res_change_geometry_restore(E_Border *bd)
1017 unsigned char valid : 1;
1026 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1027 if (!bd->pre_res_change.valid) return;
1028 if (bd->new_client) return;
1030 ecore_x_window_shadow_tree_flush();
1031 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1035 e_border_unfullscreen(bd);
1036 e_border_fullscreen(bd, e_config->fullscreen_policy);
1038 else if (bd->maximized != E_MAXIMIZE_NONE)
1042 max = bd->maximized;
1043 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1044 e_border_maximize(bd, max);
1048 int x, y, w, h, zx, zy, zw, zh;
1050 bd->saved.x = bd->pre_res_change.saved.x;
1051 bd->saved.y = bd->pre_res_change.saved.y;
1052 bd->saved.w = bd->pre_res_change.saved.w;
1053 bd->saved.h = bd->pre_res_change.saved.h;
1055 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1057 if (bd->saved.w > zw)
1059 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1060 bd->saved.x = zx + zw - bd->saved.w;
1062 if (bd->saved.h > zh)
1064 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1065 bd->saved.y = zy + zh - bd->saved.h;
1067 x = bd->pre_res_change.x;
1068 y = bd->pre_res_change.y;
1069 w = bd->pre_res_change.w;
1070 h = bd->pre_res_change.h;
1075 if ((x + w) > (zx + zw))
1077 if ((y + h) > (zy + zh))
1079 e_border_move_resize(bd, x, y, w, h);
1081 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1085 e_border_zone_set(E_Border *bd,
1088 E_Event_Border_Zone_Set *ev;
1091 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1092 E_OBJECT_CHECK(zone);
1093 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1095 if (bd->zone == zone) return;
1097 /* if the window does not lie in the new zone, move it so that it does */
1098 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1101 /* first guess -- get offset from old zone, and apply to new zone */
1102 x = zone->x + (bd->x - bd->zone->x);
1103 y = zone->y + (bd->y - bd->zone->y);
1105 /* keep window from hanging off bottom and left */
1106 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1107 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1109 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1110 if (x < zone->x) x = zone->x;
1111 if (y < zone->y) y = zone->y;
1113 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1115 /* still not in zone at all, so just move it to closest edge */
1116 if (x < zone->x) x = zone->x;
1117 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1118 if (y < zone->y) y = zone->y;
1119 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1121 e_border_move(bd, x, y);
1126 if (bd->desk->zone != bd->zone)
1127 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1129 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1131 e_object_ref(E_OBJECT(bd));
1132 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1134 e_object_ref(E_OBJECT(zone));
1136 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1138 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1139 // XXXXXXXXXXXXXXXXXXXXXXXXX
1140 // XXX ZZZZZZZZZZZZZZZZZZZzz
1141 // need to adjust this if zone pos/size changes
1143 unsigned int zgeom[4];
1145 zgeom[0] = bd->zone->x;
1146 zgeom[1] = bd->zone->y;
1147 zgeom[2] = bd->zone->w;
1148 zgeom[3] = bd->zone->h;
1149 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1151 e_remember_update(bd);
1155 e_border_desk_set(E_Border *bd,
1158 E_Event_Border_Desk_Set *ev;
1162 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1163 E_OBJECT_CHECK(desk);
1164 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1165 if (bd->desk == desk) return;
1166 ecore_x_window_shadow_tree_flush();
1169 bd->desk->fullscreen_borders--;
1170 desk->fullscreen_borders++;
1172 old_desk = bd->desk;
1174 e_border_zone_set(bd, desk->zone);
1176 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1177 e_hints_window_desktop_set(bd);
1179 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1181 e_object_ref(E_OBJECT(bd));
1182 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1183 ev->desk = old_desk;
1184 e_object_ref(E_OBJECT(old_desk));
1185 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1187 if (bd->ignore_first_unmap != 1)
1189 if ((bd->desk->visible) || (bd->sticky))
1192 e_border_hide(bd, 1);
1195 if (e_config->transient.desktop)
1199 Eina_List *list = _e_border_sub_borders_new(bd);
1201 EINA_LIST_FOREACH(list, l, child)
1203 e_border_desk_set(child, bd->desk);
1205 eina_list_free(list);
1207 e_remember_update(bd);
1210 #ifdef _F_ZONE_WINDOW_ROTATION_
1212 _e_border_vkbd_state_check(E_Border *bd,
1215 Eina_Bool res = EINA_TRUE;
1216 if (!e_config->wm_win_rotation) return EINA_FALSE;
1217 if ((rot.vkbd) && (rot.vkbd == bd))
1221 if ((rot.vkbd_hide_prepare_done) ||
1222 (rot.vkbd_hide_prepare_timer))
1227 if ((rot.vkbd_show_prepare_done) ||
1228 (rot.vkbd_show_prepare_timer))
1236 _e_border_vkbd_show_timeout(void *data)
1238 E_Border *bd = data;
1239 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1240 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1242 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1244 if (rot.vkbd_ctrl_win)
1246 ELB(ELBT_BD, "SET KBD_ON", 0);
1247 ecore_x_e_virtual_keyboard_state_set
1248 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1253 rot.vkbd_show_prepare_done = EINA_FALSE;
1255 if (rot.vkbd_show_prepare_timer)
1256 ecore_timer_del(rot.vkbd_show_prepare_timer);
1257 rot.vkbd_show_prepare_timer = NULL;
1259 if (rot.vkbd_show_timer)
1260 ecore_timer_del(rot.vkbd_show_timer);
1261 rot.vkbd_show_timer = NULL;
1263 return ECORE_CALLBACK_CANCEL;
1267 _e_border_vkbd_hide_timeout(void *data)
1269 E_Border *bd = data;
1270 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1271 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1273 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1275 if (rot.vkbd_ctrl_win)
1277 ELB(ELBT_BD, "SET KBD_OFF", 0);
1278 ecore_x_e_virtual_keyboard_state_set
1279 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1282 e_object_unref(E_OBJECT(bd));
1285 rot.vkbd_hide_prepare_done = EINA_FALSE;
1287 if (rot.vkbd_hide_prepare_timer)
1288 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1289 rot.vkbd_hide_prepare_timer = NULL;
1291 if (rot.vkbd_hide_timer)
1292 ecore_timer_del(rot.vkbd_hide_timer);
1293 rot.vkbd_hide_timer = NULL;
1295 return ECORE_CALLBACK_CANCEL;
1299 _e_border_vkbd_show(E_Border *bd)
1301 if (!e_config->wm_win_rotation) return;
1302 rot.vkbd_show_prepare_done = EINA_TRUE;
1303 if (rot.vkbd_show_prepare_timer)
1304 ecore_timer_del(rot.vkbd_show_prepare_timer);
1305 rot.vkbd_show_prepare_timer = NULL;
1306 if (rot.vkbd_show_timer)
1307 ecore_timer_del(rot.vkbd_show_timer);
1308 rot.vkbd_show_timer = NULL;
1309 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1312 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1317 _e_border_vkbd_hide(E_Border *bd)
1319 if (!e_config->wm_win_rotation) return;
1320 rot.vkbd_hide_prepare_done = EINA_TRUE;
1321 if (rot.vkbd_hide_prepare_timer)
1322 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1323 rot.vkbd_hide_prepare_timer = NULL;
1324 if (rot.vkbd_hide_timer)
1325 ecore_timer_del(rot.vkbd_hide_timer);
1326 rot.vkbd_hide_timer = NULL;
1327 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1329 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1330 e_border_hide(bd, 0);
1331 if (!e_object_is_del(E_OBJECT(bd)))
1333 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1334 e_object_del(E_OBJECT(bd));
1336 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1341 _e_border_vkbd_show_prepare_timeout(void *data)
1343 E_Border *bd = data;
1344 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1345 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1347 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1348 _e_border_vkbd_show(bd);
1350 return ECORE_CALLBACK_CANCEL;
1354 _e_border_vkbd_hide_prepare_timeout(void *data)
1356 E_Border *bd = data;
1357 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1358 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1360 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1361 _e_border_vkbd_hide(bd);
1363 return ECORE_CALLBACK_CANCEL;
1368 e_border_show(E_Border *bd)
1370 E_Event_Border_Show *ev;
1371 unsigned int visible;
1374 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1375 if (bd->visible) return;
1376 #ifdef _F_ZONE_WINDOW_ROTATION_
1377 if ((e_config->wm_win_rotation) &&
1378 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1380 (!rot.vkbd_show_prepare_done))
1382 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1383 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1384 if (rot.vkbd_show_prepare_timer)
1385 ecore_timer_del(rot.vkbd_show_prepare_timer);
1386 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1387 _e_border_vkbd_show_prepare_timeout,
1391 ELB(ELBT_BD, "SHOW", bd->client.win);
1393 ecore_x_window_shadow_tree_flush();
1394 e_container_shape_show(bd->shape);
1395 if (!bd->need_reparent)
1396 ecore_x_window_show(bd->client.win);
1397 e_hints_window_visible_set(bd);
1400 bd->changes.visible = 1;
1403 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1404 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1406 ev = E_NEW(E_Event_Border_Show, 1);
1408 e_object_ref(E_OBJECT(bd));
1409 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1410 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1412 #ifdef _F_ZONE_WINDOW_ROTATION_
1413 if ((e_config->wm_win_rotation) &&
1414 ((bd->client.e.state.rot.support) ||
1415 (bd->client.e.state.rot.app_set)))
1417 ELB(ELBT_ROT, "CHECK", bd->client.win);
1418 Eina_Bool _rot = _e_border_rotation_check(bd);
1419 /* check whether rotation is available for sub borders such as prediction and magnifier */
1424 Eina_List *_list = _e_border_sub_borders_new(bd);
1425 EINA_LIST_FOREACH(_list, ll, _child)
1427 if ((_child->client.e.state.rot.support) ||
1428 (_child->client.e.state.rot.app_set))
1429 _e_border_rotation_check(_child);
1431 eina_list_free(_list);
1438 e_border_hide(E_Border *bd,
1441 unsigned int visible;
1444 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1446 #ifdef _F_ZONE_WINDOW_ROTATION_
1447 if ((e_config->wm_win_rotation) &&
1448 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1450 (!rot.vkbd_hide_prepare_done) &&
1453 Eina_Bool need_prepare = EINA_TRUE;
1454 E_Border *child = NULL;
1457 if (e_object_is_del(E_OBJECT(bd->parent)))
1458 need_prepare = EINA_FALSE;
1461 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1462 if (bd->parent->modal == bd)
1464 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1465 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1466 bd->parent->lock_close = 0;
1467 bd->parent->saved.event_mask = 0;
1468 bd->parent->modal = NULL;
1474 need_prepare = EINA_FALSE;
1476 EINA_LIST_FREE(bd->transients, child)
1478 child->parent = NULL;
1481 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1485 e_object_ref(E_OBJECT(bd));
1486 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1487 if (rot.vkbd_hide_prepare_timer)
1488 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1489 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1490 _e_border_vkbd_hide_prepare_timeout,
1496 e_object_ref(E_OBJECT(bd));
1498 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1499 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1501 /* cleanup code from _e_border_vkbd_hide() */
1502 rot.vkbd_hide_prepare_done = EINA_TRUE;
1503 if (rot.vkbd_hide_prepare_timer)
1504 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1505 rot.vkbd_hide_prepare_timer = NULL;
1506 if (rot.vkbd_hide_timer)
1507 ecore_timer_del(rot.vkbd_hide_timer);
1508 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1511 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1513 if (!bd->visible) goto send_event;
1514 ecore_x_window_shadow_tree_flush();
1516 _e_border_move_end(bd);
1517 if (bd->resize_mode != RESIZE_NONE)
1519 _e_border_pointer_resize_end(bd);
1520 bd->resize_mode = RESIZE_NONE;
1521 _e_border_resize_end(bd);
1524 e_container_shape_hide(bd->shape);
1525 if (!bd->iconic) e_hints_window_hidden_set(bd);
1528 bd->changes.visible = 1;
1530 if (!bd->need_reparent)
1532 if ((bd->focused) ||
1533 (e_grabinput_last_focus_win_get() == bd->client.win))
1535 e_border_focus_set(bd, 0, 1);
1543 con = e_container_current_get(e_manager_current_get());
1544 zone = e_zone_current_get(con);
1545 desk = e_desk_current_get(zone);
1548 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1549 e_border_focus_set(bd->parent, 1, 1);
1550 else if (e_config->focus_revert_on_hide_or_close)
1552 /* When using pointer focus, the border under the
1553 * pointer (if any) gets focused, in sloppy/click
1554 * focus the last focused window on the current
1555 * desk gets focus */
1556 if (e_config->focus_policy == E_FOCUS_MOUSE)
1558 pbd = e_border_under_pointer_get(desk, bd);
1560 e_border_focus_set(pbd, 1, 1);
1562 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1563 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1564 (e_config->focus_policy == E_FOCUS_CLICK))
1565 _e_border_latest_stacked_focus(bd);
1569 e_desk_last_focused_focus(desk);
1579 /* Make sure that this border isn't deleted */
1580 bd->await_hide_event++;
1582 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1583 ecore_x_window_hide(bd->client.win);
1588 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1590 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1597 #ifdef _F_ZONE_WINDOW_ROTATION_
1598 _e_border_rotation_list_remove(bd);
1601 E_Event_Border_Hide *ev;
1603 ev = E_NEW(E_Event_Border_Hide, 1);
1605 e_object_ref(E_OBJECT(bd));
1606 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1607 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1612 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1616 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1617 setpriority(PRIO_PROCESS, pid, newpri);
1618 // shouldnt need to do this as default ionice class is "none" (0), and
1619 // this inherits io priority FROM nice level
1620 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1621 // IOPRIO_PRIO_VALUE(2, 5));
1625 char *file, buf[PATH_MAX];
1629 // yes - this is /proc specific... so this may not work on some
1630 // os's - works on linux. too bad for others.
1631 files = ecore_file_ls("/proc");
1632 EINA_LIST_FREE(files, file)
1634 if (isdigit(file[0]))
1636 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1637 f = fopen(buf, "r");
1642 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1648 _pri_adj(pid2, set, adj, EINA_TRUE,
1649 adj_children, do_children);
1651 _pri_adj(pid2, set, adj, use_adj,
1652 adj_children, do_children);
1664 _e_border_pri_raise(E_Border *bd)
1666 if (bd->client.netwm.pid <= 0) return;
1667 if (bd->client.netwm.pid == getpid()) return;
1668 _pri_adj(bd->client.netwm.pid,
1669 e_config->priority - 1, -1, EINA_FALSE,
1670 // EINA_TRUE, EINA_TRUE);
1671 EINA_TRUE, EINA_FALSE);
1672 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1673 // bd->client.netwm.pid, e_border_name_get(bd));
1677 _e_border_pri_norm(E_Border *bd)
1679 if (bd->client.netwm.pid <= 0) return;
1680 if (bd->client.netwm.pid == getpid()) return;
1681 _pri_adj(bd->client.netwm.pid,
1682 e_config->priority, 1, EINA_FALSE,
1683 // EINA_TRUE, EINA_TRUE);
1684 EINA_TRUE, EINA_FALSE);
1685 // printf("WIN: pid %i, title %s (NORMAL)\n",
1686 // bd->client.netwm.pid, e_border_name_get(bd));
1690 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1693 Ecore_Evas *bg_ecore_evas;
1699 bg_ecore_evas = bd->bg_ecore_evas;
1701 /* unregister old frame window */
1702 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1703 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1705 e_focus_setdown(bd);
1706 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1707 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1709 if (bd->icon_object)
1710 evas_object_del(bd->icon_object);
1712 evas_object_del(bd->bg_object);
1713 e_canvas_del(bg_ecore_evas);
1714 ecore_evas_free(bg_ecore_evas);
1717 e_object_del(E_OBJECT(bd->pointer));
1719 /* create new frame */
1721 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1722 bd->x, bd->y, bd->w, bd->h);
1725 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1726 bd->x, bd->y, bd->w, bd->h);
1727 ecore_x_window_shape_events_select(bd->win, 1);
1730 ecore_x_window_configure(bd->win,
1731 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1732 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1734 win, ECORE_X_WINDOW_STACK_BELOW);
1736 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1737 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1740 bd->bg_ecore_evas = e_canvas_new(bd->win,
1741 0, 0, bd->w, bd->h, 1, 0,
1744 e_canvas_add(bd->bg_ecore_evas);
1745 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1747 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1748 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1749 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1751 ecore_x_window_shape_events_select(bd->bg_win, 1);
1753 /* move client with shell win over to new frame */
1754 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1755 bd->client_inset.l, bd->client_inset.t);
1757 bd->pointer = e_pointer_window_new(bd->win, 0);
1759 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1760 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1767 ecore_evas_show(bd->bg_ecore_evas);
1768 ecore_x_window_show(bd->win);
1770 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1771 ecore_x_window_show(tmp->win);
1774 bd->bg_object = edje_object_add(bd->bg_evas);
1775 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1776 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1778 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1780 /* cleanup old frame */
1781 ecore_x_window_free(win);
1785 _e_border_client_move_resize_send(E_Border *bd)
1787 if (bd->internal_ecore_evas)
1788 ecore_evas_managed_move(bd->internal_ecore_evas,
1789 bd->x + bd->fx.x + bd->client_inset.l,
1790 bd->y + bd->fx.y + bd->client_inset.t);
1792 ecore_x_icccm_move_resize_send(bd->client.win,
1793 bd->x + bd->fx.x + bd->client_inset.l,
1794 bd->y + bd->fx.y + bd->client_inset.t,
1800 _e_border_pending_move_resize_add(E_Border *bd,
1807 Eina_Bool without_border,
1808 unsigned int serial)
1810 E_Border_Pending_Move_Resize *pnd;
1812 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1814 pnd->resize = resize;
1816 pnd->without_border = without_border;
1821 pnd->serial = serial;
1822 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1826 _e_border_move_internal(E_Border *bd,
1829 Eina_Bool without_border)
1831 E_Event_Border_Move *ev;
1834 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1836 ecore_x_window_shadow_tree_flush();
1839 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1845 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1847 if (e_config->allow_manip)
1850 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1855 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1860 else if (e_config->allow_manip)
1868 x -= bd->client_inset.l;
1869 y -= bd->client_inset.t;
1871 if (bd->move_intercept_cb)
1874 px = bd->x, py = bd->y;
1875 bd->move_intercept_cb(bd, x, y);
1876 if ((bd->x == px) && (bd->y == py)) return;
1878 else if ((x == bd->x) && (y == bd->y)) return;
1879 bd->pre_res_change.valid = 0;
1883 bd->changes.pos = 1;
1885 if (bd->client.netwm.sync.request)
1887 bd->client.netwm.sync.wait++;
1888 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1891 _e_border_client_move_resize_send(bd);
1892 _e_border_move_update(bd);
1893 ev = E_NEW(E_Event_Border_Move, 1);
1895 e_object_ref(E_OBJECT(bd));
1896 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1897 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1898 _e_border_zone_update(bd);
1902 * Move window to coordinates that already account border decorations.
1904 * This call will consider given position already accounts border
1905 * decorations, so it will not be considered later. This will just
1906 * work properly with borders that have being evaluated and border
1907 * decorations are known (border->client_inset).
1909 * @parm x horizontal position to place window.
1910 * @parm y vertical position to place window.
1912 * @see e_border_move_without_border()
1915 e_border_move(E_Border *bd,
1922 _e_border_move_internal(bd, x, y, 0);
1927 * Set a callback which will be called just prior to updating the
1928 * move coordinates for a border
1931 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1933 bd->move_intercept_cb = cb;
1937 * Move window to coordinates that do not account border decorations yet.
1939 * This call will consider given position does not account border
1940 * decoration, so these values (border->client_inset) will be
1941 * accounted automatically. This is specially useful when it is a new
1942 * client and has not be evaluated yet, in this case
1943 * border->client_inset will be zeroed and no information is known. It
1944 * will mark pending requests so border will be accounted on
1945 * evalutation phase.
1947 * @parm x horizontal position to place window.
1948 * @parm y vertical position to place window.
1950 * @see e_border_move()
1953 e_border_move_without_border(E_Border *bd,
1960 _e_border_move_internal(bd, x, y, 1);
1964 e_border_center(E_Border *bd)
1968 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1970 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1971 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1975 e_border_center_pos_get(E_Border *bd,
1981 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1983 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1984 if (x) *x = zx + (zw - bd->w) / 2;
1985 if (y) *y = zy + (zh - bd->h) / 2;
1989 e_border_fx_offset(E_Border *bd,
1994 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1996 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2000 bd->changes.pos = 1;
2003 if (bd->moving) _e_border_move_update(bd);
2007 _e_border_move_resize_internal(E_Border *bd,
2012 Eina_Bool without_border,
2015 E_Event_Border_Move *mev;
2016 E_Event_Border_Resize *rev;
2019 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2021 ecore_x_window_shadow_tree_flush();
2025 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2031 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2033 if (e_config->allow_manip)
2036 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2042 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2049 if (e_config->allow_manip)
2057 x -= bd->client_inset.l;
2058 y -= bd->client_inset.t;
2059 w += (bd->client_inset.l + bd->client_inset.r);
2060 h += (bd->client_inset.t + bd->client_inset.b);
2063 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2064 (w == bd->w) && (h == bd->h))
2067 bd->pre_res_change.valid = 0;
2070 bd->changes.pos = 1;
2076 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2077 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2079 if ((bd->shaped) || (bd->client.shaped))
2081 bd->need_shape_merge = 1;
2082 bd->need_shape_export = 1;
2084 if (bd->shaped_input)
2086 bd->need_shape_merge = 1;
2089 if (bd->internal_ecore_evas)
2092 bd->changes.size = 1;
2096 if (bdresize && bd->client.netwm.sync.request)
2098 bd->client.netwm.sync.wait++;
2099 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2100 * when no move is intended. The border geometry is set above anyways.
2102 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2103 bd->client.netwm.sync.serial);
2104 ecore_x_netwm_sync_request_send(bd->client.win,
2105 bd->client.netwm.sync.serial++);
2110 bd->changes.size = 1;
2114 _e_border_client_move_resize_send(bd);
2116 _e_border_resize_update(bd);
2119 mev = E_NEW(E_Event_Border_Move, 1);
2121 e_object_ref(E_OBJECT(bd));
2122 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2123 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2126 rev = E_NEW(E_Event_Border_Resize, 1);
2128 e_object_ref(E_OBJECT(bd));
2129 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2130 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2131 _e_border_zone_update(bd);
2135 * Move and resize window to values that already account border decorations.
2137 * This call will consider given values already accounts border
2138 * decorations, so it will not be considered later. This will just
2139 * work properly with borders that have being evaluated and border
2140 * decorations are known (border->client_inset).
2142 * @parm x horizontal position to place window.
2143 * @parm y vertical position to place window.
2144 * @parm w horizontal window size.
2145 * @parm h vertical window size.
2147 * @see e_border_move_resize_without_border()
2150 e_border_move_resize(E_Border *bd,
2159 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2163 * Move and resize window to values that do not account border decorations yet.
2165 * This call will consider given values already accounts border
2166 * decorations, so it will not be considered later. This will just
2167 * work properly with borders that have being evaluated and border
2168 * decorations are known (border->client_inset).
2170 * @parm x horizontal position to place window.
2171 * @parm y vertical position to place window.
2172 * @parm w horizontal window size.
2173 * @parm h vertical window size.
2175 * @see e_border_move_resize()
2178 e_border_move_resize_without_border(E_Border *bd,
2187 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2191 * Resize window to values that already account border decorations.
2193 * This call will consider given size already accounts border
2194 * decorations, so it will not be considered later. This will just
2195 * work properly with borders that have being evaluated and border
2196 * decorations are known (border->client_inset).
2198 * @parm w horizontal window size.
2199 * @parm h vertical window size.
2201 * @see e_border_resize_without_border()
2204 e_border_resize(E_Border *bd,
2211 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2215 * Resize window to values that do not account border decorations yet.
2217 * This call will consider given size does not account border
2218 * decoration, so these values (border->client_inset) will be
2219 * accounted automatically. This is specially useful when it is a new
2220 * client and has not be evaluated yet, in this case
2221 * border->client_inset will be zeroed and no information is known. It
2222 * will mark pending requests so border will be accounted on
2223 * evalutation phase.
2225 * @parm w horizontal window size.
2226 * @parm h vertical window size.
2228 * @see e_border_resize()
2231 e_border_resize_without_border(E_Border *bd,
2238 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2242 e_border_layer_set(E_Border *bd,
2248 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2250 ecore_x_window_shadow_tree_flush();
2252 oldraise = e_config->transient.raise;
2256 bd->saved.layer = layer;
2260 if (e_config->transient.layer)
2264 Eina_List *list = _e_border_sub_borders_new(bd);
2266 /* We need to set raise to one, else the child wont
2267 * follow to the new layer. It should be like this,
2268 * even if the user usually doesn't want to raise
2271 e_config->transient.raise = 1;
2272 EINA_LIST_FOREACH(list, l, child)
2274 e_border_layer_set(child, layer);
2278 e_config->transient.raise = oldraise;
2282 e_border_raise(E_Border *bd)
2284 E_Event_Border_Stack *ev;
2285 E_Border *last = NULL, *child;
2289 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2291 ecore_x_window_shadow_tree_flush();
2293 if (e_config->transient.raise)
2295 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2296 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2299 Eina_List *list = _e_border_sub_borders_new(bd);
2301 EINA_LIST_REVERSE_FOREACH(list, l, child)
2303 /* Don't stack iconic transients. If the user wants these shown,
2304 * thats another option.
2309 e_border_stack_below(child, last);
2314 /* First raise the border to find out which border we will end up above */
2315 above = e_container_border_raise(child);
2319 /* We ended up above a border, now we must stack this border to
2320 * generate the stacking event, and to check if this transient
2321 * has other transients etc.
2323 e_border_stack_above(child, above);
2327 /* If we didn't end up above any border, we are on the bottom! */
2328 e_border_lower(child);
2334 eina_list_free(list);
2335 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2339 EINA_LIST_FOREACH(bd->transients, l, child)
2341 /* Don't stack iconic transients. If the user wants these shown,
2342 * thats another option.
2346 child->layer = bd->layer;
2347 if (!last) last = child;
2348 e_border_raise (child);
2355 ev = E_NEW(E_Event_Border_Stack, 1);
2357 e_object_ref(E_OBJECT(bd));
2361 e_container_border_stack_below(bd, last);
2363 e_object_ref(E_OBJECT(last));
2364 ev->type = E_STACKING_BELOW;
2370 /* If we don't have any children, raise this border */
2371 above = e_container_border_raise(bd);
2372 e_border_raise_latest_set(bd);
2375 /* We ended up above a border */
2377 e_object_ref(E_OBJECT(above));
2378 ev->type = E_STACKING_ABOVE;
2382 /* No border to raise above, same as a lower! */
2384 ev->type = E_STACKING_ABOVE;
2388 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2389 e_remember_update(bd);
2393 e_border_lower(E_Border *bd)
2395 E_Event_Border_Stack *ev;
2396 E_Border *last = NULL, *child;
2400 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2402 ecore_x_window_shadow_tree_flush();
2404 if (e_config->transient.lower)
2406 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2407 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2410 Eina_List *list = _e_border_sub_borders_new(bd);
2412 EINA_LIST_REVERSE_FOREACH(list, l, child)
2414 /* Don't stack iconic transients. If the user wants these shown,
2415 * thats another option.
2420 e_border_stack_below(child, last);
2425 /* First lower the border to find out which border we will end up below */
2426 below = e_container_border_lower(child);
2430 /* We ended up below a border, now we must stack this border to
2431 * generate the stacking event, and to check if this transient
2432 * has other transients etc.
2434 e_border_stack_below(child, below);
2438 /* If we didn't end up below any border, we are on top! */
2439 e_border_raise(child);
2445 eina_list_free(list);
2447 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2451 EINA_LIST_FOREACH(bd->transients, l, child)
2453 /* Don't stack iconic transients. If the user wants these shown,
2454 * thats another option.
2458 child->layer = bd->layer;
2459 e_border_lower (child);
2467 ev = E_NEW(E_Event_Border_Stack, 1);
2469 e_object_ref(E_OBJECT(bd));
2473 e_container_border_stack_below(bd, last);
2475 e_object_ref(E_OBJECT(last));
2476 ev->type = E_STACKING_BELOW;
2482 /* If we don't have any children, lower this border */
2483 below = e_container_border_lower(bd);
2486 /* We ended up below a border */
2488 e_object_ref(E_OBJECT(below));
2489 ev->type = E_STACKING_BELOW;
2493 /* No border to hide under, same as a raise! */
2495 ev->type = E_STACKING_BELOW;
2499 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2500 e_remember_update(bd);
2504 e_border_stack_above(E_Border *bd,
2507 /* TODO: Should stack above allow the border to change level */
2508 E_Event_Border_Stack *ev;
2509 E_Border *last = NULL, *child;
2513 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2515 ecore_x_window_shadow_tree_flush();
2517 if (e_config->transient.raise)
2519 Eina_List *list = _e_border_sub_borders_new(bd);
2521 EINA_LIST_REVERSE_FOREACH(list, l, child)
2523 /* Don't stack iconic transients. If the user wants these shown,
2524 * thats another option.
2529 e_border_stack_below(child, last);
2531 e_border_stack_above(child, above);
2535 eina_list_free(list);
2538 ev = E_NEW(E_Event_Border_Stack, 1);
2540 e_object_ref(E_OBJECT(bd));
2544 e_container_border_stack_below(bd, last);
2546 e_object_ref(E_OBJECT(last));
2547 ev->type = E_STACKING_BELOW;
2551 e_container_border_stack_above(bd, above);
2553 e_object_ref(E_OBJECT(above));
2554 ev->type = E_STACKING_ABOVE;
2557 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2558 e_remember_update(bd);
2562 e_border_stack_below(E_Border *bd,
2565 /* TODO: Should stack below allow the border to change level */
2566 E_Event_Border_Stack *ev;
2567 E_Border *last = NULL, *child;
2571 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2573 ecore_x_window_shadow_tree_flush();
2575 if (e_config->transient.lower)
2577 Eina_List *list = _e_border_sub_borders_new(bd);
2579 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2581 /* Don't stack iconic transients. If the user wants these shown,
2582 * thats another option.
2587 e_border_stack_below(child, last);
2589 e_border_stack_below(child, below);
2593 eina_list_free(list);
2596 ev = E_NEW(E_Event_Border_Stack, 1);
2598 e_object_ref(E_OBJECT(bd));
2602 e_container_border_stack_below(bd, last);
2604 e_object_ref(E_OBJECT(last));
2605 ev->type = E_STACKING_BELOW;
2609 e_container_border_stack_below(bd, below);
2611 e_object_ref(E_OBJECT(below));
2612 ev->type = E_STACKING_BELOW;
2615 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2616 e_remember_update(bd);
2620 e_border_focus_latest_set(E_Border *bd)
2622 focus_stack = eina_list_remove(focus_stack, bd);
2623 focus_stack = eina_list_prepend(focus_stack, bd);
2627 e_border_raise_latest_set(E_Border *bd)
2629 raise_stack = eina_list_remove(raise_stack, bd);
2630 raise_stack = eina_list_prepend(raise_stack, bd);
2634 * Sets the focus to the given border if necessary
2635 * There are 3 cases of different focus_policy-configurations:
2637 * - E_FOCUS_CLICK: just set the focus, the most simple one
2639 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2640 * warp the pointer to the window. If this fails (because
2641 * the pointer is already in the window), just set the focus.
2643 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2644 * last window which was focused, if the mouse is on the
2645 * desktop. So, we need to look if there is another window
2646 * under the pointer and warp to pointer to the right
2647 * one if so (also, we set the focus afterwards). In case
2648 * there is no window under pointer, the pointer is on the
2649 * desktop and so we just set the focus.
2652 * This function is to be called when setting the focus was not
2653 * explicitly triggered by the user (by moving the mouse or
2654 * clicking for example), but implicitly (by closing a window,
2655 * the last focused window should get focus).
2659 e_border_focus_set_with_pointer(E_Border *bd)
2661 #ifdef PRINT_LOTS_OF_DEBUG
2662 E_PRINT_BORDER_INFO(bd);
2664 /* note: this is here as it seems there are enough apps that do not even
2665 * expect us to emulate a look of focus but not actually set x input
2666 * focus as we do - so simply abort any focuse set on such windows */
2667 /* be strict about accepting focus hint */
2668 if ((!bd->client.icccm.accepts_focus) &&
2669 (!bd->client.icccm.take_focus)) return;
2670 if (bd->lock_focus_out) return;
2672 e_border_focus_set(bd, 1, 1);
2674 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2675 if (!bd->visible) return;
2677 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2679 if (!e_border_under_pointer_get(bd->desk, bd))
2681 e_border_pointer_warp_to_center(bd);
2686 e_border_pointer_warp_to_center(bd);
2691 e_border_focus_set(E_Border *bd,
2695 E_Border *bd_unfocus = NULL;
2696 Eina_Bool focus_changed = EINA_FALSE;
2699 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2700 /* note: this is here as it seems there are enough apps that do not even
2701 * expect us to emulate a look of focus but not actually set x input
2702 * focus as we do - so simply abort any focuse set on such windows */
2703 /* be strict about accepting focus hint */
2704 if ((!bd->client.icccm.accepts_focus) &&
2705 (!bd->client.icccm.take_focus))
2707 if ((set) && (focus) && (bd->lock_focus_out)) return;
2709 /* dont focus an iconified window. that's silly! */
2714 e_border_uniconify(bd);
2715 if (!focus_track_frozen)
2716 e_border_focus_latest_set(bd);
2719 else if (!bd->visible)
2723 /* FIXME: hack for deskflip animation:
2724 * dont update focus when sliding previous desk */
2725 else if ((!bd->sticky) &&
2726 (bd->desk != e_desk_current_get(bd->desk->zone)))
2732 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2734 e_border_focus_set(bd->modal, focus, set);
2737 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2739 e_border_focus_set(bd->leader->modal, focus, set);
2747 if (bd->visible && bd->changes.visible)
2752 else if ((!bd->focused) ||
2753 (focus_next && (bd != eina_list_data_get(focus_next))))
2757 if ((l = eina_list_data_find_list(focus_next, bd)))
2758 focus_next = eina_list_promote_list(focus_next, l);
2760 focus_next = eina_list_prepend(focus_next, bd);
2762 if ((bd->client.icccm.take_focus) &&
2763 (bd->client.icccm.accepts_focus))
2765 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2766 /* TODO what if the client didn't take focus ? */
2768 else if (!bd->client.icccm.accepts_focus)
2770 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2772 else if (!bd->client.icccm.take_focus)
2774 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2775 /* e_border_focus_set(bd, 1, 0); */
2785 if (focused) bd_unfocus = focused;
2786 if (focusing == bd) focusing = NULL;
2791 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2793 if ((bd2->fullscreen) &&
2795 (bd2->zone == bd->zone) &&
2796 ((bd2->desk == bd->desk) ||
2797 (bd2->sticky) || (bd->sticky)))
2799 Eina_Bool unfocus_is_parent = EINA_FALSE;
2800 E_Border *bd_parent;
2802 bd_parent = bd->parent;
2805 if (bd_parent == bd2)
2807 unfocus_is_parent = EINA_TRUE;
2810 bd_parent = bd->parent;
2812 if ((!unfocus_is_parent) &&
2813 (!e_config->allow_above_fullscreen))
2815 e_border_iconify(bd2);
2820 focus_changed = EINA_TRUE;
2826 focus_next = eina_list_remove(focus_next, bd);
2827 if (bd == focusing) focusing = NULL;
2829 if ((bd->focused) &&
2830 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2832 Eina_Bool wasfocused = EINA_FALSE;
2835 /* should always be the case. anyway */
2839 wasfocused = EINA_TRUE;
2842 if ((set) && (!focus_next) && (!focusing))
2844 e_grabinput_focus(bd->zone->container->bg_win,
2845 E_FOCUS_METHOD_PASSIVE);
2847 if ((bd->fullscreen) && (wasfocused))
2849 Eina_Bool have_vis_child = EINA_FALSE;
2853 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2856 (bd2->zone == bd->zone) &&
2857 ((bd2->desk == bd->desk) ||
2858 (bd2->sticky) || (bd->sticky)))
2860 if (bd2->parent == bd)
2862 have_vis_child = EINA_TRUE;
2867 if ((!have_vis_child) &&
2868 (!e_config->allow_above_fullscreen))
2869 e_border_iconify(bd);
2875 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2876 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2878 E_Event_Border_Focus_Out *ev;
2880 bd_unfocus->focused = 0;
2881 e_focus_event_focus_out(bd_unfocus);
2883 if (bd_unfocus->raise_timer)
2884 ecore_timer_del(bd_unfocus->raise_timer);
2885 bd_unfocus->raise_timer = NULL;
2887 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2888 if (bd_unfocus->icon_object)
2889 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2891 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2892 ev->border = bd_unfocus;
2893 e_object_ref(E_OBJECT(bd_unfocus));
2895 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2896 _e_border_event_border_focus_out_free, NULL);
2897 if ((bd_unfocus->fullscreen) &&
2898 (bd != bd_unfocus) &&
2899 (bd->zone == bd_unfocus->zone) &&
2900 ((bd->desk == bd_unfocus->desk) ||
2901 (bd->sticky) || (bd_unfocus->sticky)))
2903 Eina_Bool unfocus_is_parent = EINA_FALSE;
2904 E_Border *bd_parent;
2906 bd_parent = bd->parent;
2909 if (bd_parent == bd_unfocus)
2911 unfocus_is_parent = EINA_TRUE;
2914 bd_parent = bd->parent;
2916 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2918 e_border_iconify(bd_unfocus);
2925 E_Event_Border_Focus_In *ev;
2927 e_focus_event_focus_in(bd);
2929 if (!focus_track_frozen)
2930 e_border_focus_latest_set(bd);
2932 e_hints_active_window_set(bd->zone->container->manager, bd);
2934 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2935 if (bd->icon_object)
2936 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2938 ev = E_NEW(E_Event_Border_Focus_In, 1);
2940 e_object_ref(E_OBJECT(bd));
2942 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2943 _e_border_event_border_focus_in_free, NULL);
2948 e_border_shade(E_Border *bd,
2951 E_Event_Border_Resize *ev;
2956 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2957 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2958 ((bd->maximized) && (!e_config->allow_manip))) return;
2959 if ((bd->client.border.name) &&
2960 (!strcmp("borderless", bd->client.border.name))) return;
2962 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2963 ecore_x_window_hide(tmp->win);
2965 ecore_x_window_shadow_tree_flush();
2967 bd->shade.x = bd->x;
2968 bd->shade.y = bd->y;
2969 bd->shade.dir = dir;
2971 e_hints_window_shaded_set(bd, 1);
2972 e_hints_window_shade_direction_set(bd, dir);
2974 if (e_config->border_shade_animate)
2976 bd->shade.start = ecore_loop_time_get();
2978 bd->changes.shading = 1;
2981 if (bd->shade.dir == E_DIRECTION_UP ||
2982 bd->shade.dir == E_DIRECTION_LEFT)
2983 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2985 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2987 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2988 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2992 if (bd->shade.dir == E_DIRECTION_UP)
2994 bd->h = bd->client_inset.t + bd->client_inset.b;
2996 else if (bd->shade.dir == E_DIRECTION_DOWN)
2998 bd->h = bd->client_inset.t + bd->client_inset.b;
2999 bd->y = bd->y + bd->client.h;
3000 bd->changes.pos = 1;
3002 else if (bd->shade.dir == E_DIRECTION_LEFT)
3004 bd->w = bd->client_inset.l + bd->client_inset.r;
3006 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3008 bd->w = bd->client_inset.l + bd->client_inset.r;
3009 bd->x = bd->x + bd->client.w;
3010 bd->changes.pos = 1;
3013 if ((bd->shaped) || (bd->client.shaped))
3015 bd->need_shape_merge = 1;
3016 bd->need_shape_export = 1;
3018 if (bd->shaped_input)
3020 bd->need_shape_merge = 1;
3023 bd->changes.size = 1;
3025 bd->changes.shaded = 1;
3027 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3028 e_border_frame_recalc(bd);
3029 ev = E_NEW(E_Event_Border_Resize, 1);
3031 /* The resize is added in the animator when animation complete */
3032 /* For non-animated, we add it immediately with the new size */
3033 e_object_ref(E_OBJECT(bd));
3034 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3035 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3038 e_remember_update(bd);
3042 e_border_unshade(E_Border *bd,
3045 E_Event_Border_Resize *ev;
3050 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3051 if ((!bd->shaded) || (bd->shading))
3054 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3055 ecore_x_window_show(tmp->win);
3057 ecore_x_window_shadow_tree_flush();
3059 bd->shade.dir = dir;
3061 e_hints_window_shaded_set(bd, 0);
3062 e_hints_window_shade_direction_set(bd, dir);
3064 if (bd->shade.dir == E_DIRECTION_UP ||
3065 bd->shade.dir == E_DIRECTION_LEFT)
3067 bd->shade.x = bd->x;
3068 bd->shade.y = bd->y;
3072 bd->shade.x = bd->x - bd->client.w;
3073 bd->shade.y = bd->y - bd->client.h;
3075 if (e_config->border_shade_animate)
3077 bd->shade.start = ecore_loop_time_get();
3079 bd->changes.shading = 1;
3082 if (bd->shade.dir == E_DIRECTION_UP)
3084 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3085 ecore_x_window_move_resize(bd->client.win, 0,
3086 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3088 bd->client.w, bd->client.h);
3090 else if (bd->shade.dir == E_DIRECTION_LEFT)
3092 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3093 ecore_x_window_move_resize(bd->client.win,
3094 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3096 0, bd->client.w, bd->client.h);
3099 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3101 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3102 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3106 if (bd->shade.dir == E_DIRECTION_UP)
3108 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3110 else if (bd->shade.dir == E_DIRECTION_DOWN)
3112 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3113 bd->y = bd->y - bd->client.h;
3114 bd->changes.pos = 1;
3116 else if (bd->shade.dir == E_DIRECTION_LEFT)
3118 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3120 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3122 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3123 bd->x = bd->x - bd->client.w;
3124 bd->changes.pos = 1;
3126 if ((bd->shaped) || (bd->client.shaped))
3128 bd->need_shape_merge = 1;
3129 bd->need_shape_export = 1;
3131 if (bd->shaped_input)
3133 bd->need_shape_merge = 1;
3136 bd->changes.size = 1;
3138 bd->changes.shaded = 1;
3140 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3141 e_border_frame_recalc(bd);
3142 ev = E_NEW(E_Event_Border_Resize, 1);
3144 /* The resize is added in the animator when animation complete */
3145 /* For non-animated, we add it immediately with the new size */
3146 e_object_ref(E_OBJECT(bd));
3147 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3148 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3151 e_remember_update(bd);
3155 _e_border_client_inset_calc(E_Border *bd)
3158 Evas_Coord cx, cy, cw, ch;
3162 evas_object_resize(bd->bg_object, 1000, 1000);
3163 edje_object_message_signal_process(bd->bg_object);
3164 edje_object_calc_force(bd->bg_object);
3165 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3166 bd->client_inset.l = cx;
3167 bd->client_inset.r = 1000 - (cx + cw);
3168 bd->client_inset.t = cy;
3169 bd->client_inset.b = 1000 - (cy + ch);
3173 bd->client_inset.l = 0;
3174 bd->client_inset.r = 0;
3175 bd->client_inset.t = 0;
3176 bd->client_inset.b = 0;
3179 ecore_x_netwm_frame_size_set(bd->client.win,
3180 bd->client_inset.l, bd->client_inset.r,
3181 bd->client_inset.t, bd->client_inset.b);
3182 ecore_x_e_frame_size_set(bd->client.win,
3183 bd->client_inset.l, bd->client_inset.r,
3184 bd->client_inset.t, bd->client_inset.b);
3188 _e_border_maximize(E_Border *bd, E_Maximize max)
3190 int x1, yy1, x2, y2;
3193 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3197 zx = zy = zw = zh = 0;
3199 switch (max & E_MAXIMIZE_TYPE)
3201 case E_MAXIMIZE_NONE:
3205 case E_MAXIMIZE_FULLSCREEN:
3211 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3212 _e_border_client_inset_calc(bd);
3214 e_border_resize_limit(bd, &w, &h);
3215 /* center x-direction */
3216 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3217 /* center y-direction */
3218 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3220 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3221 cy = bd->zone->y + (bd->zone->h / 2);
3224 switch (max & E_MAXIMIZE_DIRECTION)
3226 case E_MAXIMIZE_BOTH:
3227 e_border_move_resize(bd, x1, yy1, w, h);
3230 case E_MAXIMIZE_VERTICAL:
3231 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3234 case E_MAXIMIZE_HORIZONTAL:
3235 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3238 case E_MAXIMIZE_LEFT:
3239 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3242 case E_MAXIMIZE_RIGHT:
3243 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3245 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3246 case E_MAXIMIZE_TOP:
3247 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3249 case E_MAXIMIZE_BOTTOM:
3250 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3256 case E_MAXIMIZE_SMART:
3257 case E_MAXIMIZE_EXPAND:
3259 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3271 if (bd->x < zx) // window left not useful coordinates
3273 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3274 x1 = zx + zw - bd->w;
3275 else // window normal position
3278 if (bd->y < zy) // window top not useful coordinates
3280 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3281 yy1 = zy + zh - bd->h;
3282 else // window normal position
3285 switch (max & E_MAXIMIZE_DIRECTION)
3287 case E_MAXIMIZE_BOTH:
3288 e_border_move_resize(bd, zx, zy, zw, zh);
3291 case E_MAXIMIZE_VERTICAL:
3292 e_border_move_resize(bd, x1, zy, w, zh);
3295 case E_MAXIMIZE_HORIZONTAL:
3296 e_border_move_resize(bd, zx, yy1, zw, h);
3299 case E_MAXIMIZE_LEFT:
3300 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3303 case E_MAXIMIZE_RIGHT:
3304 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3308 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3311 case E_MAXIMIZE_FILL:
3314 x2 = bd->zone->x + bd->zone->w;
3315 y2 = bd->zone->y + bd->zone->h;
3317 /* walk through all shelves */
3318 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3320 /* walk through all windows */
3321 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3327 e_border_resize_limit(bd, &w, &h);
3328 /* center x-direction */
3329 x1 = x1 + (pw - w) / 2;
3330 /* center y-direction */
3331 yy1 = yy1 + (ph - h) / 2;
3333 switch (max & E_MAXIMIZE_DIRECTION)
3335 case E_MAXIMIZE_BOTH:
3336 e_border_move_resize(bd, x1, yy1, w, h);
3339 case E_MAXIMIZE_VERTICAL:
3340 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3343 case E_MAXIMIZE_HORIZONTAL:
3344 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3347 case E_MAXIMIZE_LEFT:
3348 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3351 case E_MAXIMIZE_RIGHT:
3352 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3360 e_border_maximize(E_Border *bd,
3364 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3366 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3368 if ((bd->shaded) || (bd->shading)) return;
3369 ecore_x_window_shadow_tree_flush();
3371 e_border_unfullscreen(bd);
3372 /* Only allow changes in vertical/ horizontal maximization */
3373 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3374 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3377 bd->need_maximize = 1;
3378 bd->maximized &= ~E_MAXIMIZE_TYPE;
3379 bd->maximized |= max;
3383 bd->pre_res_change.valid = 0;
3384 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3386 /* Horizontal hasn't been set */
3387 bd->saved.x = bd->x - bd->zone->x;
3388 bd->saved.w = bd->w;
3390 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3392 /* Vertical hasn't been set */
3393 bd->saved.y = bd->y - bd->zone->y;
3394 bd->saved.h = bd->h;
3397 bd->saved.zone = bd->zone->num;
3398 e_hints_window_size_set(bd);
3402 _e_border_maximize(bd, max);
3405 /* Remove previous type */
3406 bd->maximized &= ~E_MAXIMIZE_TYPE;
3407 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3408 bd->maximized |= max;
3410 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3411 bd->maximized & E_MAXIMIZE_VERTICAL);
3412 e_remember_update(bd);
3416 e_border_unmaximize(E_Border *bd,
3420 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3421 if (!(max & E_MAXIMIZE_DIRECTION))
3423 CRI("BUG: Unmaximize call without direction!");
3427 if ((bd->shaded) || (bd->shading)) return;
3428 ecore_x_window_shadow_tree_flush();
3429 /* Remove directions not used */
3430 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3431 /* Can only remove existing maximization directions */
3433 if (bd->maximized & E_MAXIMIZE_TYPE)
3435 bd->pre_res_change.valid = 0;
3436 bd->need_maximize = 0;
3438 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3442 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3443 _e_border_client_inset_calc(bd);
3446 bd->maximized = E_MAXIMIZE_NONE;
3447 _e_border_move_resize_internal(bd,
3448 bd->zone->x + bd->saved.x,
3449 bd->zone->y + bd->saved.y,
3450 bd->saved.w, bd->saved.h, 0, 1);
3451 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3452 e_hints_window_size_unset(bd);
3463 if (max & E_MAXIMIZE_VERTICAL)
3465 /* Remove vertical */
3467 y = bd->saved.y + bd->zone->y;
3468 bd->saved.h = bd->saved.y = 0;
3469 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3470 bd->maximized &= ~E_MAXIMIZE_LEFT;
3471 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3473 if (max & E_MAXIMIZE_HORIZONTAL)
3475 /* Remove horizontal */
3477 x = bd->saved.x + bd->zone->x;
3478 bd->saved.w = bd->saved.x = 0;
3479 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3482 e_border_resize_limit(bd, &w, &h);
3484 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3486 bd->maximized = E_MAXIMIZE_NONE;
3487 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3488 e_hints_window_size_unset(bd);
3489 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3493 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3494 e_hints_window_size_set(bd);
3497 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3498 bd->maximized & E_MAXIMIZE_VERTICAL);
3500 e_remember_update(bd);
3504 e_border_fullscreen(E_Border *bd,
3505 E_Fullscreen policy)
3507 E_Event_Border_Fullscreen *ev;
3510 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3512 if ((bd->shaded) || (bd->shading)) return;
3513 ecore_x_window_shadow_tree_flush();
3516 bd->need_fullscreen = 1;
3519 if (!bd->fullscreen)
3521 bd->pre_res_change.valid = 0;
3523 bd->saved.x = bd->x - bd->zone->x;
3524 bd->saved.y = bd->y - bd->zone->y;
3525 bd->saved.w = bd->client.w;
3526 bd->saved.h = bd->client.h;
3527 bd->saved.maximized = bd->maximized;
3528 bd->saved.zone = bd->zone->num;
3531 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3532 e_hints_window_size_set(bd);
3534 bd->client_inset.l = 0;
3535 bd->client_inset.r = 0;
3536 bd->client_inset.t = 0;
3537 bd->client_inset.b = 0;
3539 bd->desk->fullscreen_borders++;
3541 /* e_zone_fullscreen_set(bd->zone, 1); */
3542 bd->saved.layer = bd->layer;
3543 if (!e_config->allow_above_fullscreen)
3544 e_border_layer_set(bd, 250);
3546 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3547 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3549 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3551 else if (policy == E_FULLSCREEN_ZOOM)
3553 Ecore_X_Randr_Screen_Size_MM *sizes;
3554 int num_sizes, i, best_size_index = 0;
3556 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3558 &screen_size.height,
3560 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3564 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3565 int best_dist = INT_MAX, dist;
3567 for (i = 0; i < num_sizes; i++)
3569 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3571 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3572 if (dist < best_dist)
3574 best_size.width = sizes[i].width;
3575 best_size.height = sizes[i].height;
3577 best_size_index = i;
3581 if (((best_size.width != -1) && (best_size.height != -1)) &&
3582 ((best_size.width != screen_size.width) ||
3583 (best_size.height != screen_size.height)))
3585 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3587 screen_size_index = best_size_index;
3588 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3592 screen_size.width = -1;
3593 screen_size.height = -1;
3594 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3599 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3603 e_hints_window_fullscreen_set(bd, 1);
3604 e_hints_window_size_unset(bd);
3605 bd->client.border.changed = 1;
3608 bd->fullscreen_policy = policy;
3610 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3612 e_object_ref(E_OBJECT(bd));
3613 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3614 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3616 e_remember_update(bd);
3620 e_border_unfullscreen(E_Border *bd)
3622 E_Event_Border_Unfullscreen *ev;
3625 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3626 if ((bd->shaded) || (bd->shading)) return;
3627 ecore_x_window_shadow_tree_flush();
3630 bd->pre_res_change.valid = 0;
3632 bd->need_fullscreen = 0;
3633 bd->desk->fullscreen_borders--;
3635 if ((screen_size.width != -1) && (screen_size.height != -1))
3637 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3639 screen_size.width = -1;
3640 screen_size.height = -1;
3642 e_border_move_resize(bd,
3643 bd->saved.x + bd->zone->x,
3644 bd->saved.y + bd->zone->y,
3645 bd->saved.w, bd->saved.h);
3647 if (bd->saved.maximized)
3648 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3649 bd->saved.maximized);
3651 e_border_layer_set(bd, bd->saved.layer);
3653 e_hints_window_fullscreen_set(bd, 0);
3654 bd->client.border.changed = 1;
3657 bd->fullscreen_policy = 0;
3659 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3661 e_object_ref(E_OBJECT(bd));
3662 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3663 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3665 e_remember_update(bd);
3669 e_border_iconify(E_Border *bd)
3671 E_Event_Border_Iconify *ev;
3672 unsigned int iconic;
3675 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3676 if (bd->shading) return;
3677 ecore_x_window_shadow_tree_flush();
3681 e_border_hide(bd, 1);
3682 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3683 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3686 e_hints_window_iconic_set(bd);
3687 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3689 ev = E_NEW(E_Event_Border_Iconify, 1);
3691 e_object_ref(E_OBJECT(bd));
3692 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3693 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3695 if (e_config->transient.iconify)
3699 Eina_List *list = _e_border_sub_borders_new(bd);
3701 EINA_LIST_FOREACH(list, l, child)
3703 e_border_iconify(child);
3705 eina_list_free(list);
3707 e_remember_update(bd);
3710 #ifdef _F_DEICONIFY_APPROVE_
3712 _e_border_uniconify_timeout(void *data)
3719 if (!e_object_is_del(E_OBJECT(bd)))
3721 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3722 bd->client.e.state.deiconify_approve.render_done = 1;
3723 if (bd->client.e.state.deiconify_approve.req_list)
3725 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3727 child_bd->client.e.state.deiconify_approve.render_done = 1;
3728 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3731 bd->client.e.state.deiconify_approve.req_list = NULL;
3732 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3733 e_border_uniconify(bd);
3736 return ECORE_CALLBACK_CANCEL;
3740 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
3742 if (!bd || !bd_ancestor) return;
3744 if (e_config->deiconify_approve)
3746 if (e_config->transient.iconify)
3750 Eina_List *list = _e_border_sub_borders_new(bd);
3751 EINA_LIST_FOREACH(list, l, child)
3753 #ifdef _F_ZONE_WINDOW_ROTATION_
3754 if ((e_config->wm_win_rotation) &&
3755 ((child->client.e.state.rot.support) ||
3756 (child->client.e.state.rot.app_set)))
3758 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3759 _e_border_rotation_check(child);
3762 _e_border_deiconify_approve_send(child, bd_ancestor);
3763 if (child->client.e.state.deiconify_approve.support)
3765 ELBF(ELBT_BD, 0, child->client.win,
3766 "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
3768 ecore_x_client_message32_send(child->client.win,
3769 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3770 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3771 child->client.win, 0, 0, 0, 0);
3772 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3773 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3776 eina_list_free(list);
3782 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3784 E_Border *bd_ancestor;
3787 if (e_config->deiconify_approve)
3789 #ifdef _F_ZONE_WINDOW_ROTATION_
3790 if ((e_config->wm_win_rotation) &&
3791 ((bd->client.e.state.rot.support) ||
3792 (bd->client.e.state.rot.app_set)))
3794 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3795 _e_border_rotation_check(bd);
3799 if (e_config->transient.iconify)
3801 _e_border_deiconify_approve_send(bd, bd_ancestor);
3804 if (bd->client.e.state.deiconify_approve.support)
3806 ELBF(ELBT_BD, 0, bd->client.win,
3807 "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
3809 ecore_x_client_message32_send(bd->client.win,
3810 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3811 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3812 bd->client.win, 0, 0, 0, 0);
3813 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3820 e_border_uniconify(E_Border *bd)
3823 E_Event_Border_Uniconify *ev;
3824 unsigned int iconic;
3827 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3829 #ifdef _F_DEICONIFY_APPROVE_
3830 if (e_config->deiconify_approve)
3832 if (bd->client.e.state.deiconify_approve.support)
3834 if (bd->client.e.state.deiconify_approve.wait_timer)
3836 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3839 if (bd->client.e.state.deiconify_approve.render_done == 0)
3841 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3842 _e_border_deiconify_approve_send_all_transient(bd);
3846 bd->client.e.state.deiconify_approve.render_done = 0;
3850 #if _F_ZONE_WINDOW_ROTATION_
3851 if (!bd->client.win)
3853 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3858 if (bd->shading) return;
3859 ecore_x_window_shadow_tree_flush();
3864 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3865 desk = e_desk_current_get(bd->desk->zone);
3866 #ifdef _F_USE_EXTENDED_ICONIFY_
3867 if (e_manager_comp_evas_get(bd->zone->container->manager))
3869 if (bd->await_hide_event > 0)
3870 bd->await_hide_event--;
3873 e_border_desk_set(bd, desk);
3875 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3878 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3880 ev = E_NEW(E_Event_Border_Uniconify, 1);
3882 e_object_ref(E_OBJECT(bd));
3883 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3884 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3886 if (e_config->transient.iconify)
3890 Eina_List *list = _e_border_sub_borders_new(bd);
3892 EINA_LIST_FOREACH(list, l, child)
3894 e_border_uniconify(child);
3896 eina_list_free(list);
3898 e_remember_update(bd);
3902 e_border_stick(E_Border *bd)
3904 E_Event_Border_Stick *ev;
3907 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3908 if (bd->sticky) return;
3910 e_hints_window_sticky_set(bd, 1);
3913 if (e_config->transient.desktop)
3917 Eina_List *list = _e_border_sub_borders_new(bd);
3919 EINA_LIST_FOREACH(list, l, child)
3922 e_hints_window_sticky_set(child, 1);
3923 e_border_show(child);
3925 eina_list_free(list);
3928 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3929 ev = E_NEW(E_Event_Border_Stick, 1);
3931 e_object_ref(E_OBJECT(bd));
3932 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3933 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3934 e_remember_update(bd);
3938 e_border_unstick(E_Border *bd)
3940 E_Event_Border_Unstick *ev;
3943 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3944 /* Set the desk before we unstick the border */
3945 if (!bd->sticky) return;
3947 e_hints_window_sticky_set(bd, 0);
3949 if (e_config->transient.desktop)
3953 Eina_List *list = _e_border_sub_borders_new(bd);
3955 EINA_LIST_FOREACH(list, l, child)
3958 e_hints_window_sticky_set(child, 0);
3960 eina_list_free(list);
3963 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3964 ev = E_NEW(E_Event_Border_Unstick, 1);
3966 e_object_ref(E_OBJECT(bd));
3967 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3968 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3970 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3971 e_remember_update(bd);
3975 e_border_pinned_set(E_Border *bd,
3983 bd->borderless = set;
3984 bd->user_skip_winlist = set;
3988 stacking = E_STACKING_BELOW;
3993 stacking = E_STACKING_NONE;
3996 e_border_layer_set(bd, layer);
3997 e_hints_window_stacking_set(bd, stacking);
3999 bd->client.border.changed = 1;
4005 e_border_find_by_client_window(Ecore_X_Window win)
4009 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4010 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4011 (bd->client.win == win))
4017 e_border_find_all_by_client_window(Ecore_X_Window win)
4021 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4022 if ((bd) && (bd->client.win == win))
4028 e_border_find_by_frame_window(Ecore_X_Window win)
4032 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4033 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4034 (bd->bg_win == win))
4040 e_border_find_by_window(Ecore_X_Window win)
4044 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4045 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4052 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4057 EINA_LIST_FOREACH(borders, l, bd)
4059 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4060 (bd->client.netwm.sync.alarm == al))
4067 e_border_focused_get(void)
4073 _e_border_shape_input_rectangle_set(E_Border* bd)
4077 if ((bd->visible) && (bd->shaped_input))
4079 Ecore_X_Rectangle rects[4];
4080 Ecore_X_Window twin, twin2;
4083 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4084 0, 0, bd->w, bd->h);
4087 rects[0].width = bd->w;
4088 rects[0].height = bd->client_inset.t;
4090 rects[1].y = bd->client_inset.t;
4091 rects[1].width = bd->client_inset.l;
4092 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4093 rects[2].x = bd->w - bd->client_inset.r;
4094 rects[2].y = bd->client_inset.t;
4095 rects[2].width = bd->client_inset.r;
4096 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4098 rects[3].y = bd->h - bd->client_inset.b;
4099 rects[3].width = bd->w;
4100 rects[3].height = bd->client_inset.b;
4101 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4103 twin2 = ecore_x_window_override_new
4104 (bd->zone->container->scratch_win, 0, 0,
4105 bd->w - bd->client_inset.l - bd->client_inset.r,
4106 bd->h - bd->client_inset.t - bd->client_inset.b);
4109 if ((bd->shading) || (bd->shaded))
4111 if (bd->shade.dir == E_DIRECTION_UP)
4112 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4114 else if (bd->shade.dir == E_DIRECTION_LEFT)
4115 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4118 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4120 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4121 bd->w - bd->client_inset.l - bd->client_inset.r,
4122 bd->h - bd->client_inset.t - bd->client_inset.b);
4123 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4125 bd->client_inset.t);
4126 ecore_x_window_shape_input_window_set(bd->win, twin);
4127 ecore_x_window_free(twin2);
4128 ecore_x_window_free(twin);
4132 if (bd->visible) // not shaped input
4134 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4135 ecore_x_composite_window_events_enable(bd->win);
4137 ecore_x_composite_window_events_disable(bd->win);
4141 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4142 ecore_x_composite_window_events_enable(bd->win);
4144 ecore_x_composite_window_events_disable(bd->win);
4150 e_border_idler_before(void)
4159 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4161 EINA_LIST_FOREACH(man->containers, cl, con)
4166 // pass 1 - eval0. fetch properties on new or on change and
4167 // call hooks to decide what to do - maybe move/resize
4168 bl = e_container_border_list_last(con);
4169 while ((bd = e_container_border_list_prev(bl)))
4171 if (bd->changed) _e_border_eval0(bd);
4173 e_container_border_list_free(bl);
4175 // layout hook - this is where a hook gets to figure out what to
4177 _e_border_container_layout_hook(con);
4179 // pass 2 - show windows needing show
4180 bl = e_container_border_list_last(con);
4181 while ((bd = e_container_border_list_prev(bl)))
4183 if ((bd->changes.visible) && (bd->visible) &&
4184 (!bd->new_client) && (!bd->changes.pos) &&
4185 (!bd->changes.size))
4188 bd->changes.visible = 0;
4191 e_container_border_list_free(bl);
4193 // pass 3 - hide windows needing hide and eval (main eval)
4194 bl = e_container_border_list_first(con);
4195 while ((bd = e_container_border_list_next(bl)))
4197 if (e_object_is_del(E_OBJECT(bd))) continue;
4199 if ((bd->changes.visible) && (!bd->visible))
4202 bd->changes.visible = 0;
4205 if (bd->changed) _e_border_eval(bd);
4207 if ((bd->changes.visible) && (bd->visible))
4210 bd->changes.visible = 0;
4213 e_container_border_list_free(bl);
4219 E_Border *bd = NULL, *bd2;
4221 EINA_LIST_FREE(focus_next, bd2)
4222 if ((!bd) && (bd2->visible)) bd = bd2;
4226 /* TODO revert focus when lost here ? */
4232 /* already focused. but anyway dont be so strict, this
4233 fcks up illume setting focus on internal windows */
4238 focus_time = ecore_x_current_time_get();
4242 if ((bd->client.icccm.take_focus) &&
4243 (bd->client.icccm.accepts_focus))
4245 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4246 /* TODO what if the client didn't take focus ? */
4248 else if (!bd->client.icccm.accepts_focus)
4250 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4252 else if (!bd->client.icccm.take_focus)
4254 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4255 /* e_border_focus_set(bd, 1, 0); */
4259 #ifdef _F_ZONE_WINDOW_ROTATION_
4260 if ((e_config->wm_win_rotation) &&
4263 Ecore_X_Event_Client_Message *msg = NULL;
4265 EINA_LIST_FREE(rot.msgs, msg)
4267 t = msg->message_type;
4268 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4270 if ((rot.vkbd_ctrl_win) &&
4271 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4274 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4275 if (rot.vkbd_show_prepare_timer)
4276 _e_border_vkbd_show(rot.vkbd);
4278 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4281 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4283 if ((rot.vkbd_ctrl_win) &&
4284 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4287 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4288 if (rot.vkbd_hide_prepare_timer)
4290 _e_border_vkbd_hide(rot.vkbd);
4291 rot.vkbd_hide_prepare_timer = NULL;
4292 e_object_unref(E_OBJECT(rot.vkbd));
4295 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4298 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4300 rot.vkbd_ctrl_win = msg->data.l[0];
4301 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4303 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4305 if ((rot.vkbd_ctrl_win) &&
4306 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4308 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4309 E_Manager *m = e_manager_current_get();
4310 E_Zone *zone = NULL;
4311 if (m) zone = e_util_zone_current_get(m);
4312 if ((zone) && (rot.wait_prepare_done))
4314 if (_e_border_rotation_list_add(zone, EINA_FALSE))
4315 _e_border_rotation_change_request(zone);
4318 if (rot.prepare_timer)
4319 ecore_timer_del(rot.prepare_timer);
4320 rot.prepare_timer = NULL;
4321 rot.wait_prepare_done = EINA_FALSE;
4329 rot.fetch = EINA_FALSE;
4335 e_border_client_list(void)
4337 /* FIXME: This should be a somewhat ordered list */
4341 static Ecore_X_Window action_input_win = 0;
4342 static E_Border *action_border = NULL;
4343 static Ecore_Event_Handler *action_handler_key = NULL;
4344 static Ecore_Event_Handler *action_handler_mouse = NULL;
4345 static Ecore_Timer *action_timer = NULL;
4346 static Ecore_X_Rectangle action_orig;
4349 _e_border_show(E_Border *bd)
4354 ecore_evas_show(bd->bg_ecore_evas);
4362 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4364 _e_border_shape_input_rectangle_set(bd);
4366 // ecore_x_composite_window_events_enable(bd->win);
4367 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4370 ecore_x_window_show(bd->win);
4372 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4373 ecore_x_window_show(tmp->win);
4377 _e_border_hide(E_Border *bd)
4382 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4384 ecore_x_window_hide(bd->win);
4385 ecore_evas_hide(bd->bg_ecore_evas);
4387 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4388 ecore_x_window_hide(tmp->win);
4392 ecore_x_composite_window_events_disable(bd->win);
4393 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4398 _e_border_action_input_win_del(void)
4400 if (!action_input_win)
4403 e_grabinput_release(action_input_win, action_input_win);
4404 ecore_x_window_free(action_input_win);
4405 action_input_win = 0;
4410 _e_border_action_input_win_new(E_Border *bd)
4412 if (!action_input_win)
4414 Ecore_X_Window parent = bd->zone->container->win;
4415 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4416 if (!action_input_win)
4420 ecore_x_window_show(action_input_win);
4421 if (e_grabinput_get(action_input_win, 0, action_input_win))
4424 _e_border_action_input_win_del();
4429 _e_border_action_finish(void)
4431 _e_border_action_input_win_del();
4435 ecore_timer_del(action_timer);
4436 action_timer = NULL;
4439 if (action_handler_key)
4441 ecore_event_handler_del(action_handler_key);
4442 action_handler_key = NULL;
4445 if (action_handler_mouse)
4447 ecore_event_handler_del(action_handler_mouse);
4448 action_handler_mouse = NULL;
4451 action_border = NULL;
4455 _e_border_action_init(E_Border *bd)
4457 action_orig.x = bd->x;
4458 action_orig.y = bd->y;
4459 action_orig.width = bd->w;
4460 action_orig.height = bd->h;
4466 _e_border_action_restore_orig(E_Border *bd)
4468 if (action_border != bd)
4471 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4475 _e_border_key_down_modifier_apply(int modifier,
4478 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4480 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4493 _e_border_action_move_timeout(void *data __UNUSED__)
4495 _e_border_move_end(action_border);
4496 _e_border_action_finish();
4497 return ECORE_CALLBACK_CANCEL;
4501 _e_border_action_move_timeout_add(void)
4504 ecore_timer_del(action_timer);
4505 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4509 _e_border_move_key_down(void *data __UNUSED__,
4510 int type __UNUSED__,
4513 Ecore_Event_Key *ev = event;
4516 if (ev->event_window != action_input_win)
4517 return ECORE_CALLBACK_PASS_ON;
4520 fputs("ERROR: no action_border!\n", stderr);
4524 x = action_border->x;
4525 y = action_border->y;
4527 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4528 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4529 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4530 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4531 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4532 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4533 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4534 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4535 else if (strcmp(ev->key, "Return") == 0)
4537 else if (strcmp(ev->key, "Escape") == 0)
4539 _e_border_action_restore_orig(action_border);
4542 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4543 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4546 e_border_move(action_border, x, y);
4547 _e_border_action_move_timeout_add();
4549 return ECORE_CALLBACK_PASS_ON;
4552 _e_border_move_end(action_border);
4553 _e_border_action_finish();
4554 return ECORE_CALLBACK_DONE;
4558 _e_border_move_mouse_down(void *data __UNUSED__,
4559 int type __UNUSED__,
4562 Ecore_Event_Mouse_Button *ev = event;
4564 if (ev->event_window != action_input_win)
4565 return ECORE_CALLBACK_PASS_ON;
4568 fputs("ERROR: no action_border!\n", stderr);
4570 _e_border_move_end(action_border);
4571 _e_border_action_finish();
4572 return ECORE_CALLBACK_DONE;
4576 e_border_act_move_keyboard(E_Border *bd)
4581 if (!_e_border_move_begin(bd))
4584 if (!_e_border_action_input_win_new(bd))
4586 _e_border_move_end(bd);
4590 _e_border_action_init(bd);
4591 _e_border_action_move_timeout_add();
4592 _e_border_move_update(bd);
4594 if (action_handler_key)
4595 ecore_event_handler_del(action_handler_key);
4596 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4598 if (action_handler_mouse)
4599 ecore_event_handler_del(action_handler_mouse);
4600 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4604 _e_border_action_resize_timeout(void *data __UNUSED__)
4606 _e_border_resize_end(action_border);
4607 _e_border_action_finish();
4608 return ECORE_CALLBACK_CANCEL;
4612 _e_border_action_resize_timeout_add(void)
4615 ecore_timer_del(action_timer);
4616 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4620 _e_border_resize_key_down(void *data __UNUSED__,
4621 int type __UNUSED__,
4624 Ecore_Event_Key *ev = event;
4627 if (ev->event_window != action_input_win)
4628 return ECORE_CALLBACK_PASS_ON;
4631 fputs("ERROR: no action_border!\n", stderr);
4635 w = action_border->w;
4636 h = action_border->h;
4638 dx = e_config->border_keyboard.resize.dx;
4639 if (dx < action_border->client.icccm.step_w)
4640 dx = action_border->client.icccm.step_w;
4641 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4642 if (dx < action_border->client.icccm.step_w)
4643 dx = action_border->client.icccm.step_w;
4645 dy = e_config->border_keyboard.resize.dy;
4646 if (dy < action_border->client.icccm.step_h)
4647 dy = action_border->client.icccm.step_h;
4648 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4649 if (dy < action_border->client.icccm.step_h)
4650 dy = action_border->client.icccm.step_h;
4652 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4654 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4656 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4658 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4660 else if (strcmp(ev->key, "Return") == 0)
4662 else if (strcmp(ev->key, "Escape") == 0)
4664 _e_border_action_restore_orig(action_border);
4667 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4668 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4671 e_border_resize_limit(action_border, &w, &h);
4672 e_border_resize(action_border, w, h);
4673 _e_border_action_resize_timeout_add();
4675 return ECORE_CALLBACK_PASS_ON;
4678 _e_border_resize_end(action_border);
4679 _e_border_action_finish();
4680 return ECORE_CALLBACK_DONE;
4684 _e_border_resize_mouse_down(void *data __UNUSED__,
4685 int type __UNUSED__,
4688 Ecore_Event_Mouse_Button *ev = event;
4690 if (ev->event_window != action_input_win)
4691 return ECORE_CALLBACK_PASS_ON;
4694 fputs("ERROR: no action_border!\n", stderr);
4696 _e_border_resize_end(action_border);
4697 _e_border_action_finish();
4698 return ECORE_CALLBACK_DONE;
4702 e_border_act_resize_keyboard(E_Border *bd)
4707 if (!_e_border_resize_begin(bd))
4710 if (!_e_border_action_input_win_new(bd))
4712 _e_border_resize_end(bd);
4716 _e_border_action_init(bd);
4717 _e_border_action_resize_timeout_add();
4718 _e_border_resize_update(bd);
4720 if (action_handler_key)
4721 ecore_event_handler_del(action_handler_key);
4722 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4724 if (action_handler_mouse)
4725 ecore_event_handler_del(action_handler_mouse);
4726 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4730 e_border_act_move_begin(E_Border *bd,
4731 Ecore_Event_Mouse_Button *ev)
4734 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4735 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4736 if (!_e_border_move_begin(bd))
4739 e_zone_edge_disable();
4741 _e_border_pointer_move_begin(bd);
4746 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4747 _e_border_moveinfo_gather(bd, source);
4752 e_border_act_move_end(E_Border *bd,
4753 Ecore_Event_Mouse_Button *ev __UNUSED__)
4756 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4757 if (!bd->moving) return;
4759 _e_border_pointer_move_end(bd);
4760 e_zone_edge_enable();
4761 _e_border_move_end(bd);
4762 e_zone_flip_coords_handle(bd->zone, -1, -1);
4766 e_border_act_resize_begin(E_Border *bd,
4767 Ecore_Event_Mouse_Button *ev)
4770 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4771 if (bd->lock_user_size) return;
4772 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4773 if (!_e_border_resize_begin(bd))
4775 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4777 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4779 bd->resize_mode = RESIZE_TL;
4780 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4784 bd->resize_mode = RESIZE_BL;
4785 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4790 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4792 bd->resize_mode = RESIZE_TR;
4793 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4797 bd->resize_mode = RESIZE_BR;
4798 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4801 _e_border_pointer_resize_begin(bd);
4806 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4807 _e_border_moveinfo_gather(bd, source);
4812 e_border_act_resize_end(E_Border *bd,
4813 Ecore_Event_Mouse_Button *ev __UNUSED__)
4816 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4817 if (bd->resize_mode != RESIZE_NONE)
4819 _e_border_pointer_resize_end(bd);
4820 bd->resize_mode = RESIZE_NONE;
4821 _e_border_resize_end(bd);
4822 bd->changes.reset_gravity = 1;
4828 e_border_act_menu_begin(E_Border *bd,
4829 Ecore_Event_Mouse_Button *ev,
4833 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4836 e_int_border_menu_show(bd,
4837 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4838 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4845 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4846 e_int_border_menu_show(bd, x, y, key, 0);
4851 e_border_act_close_begin(E_Border *bd)
4854 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4855 if (bd->lock_close) return;
4856 if (bd->client.icccm.delete_request)
4858 bd->delete_requested = 1;
4859 ecore_x_window_delete_request_send(bd->client.win);
4860 if (bd->client.netwm.ping)
4863 else if (e_config->kill_if_close_not_possible)
4865 e_border_act_kill_begin(bd);
4870 e_border_act_kill_begin(E_Border *bd)
4873 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4874 if (bd->internal) return;
4875 if (bd->lock_close) return;
4876 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4878 kill(bd->client.netwm.pid, SIGINT);
4879 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4880 _e_border_cb_kill_timer, bd);
4884 if (!bd->internal) ecore_x_kill(bd->client.win);
4889 e_border_icon_add(E_Border *bd,
4894 E_OBJECT_CHECK_RETURN(bd, NULL);
4895 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4900 if (!bd->internal_icon)
4902 o = e_icon_add(evas);
4903 e_util_icon_theme_set(o, "enlightenment");
4907 if (!bd->internal_icon_key)
4911 ext = strrchr(bd->internal_icon, '.');
4912 if ((ext) && ((!strcmp(ext, ".edj"))))
4914 o = edje_object_add(evas);
4915 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4916 e_util_icon_theme_set(o, "enlightenment");
4920 o = e_icon_add(evas);
4921 e_icon_file_set(o, bd->internal_icon);
4925 o = e_icon_add(evas);
4926 if (!e_util_icon_theme_set(o, bd->internal_icon))
4927 e_util_icon_theme_set(o, "enlightenment");
4932 o = edje_object_add(evas);
4933 edje_object_file_set(o, bd->internal_icon,
4934 bd->internal_icon_key);
4939 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4941 if (bd->client.netwm.icons)
4943 o = e_icon_add(evas);
4944 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4945 bd->client.netwm.icons[0].width,
4946 bd->client.netwm.icons[0].height);
4947 e_icon_alpha_set(o, 1);
4953 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4955 o = e_icon_add(evas);
4958 e_icon_fdo_icon_set(o, bd->desktop->icon);
4962 else if (bd->client.netwm.icons)
4964 o = e_icon_add(evas);
4965 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4966 bd->client.netwm.icons[0].width,
4967 bd->client.netwm.icons[0].height);
4968 e_icon_alpha_set(o, 1);
4973 o = e_icon_add(evas);
4974 e_util_icon_theme_set(o, "unknown");
4979 e_border_button_bindings_ungrab_all(void)
4984 EINA_LIST_FOREACH(borders, l, bd)
4986 e_focus_setdown(bd);
4987 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4988 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4993 e_border_button_bindings_grab_all(void)
4998 EINA_LIST_FOREACH(borders, l, bd)
5000 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5001 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5007 e_border_focus_stack_get(void)
5013 e_border_raise_stack_get(void)
5019 e_border_lost_windows_get(E_Zone *zone)
5021 Eina_List *list = NULL, *l;
5023 int loss_overlap = 5;
5025 E_OBJECT_CHECK_RETURN(zone, NULL);
5026 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5027 EINA_LIST_FOREACH(borders, l, bd)
5032 if ((bd->zone != zone) ||
5033 (bd->zone->container != zone->container))
5036 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5037 bd->zone->y + loss_overlap,
5038 bd->zone->w - (2 * loss_overlap),
5039 bd->zone->h - (2 * loss_overlap),
5040 bd->x, bd->y, bd->w, bd->h))
5042 list = eina_list_append(list, bd);
5044 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5045 bd->zone->w, bd->zone->h,
5046 bd->x, bd->y, bd->w, bd->h)) &&
5049 Ecore_X_Rectangle *rect;
5052 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5058 for (i = 0; i < num; i++)
5060 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5061 bd->zone->y + loss_overlap,
5062 bd->zone->w - (2 * loss_overlap),
5063 bd->zone->h - (2 * loss_overlap),
5064 rect[i].x, rect[i].y,
5065 (int)rect[i].width, (int)rect[i].height))
5073 list = eina_list_append(list, bd);
5081 e_border_ping(E_Border *bd)
5084 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5085 if (!e_config->ping_clients) return;
5087 ecore_x_netwm_ping_send(bd->client.win);
5088 bd->ping = ecore_loop_time_get();
5089 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5090 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5091 e_config->ping_clients_interval,
5092 _e_border_cb_ping_poller, bd);
5096 e_border_move_cancel(void)
5100 if (bdmove->cur_mouse_action)
5105 e_object_ref(E_OBJECT(bd));
5106 if (bd->cur_mouse_action->func.end_mouse)
5107 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5108 else if (bd->cur_mouse_action->func.end)
5109 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5110 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5111 bd->cur_mouse_action = NULL;
5112 e_object_unref(E_OBJECT(bd));
5115 _e_border_move_end(bdmove);
5120 e_border_resize_cancel(void)
5124 if (bdresize->cur_mouse_action)
5129 e_object_ref(E_OBJECT(bd));
5130 if (bd->cur_mouse_action->func.end_mouse)
5131 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5132 else if (bd->cur_mouse_action->func.end)
5133 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5134 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5135 bd->cur_mouse_action = NULL;
5136 e_object_unref(E_OBJECT(bd));
5140 bdresize->resize_mode = RESIZE_NONE;
5141 _e_border_resize_end(bdresize);
5147 e_border_frame_recalc(E_Border *bd)
5149 if (!bd->bg_object) return;
5151 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5152 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5154 _e_border_client_inset_calc(bd);
5156 bd->w += (bd->client_inset.l + bd->client_inset.r);
5157 bd->h += (bd->client_inset.t + bd->client_inset.b);
5160 bd->changes.size = 1;
5161 if ((bd->shaped) || (bd->client.shaped))
5163 bd->need_shape_merge = 1;
5164 bd->need_shape_export = 1;
5166 if (bd->shaped_input)
5168 bd->need_shape_merge = 1;
5170 _e_border_client_move_resize_send(bd);
5174 e_border_immortal_windows_get(void)
5176 Eina_List *list = NULL, *l;
5179 EINA_LIST_FOREACH(borders, l, bd)
5182 list = eina_list_append(list, bd);
5188 e_border_name_get(const E_Border *bd)
5190 E_OBJECT_CHECK_RETURN(bd, "");
5191 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5192 if (bd->client.netwm.name)
5193 return bd->client.netwm.name;
5194 else if (bd->client.icccm.title)
5195 return bd->client.icccm.title;
5200 e_border_signal_move_begin(E_Border *bd,
5202 const char *src __UNUSED__)
5205 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5207 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5208 if (!_e_border_move_begin(bd)) return;
5210 _e_border_pointer_move_begin(bd);
5211 e_zone_edge_disable();
5212 _e_border_moveinfo_gather(bd, sig);
5213 if (bd->cur_mouse_action)
5215 if ((!bd->cur_mouse_action->func.end_mouse) &&
5216 (!bd->cur_mouse_action->func.end))
5217 bd->cur_mouse_action = NULL;
5219 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5221 bd->cur_mouse_action = e_action_find("window_move");
5222 if (bd->cur_mouse_action)
5223 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5227 e_border_signal_move_end(E_Border *bd,
5228 const char *sig __UNUSED__,
5229 const char *src __UNUSED__)
5232 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5233 if (!bd->moving) return;
5235 _e_border_pointer_move_end(bd);
5236 e_zone_edge_enable();
5237 _e_border_move_end(bd);
5238 e_zone_flip_coords_handle(bd->zone, -1, -1);
5242 e_border_resizing_get(E_Border *bd)
5244 E_OBJECT_CHECK_RETURN(bd, 0);
5245 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5246 if (bd->resize_mode == RESIZE_NONE) return 0;
5251 e_border_signal_resize_begin(E_Border *bd,
5254 const char *src __UNUSED__)
5256 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5257 int resize_mode = RESIZE_BR;
5260 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5262 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5263 if (!_e_border_resize_begin(bd))
5265 if (!strcmp(dir, "tl"))
5267 resize_mode = RESIZE_TL;
5268 grav = ECORE_X_GRAVITY_SE;
5270 else if (!strcmp(dir, "t"))
5272 resize_mode = RESIZE_T;
5273 grav = ECORE_X_GRAVITY_S;
5275 else if (!strcmp(dir, "tr"))
5277 resize_mode = RESIZE_TR;
5278 grav = ECORE_X_GRAVITY_SW;
5280 else if (!strcmp(dir, "r"))
5282 resize_mode = RESIZE_R;
5283 grav = ECORE_X_GRAVITY_W;
5285 else if (!strcmp(dir, "br"))
5287 resize_mode = RESIZE_BR;
5288 grav = ECORE_X_GRAVITY_NW;
5290 else if (!strcmp(dir, "b"))
5292 resize_mode = RESIZE_B;
5293 grav = ECORE_X_GRAVITY_N;
5295 else if (!strcmp(dir, "bl"))
5297 resize_mode = RESIZE_BL;
5298 grav = ECORE_X_GRAVITY_NE;
5300 else if (!strcmp(dir, "l"))
5302 resize_mode = RESIZE_L;
5303 grav = ECORE_X_GRAVITY_E;
5305 bd->resize_mode = resize_mode;
5306 _e_border_pointer_resize_begin(bd);
5307 _e_border_moveinfo_gather(bd, sig);
5309 if (bd->cur_mouse_action)
5311 if ((!bd->cur_mouse_action->func.end_mouse) &&
5312 (!bd->cur_mouse_action->func.end))
5313 bd->cur_mouse_action = NULL;
5315 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5317 bd->cur_mouse_action = e_action_find("window_resize");
5318 if (bd->cur_mouse_action)
5319 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5323 e_border_signal_resize_end(E_Border *bd,
5324 const char *dir __UNUSED__,
5325 const char *sig __UNUSED__,
5326 const char *src __UNUSED__)
5329 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5330 if (bd->resize_mode == RESIZE_NONE) return;
5331 _e_border_resize_handle(bd);
5332 _e_border_pointer_resize_end(bd);
5333 bd->resize_mode = RESIZE_NONE;
5334 _e_border_resize_end(bd);
5335 bd->changes.reset_gravity = 1;
5340 e_border_resize_limit(E_Border *bd,
5347 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5348 *w -= bd->client_inset.l + bd->client_inset.r;
5349 *h -= bd->client_inset.t + bd->client_inset.b;
5352 if ((bd->client.icccm.base_w >= 0) &&
5353 (bd->client.icccm.base_h >= 0))
5357 tw = *w - bd->client.icccm.base_w;
5358 th = *h - bd->client.icccm.base_h;
5361 a = (double)(tw) / (double)(th);
5362 if ((bd->client.icccm.min_aspect != 0.0) &&
5363 (a < bd->client.icccm.min_aspect))
5365 th = tw / bd->client.icccm.max_aspect;
5366 *h = th + bd->client.icccm.base_h;
5368 else if ((bd->client.icccm.max_aspect != 0.0) &&
5369 (a > bd->client.icccm.max_aspect))
5371 tw = th * bd->client.icccm.max_aspect;
5372 *w = tw + bd->client.icccm.base_w;
5377 a = (double)*w / (double)*h;
5378 if ((bd->client.icccm.min_aspect != 0.0) &&
5379 (a < bd->client.icccm.min_aspect))
5380 *h = *w / bd->client.icccm.min_aspect;
5381 else if ((bd->client.icccm.max_aspect != 0.0) &&
5382 (a > bd->client.icccm.max_aspect))
5383 *w = *h * bd->client.icccm.max_aspect;
5385 if (bd->client.icccm.step_w > 0)
5387 if (bd->client.icccm.base_w >= 0)
5388 *w = bd->client.icccm.base_w +
5389 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5390 bd->client.icccm.step_w);
5392 *w = bd->client.icccm.min_w +
5393 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5394 bd->client.icccm.step_w);
5396 if (bd->client.icccm.step_h > 0)
5398 if (bd->client.icccm.base_h >= 0)
5399 *h = bd->client.icccm.base_h +
5400 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5401 bd->client.icccm.step_h);
5403 *h = bd->client.icccm.min_h +
5404 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5405 bd->client.icccm.step_h);
5411 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5412 else if (*w < bd->client.icccm.min_w)
5413 *w = bd->client.icccm.min_w;
5414 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5415 else if (*h < bd->client.icccm.min_h)
5416 *h = bd->client.icccm.min_h;
5418 *w += bd->client_inset.l + bd->client_inset.r;
5419 *h += bd->client_inset.t + bd->client_inset.b;
5422 /* local subsystem functions */
5424 _e_border_free(E_Border *bd)
5426 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5429 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5431 bd->client.e.state.video_parent_border->client.e.state.video_child =
5433 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5436 if (bd->client.e.state.video_child)
5440 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5442 tmp->client.e.state.video_parent_border = NULL;
5447 efreet_desktop_free(bd->desktop);
5452 ecore_idle_enterer_del(bd->post_job);
5453 bd->post_job = NULL;
5457 e_object_del(E_OBJECT(bd->pointer));
5461 _e_border_resize_end(bd);
5463 _e_border_move_end(bd);
5464 /* TODO: Other states to end before dying? */
5466 if (bd->cur_mouse_action)
5468 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5469 bd->cur_mouse_action = NULL;
5472 E_FREE(bd->shape_rects);
5473 bd->shape_rects_num = 0;
5475 if (bd->dangling_ref_check)
5477 ecore_timer_del(bd->dangling_ref_check);
5478 bd->dangling_ref_check = NULL;
5483 ecore_timer_del(bd->kill_timer);
5484 bd->kill_timer = NULL;
5486 if (bd->ping_poller)
5488 ecore_poller_del(bd->ping_poller);
5489 bd->ping_poller = NULL;
5491 E_FREE_LIST(bd->pending_move_resize, free);
5493 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5494 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5496 if (bd->border_locks_dialog)
5498 e_object_del(E_OBJECT(bd->border_locks_dialog));
5499 bd->border_locks_dialog = NULL;
5501 if (bd->border_remember_dialog)
5503 e_object_del(E_OBJECT(bd->border_remember_dialog));
5504 bd->border_remember_dialog = NULL;
5506 if (bd->border_border_dialog)
5508 e_object_del(E_OBJECT(bd->border_border_dialog));
5509 bd->border_border_dialog = NULL;
5511 if (bd->border_prop_dialog)
5513 e_object_del(E_OBJECT(bd->border_prop_dialog));
5514 bd->border_prop_dialog = NULL;
5517 e_int_border_menu_del(bd);
5522 focus_next = eina_list_remove(focus_next, bd);
5524 if ((focused == bd) ||
5525 (e_grabinput_last_focus_win_get() == bd->client.win))
5527 if ((!focus_next) && (!focusing))
5529 e_grabinput_focus(bd->zone->container->bg_win,
5530 E_FOCUS_METHOD_PASSIVE);
5531 e_hints_active_window_set(bd->zone->container->manager, NULL);
5536 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5542 bd->remember = NULL;
5543 e_remember_unuse(rem);
5545 if (!bd->already_unparented)
5547 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5548 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5549 ecore_x_window_save_set_del(bd->client.win);
5550 bd->already_unparented = 1;
5552 if (bd->group) eina_list_free(bd->group);
5553 if (bd->transients) eina_list_free(bd->transients);
5554 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5555 if (bd->client.netwm.icons)
5558 for (i = 0; i < bd->client.netwm.num_icons; i++)
5559 free(bd->client.netwm.icons[i].data);
5560 free(bd->client.netwm.icons);
5562 if (bd->client.netwm.extra_types)
5563 free(bd->client.netwm.extra_types);
5564 if (bd->client.border.name)
5565 eina_stringshare_del(bd->client.border.name);
5567 eina_stringshare_del(bd->bordername);
5568 if (bd->client.icccm.name)
5569 eina_stringshare_del(bd->client.icccm.name);
5570 if (bd->client.icccm.class)
5572 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5573 e_bindings_mapping_change_enable(EINA_TRUE);
5574 eina_stringshare_del(bd->client.icccm.class);
5576 if (bd->client.icccm.title)
5577 eina_stringshare_del(bd->client.icccm.title);
5578 if (bd->client.icccm.icon_name)
5579 eina_stringshare_del(bd->client.icccm.icon_name);
5580 if (bd->client.icccm.machine)
5581 eina_stringshare_del(bd->client.icccm.machine);
5582 if (bd->client.icccm.window_role)
5583 eina_stringshare_del(bd->client.icccm.window_role);
5585 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5589 for (i = 0; i < bd->client.icccm.command.argc; i++)
5590 free(bd->client.icccm.command.argv[i]);
5591 free(bd->client.icccm.command.argv);
5593 if (bd->client.netwm.name)
5594 eina_stringshare_del(bd->client.netwm.name);
5595 if (bd->client.netwm.icon_name)
5596 eina_stringshare_del(bd->client.netwm.icon_name);
5597 e_object_del(E_OBJECT(bd->shape));
5598 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5599 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5600 if (bd->icon_object) evas_object_del(bd->icon_object);
5601 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5602 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5604 if (str) eina_stringshare_del(str);
5606 bd->client.e.state.profiles = NULL;
5607 if (bd->client.e.state.profile)
5608 eina_stringshare_del(bd->client.e.state.profile);
5609 bd->client.e.state.profile = NULL;
5611 #ifdef _F_ZONE_WINDOW_ROTATION_
5612 if (e_config->wm_win_rotation)
5614 bd->client.e.fetch.rot.app_set = 0;
5615 bd->client.e.state.rot.preferred_rot = -1;
5617 if (bd->client.e.state.rot.available_rots)
5618 E_FREE(bd->client.e.state.rot.available_rots);
5620 _e_border_rotation_list_remove(bd);
5621 if ((rot.vkbd) && (rot.vkbd == bd))
5623 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5625 if (rot.vkbd_ctrl_win)
5627 ELB(ELBT_BD, "SET KBD_OFF", 0);
5628 ecore_x_e_virtual_keyboard_state_set
5629 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5632 rot.vkbd_hide_prepare_done = EINA_FALSE;
5633 if (rot.vkbd_hide_prepare_timer)
5634 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5635 rot.vkbd_hide_prepare_timer = NULL;
5636 if (rot.vkbd_hide_timer)
5637 ecore_timer_del(rot.vkbd_hide_timer);
5638 rot.vkbd_hide_timer = NULL;
5640 rot.vkbd_show_prepare_done = EINA_FALSE;
5641 if (rot.vkbd_show_prepare_timer)
5642 ecore_timer_del(rot.vkbd_show_prepare_timer);
5643 rot.vkbd_show_prepare_timer = NULL;
5644 if (rot.vkbd_show_timer)
5645 ecore_timer_del(rot.vkbd_show_timer);
5646 rot.vkbd_show_timer = NULL;
5648 else if ((rot.vkbd_prediction) &&
5649 (rot.vkbd_prediction == bd))
5650 rot.vkbd_prediction = NULL;
5653 evas_object_del(bd->bg_object);
5654 e_canvas_del(bd->bg_ecore_evas);
5655 ecore_evas_free(bd->bg_ecore_evas);
5656 ecore_x_window_free(bd->client.shell_win);
5657 e_focus_setdown(bd);
5658 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5659 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5660 ecore_x_window_free(bd->win);
5662 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5663 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5664 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5665 borders = eina_list_remove(borders, bd);
5666 focus_stack = eina_list_remove(focus_stack, bd);
5667 raise_stack = eina_list_remove(raise_stack, bd);
5669 e_container_border_remove(bd);
5675 _e_border_del_dangling_ref_check(void *data)
5681 printf("EEK EEK border still around 1 second after being deleted!\n");
5682 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5683 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5684 bd->client.icccm.name, bd->client.icccm.class);
5685 // e_object_breadcrumb_debug(E_OBJECT(bd));
5692 _e_border_del(E_Border *bd)
5694 E_Event_Border_Remove *ev;
5697 #ifdef _F_BORDER_HOOK_PATCH_
5698 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5709 focus_next = eina_list_remove(focus_next, bd);
5711 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5713 if ((drag_border) && (drag_border->data == bd))
5715 e_object_del(E_OBJECT(drag_border));
5718 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5720 if (bd->border_locks_dialog)
5722 e_object_del(E_OBJECT(bd->border_locks_dialog));
5723 bd->border_locks_dialog = NULL;
5725 if (bd->border_remember_dialog)
5727 e_object_del(E_OBJECT(bd->border_remember_dialog));
5728 bd->border_remember_dialog = NULL;
5730 if (bd->border_border_dialog)
5732 e_object_del(E_OBJECT(bd->border_border_dialog));
5733 bd->border_border_dialog = NULL;
5735 if (bd->border_prop_dialog)
5737 e_object_del(E_OBJECT(bd->border_prop_dialog));
5738 bd->border_prop_dialog = NULL;
5741 e_int_border_menu_del(bd);
5743 if (bd->raise_timer)
5745 ecore_timer_del(bd->raise_timer);
5746 bd->raise_timer = NULL;
5748 if (!bd->already_unparented)
5750 ecore_x_window_reparent(bd->client.win,
5751 bd->zone->container->manager->root,
5752 bd->x + bd->client_inset.l,
5753 bd->y + bd->client_inset.t);
5754 ecore_x_window_save_set_del(bd->client.win);
5755 bd->already_unparented = 1;
5756 // bd->client.win = 0;
5758 bd->already_unparented = 1;
5760 if ((!bd->new_client) && (!stopping))
5762 ev = E_NEW(E_Event_Border_Remove, 1);
5764 e_object_ref(E_OBJECT(bd));
5765 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5766 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5771 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5772 if (bd->parent->modal == bd)
5774 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5775 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5776 bd->parent->lock_close = 0;
5777 bd->parent->saved.event_mask = 0;
5778 bd->parent->modal = NULL;
5782 EINA_LIST_FREE(bd->transients, child)
5784 child->parent = NULL;
5787 #ifdef _F_DEICONIFY_APPROVE_
5788 bd->client.e.state.deiconify_approve.render_done = 0;
5790 E_Border *ancestor_bd;
5791 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5792 if ((ancestor_bd) &&
5793 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5795 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5796 bd->client.e.state.deiconify_approve.ancestor = NULL;
5798 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5799 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5801 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5803 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5804 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5805 e_border_uniconify(ancestor_bd);
5810 if (bd->client.e.state.deiconify_approve.wait_timer)
5812 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5813 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5816 if (bd->client.e.state.deiconify_approve.req_list)
5818 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5820 child->client.e.state.deiconify_approve.render_done = 0;
5821 child->client.e.state.deiconify_approve.ancestor = NULL;
5828 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5829 if (bd->leader->modal == bd)
5830 bd->leader->modal = NULL;
5833 EINA_LIST_FREE(bd->group, child)
5835 child->leader = NULL;
5839 #ifdef PRINT_LOTS_OF_DEBUG
5841 _e_border_print(E_Border *bd,
5850 "\tBorderless: %s\n",
5851 bd, bd->client.icccm.name, bd->client.icccm.title,
5852 bd->borderless ? "TRUE" : "FALSE");
5858 _e_border_cb_window_show_request(void *data __UNUSED__,
5859 int ev_type __UNUSED__,
5863 Ecore_X_Event_Window_Show_Request *e;
5866 bd = e_border_find_by_client_window(e->win);
5867 if (!bd) return ECORE_CALLBACK_PASS_ON;
5870 if (!bd->lock_client_iconify)
5871 e_border_uniconify(bd);
5875 /* FIXME: make border "urgent" for a bit - it wants attention */
5876 /* e_border_show(bd); */
5877 if (!bd->lock_client_stacking)
5880 return ECORE_CALLBACK_PASS_ON;
5884 _e_border_cb_window_destroy(void *data __UNUSED__,
5885 int ev_type __UNUSED__,
5889 Ecore_X_Event_Window_Destroy *e;
5892 bd = e_border_find_by_client_window(e->win);
5893 if (!bd) return ECORE_CALLBACK_PASS_ON;
5894 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
5895 #ifdef _F_ZONE_WINDOW_ROTATION_
5896 if (e_config->wm_win_rotation)
5898 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5900 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
5901 if (!rot.vkbd_hide_prepare_timer)
5903 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
5904 e_border_hide(bd, 0);
5905 if (!rot.vkbd_hide_prepare_timer)
5907 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
5908 e_object_del(E_OBJECT(bd));
5911 return ECORE_CALLBACK_PASS_ON;
5915 e_border_hide(bd, 0);
5916 e_object_del(E_OBJECT(bd));
5917 return ECORE_CALLBACK_PASS_ON;
5921 _e_border_cb_window_hide(void *data __UNUSED__,
5922 int ev_type __UNUSED__,
5925 E_Border *bd = NULL;
5926 Ecore_X_Event_Window_Hide *e;
5929 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5930 // not interested in hide events from windows other than the window in question
5931 if (e->win != e->event_win)
5933 bd = e_border_find_by_client_window(e->win);
5934 if (!bd) return ECORE_CALLBACK_PASS_ON;
5935 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5939 (bd->zone->container->manager->root == e->event_win)))
5940 return ECORE_CALLBACK_PASS_ON;
5943 if (!bd) bd = e_border_find_by_client_window(e->win);
5944 // printf(" bd = %p\n", bd);
5947 if (ecore_x_window_visible_get(e->win))
5949 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5950 ecore_x_window_hide(e->win);
5952 return ECORE_CALLBACK_PASS_ON;
5955 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5956 if (bd->ignore_first_unmap > 0)
5958 bd->ignore_first_unmap--;
5959 return ECORE_CALLBACK_PASS_ON;
5961 /* Don't delete hidden or iconified windows */
5962 #ifdef _F_USE_EXTENDED_ICONIFY_
5963 if (bd->await_hide_event > 0)
5965 if ((bd->iconic) || (bd->await_hide_event > 0))
5968 // printf(" Don't delete hidden or iconified windows\n");
5969 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
5970 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
5971 if (bd->await_hide_event > 0)
5973 bd->await_hide_event--;
5977 // printf(" hide really\n");
5978 /* Only hide the border if it is visible */
5979 if (bd->visible) e_border_hide(bd, 1);
5984 // printf(" hide2\n");
5985 #ifdef _F_USE_EXTENDED_ICONIFY_
5993 #ifdef _F_ZONE_WINDOW_ROTATION_
5994 if (e_config->wm_win_rotation)
5996 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5998 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
5999 if (!rot.vkbd_hide_prepare_timer)
6001 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6002 e_border_hide(bd, 0);
6003 if (!rot.vkbd_hide_prepare_timer)
6005 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6006 e_object_del(E_OBJECT(bd));
6009 return ECORE_CALLBACK_PASS_ON;
6013 e_border_hide(bd, 0);
6014 e_object_del(E_OBJECT(bd));
6016 return ECORE_CALLBACK_PASS_ON;
6020 _e_border_cb_window_reparent(void *data __UNUSED__,
6021 int ev_type __UNUSED__,
6022 void *ev __UNUSED__)
6026 Ecore_X_Event_Window_Reparent *e;
6029 bd = e_border_find_by_client_window(e->win);
6031 if (e->parent == bd->client.shell_win) return 1;
6032 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6036 e_border_hide(bd, 0);
6037 e_object_del(E_OBJECT(bd));
6039 return ECORE_CALLBACK_PASS_ON;
6043 _e_border_cb_window_configure_request(void *data __UNUSED__,
6044 int ev_type __UNUSED__,
6048 Ecore_X_Event_Window_Configure_Request *e;
6051 bd = e_border_find_by_client_window(e->win);
6054 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6055 if (!e_util_container_window_find(e->win))
6056 ecore_x_window_configure(e->win, e->value_mask,
6057 e->x, e->y, e->w, e->h, e->border,
6058 e->abovewin, e->detail);
6059 return ECORE_CALLBACK_PASS_ON;
6062 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6063 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6069 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6071 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6073 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6074 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6080 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6081 w = e->w + bd->client_inset.l + bd->client_inset.r;
6082 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6083 h = e->h + bd->client_inset.t + bd->client_inset.b;
6084 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6086 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6088 bd->saved.x = x - bd->zone->x;
6089 bd->saved.y = y - bd->zone->y;
6094 e_border_move_resize(bd, x, y, w, h);
6096 else if (!bd->lock_client_location)
6098 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6100 bd->saved.x = x - bd->zone->x;
6101 bd->saved.y = y - bd->zone->y;
6104 e_border_move(bd, x, y);
6106 else if (!bd->lock_client_size)
6108 if ((bd->shaded) || (bd->shading))
6114 if ((bd->shade.dir == E_DIRECTION_UP) ||
6115 (bd->shade.dir == E_DIRECTION_DOWN))
6117 e_border_resize(bd, w, bd->h);
6122 e_border_resize(bd, bd->w, h);
6128 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6134 e_border_resize(bd, w, h);
6140 if (!bd->lock_client_location)
6142 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6144 bd->saved.x = x - bd->zone->x;
6145 bd->saved.y = y - bd->zone->y;
6148 e_border_move(bd, x, y);
6152 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6153 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6159 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6160 w = e->w + bd->client_inset.l + bd->client_inset.r;
6161 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6162 h = e->h + bd->client_inset.t + bd->client_inset.b;
6163 #ifdef _F_ZONE_WINDOW_ROTATION_
6164 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6166 if (!bd->lock_client_size)
6168 if ((bd->shaded) || (bd->shading))
6174 if ((bd->shade.dir == E_DIRECTION_UP) ||
6175 (bd->shade.dir == E_DIRECTION_DOWN))
6177 e_border_resize(bd, w, bd->h);
6182 e_border_resize(bd, bd->w, h);
6188 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6193 zx = zy = zw = zh = 0;
6196 * This code does resize and move a window on a
6197 * X configure request into an useful geometry.
6198 * This is really useful for size jumping file dialogs.
6203 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6205 if (e_config->geometry_auto_resize_limit == 1)
6214 e_border_resize(bd, w, h);
6216 if (e_config->geometry_auto_move == 1)
6218 /* z{x,y,w,h} are only set here; FIXME! */
6221 // move window horizontal if resize to not useful geometry
6222 if (bd->x + bd->w > zx + zw)
6223 rx = zx + zw - bd->w;
6224 else if (bd->x < zx)
6227 // move window vertical if resize to not useful geometry
6228 if (bd->y + bd->h > zy + zh)
6229 ry = zy + zh - bd->h;
6230 else if (bd->y < zy)
6233 e_border_move(bd, rx, ry);
6239 if (!bd->lock_client_stacking)
6241 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6242 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6246 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6248 obd = e_border_find_by_client_window(e->abovewin);
6251 e_border_stack_above(bd, obd);
6255 ecore_x_window_configure(bd->win,
6256 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6257 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6259 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6260 /* FIXME: need to rebuiuld border list from current stacking */
6263 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6265 obd = e_border_find_by_client_window(e->abovewin);
6268 e_border_stack_below(bd, obd);
6272 ecore_x_window_configure(bd->win,
6273 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6274 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6276 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6277 /* FIXME: need to rebuiuld border list from current stacking */
6280 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6284 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6288 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6293 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6295 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6299 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6303 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6307 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6311 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6318 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6319 _e_border_client_move_resize_send(bd);
6320 return ECORE_CALLBACK_PASS_ON;
6324 _e_border_cb_window_resize_request(void *data __UNUSED__,
6325 int ev_type __UNUSED__,
6329 Ecore_X_Event_Window_Resize_Request *e;
6332 bd = e_border_find_by_client_window(e->win);
6335 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6336 ecore_x_window_resize(e->win, e->w, e->h);
6337 return ECORE_CALLBACK_PASS_ON;
6342 w = e->w + bd->client_inset.l + bd->client_inset.r;
6343 h = e->h + bd->client_inset.t + bd->client_inset.b;
6344 if ((bd->shaded) || (bd->shading))
6350 if ((bd->shade.dir == E_DIRECTION_UP) ||
6351 (bd->shade.dir == E_DIRECTION_DOWN))
6353 e_border_resize(bd, w, bd->h);
6358 e_border_resize(bd, bd->w, h);
6363 e_border_resize(bd, w, h);
6366 _e_border_client_move_resize_send(bd);
6367 return ECORE_CALLBACK_PASS_ON;
6371 _e_border_cb_window_gravity(void *data __UNUSED__,
6372 int ev_type __UNUSED__,
6373 void *ev __UNUSED__)
6376 // Ecore_X_Event_Window_Gravity *e;
6379 // bd = e_border_find_by_client_window(e->win);
6380 // if (!bd) return 1;
6385 _e_border_cb_window_stack_request(void *data __UNUSED__,
6386 int ev_type __UNUSED__,
6390 Ecore_X_Event_Window_Stack_Request *e;
6393 bd = e_border_find_by_client_window(e->win);
6396 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6397 if (!e_util_container_window_find(e->win))
6399 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6400 ecore_x_window_raise(e->win);
6401 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6402 ecore_x_window_lower(e->win);
6404 return ECORE_CALLBACK_PASS_ON;
6406 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6408 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6410 return ECORE_CALLBACK_PASS_ON;
6414 _e_border_cb_window_property(void *data __UNUSED__,
6415 int ev_type __UNUSED__,
6419 Ecore_X_Event_Window_Property *e;
6422 bd = e_border_find_by_client_window(e->win);
6423 if (!bd) return ECORE_CALLBACK_PASS_ON;
6424 if (e->atom == ECORE_X_ATOM_WM_NAME)
6426 if ((!bd->client.netwm.name) &&
6427 (!bd->client.netwm.fetch.name))
6429 bd->client.icccm.fetch.title = 1;
6433 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6435 bd->client.netwm.fetch.name = 1;
6438 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6440 bd->client.icccm.fetch.name_class = 1;
6443 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6445 if ((!bd->client.netwm.icon_name) &&
6446 (!bd->client.netwm.fetch.icon_name))
6448 bd->client.icccm.fetch.icon_name = 1;
6452 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6454 bd->client.netwm.fetch.icon_name = 1;
6457 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6459 bd->client.icccm.fetch.machine = 1;
6462 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6464 bd->client.icccm.fetch.protocol = 1;
6467 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6469 bd->client.icccm.fetch.hints = 1;
6472 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6474 bd->client.icccm.fetch.size_pos_hints = 1;
6477 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6480 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6481 (!bd->client.netwm.fetch.type))
6484 bd->client.mwm.fetch.hints = 1;
6490 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6492 bd->client.icccm.fetch.transient_for = 1;
6495 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6497 bd->client.icccm.fetch.client_leader = 1;
6500 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6502 bd->client.icccm.fetch.window_role = 1;
6505 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6507 bd->client.netwm.fetch.icon = 1;
6510 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6512 bd->client.qtopia.fetch.soft_menu = 1;
6515 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6517 bd->client.qtopia.fetch.soft_menus = 1;
6520 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6522 bd->client.vkbd.fetch.state = 1;
6525 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6527 bd->client.vkbd.fetch.vkbd = 1;
6530 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6532 bd->client.illume.conformant.fetch.conformant = 1;
6535 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6537 bd->client.illume.quickpanel.fetch.state = 1;
6540 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6542 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6545 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6547 bd->client.illume.quickpanel.fetch.priority.major = 1;
6550 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6552 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6555 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6557 bd->client.illume.quickpanel.fetch.zone = 1;
6560 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6562 bd->client.illume.drag.fetch.locked = 1;
6565 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6567 bd->client.illume.drag.fetch.drag = 1;
6570 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6572 bd->client.illume.win_state.fetch.state = 1;
6576 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6578 bd->client.netwm.fetch.user_time = 1;
6581 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6583 bd->client.netwm.fetch.strut = 1;
6586 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6588 bd->client.netwm.fetch.strut = 1;
6592 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6594 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6596 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6598 bd->client.e.fetch.video_position = 1;
6601 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6603 bd->client.e.fetch.video_parent = 1;
6606 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6608 bd->client.netwm.fetch.state = 1;
6611 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6612 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6614 bd->client.e.fetch.profile_list = 1;
6618 #ifdef _F_ZONE_WINDOW_ROTATION_
6619 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6621 if (e_config->wm_win_rotation)
6623 bd->client.e.fetch.rot.support = 1;
6627 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6628 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6629 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6630 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6632 if (e_config->wm_win_rotation)
6634 bd->client.e.fetch.rot.geom_hint = 1;
6638 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6640 if (e_config->wm_win_rotation)
6642 bd->client.e.fetch.rot.app_set = 1;
6646 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6648 if (e_config->wm_win_rotation)
6650 bd->client.e.fetch.rot.preferred_rot = 1;
6654 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6656 if (e_config->wm_win_rotation)
6658 bd->client.e.fetch.rot.available_rots = 1;
6664 return ECORE_CALLBACK_PASS_ON;
6668 _e_border_cb_window_colormap(void *data __UNUSED__,
6669 int ev_type __UNUSED__,
6673 Ecore_X_Event_Window_Colormap *e;
6676 bd = e_border_find_by_client_window(e->win);
6677 if (!bd) return ECORE_CALLBACK_PASS_ON;
6678 return ECORE_CALLBACK_PASS_ON;
6682 _e_border_cb_window_shape(void *data __UNUSED__,
6683 int ev_type __UNUSED__,
6687 Ecore_X_Event_Window_Shape *e;
6690 bd = e_border_find_by_client_window(e->win);
6692 if (e->type == ECORE_X_SHAPE_INPUT)
6696 bd->need_shape_merge = 1;
6697 // YYY bd->shaped_input = 1;
6698 bd->changes.shape_input = 1;
6702 return ECORE_CALLBACK_PASS_ON;
6707 bd->changes.shape = 1;
6709 return ECORE_CALLBACK_PASS_ON;
6711 bd = e_border_find_by_window(e->win);
6714 bd->need_shape_export = 1;
6716 return ECORE_CALLBACK_PASS_ON;
6718 bd = e_border_find_by_frame_window(e->win);
6721 bd->need_shape_merge = 1;
6723 return ECORE_CALLBACK_PASS_ON;
6725 return ECORE_CALLBACK_PASS_ON;
6729 _e_border_cb_window_focus_in(void *data __UNUSED__,
6730 int ev_type __UNUSED__,
6734 Ecore_X_Event_Window_Focus_In *e;
6737 bd = e_border_find_by_client_window(e->win);
6738 if (!bd) return ECORE_CALLBACK_PASS_ON;
6739 #ifdef INOUTDEBUG_FOCUS
6744 const char *modes[] = {
6746 "MODE_WHILE_GRABBED",
6750 const char *details[] = {
6754 "DETAIL_NON_LINEAR",
6755 "DETAIL_NON_LINEAR_VIRTUAL",
6757 "DETAIL_POINTER_ROOT",
6758 "DETAIL_DETAIL_NONE"
6762 ct[strlen(ct) - 1] = 0;
6763 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6768 details[e->detail]);
6770 DBG("%s cb focus in %d %d\n",
6771 e_border_name_get(bd),
6772 bd->client.icccm.accepts_focus,
6773 bd->client.icccm.take_focus);
6776 _e_border_pri_raise(bd);
6777 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6779 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6781 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6783 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6786 /* ignore focus in from !take_focus windows, we just gave it em */
6787 /* if (!bd->client.icccm.take_focus)
6788 * return ECORE_CALLBACK_PASS_ON; */
6790 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6791 if (e->time >= focus_time)
6792 e_border_focus_set(bd, 1, 0);
6793 return ECORE_CALLBACK_PASS_ON;
6797 _e_border_cb_window_focus_out(void *data __UNUSED__,
6798 int ev_type __UNUSED__,
6802 Ecore_X_Event_Window_Focus_Out *e;
6805 bd = e_border_find_by_client_window(e->win);
6806 if (!bd) return ECORE_CALLBACK_PASS_ON;
6807 #ifdef INOUTDEBUG_FOCUS
6812 const char *modes[] = {
6814 "MODE_WHILE_GRABBED",
6818 const char *details[] = {
6822 "DETAIL_NON_LINEAR",
6823 "DETAIL_NON_LINEAR_VIRTUAL",
6825 "DETAIL_POINTER_ROOT",
6826 "DETAIL_DETAIL_NONE"
6830 ct[strlen(ct) - 1] = 0;
6831 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6836 details[e->detail]);
6838 DBG("%s cb focus out %d %d",
6839 e_border_name_get(bd),
6840 bd->client.icccm.accepts_focus,
6841 bd->client.icccm.take_focus);
6844 _e_border_pri_norm(bd);
6845 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6847 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6848 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6849 return ECORE_CALLBACK_PASS_ON;
6850 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6851 return ECORE_CALLBACK_PASS_ON;
6853 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6855 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6856 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6857 return ECORE_CALLBACK_PASS_ON;
6858 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6859 return ECORE_CALLBACK_PASS_ON;
6860 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6861 return ECORE_CALLBACK_PASS_ON;
6862 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6863 return ECORE_CALLBACK_PASS_ON;
6865 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6867 /* for firefox/thunderbird (xul) menu walking */
6868 /* NB: why did i disable this before? */
6869 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6870 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6871 return ECORE_CALLBACK_PASS_ON;
6873 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6875 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6876 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6877 return ECORE_CALLBACK_PASS_ON;
6879 e_border_focus_set(bd, 0, 0);
6880 return ECORE_CALLBACK_PASS_ON;
6883 #if _F_BORDER_CLIP_TO_ZONE_
6885 _e_border_shape_input_clip_to_zone(E_Border *bd)
6887 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6891 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6892 bd->zone->w, bd->zone->h,
6893 bd->x, bd->y, bd->w, bd->h)))
6896 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6897 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6898 bd->zone->x, bd->zone->y,
6899 bd->zone->w, bd->zone->h);
6902 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6903 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6907 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6908 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6911 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6914 _e_border_cb_client_message(void *data __UNUSED__,
6915 int ev_type __UNUSED__,
6918 Ecore_X_Event_Client_Message *e;
6922 #ifdef _F_DEICONIFY_APPROVE_
6923 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6925 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6927 bd = e_border_find_by_client_window(e->win);
6930 if (bd->client.e.state.deiconify_approve.support)
6932 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6933 bd->client.e.state.deiconify_approve.render_done = 1;
6935 E_Border *ancestor_bd;
6936 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
6939 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
6940 bd->client.e.state.deiconify_approve.ancestor = NULL;
6947 ELBF(ELBT_BD, 0, bd->client.win,
6948 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
6950 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
6951 (ancestor_bd->client.e.state.deiconify_approve.render_done))
6953 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
6955 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
6956 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
6957 e_border_uniconify(ancestor_bd);
6961 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
6962 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
6967 return ECORE_CALLBACK_PASS_ON;
6971 #ifdef _F_ZONE_WINDOW_ROTATION_
6972 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
6974 bd = e_border_find_by_client_window(e->win);
6977 if (e_config->wm_win_rotation)
6979 Ecore_X_Event_Client_Message *msg = NULL;
6980 Ecore_X_Atom t = e->message_type;
6981 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
6982 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
6983 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
6984 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
6986 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
6987 if (!msg) return ECORE_CALLBACK_PASS_ON;
6990 msg->message_type = e->message_type;
6991 msg->data.l[0] = e->data.l[0];
6992 msg->data.l[1] = e->data.l[1];
6993 msg->data.l[2] = e->data.l[2];
6994 msg->data.l[3] = e->data.l[3];
6995 msg->data.l[4] = e->data.l[4];
6996 rot.msgs = eina_list_append(rot.msgs, msg);
6998 rot.fetch = EINA_TRUE;
7001 return ECORE_CALLBACK_PASS_ON;
7004 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7006 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7007 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7009 if (e_config->wm_win_rotation)
7011 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7012 _e_border_rotation_list_remove(bd);
7016 return ECORE_CALLBACK_PASS_ON;
7020 _e_border_cb_window_state_request(void *data __UNUSED__,
7021 int ev_type __UNUSED__,
7025 Ecore_X_Event_Window_State_Request *e;
7029 bd = e_border_find_by_client_window(e->win);
7030 if (!bd) return ECORE_CALLBACK_PASS_ON;
7032 for (i = 0; i < 2; i++)
7033 e_hints_window_state_update(bd, e->state[i], e->action);
7035 return ECORE_CALLBACK_PASS_ON;
7039 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7040 int ev_type __UNUSED__,
7044 Ecore_X_Event_Window_Move_Resize_Request *e;
7047 bd = e_border_find_by_client_window(e->win);
7048 if (!bd) return ECORE_CALLBACK_PASS_ON;
7050 if ((bd->shaded) || (bd->shading) ||
7051 (bd->fullscreen) || (bd->moving) ||
7052 (bd->resize_mode != RESIZE_NONE))
7053 return ECORE_CALLBACK_PASS_ON;
7055 if ((e->button >= 1) && (e->button <= 3))
7057 bd->mouse.last_down[e->button - 1].mx = e->x;
7058 bd->mouse.last_down[e->button - 1].my = e->y;
7059 bd->mouse.last_down[e->button - 1].x = bd->x;
7060 bd->mouse.last_down[e->button - 1].y = bd->y;
7061 bd->mouse.last_down[e->button - 1].w = bd->w;
7062 bd->mouse.last_down[e->button - 1].h = bd->h;
7066 bd->moveinfo.down.x = bd->x;
7067 bd->moveinfo.down.y = bd->y;
7068 bd->moveinfo.down.w = bd->w;
7069 bd->moveinfo.down.h = bd->h;
7071 bd->mouse.current.mx = e->x;
7072 bd->mouse.current.my = e->y;
7073 bd->moveinfo.down.button = e->button;
7074 bd->moveinfo.down.mx = e->x;
7075 bd->moveinfo.down.my = e->y;
7078 if (!bd->lock_user_stacking)
7081 if (e->direction == MOVE)
7083 bd->cur_mouse_action = e_action_find("window_move");
7084 if (bd->cur_mouse_action)
7086 if ((!bd->cur_mouse_action->func.end_mouse) &&
7087 (!bd->cur_mouse_action->func.end))
7088 bd->cur_mouse_action = NULL;
7089 if (bd->cur_mouse_action)
7091 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7092 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7095 return ECORE_CALLBACK_PASS_ON;
7098 if (!_e_border_resize_begin(bd))
7099 return ECORE_CALLBACK_PASS_ON;
7101 switch (e->direction)
7104 bd->resize_mode = RESIZE_TL;
7105 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7109 bd->resize_mode = RESIZE_T;
7110 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7114 bd->resize_mode = RESIZE_TR;
7115 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7119 bd->resize_mode = RESIZE_R;
7120 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7124 bd->resize_mode = RESIZE_BR;
7125 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7129 bd->resize_mode = RESIZE_B;
7130 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7134 bd->resize_mode = RESIZE_BL;
7135 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7139 bd->resize_mode = RESIZE_L;
7140 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7144 return ECORE_CALLBACK_PASS_ON;
7147 bd->cur_mouse_action = e_action_find("window_resize");
7148 if (bd->cur_mouse_action)
7150 if ((!bd->cur_mouse_action->func.end_mouse) &&
7151 (!bd->cur_mouse_action->func.end))
7152 bd->cur_mouse_action = NULL;
7154 if (bd->cur_mouse_action)
7155 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7157 return ECORE_CALLBACK_PASS_ON;
7161 _e_border_cb_desktop_change(void *data __UNUSED__,
7162 int ev_type __UNUSED__,
7166 Ecore_X_Event_Desktop_Change *e;
7169 bd = e_border_find_by_client_window(e->win);
7172 if (e->desk == 0xffffffff)
7174 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7178 desk = e_desk_at_pos_get(bd->zone, e->desk);
7180 e_border_desk_set(bd, desk);
7185 ecore_x_netwm_desktop_set(e->win, e->desk);
7187 return ECORE_CALLBACK_PASS_ON;
7191 _e_border_cb_sync_alarm(void *data __UNUSED__,
7192 int ev_type __UNUSED__,
7196 Ecore_X_Event_Sync_Alarm *e;
7197 unsigned int serial;
7200 bd = e_border_find_by_alarm(e->alarm);
7201 if (!bd) return ECORE_CALLBACK_PASS_ON;
7203 if (bd->client.netwm.sync.wait)
7204 bd->client.netwm.sync.wait--;
7206 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7208 E_Border_Pending_Move_Resize *pnd = NULL;
7210 /* skip pending for which we didn't get a reply */
7211 while (bd->pending_move_resize)
7213 pnd = bd->pending_move_resize->data;
7214 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7216 if (serial == pnd->serial)
7228 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7229 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7234 bd->changes.size = 1;
7235 bd->changes.pos = 1;
7238 evas_render(bd->bg_evas);
7240 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7241 &bd->mouse.current.mx,
7242 &bd->mouse.current.my);
7244 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7245 _e_border_resize_handle(bd);
7247 return ECORE_CALLBACK_PASS_ON;
7251 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7252 int ev_type __UNUSED__,
7253 void *ev __UNUSED__)
7258 /* mark all borders for desktop/icon updates */
7259 EINA_LIST_FOREACH(borders, l, bd)
7263 efreet_desktop_free(bd->desktop);
7266 bd->changes.icon = 1;
7270 e_init_status_set(_("Desktop files scan done"));
7273 return ECORE_CALLBACK_PASS_ON;
7277 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7278 int ev_type __UNUSED__,
7279 void *ev __UNUSED__)
7284 /* mark all borders for desktop/icon updates */
7285 EINA_LIST_FOREACH(borders, l, bd)
7287 bd->changes.icon = 1;
7290 return ECORE_CALLBACK_PASS_ON;
7294 _e_border_cb_pointer_warp(void *data __UNUSED__,
7295 int ev_type __UNUSED__,
7298 E_Event_Pointer_Warp *e;
7301 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7302 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7303 return ECORE_CALLBACK_PASS_ON;
7307 _e_border_cb_signal_bind(void *data,
7308 Evas_Object *obj __UNUSED__,
7309 const char *emission,
7315 if (e_dnd_active()) return;
7316 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7321 _e_border_cb_mouse_in(void *data,
7322 int type __UNUSED__,
7325 Ecore_X_Event_Mouse_In *ev;
7330 #ifdef INOUTDEBUG_MOUSE
7335 const char *modes[] = {
7337 "MODE_WHILE_GRABBED",
7341 const char *details[] = {
7345 "DETAIL_NON_LINEAR",
7346 "DETAIL_NON_LINEAR_VIRTUAL",
7348 "DETAIL_POINTER_ROOT",
7349 "DETAIL_DETAIL_NONE"
7353 ct[strlen(ct) - 1] = 0;
7354 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7355 ev->win, ev->event_win,
7358 details[ev->detail]);
7361 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7362 if (ev->event_win == bd->win)
7364 e_focus_event_mouse_in(bd);
7367 if ((ev->win != bd->win) &&
7368 (ev->win != bd->event_win) &&
7369 (ev->event_win != bd->win) &&
7370 (ev->event_win != bd->event_win))
7371 return ECORE_CALLBACK_PASS_ON;
7373 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7375 bd->mouse.current.mx = ev->root.x;
7376 bd->mouse.current.my = ev->root.y;
7377 if (!bd->bg_evas_in)
7379 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7380 bd->bg_evas_in = EINA_TRUE;
7382 return ECORE_CALLBACK_PASS_ON;
7386 _e_border_cb_mouse_out(void *data,
7387 int type __UNUSED__,
7390 Ecore_X_Event_Mouse_Out *ev;
7395 #ifdef INOUTDEBUG_MOUSE
7400 const char *modes[] = {
7402 "MODE_WHILE_GRABBED",
7406 const char *details[] = {
7410 "DETAIL_NON_LINEAR",
7411 "DETAIL_NON_LINEAR_VIRTUAL",
7413 "DETAIL_POINTER_ROOT",
7414 "DETAIL_DETAIL_NONE"
7418 ct[strlen(ct) - 1] = 0;
7419 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7420 ev->win, ev->event_win,
7423 details[ev->detail]);
7426 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7427 if (ev->event_win == bd->win)
7430 return ECORE_CALLBACK_PASS_ON;
7431 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7432 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7433 return ECORE_CALLBACK_PASS_ON;
7434 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7435 return ECORE_CALLBACK_PASS_ON;
7436 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7437 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7438 return ECORE_CALLBACK_PASS_ON;
7439 e_focus_event_mouse_out(bd);
7442 if ((ev->win != bd->win) &&
7443 (ev->win != bd->event_win) &&
7444 (ev->event_win != bd->win) &&
7445 (ev->event_win != bd->event_win))
7446 return ECORE_CALLBACK_PASS_ON;
7448 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7450 bd->mouse.current.mx = ev->root.x;
7451 bd->mouse.current.my = ev->root.y;
7454 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7455 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7456 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7458 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7459 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7460 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7461 bd->bg_evas_in = EINA_FALSE;
7464 return ECORE_CALLBACK_PASS_ON;
7468 _e_border_cb_mouse_wheel(void *data,
7469 int type __UNUSED__,
7472 Ecore_Event_Mouse_Wheel *ev;
7477 if ((ev->event_window == bd->win) ||
7478 (ev->event_window == bd->event_win))
7480 bd->mouse.current.mx = ev->root.x;
7481 bd->mouse.current.my = ev->root.y;
7482 if (!bd->cur_mouse_action)
7483 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7486 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7487 return ECORE_CALLBACK_PASS_ON;
7491 _e_border_cb_mouse_down(void *data,
7492 int type __UNUSED__,
7495 Ecore_Event_Mouse_Button *ev;
7500 if ((ev->event_window == bd->win) ||
7501 (ev->event_window == bd->event_win))
7503 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7505 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7506 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7507 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7508 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7509 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7510 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7514 bd->moveinfo.down.x = bd->x + bd->fx.x;
7515 bd->moveinfo.down.y = bd->y + bd->fx.y;
7516 bd->moveinfo.down.w = bd->w;
7517 bd->moveinfo.down.h = bd->h;
7519 bd->mouse.current.mx = ev->root.x;
7520 bd->mouse.current.my = ev->root.y;
7521 if (!bd->cur_mouse_action)
7523 bd->cur_mouse_action =
7524 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7526 if (bd->cur_mouse_action)
7528 if ((!bd->cur_mouse_action->func.end_mouse) &&
7529 (!bd->cur_mouse_action->func.end))
7530 bd->cur_mouse_action = NULL;
7531 if (bd->cur_mouse_action)
7532 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7535 e_focus_event_mouse_down(bd);
7537 if (ev->window != ev->event_window)
7541 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7545 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7547 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7548 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7549 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7550 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7551 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7552 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7556 bd->moveinfo.down.x = bd->x + bd->fx.x;
7557 bd->moveinfo.down.y = bd->y + bd->fx.y;
7558 bd->moveinfo.down.w = bd->w;
7559 bd->moveinfo.down.h = bd->h;
7561 bd->mouse.current.mx = ev->root.x;
7562 bd->mouse.current.my = ev->root.y;
7567 else if (bd->resize_mode != RESIZE_NONE)
7573 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7575 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7576 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7577 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7579 return ECORE_CALLBACK_PASS_ON;
7583 _e_border_cb_mouse_up(void *data,
7584 int type __UNUSED__,
7587 Ecore_Event_Mouse_Button *ev;
7592 if ((ev->event_window == bd->win) ||
7593 (ev->event_window == bd->event_win))
7595 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7597 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7598 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7599 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7600 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7602 bd->mouse.current.mx = ev->root.x;
7603 bd->mouse.current.my = ev->root.y;
7604 /* also we dont pass the same params that went in - then again that */
7605 /* should be ok as we are just ending the action if it has an end */
7606 if (bd->cur_mouse_action)
7608 if (bd->cur_mouse_action->func.end_mouse)
7609 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7610 else if (bd->cur_mouse_action->func.end)
7611 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7612 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7613 bd->cur_mouse_action = NULL;
7617 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7618 e_focus_event_mouse_up(bd);
7621 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7622 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7624 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7625 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7626 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7627 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7629 bd->mouse.current.mx = ev->root.x;
7630 bd->mouse.current.my = ev->root.y;
7634 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7635 return ECORE_CALLBACK_PASS_ON;
7639 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7641 #ifdef _F_BORDER_CLIP_TO_ZONE_
7642 int new_x_max, new_y_max;
7643 int new_x_min, new_y_min;
7644 int margin_x, margin_y;
7646 margin_x = bd->w - 100;
7647 margin_y = bd->h - 100;
7649 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7650 new_x_min = bd->zone->x - margin_x;
7651 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7652 new_y_min = bd->zone->y - margin_y;
7654 if (x >= new_x_max) *new_x = new_x_max;
7655 else if (x <= new_x_min) *new_x = new_x_min;
7657 if (y >= new_y_max) *new_y = new_y_max;
7658 else if (y <= new_y_min) *new_y = new_y_min;
7663 _e_border_cb_mouse_move(void *data,
7664 int type __UNUSED__,
7667 Ecore_Event_Mouse_Move *ev;
7672 if ((ev->window != bd->event_win) &&
7673 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7674 bd->mouse.current.mx = ev->root.x;
7675 bd->mouse.current.my = ev->root.y;
7678 int x, y, new_x, new_y;
7680 Eina_List *skiplist = NULL;
7682 // FIXME: remove? sync what for when only moving?
7683 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7684 bd->client.netwm.sync.wait = 0;
7685 if ((bd->client.netwm.sync.request) &&
7686 (bd->client.netwm.sync.alarm) &&
7687 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7689 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7691 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7692 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7693 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7694 (bd->mouse.current.my - bd->moveinfo.down.my);
7698 x = bd->moveinfo.down.x +
7699 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7700 y = bd->moveinfo.down.y +
7701 (bd->mouse.current.my - bd->moveinfo.down.my);
7706 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7707 skiplist = eina_list_append(skiplist, bd);
7708 e_resist_container_border_position(bd->zone->container, skiplist,
7709 bd->x, bd->y, bd->w, bd->h,
7711 &new_x, &new_y, &new_w, &new_h);
7712 eina_list_free(skiplist);
7714 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7716 /* if (e_config->window_out_of_vscreen_limits_partly) */
7718 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7721 skiplist = eina_list_append(skiplist, bd);
7722 e_resist_container_border_position(bd->zone->container, skiplist,
7723 bd->x, bd->y, bd->w, bd->h,
7725 &new_x, &new_y, &new_w, &new_h);
7726 eina_list_free(skiplist);
7729 bd->shelf_fix.x = 0;
7730 bd->shelf_fix.y = 0;
7731 bd->shelf_fix.modified = 0;
7732 e_border_move(bd, new_x, new_y);
7733 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7735 else if (bd->resize_mode != RESIZE_NONE)
7737 if ((bd->client.netwm.sync.request) &&
7738 (bd->client.netwm.sync.alarm))
7740 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7742 E_Border_Pending_Move_Resize *pnd;
7744 if (bd->pending_move_resize)
7746 bd->changes.pos = 1;
7747 bd->changes.size = 1;
7749 _e_border_client_move_resize_send(bd);
7751 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7754 bd->client.netwm.sync.wait = 0;
7756 /* sync.wait is incremented when resize_handle sends
7757 * sync-request and decremented by sync-alarm cb. so
7758 * we resize here either on initial resize, timeout or
7759 * when no new resize-request was added by sync-alarm cb.
7761 if (!bd->client.netwm.sync.wait)
7762 _e_border_resize_handle(bd);
7765 _e_border_resize_handle(bd);
7771 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7773 bd->drag.x = ev->root.x;
7774 bd->drag.y = ev->root.y;
7780 dx = bd->drag.x - ev->root.x;
7781 dy = bd->drag.y - ev->root.y;
7782 if (((dx * dx) + (dy * dy)) >
7783 (e_config->drag_resist * e_config->drag_resist))
7786 if (bd->icon_object)
7788 Evas_Object *o = NULL;
7789 Evas_Coord x, y, w, h;
7790 const char *drag_types[] = { "enlightenment/border" };
7792 e_object_ref(E_OBJECT(bd));
7793 evas_object_geometry_get(bd->icon_object,
7795 drag_border = e_drag_new(bd->zone->container,
7796 bd->x + bd->fx.x + x,
7797 bd->y + bd->fx.y + y,
7798 drag_types, 1, bd, -1,
7800 _e_border_cb_drag_finished);
7801 o = e_border_icon_add(bd, drag_border->evas);
7804 /* FIXME: fallback icon for drag */
7805 o = evas_object_rectangle_add(drag_border->evas);
7806 evas_object_color_set(o, 255, 255, 255, 255);
7808 e_drag_object_set(drag_border, o);
7810 e_drag_resize(drag_border, w, h);
7811 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7817 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7819 return ECORE_CALLBACK_PASS_ON;
7823 _e_border_cb_grab_replay(void *data __UNUSED__,
7827 Ecore_Event_Mouse_Button *ev;
7829 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7831 if ((e_config->pass_click_on)
7832 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7833 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7838 bd = e_border_find_by_window(ev->event_window);
7841 if (bd->cur_mouse_action)
7842 return ECORE_CALLBACK_DONE;
7843 if (ev->event_window == bd->win)
7845 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7846 E_OBJECT(bd), ev, NULL))
7847 return ECORE_CALLBACK_PASS_ON;
7851 return ECORE_CALLBACK_DONE;
7855 _e_border_cb_drag_finished(E_Drag *drag,
7856 int dropped __UNUSED__)
7861 e_object_unref(E_OBJECT(bd));
7865 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7867 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7868 int ev_type __UNUSED__,
7871 E_Event_Desk_Window_Profile_Change *e;
7876 EINA_LIST_FOREACH(borders, l, bd)
7878 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7880 bd->client.e.fetch.profile_list = 1;
7884 return ECORE_CALLBACK_PASS_ON;
7888 #ifdef _F_ZONE_WINDOW_ROTATION_
7890 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
7891 int ev_type __UNUSED__,
7894 E_Event_Zone_Rotation_Change_Begin *e = ev;
7895 Eina_Bool res = EINA_FALSE;
7897 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7898 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7900 res = _e_border_rotation_zone_check(e->zone);
7901 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: result:%d (%d)", res, e->zone->rot.curr);
7904 e_manager_comp_screen_lock(e_manager_current_get());
7905 res = _e_border_rotation_zone_vkbd_check(e->zone);
7906 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd result:%d (%d)", res, e->zone->rot.curr);
7909 res = _e_border_rotation_transient_for_check(rot.vkbd,
7911 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd transient_for result:%d (%d)", res, e->zone->rot.curr);
7916 if (rot.prepare_timer)
7917 ecore_timer_del(rot.prepare_timer);
7918 rot.prepare_timer = NULL;
7921 ecore_timer_del(rot.done_timer);
7922 rot.done_timer = NULL;
7924 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
7925 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
7928 rot.prepare_timer = ecore_timer_add(4.0f,
7929 _e_border_rotation_change_prepare_timeout,
7931 rot.wait_prepare_done = EINA_TRUE;
7935 _e_border_rotation_list_add(e->zone, EINA_TRUE);
7936 _e_border_rotation_change_request(e->zone);
7941 /* there is no border which supports window manager rotation */
7942 e_zone_rotation_update_cancel(e->zone);
7944 return ECORE_CALLBACK_PASS_ON;
7948 _e_border_rotation_change_prepare_timeout(void *data)
7950 E_Zone *zone = data;
7951 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7953 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
7955 if ((rot.wait_prepare_done) &&
7957 (_e_border_rotation_list_add(zone, EINA_FALSE)))
7959 _e_border_rotation_change_request(zone);
7963 if (rot.prepare_timer)
7964 ecore_timer_del(rot.prepare_timer);
7965 rot.prepare_timer = NULL;
7966 rot.wait_prepare_done = EINA_FALSE;
7968 return ECORE_CALLBACK_CANCEL;
7972 _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
7974 Eina_List *l = NULL;
7975 E_Border_Rotation_Info *info = NULL;
7977 if (!e_config->wm_win_rotation) return;
7978 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
7979 rot.prepare_timer = NULL;
7980 rot.wait_prepare_done = EINA_FALSE;
7982 EINA_LIST_FOREACH(rot.list, l, info)
7984 _e_border_event_border_rotation_change_begin_send(info->bd);
7986 ELBF(ELBT_ROT, 1, info->bd->client.win,
7987 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
7988 info->ang, info->win_resize, info->w, info->h);
7990 ecore_x_e_window_rotation_change_prepare_send
7991 (info->bd->client.win, info->ang,
7992 info->win_resize, info->w, info->h);
7994 if (!info->bd->client.e.state.rot.pending_change_request)
7996 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
7997 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8003 ecore_timer_del(rot.done_timer);
8004 rot.done_timer = ecore_timer_add(4.0f,
8005 _e_border_rotation_change_done_timeout,
8010 _e_border_rotation_list_remove(E_Border *bd)
8012 Eina_List *l = NULL;
8013 E_Border_Rotation_Info *info = NULL;
8014 E_Event_Border_Rotation_Change_End *ev = NULL;
8015 if (!e_config->wm_win_rotation) return;
8017 EINA_LIST_FOREACH(rot.list, l, info)
8021 rot.list = eina_list_remove(rot.list, info);
8026 if (bd->client.e.state.rot.wait_for_done)
8028 bd->client.e.state.rot.wait_for_done = 0;
8030 /* if we make the border event in the _e_border_free function,
8031 * then we may meet a crash problem, only work this at least e_border_hide.
8033 if (!e_object_is_del(E_OBJECT(bd)))
8035 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8039 e_object_ref(E_OBJECT(bd));
8040 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8042 _e_border_event_border_rotation_change_end_free,
8046 if (eina_list_count(rot.list) == 0)
8048 _e_border_rotation_change_done();
8054 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8056 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8057 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8058 _e_border_rotation_change_done();
8059 return ECORE_CALLBACK_CANCEL;
8063 _e_border_rotation_change_done(void)
8065 E_Manager *m = NULL;
8066 E_Border_Rotation_Info *info = NULL;
8068 if (!e_config->wm_win_rotation) return;
8070 if (rot.prepare_timer)
8071 ecore_timer_del(rot.prepare_timer);
8072 rot.prepare_timer = NULL;
8074 rot.wait_prepare_done = EINA_FALSE;
8077 ecore_timer_del(rot.done_timer);
8078 rot.done_timer = NULL;
8080 EINA_LIST_FREE(rot.list, info)
8084 info->bd->client.e.state.rot.wait_for_done = 0;
8085 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8092 m = e_manager_current_get();
8093 e_manager_comp_screen_unlock(m);
8094 e_zone_rotation_update_done(e_util_zone_current_get(m));
8098 _prev_angle_get(Ecore_X_Window win)
8100 int ret, count = 0, ang = -1;
8101 unsigned char* data = NULL;
8103 ret = ecore_x_window_prop_property_get
8104 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8105 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8107 if ((ret) && (data) && (count))
8108 ang = ((int *)data)[0];
8109 if (data) free(data);
8113 /* get proper rotation value using preferred rotation and list of available rotations */
8115 _e_border_rotation_get(E_Border *bd,
8119 int current_ang = bd->client.e.state.rot.curr;
8121 Eina_Bool found = EINA_FALSE;
8122 Eina_Bool found_curr_ang = EINA_FALSE;
8124 if (!e_config->wm_win_rotation) return ang;
8125 if (!bd->client.e.state.rot.app_set) return ang;
8127 if (bd->client.e.state.rot.preferred_rot != -1)
8129 ang = bd->client.e.state.rot.preferred_rot;
8130 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8132 else if ((bd->client.e.state.rot.available_rots) &&
8133 (bd->client.e.state.rot.count))
8135 for (i = 0; i < bd->client.e.state.rot.count; i++)
8137 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8143 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8144 found_curr_ang = EINA_TRUE;
8147 /* do nothing. this window wants to maintain current state.
8148 * for example, window's available_rots: 0, 90, 270,
8149 * current zone rotation request: 180. the WM does nothing
8154 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8155 ang = bd->client.e.state.rot.curr;
8157 ang = bd->client.e.state.rot.available_rots[0];
8162 /* In this case, border doesn't have a list of
8163 * available rotations, thus WM should request
8164 * rotation with '0' degree to the application.
8172 #define REGION_EQUAL_TO_ZONE(a, z) \
8173 ((((a)->x) == ((z)->x)) && \
8174 (((a)->y) == ((z)->y)) && \
8175 (((a)->w) == ((z)->w)) && \
8176 (((a)->h) == ((z)->h)))
8179 _e_border_rotation_check(E_Border *bd)
8181 E_Zone *zone = bd->zone;
8182 int x, y, w, h, ang = 0;
8183 int diff = 0, _ang = 0;
8184 Eina_Bool resize = EINA_TRUE;
8185 Eina_Bool hint = EINA_FALSE;
8186 Eina_Bool move = EINA_TRUE;
8188 if (!e_config->wm_win_rotation) return EINA_FALSE;
8190 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8192 ang = zone->rot.curr;
8194 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8196 ELBF(ELBT_ROT, 1, bd->client.win,
8197 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8198 (rot.vkbd == bd) ? "vkbd" : "prediction",
8199 bd->parent ? bd->parent->client.win : 0,
8200 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8201 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8202 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8206 ang = bd->parent->client.e.state.rot.curr;
8207 if ((!bd->parent->client.e.state.rot.support) &&
8208 (!bd->parent->client.e.state.rot.app_set))
8215 if ((!bd->client.e.state.rot.app_set) &&
8216 (!bd->client.e.state.rot.support))
8218 /* hack for magnifier and keyboard popup */
8219 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8220 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8222 ELB(ELBT_BD, "MAG", bd->client.win);
8224 if ((rot.vkbd) && (rot.vkbd->visible))
8225 ang = rot.vkbd->client.e.state.rot.curr;
8226 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8229 ELBF(ELBT_ROT, 1, bd->client.win, "MAG %d,%d %dx%d m:%d", x, y, w, h, move);
8230 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8236 if (bd->client.e.state.rot.app_set)
8238 /* utility type window should be rotated according to
8239 * rotation of the transient_for window.
8242 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8244 ang = bd->parent->client.e.state.rot.curr;
8245 if ((!bd->parent->client.e.state.rot.support) &&
8246 (!bd->parent->client.e.state.rot.app_set))
8248 /* if transient_for window doesn't support rotation feature,
8249 * then this window should't be rotated.
8250 * TODO: need to check whether window supports '0' degree or not.
8253 ELBF(ELBT_ROT, 0, bd->client.win,
8254 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8255 ang, bd->parent->client.win);
8259 ang = _e_border_rotation_get(bd->parent, ang);
8260 ELBF(ELBT_ROT, 0, bd->client.win,
8261 "GET ROT ang:%d Transient_For:0x%08x",
8262 ang, bd->parent->client.win);
8267 ang = _e_border_rotation_get(bd, ang);
8268 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8269 ang, bd->parent ? bd->parent->client.win : 0,
8270 bd->client.netwm.type);
8274 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8276 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8278 /* need to check previous rotation angle, this may be because
8279 * the window was unmapped with non-0 rotation degree.
8280 * and now, the window wants to show on the 0 degree zone,
8281 * thus the wm should request to rotate the window to 0 degree.
8285 _ang = _prev_angle_get(bd->client.win);
8287 bd->client.e.state.rot.curr = _ang;
8288 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8291 if (bd->client.e.state.rot.curr != ang)
8293 if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) &&
8294 /* check whether virtual keyboard is visible on the zone */
8295 (_e_border_rotation_zone_vkbd_check(bd->zone)) &&
8296 /* check whether virtual keyboard belongs to this border (transient_for) */
8297 (_e_border_rotation_vkbd_transient_for_check(bd)) &&
8298 /* check rotation of the virtual keyboard */
8299 (((rot.vkbd) && (rot.vkbd->client.e.state.rot.curr != ang)) ||
8300 ((rot.vkbd_prediction) && (rot.vkbd_prediction->client.e.state.rot.curr != ang))) &&
8301 (!rot.wait_prepare_done))
8303 ELB(ELBT_ROT, "DO VKBD ROT", bd->client.win);
8304 e_manager_comp_screen_lock(e_manager_current_get());
8306 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8307 rot.prepare_timer = NULL;
8309 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8310 rot.done_timer = NULL;
8312 ELB(ELBT_ROT, "send rot_change_prepare", rot.vkbd_ctrl_win);
8313 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8316 rot.prepare_timer = ecore_timer_add(4.0f,
8317 _e_border_rotation_change_prepare_timeout,
8319 rot.wait_prepare_done = EINA_TRUE;
8322 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8323 bd->client.e.state.rot.curr = ang;
8324 bd->client.e.state.rot.wait_for_done = 1;
8326 diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8327 if ((diff == 180) || (diff == -180))
8328 resize = EINA_FALSE;
8330 /* Check if it has size hint, full size or not, and needs to resize.
8331 * Under the below condition, replace width value with height.
8333 if ((!hint) && (!REGION_EQUAL_TO_ZONE(bd, bd->zone)) && (resize))
8335 x = bd->x; y = bd->y;
8336 w = bd->w; h = bd->h;
8339 resize = EINA_FALSE;
8345 _e_border_move_resize_internal(bd, x, y, w, h,
8346 EINA_TRUE, EINA_FALSE);
8351 if (bd->client.e.state.rot.app_set) resize = EINA_FALSE;
8353 E_Border_Rotation_Info *info = NULL;
8354 info = E_NEW(E_Border_Rotation_Info, 1);
8359 info->x = x; info->y = y;
8360 info->w = w; info->h = h;
8361 info->win_resize = resize;
8362 rot.list = eina_list_append(rot.list, info);
8364 if (info->win_resize)
8365 bd->client.e.state.rot.pending_change_request = 1;
8367 _e_border_event_border_rotation_change_begin_send(bd);
8369 ELBF(ELBT_ROT, 1, info->bd->client.win,
8370 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8371 info->ang, info->win_resize, info->w, info->h);
8373 ecore_x_e_window_rotation_change_prepare_send
8374 (info->bd->client.win, info->ang,
8375 info->win_resize, info->w, info->h);
8377 if (!info->bd->client.e.state.rot.pending_change_request)
8379 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8380 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8385 ecore_timer_del(rot.done_timer);
8386 rot.done_timer = ecore_timer_add(4.0f,
8387 _e_border_rotation_change_done_timeout,
8395 _e_border_rotation_zone_check(E_Zone *zone)
8397 Eina_Bool wait = EINA_FALSE;
8398 E_Border_List *l = NULL;
8399 E_Border *bd = NULL;
8401 if (!e_config->wm_win_rotation) return EINA_FALSE;
8403 l = e_container_border_list_last(zone->container);
8404 if (!l) return EINA_FALSE;
8405 while ((bd = e_container_border_list_prev(l)))
8407 if ((!bd) || (e_object_is_del(E_OBJECT(bd))) ||
8408 (!bd->visible) || (bd->zone != zone) ||
8409 (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8410 bd->x, bd->y, bd->w, bd->h))) continue;
8412 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8413 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)) ||
8414 ((REGION_EQUAL_TO_ZONE(bd, zone)) &&
8415 (bd->client.e.state.rot.preferred_rot != -1))) continue;
8417 if (_e_border_rotation_border_check(bd, zone->rot.curr))
8423 if (l) e_container_border_list_free(l);
8428 // check if border is rotatable in ang.
8430 _e_border_rotation_border_check(E_Border *bd, int ang)
8432 Eina_Bool wait = EINA_FALSE;
8434 if (!bd) return wait;
8436 if (((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8437 /* basically WM allows only fullscreen window to rotate */
8438 ((REGION_EQUAL_TO_ZONE(bd, bd->zone)) ||
8439 /* we don't like this kind of code.
8440 * it means that the WM also allows non-fullscreen window to rotate if it sets geom hint.
8441 * such as large editable window.
8443 ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE) && (bd->client.e.state.rot.geom_hint)) ||
8444 /* and floating mode window is also rotatable */
8445 (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) &&
8446 (bd->client.e.state.rot.preferred_rot == -1))
8450 if (bd->client.e.state.rot.app_set)
8452 if (bd->client.e.state.rot.available_rots &&
8453 bd->client.e.state.rot.count)
8455 Eina_Bool found = EINA_FALSE;
8456 for (i = 0; i < bd->client.e.state.rot.count; i++)
8458 if (bd->client.e.state.rot.available_rots[i] == ang)
8463 if ((found) && (ang != bd->client.e.state.rot.curr))
8469 ELB(ELBT_ROT, "ROT CANCEL for preferred rot", bd->client.win);
8476 ELB(ELBT_ROT, "DO ROT", 0);
8484 /* check whether virtual keyboard is visible on the zone */
8486 _e_border_rotation_zone_vkbd_check(E_Zone *zone)
8488 if (!e_config->wm_win_rotation) return EINA_FALSE;
8490 if ((rot.vkbd_ctrl_win) &&
8492 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8493 (rot.vkbd->visible) &&
8494 (rot.vkbd->zone == zone) &&
8495 (E_INTERSECTS(zone->x, zone->y,
8497 rot.vkbd->x, rot.vkbd->y,
8498 rot.vkbd->w, rot.vkbd->h)))
8505 /* check whether border is parent of the virtual keyboard */
8507 _e_border_rotation_vkbd_transient_for_check(E_Border *bd)
8509 if (!e_config->wm_win_rotation) return EINA_FALSE;
8511 if (rot.vkbd_ctrl_win)
8513 if ((rot.vkbd) && (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8516 if (rot.vkbd->parent == bd)
8520 if ((rot.vkbd_prediction) && (!e_object_is_del(E_OBJECT(rot.vkbd_prediction))) &&
8521 (rot.vkbd_prediction != bd))
8523 if (rot.vkbd_prediction == bd)
8531 // check if bd's parent is rotatable.
8533 _e_border_rotation_transient_for_check(E_Border *bd, int ang)
8535 Eina_Bool ret = EINA_FALSE;
8537 if (!e_config->wm_win_rotation) return EINA_FALSE;
8538 if (!bd) return EINA_FALSE;
8540 if (!bd->parent) ret = EINA_TRUE;
8543 if (_e_border_rotation_border_check(bd->parent, ang))
8551 _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
8553 Eina_Bool wait = EINA_FALSE;
8554 E_Border_List *l = NULL;
8555 Eina_List *nl = NULL;
8556 E_Border *bd = NULL;
8557 E_Border_Rotation_Info *info = NULL;
8559 if (!e_config->wm_win_rotation) return EINA_FALSE;
8561 l = e_container_border_list_last(zone->container);
8562 if (!l) return EINA_FALSE;
8563 while ((bd = e_container_border_list_prev(l)))
8565 if ((!bd) || (e_object_is_del(E_OBJECT(bd)))) continue;
8567 if ((without_vkbd) &&
8568 (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE))
8573 if ((bd->visible) &&
8574 ((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8575 (bd->zone == zone) &&
8576 (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8577 bd->x, bd->y, bd->w, bd->h)))
8579 // check if this window is available to be rotate.
8580 if ((bd->client.e.state.rot.app_set) &&
8581 (bd->client.e.state.rot.preferred_rot != -1)) continue;
8583 /* check list of available rotations */
8584 int ang = zone->rot.curr;
8585 if (bd->client.e.state.rot.app_set)
8587 ang = _e_border_rotation_get(bd, ang);
8588 ELBF(ELBT_ROT, 0, bd->client.win, "returned ang:%d", ang);
8591 /* skip same angle */
8592 if (bd->client.e.state.rot.curr == ang)
8594 /* FIXME: hack for rotating vkbd:
8595 * even if angle of zone is not changed,
8596 * if preferred_rot of parent is set with specific angle, vkbd has to rotate, too.
8597 * all of other transient window like this case.
8600 (bd->parent->client.e.state.rot.preferred_rot != -1))
8601 ang = bd->parent->client.e.state.rot.preferred_rot;
8602 if (bd->client.e.state.rot.curr == ang)
8604 ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang);
8607 ELBF(ELBT_ROT, 0, bd->client.win, "rotate by parent ang:%d", ang);
8611 ELBF(ELBT_ROT, 0, bd->client.win, "ADD ROT_LIST curr:%d != ang:%d",
8612 bd->client.e.state.rot.curr, ang);
8615 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8616 bd->client.e.state.rot.curr = ang;
8617 bd->client.e.state.rot.wait_for_done = 1;
8619 info = E_NEW(E_Border_Rotation_Info, 1);
8624 info->x = bd->x; info->y = bd->y;
8625 info->w = bd->w; info->h = bd->h;
8626 info->win_resize = EINA_FALSE;
8627 nl = eina_list_append(nl, info);
8630 if (REGION_EQUAL_TO_ZONE(bd, zone))
8632 wait = EINA_TRUE; // for the maximized window
8636 int diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8638 Eina_Bool resize = EINA_TRUE;
8639 if ((diff == 180) || (diff == -180))
8640 resize = EINA_FALSE;
8642 Eina_Bool move = EINA_TRUE;
8643 Eina_Bool hint = EINA_FALSE;
8644 hint = _e_border_rotation_geom_get(bd, zone, ang,
8645 &x, &y, &w, &h, &move);
8647 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8650 x = bd->x; y = bd->y;
8651 w = bd->w; h = bd->h;
8655 resize = EINA_FALSE;
8658 // swap width and height and resize border
8662 _e_border_move_resize_internal(bd, x, y, w, h,
8663 EINA_TRUE, EINA_TRUE);
8670 info->x = x; info->y = y;
8671 info->w = w; info->h = h;
8672 info->win_resize = resize;
8676 bd->client.e.state.rot.pending_change_request = 1;
8681 /* check whether rotation is available for sub borders such as prediction and magnifier */
8684 Eina_List *_list = _e_border_sub_borders_new(bd);
8685 EINA_LIST_FOREACH(_list, ll, _child)
8687 if ((_child->client.e.state.rot.support) ||
8688 (_child->client.e.state.rot.app_set))
8689 _e_border_rotation_check(_child);
8691 eina_list_free(_list);
8695 if (l) e_container_border_list_free(l);
8699 // clear previous list
8700 EINA_LIST_FREE(rot.list, info)
8711 _e_border_cb_window_configure(void *data __UNUSED__,
8712 int ev_type __UNUSED__,
8715 Ecore_X_Event_Window_Configure *e = ev;
8716 if (!e) return ECORE_CALLBACK_PASS_ON;
8717 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8719 E_Border *bd = e_border_find_by_client_window(e->win);
8720 if (!bd) return ECORE_CALLBACK_PASS_ON;
8722 if (bd->client.e.state.rot.pending_change_request)
8724 if ((e->w == bd->w) && (e->h == bd->h))
8726 ELBF(ELBT_ROT, 0, bd->client.win,
8727 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8728 bd->client.e.state.rot.curr,
8731 bd->client.e.state.rot.pending_change_request = 0;
8733 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8734 bd->client.e.state.rot.curr);
8737 return ECORE_CALLBACK_PASS_ON;
8741 _e_border_rotation_geom_get(E_Border *bd,
8750 if (!e_config->wm_win_rotation) return EINA_FALSE;
8752 Eina_Bool res = EINA_FALSE;
8753 Eina_Bool _move = EINA_TRUE;
8763 if (move) *move = EINA_TRUE;
8765 if (bd->client.e.state.rot.geom_hint)
8770 _w = bd->client.e.state.rot.geom[0].w;
8771 _h = bd->client.e.state.rot.geom[0].h;
8772 if (_w == 0) _w = bd->w;
8773 if (_h == 0) _h = bd->h;
8774 _x = 0; _y = zone->h - _h;
8777 _w = bd->client.e.state.rot.geom[1].w;
8778 _h = bd->client.e.state.rot.geom[1].h;
8779 if (_w == 0) _w = bd->w;
8780 if (_h == 0) _h = bd->h;
8781 _x = zone->w - _w; _y = 0;
8784 _w = bd->client.e.state.rot.geom[2].w;
8785 _h = bd->client.e.state.rot.geom[2].h;
8786 if (_w == 0) _w = bd->w;
8787 if (_h == 0) _h = bd->h;
8791 _w = bd->client.e.state.rot.geom[3].w;
8792 _h = bd->client.e.state.rot.geom[3].h;
8793 if (_w == 0) _w = bd->w;
8794 if (_h == 0) _h = bd->h;
8804 if (!((rot.vkbd) && (rot.vkbd == bd)))
8808 if (move) *move = EINA_FALSE;
8816 _x = 0; _y = 0; _w = 0; _h = 0;
8821 if (move) _move = *move;
8823 ELBF(ELBT_ROT, 1, bd->client.win,
8824 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8825 ang, _x, _y, _w, _h, _move);
8833 _e_border_post_move_resize_job(void *data)
8837 bd = (E_Border *)data;
8843 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8844 ecore_x_window_move(tmp->win,
8846 bd->client_inset.l +
8848 tmp->client.e.state.video_position.x,
8850 bd->client_inset.t +
8852 tmp->client.e.state.video_position.y);
8854 if (bd->client.e.state.video)
8858 parent = bd->client.e.state.video_parent_border;
8859 ecore_x_window_move(bd->win,
8861 parent->client_inset.l +
8863 bd->client.e.state.video_position.x,
8865 parent->client_inset.t +
8867 bd->client.e.state.video_position.y);
8869 else if ((bd->post_move) && (bd->post_resize))
8871 ecore_x_window_move_resize(bd->win,
8876 else if (bd->post_move)
8878 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
8880 else if (bd->post_resize)
8882 ecore_x_window_resize(bd->win, bd->w, bd->h);
8885 if (bd->client.e.state.video)
8887 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
8889 bd->client.e.state.video_parent_border->x +
8890 bd->client.e.state.video_parent_border->client_inset.l +
8891 bd->client.e.state.video_parent_border->fx.x +
8892 bd->client.e.state.video_position.x,
8893 bd->client.e.state.video_parent_border->y +
8894 bd->client.e.state.video_parent_border->client_inset.t +
8895 bd->client.e.state.video_parent_border->fx.y +
8896 bd->client.e.state.video_position.y,
8904 bd->post_job = NULL;
8910 bd->post_resize = 0;
8911 bd->post_job = NULL;
8912 return ECORE_CALLBACK_CANCEL;
8916 _e_border_container_layout_hook(E_Container *con)
8918 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
8922 _e_border_eval0(E_Border *bd)
8924 int change_urgent = 0;
8926 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8927 Eina_Bool need_desk_set = EINA_FALSE;
8929 #ifdef _F_ZONE_WINDOW_ROTATION_
8930 Eina_Bool need_rotation_set = EINA_FALSE;
8932 if ((e_config->wm_win_rotation) &&
8933 (bd->client.icccm.fetch.transient_for))
8935 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8936 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
8938 need_rotation_set = EINA_TRUE;
8939 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
8944 if (e_object_is_del(E_OBJECT(bd)))
8946 CRI("_e_border_eval(%p) with deleted border!\n", bd);
8951 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
8953 bd->changes.border = 0;
8955 /* fetch any info queued to be fetched */
8956 if (bd->client.netwm.fetch.state)
8958 e_hints_window_state_get(bd);
8959 bd->client.netwm.fetch.state = 0;
8962 if (bd->client.icccm.fetch.client_leader)
8964 /* TODO: What do to if the client leader isn't mapped yet? */
8965 E_Border *bd_leader = NULL;
8967 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
8968 if (bd->client.icccm.client_leader)
8969 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
8972 if (bd->leader != bd_leader)
8974 bd->leader->group = eina_list_remove(bd->leader->group, bd);
8975 if (bd->leader->modal == bd) bd->leader->modal = NULL;
8981 /* If this border is the leader of the group, don't register itself */
8982 if ((bd_leader) && (bd_leader != bd))
8984 bd_leader->group = eina_list_append(bd_leader->group, bd);
8985 bd->leader = bd_leader;
8986 /* Only set the window modal to the leader it there is no parent */
8987 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
8988 ((!bd->parent) || (bd->parent->modal != bd)))
8990 bd->leader->modal = bd;
8991 if (bd->leader->focused)
8992 e_border_focus_set(bd, 1, 1);
8998 EINA_LIST_FOREACH(bd->leader->group, l, child)
9000 if ((child != bd) && (child->focused))
9001 e_border_focus_set(bd, 1, 1);
9006 bd->client.icccm.fetch.client_leader = 0;
9009 if (bd->client.icccm.fetch.title)
9011 char *title = ecore_x_icccm_title_get(bd->client.win);
9012 eina_stringshare_replace(&bd->client.icccm.title, title);
9013 if (title) free(title);
9016 edje_object_part_text_set(bd->bg_object, "e.text.title",
9017 bd->client.icccm.title);
9018 bd->client.icccm.fetch.title = 0;
9021 if (bd->client.netwm.fetch.name)
9024 ecore_x_netwm_name_get(bd->client.win, &name);
9025 eina_stringshare_replace(&bd->client.netwm.name, name);
9026 if (name) free(name);
9029 edje_object_part_text_set(bd->bg_object, "e.text.title",
9030 bd->client.netwm.name);
9031 bd->client.netwm.fetch.name = 0;
9034 if (bd->client.icccm.fetch.name_class)
9036 const char *pname, *pclass;
9037 char *nname, *nclass;
9039 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9040 pname = bd->client.icccm.name;
9041 pclass = bd->client.icccm.class;
9042 bd->client.icccm.name = eina_stringshare_add(nname);
9043 bd->client.icccm.class = eina_stringshare_add(nclass);
9044 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9045 e_bindings_mapping_change_enable(EINA_FALSE);
9046 #ifdef _F_ZONE_WINDOW_ROTATION_
9047 if (e_config->wm_win_rotation)
9049 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9051 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9052 (!strcmp(bd->client.icccm.class, "ISF")))
9054 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9055 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9058 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9059 (!strcmp(bd->client.icccm.class, "ISF")))
9061 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9062 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9063 rot.vkbd_prediction = bd;
9065 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9066 (!strcmp(bd->client.icccm.class, "ISF")))
9068 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9069 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9071 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9072 (!strcmp(bd->client.icccm.class, "ISF")))
9074 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9075 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9080 if (nname) free(nname);
9081 if (nclass) free(nclass);
9083 if (!((bd->client.icccm.name == pname) &&
9084 (bd->client.icccm.class == pclass)))
9085 bd->changes.icon = 1;
9087 if (pname) eina_stringshare_del(pname);
9088 if (pclass) eina_stringshare_del(pclass);
9089 bd->client.icccm.fetch.name_class = 0;
9090 bd->changes.icon = 1;
9093 if (bd->client.icccm.fetch.state)
9095 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9096 bd->client.icccm.fetch.state = 0;
9099 if (bd->client.e.fetch.state)
9101 e_hints_window_e_state_get(bd);
9102 bd->client.e.fetch.state = 0;
9105 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9106 if (bd->client.e.fetch.profile_list)
9108 const char **profiles = NULL;
9112 if (bd->client.e.state.profile)
9113 eina_stringshare_del(bd->client.e.state.profile);
9114 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9116 if (str) eina_stringshare_del(str);
9118 bd->client.e.state.profile = NULL;
9119 bd->client.e.state.profiles = NULL;
9120 bd->client.e.state.profile_list = 0;
9122 if (ecore_x_e_window_profile_list_get(bd->client.win,
9125 bd->client.e.state.profile_list = 1;
9126 for (i = 0; i < num; i++)
9128 str = eina_stringshare_add(profiles[i]);
9129 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9132 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9133 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9135 need_desk_set = EINA_TRUE;
9139 if (strcmp(bd->desk->window_profile,
9140 e_config->desktop_default_window_profile) != 0)
9142 ecore_x_e_window_profile_set(bd->client.win,
9143 bd->desk->window_profile);
9149 for (i = 0; i < num; i++)
9150 if (profiles[i]) free(profiles[i]);
9154 bd->client.e.fetch.profile_list = 0;
9157 #ifdef _F_ZONE_WINDOW_ROTATION_
9158 if ((e_config->wm_win_rotation) &&
9159 (bd->client.e.fetch.rot.support))
9162 unsigned int support = 0;
9164 ret = ecore_x_window_prop_card32_get
9166 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9169 bd->client.e.state.rot.support = 0;
9170 if ((ret == 1) && (support == 1))
9171 bd->client.e.state.rot.support = 1;
9173 if (bd->client.e.state.rot.support)
9174 need_rotation_set = EINA_TRUE;
9176 bd->client.e.fetch.rot.support = 0;
9178 if ((e_config->wm_win_rotation) &&
9179 (bd->client.e.fetch.rot.geom_hint))
9181 Eina_Rectangle r[4];
9183 bd->client.e.state.rot.geom_hint = 0;
9184 for (i = 0; i < 4; i++)
9186 r[i].x = bd->client.e.state.rot.geom[i].x;
9187 r[i].y = bd->client.e.state.rot.geom[i].y;
9188 r[i].w = bd->client.e.state.rot.geom[i].w;
9189 r[i].h = bd->client.e.state.rot.geom[i].h;
9191 bd->client.e.state.rot.geom[i].x = 0;
9192 bd->client.e.state.rot.geom[i].y = 0;
9193 bd->client.e.state.rot.geom[i].w = 0;
9194 bd->client.e.state.rot.geom[i].h = 0;
9197 for (i = 0; i < 4; i++)
9199 x = 0; y = 0; w = 0; h = 0;
9200 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9202 bd->client.e.state.rot.geom_hint = 1;
9203 bd->client.e.state.rot.geom[i].x = x;
9204 bd->client.e.state.rot.geom[i].y = y;
9205 bd->client.e.state.rot.geom[i].w = w;
9206 bd->client.e.state.rot.geom[i].h = h;
9208 if (!((r[i].x == x) && (r[i].y == y) &&
9209 (r[i].w == w) && (r[i].h == h)))
9211 need_rotation_set = EINA_TRUE;
9215 bd->client.e.fetch.rot.geom_hint = 0;
9217 if ((e_config->wm_win_rotation) &&
9218 (bd->client.e.fetch.rot.app_set))
9220 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9221 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9222 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9224 if (_prev_app_set != bd->client.e.state.rot.app_set)
9225 need_rotation_set = EINA_TRUE;
9227 bd->client.e.fetch.rot.app_set = 0;
9229 if ((e_config->wm_win_rotation) &&
9230 (bd->client.e.fetch.rot.preferred_rot))
9232 int r = 0, _prev_preferred_rot;
9233 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9234 bd->client.e.state.rot.preferred_rot = -1;
9235 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9237 bd->client.e.state.rot.preferred_rot = r;
9238 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9242 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9245 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9246 need_rotation_set = EINA_TRUE;
9248 bd->client.e.fetch.rot.preferred_rot = 0;
9250 if ((e_config->wm_win_rotation) &&
9251 (bd->client.e.fetch.rot.available_rots))
9253 Eina_Bool res, diff = EINA_FALSE;
9255 unsigned int count = 0, i = 0;
9256 int _prev_rots[4] = { -1, };
9258 if (bd->client.e.state.rot.available_rots)
9261 bd->client.e.state.rot.available_rots,
9262 (sizeof(int) * bd->client.e.state.rot.count));
9264 E_FREE(bd->client.e.state.rot.available_rots);
9267 bd->client.e.state.rot.count = 0;
9269 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9271 if ((res) && (count > 0) && (rots))
9273 bd->client.e.state.rot.available_rots = rots;
9274 bd->client.e.state.rot.count = count;
9276 for (i = 0; i < count; i++)
9278 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9279 if ((!diff) && (_prev_rots[i] != rots[i]))
9281 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9282 count, i, _prev_rots[i], rots[i]);
9289 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9293 if (diff) need_rotation_set = EINA_TRUE;
9294 bd->client.e.fetch.rot.available_rots = 0;
9297 if (bd->client.netwm.fetch.type)
9299 e_hints_window_type_get(bd);
9300 if ((!bd->lock_border) || (!bd->client.border.name))
9301 bd->client.border.changed = 1;
9303 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9305 if (!bd->client.netwm.state.skip_pager)
9307 bd->client.netwm.state.skip_pager = 1;
9308 bd->client.netwm.update.state = 1;
9310 if (!bd->client.netwm.state.skip_taskbar)
9312 bd->client.netwm.state.skip_taskbar = 1;
9313 bd->client.netwm.update.state = 1;
9316 bd->client.netwm.fetch.type = 0;
9318 if (bd->client.icccm.fetch.machine)
9320 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9322 if ((!machine) && (bd->client.icccm.client_leader))
9323 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9325 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9326 if (machine) free(machine);
9328 bd->client.icccm.fetch.machine = 0;
9331 if (bd->client.icccm.fetch.command)
9333 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9337 for (i = 0; i < bd->client.icccm.command.argc; i++)
9338 free(bd->client.icccm.command.argv[i]);
9339 free(bd->client.icccm.command.argv);
9341 bd->client.icccm.command.argc = 0;
9342 bd->client.icccm.command.argv = NULL;
9343 ecore_x_icccm_command_get(bd->client.win,
9344 &(bd->client.icccm.command.argc),
9345 &(bd->client.icccm.command.argv));
9346 if ((bd->client.icccm.client_leader) &&
9347 (!bd->client.icccm.command.argv))
9348 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9349 &(bd->client.icccm.command.argc),
9350 &(bd->client.icccm.command.argv));
9351 bd->client.icccm.fetch.command = 0;
9354 if (bd->client.icccm.fetch.hints)
9356 Eina_Bool accepts_focus, is_urgent;
9358 accepts_focus = EINA_TRUE;
9359 is_urgent = EINA_FALSE;
9360 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9361 if (ecore_x_icccm_hints_get(bd->client.win,
9363 &bd->client.icccm.initial_state,
9364 &bd->client.icccm.icon_pixmap,
9365 &bd->client.icccm.icon_mask,
9366 &bd->client.icccm.icon_window,
9367 &bd->client.icccm.window_group,
9370 bd->client.icccm.accepts_focus = accepts_focus;
9371 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9373 bd->client.icccm.urgent = is_urgent;
9375 /* If this is a new window, set the state as requested. */
9376 if ((bd->new_client) &&
9377 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9379 e_border_iconify(bd);
9380 e_border_hide(bd, 1);
9383 bd->client.icccm.fetch.hints = 0;
9386 if (bd->client.icccm.fetch.size_pos_hints)
9388 Eina_Bool request_pos;
9390 request_pos = EINA_FALSE;
9391 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9393 &bd->client.icccm.gravity,
9394 &bd->client.icccm.min_w,
9395 &bd->client.icccm.min_h,
9396 &bd->client.icccm.max_w,
9397 &bd->client.icccm.max_h,
9398 &bd->client.icccm.base_w,
9399 &bd->client.icccm.base_h,
9400 &bd->client.icccm.step_w,
9401 &bd->client.icccm.step_h,
9402 &bd->client.icccm.min_aspect,
9403 &bd->client.icccm.max_aspect))
9405 bd->client.icccm.request_pos = request_pos;
9410 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9411 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9412 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9413 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9414 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9415 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9416 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9417 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9418 // if doing a resize, fix it up
9419 if (bd->resize_mode != RESIZE_NONE)
9421 int x, y, w, h, new_w, new_h;
9429 e_border_resize_limit(bd, &new_w, &new_h);
9430 if ((bd->resize_mode == RESIZE_TL) ||
9431 (bd->resize_mode == RESIZE_L) ||
9432 (bd->resize_mode == RESIZE_BL))
9434 if ((bd->resize_mode == RESIZE_TL) ||
9435 (bd->resize_mode == RESIZE_T) ||
9436 (bd->resize_mode == RESIZE_TR))
9438 e_border_move_resize(bd, x, y, new_w, new_h);
9440 bd->client.icccm.fetch.size_pos_hints = 0;
9443 if (bd->client.icccm.fetch.protocol)
9446 Ecore_X_WM_Protocol *proto;
9448 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9451 for (i = 0; i < num; i++)
9453 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9454 bd->client.icccm.delete_request = 1;
9455 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9456 bd->client.icccm.take_focus = 1;
9457 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9458 bd->client.netwm.ping = 1;
9459 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9461 bd->client.netwm.sync.request = 1;
9462 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9463 &bd->client.netwm.sync.counter))
9464 bd->client.netwm.sync.request = 0;
9469 if (bd->client.netwm.ping)
9473 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9474 bd->ping_poller = NULL;
9476 bd->client.icccm.fetch.protocol = 0;
9478 if (bd->client.icccm.fetch.transient_for)
9480 /* TODO: What do to if the transient for isn't mapped yet? */
9481 E_Border *bd_parent = NULL;
9482 #ifdef _F_DEICONIFY_APPROVE_
9483 Eina_Bool change_parent = EINA_FALSE;
9486 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9487 if (bd->client.icccm.transient_for)
9488 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9489 /* If we already have a parent, remove it */
9492 if (bd_parent != bd->parent)
9494 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9495 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9501 if ((bd_parent) && (bd_parent != bd) &&
9502 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9504 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9505 bd->parent = bd_parent;
9506 #ifdef _F_DEICONIFY_APPROVE_
9507 change_parent = EINA_TRUE;
9512 e_border_layer_set(bd, bd->parent->layer);
9513 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9515 Ecore_X_Window_Attributes attr;
9516 bd->parent->modal = bd;
9517 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9518 bd->parent->saved.event_mask = attr.event_mask.mine;
9519 bd->parent->lock_close = 1;
9520 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9521 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9524 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9525 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9529 #ifdef _F_DEICONIFY_APPROVE_
9532 bd->client.e.state.deiconify_approve.render_done = 0;
9534 E_Border *ancestor_bd;
9535 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9536 if ((ancestor_bd) &&
9537 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9539 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9540 bd->client.e.state.deiconify_approve.ancestor = NULL;
9542 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9543 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9545 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9547 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9548 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9549 e_border_uniconify(ancestor_bd);
9555 bd->client.icccm.fetch.transient_for = 0;
9558 if (bd->client.icccm.fetch.window_role)
9560 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9561 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9562 if (role) free(role);
9564 bd->client.icccm.fetch.window_role = 0;
9567 if (bd->client.icccm.fetch.icon_name)
9569 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9570 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9571 if (icon_name) free(icon_name);
9573 bd->client.icccm.fetch.icon_name = 0;
9576 if (bd->client.netwm.fetch.icon_name)
9579 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9580 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9581 if (icon_name) free(icon_name);
9583 bd->client.netwm.fetch.icon_name = 0;
9586 if (bd->client.netwm.fetch.icon)
9589 if (bd->client.netwm.icons)
9591 for (i = 0; i < bd->client.netwm.num_icons; i++)
9593 free(bd->client.netwm.icons[i].data);
9594 bd->client.netwm.icons[i].data = NULL;
9596 free(bd->client.netwm.icons);
9598 bd->client.netwm.icons = NULL;
9599 bd->client.netwm.num_icons = 0;
9600 if (ecore_x_netwm_icons_get(bd->client.win,
9601 &bd->client.netwm.icons,
9602 &bd->client.netwm.num_icons))
9604 // unless the rest of e17 uses border icons OTHER than icon #0
9605 // then free the rest that we don't need anymore.
9606 for (i = 1; i < bd->client.netwm.num_icons; i++)
9608 free(bd->client.netwm.icons[i].data);
9609 bd->client.netwm.icons[i].data = NULL;
9611 bd->client.netwm.num_icons = 1;
9612 bd->changes.icon = 1;
9614 bd->client.netwm.fetch.icon = 0;
9616 if (bd->client.netwm.fetch.user_time)
9618 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9619 bd->client.netwm.fetch.user_time = 0;
9621 if (bd->client.netwm.fetch.strut)
9623 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9624 &bd->client.netwm.strut.left,
9625 &bd->client.netwm.strut.right,
9626 &bd->client.netwm.strut.top,
9627 &bd->client.netwm.strut.bottom,
9628 &bd->client.netwm.strut.left_start_y,
9629 &bd->client.netwm.strut.left_end_y,
9630 &bd->client.netwm.strut.right_start_y,
9631 &bd->client.netwm.strut.right_end_y,
9632 &bd->client.netwm.strut.top_start_x,
9633 &bd->client.netwm.strut.top_end_x,
9634 &bd->client.netwm.strut.bottom_start_x,
9635 &bd->client.netwm.strut.bottom_end_x))
9637 ecore_x_netwm_strut_get(bd->client.win,
9638 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9639 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9641 bd->client.netwm.strut.left_start_y = 0;
9642 bd->client.netwm.strut.left_end_y = 0;
9643 bd->client.netwm.strut.right_start_y = 0;
9644 bd->client.netwm.strut.right_end_y = 0;
9645 bd->client.netwm.strut.top_start_x = 0;
9646 bd->client.netwm.strut.top_end_x = 0;
9647 bd->client.netwm.strut.bottom_start_x = 0;
9648 bd->client.netwm.strut.bottom_end_x = 0;
9650 bd->client.netwm.fetch.strut = 0;
9652 if (bd->client.qtopia.fetch.soft_menu)
9654 e_hints_window_qtopia_soft_menu_get(bd);
9655 bd->client.qtopia.fetch.soft_menu = 0;
9658 if (bd->client.qtopia.fetch.soft_menus)
9660 e_hints_window_qtopia_soft_menus_get(bd);
9661 bd->client.qtopia.fetch.soft_menus = 0;
9664 if (bd->client.vkbd.fetch.state)
9666 e_hints_window_virtual_keyboard_state_get(bd);
9667 bd->client.vkbd.fetch.state = 0;
9670 if (bd->client.vkbd.fetch.vkbd)
9672 e_hints_window_virtual_keyboard_get(bd);
9673 bd->client.vkbd.fetch.vkbd = 0;
9676 if (bd->client.illume.conformant.fetch.conformant)
9678 bd->client.illume.conformant.conformant =
9679 ecore_x_e_illume_conformant_get(bd->client.win);
9680 bd->client.illume.conformant.fetch.conformant = 0;
9682 if (bd->client.illume.quickpanel.fetch.state)
9684 bd->client.illume.quickpanel.state =
9685 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9686 bd->client.illume.quickpanel.fetch.state = 0;
9688 if (bd->client.illume.quickpanel.fetch.quickpanel)
9690 bd->client.illume.quickpanel.quickpanel =
9691 ecore_x_e_illume_quickpanel_get(bd->client.win);
9692 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9694 if (bd->client.illume.quickpanel.fetch.priority.major)
9696 bd->client.illume.quickpanel.priority.major =
9697 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9698 bd->client.illume.quickpanel.fetch.priority.major = 0;
9700 if (bd->client.illume.quickpanel.fetch.priority.minor)
9702 bd->client.illume.quickpanel.priority.minor =
9703 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9704 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9706 if (bd->client.illume.quickpanel.fetch.zone)
9708 bd->client.illume.quickpanel.zone =
9709 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9710 bd->client.illume.quickpanel.fetch.zone = 0;
9712 if (bd->client.illume.drag.fetch.drag)
9714 bd->client.illume.drag.drag =
9715 ecore_x_e_illume_drag_get(bd->client.win);
9716 bd->client.illume.drag.fetch.drag = 0;
9718 if (bd->client.illume.drag.fetch.locked)
9720 bd->client.illume.drag.locked =
9721 ecore_x_e_illume_drag_locked_get(bd->client.win);
9722 bd->client.illume.drag.fetch.locked = 0;
9724 if (bd->client.illume.win_state.fetch.state)
9726 bd->client.illume.win_state.state =
9727 ecore_x_e_illume_window_state_get(bd->client.win);
9728 bd->client.illume.win_state.fetch.state = 0;
9730 if (bd->changes.shape)
9732 Ecore_X_Rectangle *rects;
9735 bd->changes.shape = 0;
9736 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9741 /* This doesn't fix the race, but makes it smaller. we detect
9742 * this and if cw and ch != client w/h then mark this as needing
9743 * a shape change again to fixup next event loop.
9745 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9746 if ((cw != bd->client.w) || (ch != bd->client.h))
9747 bd->changes.shape = 1;
9749 (rects[0].x == 0) &&
9750 (rects[0].y == 0) &&
9751 ((int)rects[0].width == cw) &&
9752 ((int)rects[0].height == ch))
9754 if (bd->client.shaped)
9756 bd->client.shaped = 0;
9757 if (!bd->bordername)
9758 bd->client.border.changed = 1;
9763 if (!bd->client.shaped)
9765 bd->client.shaped = 1;
9766 if (!bd->bordername)
9767 bd->client.border.changed = 1;
9774 // FIXME: no rects i think can mean... totally empty window
9775 bd->client.shaped = 0;
9776 if (!bd->bordername)
9777 bd->client.border.changed = 1;
9779 bd->need_shape_merge = 1;
9781 if (bd->changes.shape_input)
9783 Ecore_X_Rectangle *rects;
9786 bd->changes.shape_input = 0;
9787 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9792 /* This doesn't fix the race, but makes it smaller. we detect
9793 * this and if cw and ch != client w/h then mark this as needing
9794 * a shape change again to fixup next event loop.
9796 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9797 if ((cw != bd->client.w) || (ch != bd->client.h))
9798 bd->changes.shape_input = 1;
9800 (rects[0].x == 0) &&
9801 (rects[0].y == 0) &&
9802 ((int)rects[0].width == cw) &&
9803 ((int)rects[0].height == ch))
9805 if (bd->shaped_input)
9807 bd->shaped_input = 0;
9808 if (!bd->bordername)
9809 bd->client.border.changed = 1;
9814 if (!bd->shaped_input)
9816 bd->shaped_input = 1;
9817 if (!bd->bordername)
9818 bd->client.border.changed = 1;
9825 bd->shaped_input = 1;
9826 if (!bd->bordername)
9827 bd->client.border.changed = 1;
9829 bd->need_shape_merge = 1;
9831 if (bd->client.mwm.fetch.hints)
9835 bd->client.mwm.exists =
9836 ecore_x_mwm_hints_get(bd->client.win,
9837 &bd->client.mwm.func,
9838 &bd->client.mwm.decor,
9839 &bd->client.mwm.input);
9840 pb = bd->client.mwm.borderless;
9841 bd->client.mwm.borderless = 0;
9842 if (bd->client.mwm.exists)
9844 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9845 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9846 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9847 bd->client.mwm.borderless = 1;
9849 if (bd->client.mwm.borderless != pb)
9851 if ((!bd->lock_border) || (!bd->client.border.name))
9852 bd->client.border.changed = 1;
9854 bd->client.mwm.fetch.hints = 0;
9857 if (bd->client.e.fetch.video_parent)
9859 /* unlinking child/parent */
9860 if (bd->client.e.state.video_parent_border != NULL)
9862 bd->client.e.state.video_parent_border->client.e.state.video_child =
9864 (bd->client.e.state.video_parent_border->client.e.state.video_child,
9868 ecore_x_window_prop_card32_get(bd->client.win,
9869 ECORE_X_ATOM_E_VIDEO_PARENT,
9870 &bd->client.e.state.video_parent,
9873 /* linking child/parent */
9874 if (bd->client.e.state.video_parent != 0)
9879 EINA_LIST_FOREACH(borders, l, tmp)
9880 if (tmp->client.win == bd->client.e.state.video_parent)
9882 /* fprintf(stderr, "child added to parent \\o/\n"); */
9883 bd->client.e.state.video_parent_border = tmp;
9884 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
9886 if (bd->desk != tmp->desk)
9887 e_border_desk_set(bd, tmp->desk);
9892 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
9894 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
9897 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
9901 ecore_x_window_prop_card32_get(bd->client.win,
9902 ECORE_X_ATOM_E_VIDEO_POSITION,
9905 bd->client.e.state.video_position.x = xy[0];
9906 bd->client.e.state.video_position.y = xy[1];
9907 bd->client.e.state.video_position.updated = 1;
9908 bd->client.e.fetch.video_position = 0;
9909 bd->x = bd->client.e.state.video_position.x;
9910 bd->y = bd->client.e.state.video_position.y;
9912 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
9914 if (bd->client.netwm.update.state)
9916 e_hints_window_state_set(bd);
9917 /* Some stats might change the border, like modal */
9918 if (((!bd->lock_border) || (!bd->client.border.name)) &&
9919 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9921 bd->client.border.changed = 1;
9925 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9927 bd->parent->modal = bd;
9928 if (bd->parent->focused)
9929 e_border_focus_set(bd, 1, 1);
9932 else if (bd->leader)
9934 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9936 bd->leader->modal = bd;
9937 if (bd->leader->focused)
9938 e_border_focus_set(bd, 1, 1);
9944 EINA_LIST_FOREACH(bd->leader->group, l, child)
9946 if ((child != bd) && (child->focused))
9947 e_border_focus_set(bd, 1, 1);
9952 bd->client.netwm.update.state = 0;
9957 E_Event_Border_Add *ev;
9958 E_Exec_Instance *inst;
9960 ev = E_NEW(E_Event_Border_Add, 1);
9962 e_object_ref(E_OBJECT(bd));
9963 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
9964 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
9966 if ((!bd->lock_border) || (!bd->client.border.name))
9967 bd->client.border.changed = 1;
9972 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
9973 ((bd->client.icccm.client_leader > 0) &&
9974 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
9977 if (!strncmp(str, "E_START|", 8))
9982 if (id > 0) bd->client.netwm.startup_id = id;
9987 /* It's ok not to have fetch flag, should only be set on startup
9988 * * and not changed. */
9989 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
9991 if (bd->client.icccm.client_leader)
9993 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
9994 bd->client.netwm.pid = -1;
9997 bd->client.netwm.pid = -1;
10000 if (!bd->re_manage)
10002 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10003 bd->client.netwm.pid);
10004 if ((inst) && (inst->used == 0))
10010 zone = e_container_zone_number_get(bd->zone->container,
10012 if (zone) e_border_zone_set(bd, zone);
10013 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10015 if (desk) e_border_desk_set(bd, desk);
10016 e_exec_instance_found(inst);
10019 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10021 E_Border *bdl = NULL;
10026 if (bd->leader) bdl = bd->leader;
10033 bl = e_container_border_list_first(bd->zone->container);
10034 while ((child = e_container_border_list_next(bl)))
10036 if (child == bd) continue;
10037 if (e_object_is_del(E_OBJECT(child))) continue;
10038 if ((bd->client.icccm.client_leader) &&
10039 (child->client.icccm.client_leader ==
10040 bd->client.icccm.client_leader))
10046 e_container_border_list_free(bl);
10051 e_border_zone_set(bd, bdl->zone);
10053 e_border_desk_set(bd, bdl->desk);
10055 e_border_stick(bd);
10061 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10064 E_Container *con = bd->zone->container;
10065 E_Desk *desk = NULL;
10068 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10070 desk = e_container_desk_window_profile_get(con, str);
10073 if (bd->desk != desk)
10075 bd->client.e.state.profile = eina_stringshare_add(str);
10076 if (bd->zone != desk->zone)
10077 e_border_zone_set(bd, desk->zone);
10078 e_border_desk_set(bd, desk);
10085 #ifdef _F_ZONE_WINDOW_ROTATION_
10086 if ((e_config->wm_win_rotation) &&
10087 (need_rotation_set))
10089 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10090 Eina_Bool _rot = _e_border_rotation_check(bd);
10091 /* check whether rotation is available for sub borders such as prediction and magnifier */
10096 Eina_List *_list = _e_border_sub_borders_new(bd);
10097 EINA_LIST_FOREACH(_list, ll, _child)
10099 if ((_child->client.e.state.rot.support) ||
10100 (_child->client.e.state.rot.app_set))
10101 _e_border_rotation_check(_child);
10103 eina_list_free(_list);
10108 /* PRE_POST_FETCH calls e_remember apply for new client */
10109 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10110 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10111 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10113 if (bd->need_reparent)
10116 ecore_x_window_save_set_add(bd->client.win);
10117 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10120 if ((bd->new_client) && (bd->internal) &&
10121 (bd->internal_ecore_evas))
10122 ecore_evas_show(bd->internal_ecore_evas);
10123 ecore_x_window_show(bd->client.win);
10125 bd->need_reparent = 0;
10128 if ((bd->client.border.changed) && (!bd->shaded) &&
10129 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10131 const char *bordername;
10133 if (bd->fullscreen)
10134 bordername = "borderless";
10135 else if (bd->bordername)
10136 bordername = bd->bordername;
10137 else if ((bd->client.mwm.borderless) || (bd->borderless))
10138 bordername = "borderless";
10139 else if (((bd->client.icccm.transient_for != 0) ||
10140 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10141 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10142 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10143 bordername = "noresize_dialog";
10144 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10145 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10146 bordername = "noresize";
10147 else if (bd->client.shaped)
10148 bordername = "shaped";
10149 else if ((!bd->client.icccm.accepts_focus) &&
10150 (!bd->client.icccm.take_focus))
10151 bordername = "nofocus";
10152 else if (bd->client.icccm.urgent)
10153 bordername = "urgent";
10154 else if ((bd->client.icccm.transient_for != 0) ||
10155 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10156 bordername = "dialog";
10157 else if (bd->client.netwm.state.modal)
10158 bordername = "modal";
10159 else if ((bd->client.netwm.state.skip_taskbar) ||
10160 (bd->client.netwm.state.skip_pager))
10161 bordername = "skipped";
10162 else if ((bd->internal) && (bd->client.icccm.class) &&
10163 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10164 bordername = "internal_fileman";
10166 bordername = e_config->theme_default_border_style;
10167 if (!bordername) bordername = "default";
10169 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10175 bd->changes.border = 1;
10176 eina_stringshare_replace(&bd->client.border.name, bordername);
10180 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10181 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10182 bd->changes.size = 1;
10183 evas_object_del(bd->bg_object);
10185 o = edje_object_add(bd->bg_evas);
10186 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10187 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10188 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10190 if (bd->client.border.name != e_config->theme_default_border_style)
10192 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10193 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10197 ok = e_theme_edje_object_set(o, "base/theme/borders",
10198 "e/widgets/border/default/border");
10201 /* Reset default border style to default */
10202 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10203 e_config_save_queue();
10211 const char *shape_option, *argb_option;
10216 if ((e_config->use_composite) && (!bd->client.argb))
10218 argb_option = edje_object_data_get(o, "argb");
10219 if ((argb_option) && (!strcmp(argb_option, "1")))
10222 if (use_argb != bd->argb)
10223 _e_border_frame_replace(bd, use_argb);
10230 shape_option = edje_object_data_get(o, "shaped");
10231 if ((shape_option) && (!strcmp(shape_option, "1")))
10235 if (bd->client.netwm.name)
10236 edje_object_part_text_set(o, "e.text.title",
10237 bd->client.netwm.name);
10238 else if (bd->client.icccm.title)
10239 edje_object_part_text_set(o, "e.text.title",
10240 bd->client.icccm.title);
10244 evas_object_del(o);
10245 bd->bg_object = NULL;
10248 _e_border_client_inset_calc(bd);
10250 bd->w += (bd->client_inset.l + bd->client_inset.r);
10251 bd->h += (bd->client_inset.t + bd->client_inset.b);
10252 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10253 bd->changes.size = 1;
10254 /* really needed ? */
10255 ecore_x_window_move(bd->client.shell_win,
10256 bd->client_inset.l,
10257 bd->client_inset.t);
10259 if (bd->maximized != E_MAXIMIZE_NONE)
10261 E_Maximize maximized = bd->maximized;
10263 /* to force possible resizes */
10264 bd->maximized = E_MAXIMIZE_NONE;
10266 _e_border_maximize(bd, maximized);
10268 /* restore maximized state */
10269 bd->maximized = maximized;
10271 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10272 bd->maximized & E_MAXIMIZE_VERTICAL);
10276 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10277 _e_border_cb_signal_bind, bd);
10280 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10281 if (bd->icon_object)
10282 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10285 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10287 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10289 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10290 // FIXME: in eval -do differently
10291 // edje_object_message_signal_process(bd->bg_object);
10292 // e_border_frame_recalc(bd);
10294 evas_object_move(bd->bg_object, 0, 0);
10295 evas_object_resize(bd->bg_object, bd->w, bd->h);
10296 evas_object_show(bd->bg_object);
10299 bd->client.border.changed = 0;
10301 if (bd->icon_object)
10305 evas_object_show(bd->icon_object);
10306 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10309 evas_object_hide(bd->icon_object);
10313 if (rem_change) e_remember_update(bd);
10317 E_Event_Border_Urgent_Change *ev;
10319 if (bd->client.icccm.urgent)
10320 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10322 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10324 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10326 e_object_ref(E_OBJECT(bd));
10327 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10328 _e_border_event_border_urgent_change_free, NULL);
10331 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10334 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10336 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10338 E_Border* temp_bd = NULL;
10339 E_Border* top_focusable_bd = NULL;
10340 Eina_Bool is_fully_obscured = EINA_FALSE;
10341 Ecore_X_XRegion *visible_region = NULL;
10342 Ecore_X_XRegion *win_region = NULL;
10343 Ecore_X_Rectangle visible_rect, win_rect;
10346 // set the entire visible region as a root geometry
10347 visible_rect.x = bd->zone->x;
10348 visible_rect.y = bd->zone->y;
10349 visible_rect.width = bd->zone->w;
10350 visible_rect.height = bd->zone->h;
10352 visible_region = ecore_x_xregion_new();
10353 if (!visible_region) return;
10355 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10357 bl = e_container_border_list_last(bd->zone->container);
10358 while ((temp_bd = e_container_border_list_prev(bl)))
10360 if (temp_bd == bd) break;
10362 if (temp_bd == focused) continue;
10363 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10364 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10365 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10366 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10367 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10368 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10369 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10370 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10371 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10373 if (!top_focusable_bd)
10375 top_focusable_bd = temp_bd;
10378 win_rect.x = temp_bd->x;
10379 win_rect.y = temp_bd->y;
10380 win_rect.width = temp_bd->w;
10381 win_rect.height = temp_bd->h;
10383 // if it stick out or is bigger than the entire visible region,
10384 // clip it by the entire visible's geometry.
10385 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10386 win_rect.width, win_rect.height,
10387 visible_rect.x, visible_rect.y,
10388 (int)(visible_rect.width), (int)(visible_rect.height));
10390 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10392 win_region = ecore_x_xregion_new();
10395 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10396 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10397 ecore_x_xregion_free(win_region);
10400 if (ecore_x_xregion_is_empty(visible_region))
10402 is_fully_obscured = EINA_TRUE;
10410 if (is_fully_obscured == EINA_TRUE)
10412 e_border_focus_set(top_focusable_bd, 1, 1);
10416 e_border_focus_set(bd, 1, 1);
10419 if (visible_region) ecore_x_xregion_free(visible_region);
10420 e_container_border_list_free(bl);
10424 _e_border_latest_stacked_focus(E_Border *bd)
10427 int root_w, root_h;
10429 root_w = bd->zone->w;
10430 root_h = bd->zone->h;
10433 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10435 if (bd == temp_bd) continue;
10436 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10437 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10439 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10440 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10441 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10442 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10443 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10444 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10445 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10447 _e_border_latest_stacked_focus_check_set(temp_bd);
10454 _e_border_check_stack (E_Border *bd)
10456 E_Border* temp_bd = NULL;
10457 E_Border* top_bd = NULL;
10458 int passed_focus = 0;
10460 int root_w = bd->zone->w;
10461 int root_h = bd->zone->h;
10464 bl = e_container_border_list_last(bd->zone->container);
10465 while ((temp_bd = e_container_border_list_prev(bl)))
10467 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10468 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10469 if ((temp_bd != bd) &&
10470 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10472 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10473 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10474 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10475 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10476 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10477 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10478 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10484 e_border_focus_set_with_pointer(bd);
10491 e_border_focus_set_with_pointer(top_bd);
10500 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10502 if (!bd->lock_focus_out)
10504 e_border_focus_latest_set(bd);
10516 if (temp_bd == focused)
10522 e_container_border_list_free(bl);
10526 _e_border_focus_top_stack_set(E_Border* bd)
10529 int root_w, root_h;
10531 root_w = bd->zone->w;
10532 root_h = bd->zone->h;
10535 bl = e_container_border_list_last(bd->zone->container);
10536 while ((temp_bd = e_container_border_list_prev(bl)))
10538 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10539 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10540 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10542 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10543 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10544 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10545 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10546 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10547 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10548 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10550 if (!temp_bd->focused)
10552 /* this border is the top of the latest stack */
10553 e_border_focus_set (temp_bd, 1, 1);
10558 e_container_border_list_free(bl);
10563 _e_border_eval(E_Border *bd)
10565 E_Event_Border_Property *event;
10566 E_Border_Pending_Move_Resize *pnd;
10567 int rem_change = 0;
10568 int send_event = 1;
10570 if (e_object_is_del(E_OBJECT(bd)))
10572 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10577 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10579 if (bd->new_client)
10581 int zx = 0, zy = 0, zw = 0, zh = 0;
10584 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10587 * Limit maximum size of windows to useful geometry
10589 // TODO: temoporary limited maximize algorithm
10601 if ((rw != bd->w) || (rh != bd->h))
10605 e_border_resize (bd, bd->w, bd->h);
10611 bd->x -= bd->client_inset.l;
10612 bd->y -= bd->client_inset.t;
10613 bd->changes.pos = 1;
10616 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10619 Ecore_X_Window_Attributes *att;
10622 att = &bd->client.initial_attributes;
10623 bw = att->border * 2;
10624 switch (bd->client.icccm.gravity)
10626 case ECORE_X_GRAVITY_N:
10627 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10631 case ECORE_X_GRAVITY_NE:
10632 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10636 case ECORE_X_GRAVITY_E:
10637 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10638 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10641 case ECORE_X_GRAVITY_SE:
10642 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10643 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10646 case ECORE_X_GRAVITY_S:
10647 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10648 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10651 case ECORE_X_GRAVITY_SW:
10653 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10656 case ECORE_X_GRAVITY_W:
10658 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10661 case ECORE_X_GRAVITY_CENTER:
10662 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10663 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10666 case ECORE_X_GRAVITY_NW:
10673 * This ensures that windows that like to open with a x/y
10674 * position smaller than returned by e_zone_useful_geometry_get()
10675 * are moved to useful positions.
10678 if (e_config->geometry_auto_move)
10686 if (bd->x + bd->w > zx + zw)
10687 bd->x = zx + zw - bd->w;
10689 if (bd->y + bd->h > zy + zh)
10690 bd->y = zy + zh - bd->h;
10693 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10695 bd->changes.pos = 1;
10701 bd->changes.pos = 1;
10707 /* FIXME: special placement for dialogs etc. etc. etc goes
10709 /* FIXME: what if parent is not on this desktop - or zone? */
10710 if ((bd->parent) && (bd->parent->visible))
10712 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10713 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10714 bd->changes.pos = 1;
10718 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10720 /* TODO: Place in center of group */
10723 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10725 bd->x = zx + ((zw - bd->w) / 2);
10726 bd->y = zy + ((zh - bd->h) / 2);
10727 bd->changes.pos = 1;
10733 Eina_List *skiplist = NULL;
10737 new_x = zx + (rand() % (zw - bd->w));
10741 new_y = zy + (rand() % (zh - bd->h));
10745 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10747 skiplist = eina_list_append(skiplist, bd);
10749 e_place_desk_region_smart(bd->desk, skiplist,
10750 bd->x, bd->y, bd->w, bd->h,
10753 e_place_zone_region_smart(bd->zone, skiplist,
10754 bd->x, bd->y, bd->w, bd->h,
10756 eina_list_free(skiplist);
10758 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10760 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10765 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10766 bd->client_inset.t, &new_x, &new_y);
10770 bd->changes.pos = 1;
10773 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10775 if ((!bd->lock_client_location) && (pnd->move))
10779 bd->changes.pos = 1;
10781 if (pnd->without_border)
10783 bd->x -= bd->client_inset.l;
10784 bd->y -= bd->client_inset.t;
10787 if ((!bd->lock_client_size) && (pnd->resize))
10789 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10790 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10791 bd->client.w = pnd->w;
10792 bd->client.h = pnd->h;
10793 bd->changes.size = 1;
10799 /* Recreate state */
10800 e_hints_window_init(bd);
10801 if ((bd->client.e.state.centered) &&
10802 ((!bd->remember) ||
10803 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10805 bd->x = zx + (zw - bd->w) / 2;
10806 bd->y = zy + (zh - bd->h) / 2;
10807 bd->changes.pos = 1;
10811 _e_border_client_move_resize_send(bd);
10813 /* if the explicit geometry request asks for the app to be
10814 * in another zone - well move it there */
10818 zone = e_container_zone_at_point_get(bd->zone->container,
10819 bd->x + (bd->w / 2),
10820 bd->y + (bd->h / 2));
10822 zone = e_container_zone_at_point_get(bd->zone->container,
10826 zone = e_container_zone_at_point_get(bd->zone->container,
10830 zone = e_container_zone_at_point_get(bd->zone->container,
10832 bd->y + bd->h - 1);
10834 zone = e_container_zone_at_point_get(bd->zone->container,
10836 bd->y + bd->h - 1);
10837 if ((zone) && (zone != bd->zone))
10838 e_border_zone_set(bd, zone);
10842 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10844 /* effect changes to the window border itself */
10845 if ((bd->changes.shading))
10847 /* show at start of unshade (but don't hide until end of shade) */
10849 ecore_x_window_raise(bd->client.shell_win);
10850 bd->changes.shading = 0;
10853 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
10856 ecore_x_window_lower(bd->client.shell_win);
10858 ecore_x_window_raise(bd->client.shell_win);
10859 bd->changes.shaded = 0;
10862 else if ((bd->changes.shaded) && (bd->changes.pos))
10865 ecore_x_window_lower(bd->client.shell_win);
10867 ecore_x_window_raise(bd->client.shell_win);
10868 bd->changes.size = 1;
10869 bd->changes.shaded = 0;
10872 else if ((bd->changes.shaded) && (bd->changes.size))
10875 ecore_x_window_lower(bd->client.shell_win);
10877 ecore_x_window_raise(bd->client.shell_win);
10878 bd->changes.shaded = 0;
10881 else if (bd->changes.shaded)
10884 ecore_x_window_lower(bd->client.shell_win);
10886 ecore_x_window_raise(bd->client.shell_win);
10887 bd->changes.size = 1;
10888 bd->changes.shaded = 0;
10892 if (bd->changes.size)
10894 int x = 0, y = 0, xx = 0, yy = 0;
10896 if ((bd->shaded) && (!bd->shading))
10898 evas_obscured_clear(bd->bg_evas);
10902 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
10903 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
10905 evas_obscured_clear(bd->bg_evas);
10906 evas_obscured_rectangle_add(bd->bg_evas,
10907 bd->client_inset.l, bd->client_inset.t, xx, yy);
10911 if (bd->shade.dir == E_DIRECTION_UP)
10913 y = yy - bd->client.h;
10915 else if (bd->shade.dir == E_DIRECTION_LEFT)
10917 x = xx - bd->client.w;
10922 if (bd->client.e.state.video)
10924 if (bd->client.e.state.video_position.updated)
10926 ecore_x_window_move(bd->win,
10927 bd->client.e.state.video_parent_border->x +
10928 bd->client.e.state.video_parent_border->client_inset.l +
10929 bd->client.e.state.video_parent_border->fx.x +
10930 bd->client.e.state.video_position.x,
10931 bd->client.e.state.video_parent_border->y +
10932 bd->client.e.state.video_parent_border->client_inset.t +
10933 bd->client.e.state.video_parent_border->fx.y +
10934 bd->client.e.state.video_position.y);
10935 bd->client.e.state.video_position.updated = 0;
10938 else if (!bd->changes.pos)
10940 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10941 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10942 bd->post_resize = 1;
10949 ecore_x_window_move_resize(bd->win,
10954 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
10955 ecore_x_window_move(tmp->win,
10956 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
10957 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
10960 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
10962 if ((!bd->shaded) || (bd->shading))
10963 ecore_x_window_move_resize(bd->client.shell_win,
10964 bd->client_inset.l, bd->client_inset.t, xx, yy);
10966 if (bd->internal_ecore_evas)
10967 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
10968 else if (!bd->client.e.state.video)
10969 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
10971 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
10972 evas_object_resize(bd->bg_object, bd->w, bd->h);
10973 e_container_shape_resize(bd->shape, bd->w, bd->h);
10974 if (bd->changes.pos)
10975 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10977 _e_border_client_move_resize_send(bd);
10979 bd->changes.pos = 0;
10980 bd->changes.size = 0;
10983 else if (bd->changes.pos)
10985 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10986 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10989 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10991 _e_border_client_move_resize_send(bd);
10993 bd->changes.pos = 0;
10997 if (bd->changes.reset_gravity)
10999 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11000 bd->changes.reset_gravity = 0;
11004 if (bd->need_shape_merge)
11006 _e_border_shape_input_rectangle_set(bd);
11007 if ((bd->shaped) || (bd->client.shaped))
11009 Ecore_X_Window twin, twin2;
11012 twin = ecore_x_window_override_new
11013 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11015 ecore_x_window_shape_window_set(twin, bd->bg_win);
11018 Ecore_X_Rectangle rects[4];
11022 rects[0].width = bd->w;
11023 rects[0].height = bd->client_inset.t;
11025 rects[1].y = bd->client_inset.t;
11026 rects[1].width = bd->client_inset.l;
11027 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11028 rects[2].x = bd->w - bd->client_inset.r;
11029 rects[2].y = bd->client_inset.t;
11030 rects[2].width = bd->client_inset.r;
11031 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11033 rects[3].y = bd->h - bd->client_inset.b;
11034 rects[3].width = bd->w;
11035 rects[3].height = bd->client_inset.b;
11036 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11038 twin2 = ecore_x_window_override_new
11039 (bd->zone->container->scratch_win, 0, 0,
11040 bd->w - bd->client_inset.l - bd->client_inset.r,
11041 bd->h - bd->client_inset.t - bd->client_inset.b);
11044 if ((bd->shading) || (bd->shaded))
11046 if (bd->shade.dir == E_DIRECTION_UP)
11047 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11048 else if (bd->shade.dir == E_DIRECTION_LEFT)
11049 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11051 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11053 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11054 bd->w - bd->client_inset.l - bd->client_inset.r,
11055 bd->h - bd->client_inset.t - bd->client_inset.b);
11056 ecore_x_window_shape_window_add_xy(twin, twin2,
11057 bd->client_inset.l,
11058 bd->client_inset.t);
11059 ecore_x_window_free(twin2);
11060 ecore_x_window_shape_window_set(bd->win, twin);
11061 ecore_x_window_free(twin);
11064 ecore_x_window_shape_mask_set(bd->win, 0);
11065 // bd->need_shape_export = 1;
11066 bd->need_shape_merge = 0;
11069 if (bd->need_shape_export)
11071 Ecore_X_Rectangle *rects, *orects;
11074 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11080 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11084 orects = bd->shape_rects;
11086 for (i = 0; i < num; i++)
11088 if (rects[i].x < 0)
11090 rects[i].width -= rects[i].x;
11093 if ((rects[i].x + (int)rects[i].width) > bd->w)
11094 rects[i].width = rects[i].width - rects[i].x;
11095 if (rects[i].y < 0)
11097 rects[i].height -= rects[i].y;
11100 if ((rects[i].y + (int)rects[i].height) > bd->h)
11101 rects[i].height = rects[i].height - rects[i].y;
11103 if ((orects[i].x != rects[i].x) ||
11104 (orects[i].y != rects[i].y) ||
11105 (orects[i].width != rects[i].width) ||
11106 (orects[i].height != rects[i].height))
11115 if (bd->client.shaped)
11116 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11118 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11119 E_FREE(bd->shape_rects);
11120 bd->shape_rects = rects;
11121 bd->shape_rects_num = num;
11122 e_container_shape_rects_set(bd->shape, rects, num);
11129 E_FREE(bd->shape_rects);
11130 bd->shape_rects = NULL;
11131 bd->shape_rects_num = 0;
11132 e_container_shape_rects_set(bd->shape, NULL, 0);
11134 bd->need_shape_export = 0;
11137 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11141 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11142 if ((!bd->placed) && (!bd->re_manage) &&
11143 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11144 (!((bd->client.icccm.transient_for != 0) ||
11145 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11146 (!bdmove) && (!bdresize))
11148 /* Set this window into moving state */
11150 bd->cur_mouse_action = e_action_find("window_move");
11151 if (bd->cur_mouse_action)
11153 if ((!bd->cur_mouse_action->func.end_mouse) &&
11154 (!bd->cur_mouse_action->func.end))
11155 bd->cur_mouse_action = NULL;
11156 if (bd->cur_mouse_action)
11158 bd->x = x - (bd->w >> 1);
11159 bd->y = y - (bd->client_inset.t >> 1);
11161 bd->changes.pos = 1;
11163 _e_border_client_move_resize_send(bd);
11168 _e_border_show(bd);
11170 if (bd->cur_mouse_action)
11172 bd->moveinfo.down.x = bd->x + bd->fx.x;
11173 bd->moveinfo.down.y = bd->y + bd->fx.y;
11174 bd->moveinfo.down.w = bd->w;
11175 bd->moveinfo.down.h = bd->h;
11176 bd->mouse.current.mx = x;
11177 bd->mouse.current.my = y;
11178 bd->moveinfo.down.button = 0;
11179 bd->moveinfo.down.mx = x;
11180 bd->moveinfo.down.my = y;
11183 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11184 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11185 if (e_config->border_raise_on_mouse_action)
11186 e_border_raise(bd);
11187 e_border_focus_set(bd, 1, 1);
11189 bd->changes.visible = 0;
11193 if (bd->changes.icon)
11197 efreet_desktop_free(bd->desktop);
11198 bd->desktop = NULL;
11200 if (bd->icon_object)
11202 evas_object_del(bd->icon_object);
11203 bd->icon_object = NULL;
11205 if (bd->remember && bd->remember->prop.desktop_file)
11207 const char *desktop = bd->remember->prop.desktop_file;
11209 bd->desktop = efreet_desktop_get(desktop);
11211 bd->desktop = efreet_util_desktop_name_find(desktop);
11215 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11216 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11217 bd->client.icccm.class);
11221 /* libreoffice and maybe others match window class
11222 with .desktop file name */
11223 if (bd->client.icccm.class)
11226 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11227 bd->desktop = efreet_util_desktop_file_id_find(buf);
11232 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11233 bd->client.netwm.pid);
11234 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11236 if (!bd->desktop && bd->client.icccm.name)
11238 /* this works for most cases as fallback. useful when app is
11239 run from a shell */
11240 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11242 if (!bd->desktop && bd->client.icccm.transient_for)
11244 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11245 if (bd2 && bd2->desktop)
11247 efreet_desktop_ref(bd2->desktop);
11248 bd->desktop = bd2->desktop;
11253 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11254 bd->desktop->orig_path);
11257 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11258 if ((bd->focused) && (bd->icon_object))
11259 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11262 evas_object_show(bd->icon_object);
11263 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11266 evas_object_hide(bd->icon_object);
11269 E_Event_Border_Icon_Change *ev;
11271 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11273 e_object_ref(E_OBJECT(bd));
11274 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11275 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11276 _e_border_event_border_icon_change_free, NULL);
11278 bd->changes.icon = 0;
11281 bd->new_client = 0;
11283 bd->changes.stack = 0;
11284 bd->changes.prop = 0;
11286 if ((bd->take_focus) || (bd->want_focus))
11288 bd->take_focus = 0;
11289 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11290 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11291 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11294 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11297 bd->want_focus = 0;
11298 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11299 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11300 _e_border_check_stack(bd);
11303 e_border_focus_set_with_pointer(bd);
11305 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11307 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11308 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11309 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11310 e_border_focused_get())))
11312 e_border_focus_set_with_pointer(bd);
11317 /* focus window by default when it is the only one on desk */
11318 E_Border *bd2 = NULL;
11320 EINA_LIST_FOREACH(focus_stack, l, bd2)
11322 if (bd == bd2) continue;
11323 if ((!bd2->iconic) && (bd2->visible) &&
11324 ((bd->desk == bd2->desk) || bd2->sticky))
11330 e_border_focus_set_with_pointer(bd);
11335 if (bd->need_maximize)
11338 max = bd->maximized;
11339 bd->maximized = E_MAXIMIZE_NONE;
11340 e_border_maximize(bd, max);
11341 bd->need_maximize = 0;
11344 if (bd->need_fullscreen)
11346 e_border_fullscreen(bd, e_config->fullscreen_policy);
11347 bd->need_fullscreen = 0;
11351 e_remember_update(bd);
11353 if (send_event) // FIXME: send only if a property changed - above need to
11354 { // check on that. for now - always send.
11355 event = E_NEW(E_Event_Border_Property, 1);
11356 event->border = bd;
11357 e_object_ref(E_OBJECT(bd));
11358 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11360 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11364 _e_border_moveinfo_gather(E_Border *bd,
11365 const char *source)
11367 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11368 else if (e_util_glob_match(source, "mouse,*,2"))
11369 bd->moveinfo.down.button = 2;
11370 else if (e_util_glob_match(source, "mouse,*,3"))
11371 bd->moveinfo.down.button = 3;
11372 else bd->moveinfo.down.button = 0;
11373 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11375 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11376 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11380 bd->moveinfo.down.mx = bd->mouse.current.mx;
11381 bd->moveinfo.down.my = bd->mouse.current.my;
11386 _e_border_resize_handle(E_Border *bd)
11389 int new_x, new_y, new_w, new_h;
11391 Eina_List *skiplist = NULL;
11398 if ((bd->resize_mode == RESIZE_TR) ||
11399 (bd->resize_mode == RESIZE_R) ||
11400 (bd->resize_mode == RESIZE_BR))
11402 if ((bd->moveinfo.down.button >= 1) &&
11403 (bd->moveinfo.down.button <= 3))
11404 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11405 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11407 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11409 else if ((bd->resize_mode == RESIZE_TL) ||
11410 (bd->resize_mode == RESIZE_L) ||
11411 (bd->resize_mode == RESIZE_BL))
11413 if ((bd->moveinfo.down.button >= 1) &&
11414 (bd->moveinfo.down.button <= 3))
11415 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11416 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11418 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11421 if ((bd->resize_mode == RESIZE_TL) ||
11422 (bd->resize_mode == RESIZE_T) ||
11423 (bd->resize_mode == RESIZE_TR))
11425 if ((bd->moveinfo.down.button >= 1) &&
11426 (bd->moveinfo.down.button <= 3))
11427 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11428 (bd->mouse.current.my - bd->moveinfo.down.my);
11430 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11432 else if ((bd->resize_mode == RESIZE_BL) ||
11433 (bd->resize_mode == RESIZE_B) ||
11434 (bd->resize_mode == RESIZE_BR))
11436 if ((bd->moveinfo.down.button >= 1) &&
11437 (bd->moveinfo.down.button <= 3))
11438 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11439 (bd->mouse.current.my - bd->moveinfo.down.my);
11441 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11447 if ((bd->resize_mode == RESIZE_TL) ||
11448 (bd->resize_mode == RESIZE_L) ||
11449 (bd->resize_mode == RESIZE_BL))
11451 if ((bd->resize_mode == RESIZE_TL) ||
11452 (bd->resize_mode == RESIZE_T) ||
11453 (bd->resize_mode == RESIZE_TR))
11456 skiplist = eina_list_append(skiplist, bd);
11457 e_resist_container_border_position(bd->zone->container, skiplist,
11458 bd->x, bd->y, bd->w, bd->h,
11460 &new_x, &new_y, &new_w, &new_h);
11461 eina_list_free(skiplist);
11465 e_border_resize_limit(bd, &new_w, &new_h);
11466 if ((bd->resize_mode == RESIZE_TL) ||
11467 (bd->resize_mode == RESIZE_L) ||
11468 (bd->resize_mode == RESIZE_BL))
11469 new_x += (w - new_w);
11470 if ((bd->resize_mode == RESIZE_TL) ||
11471 (bd->resize_mode == RESIZE_T) ||
11472 (bd->resize_mode == RESIZE_TR))
11473 new_y += (h - new_h);
11475 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11479 _e_border_shade_animator(void *data)
11481 E_Border *bd = data;
11483 double dur = bd->client.h / e_config->border_shade_speed;
11485 dt = ecore_loop_time_get() - bd->shade.start;
11488 if (val < 0.0) val = 0.0;
11489 else if (val > 1.0) val = 1.0;
11491 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11494 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11495 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11497 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11500 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11501 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11503 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11506 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11507 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11509 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11512 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11513 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11515 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11518 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11519 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11521 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11524 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11525 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11527 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11530 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11531 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11533 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11536 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11537 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11539 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11542 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11543 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11548 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11549 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11552 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11553 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11554 else if (bd->shade.val > .999)
11555 bd->shade.val = 1.0;
11557 if (bd->shade.dir == E_DIRECTION_UP)
11558 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11559 else if (bd->shade.dir == E_DIRECTION_DOWN)
11561 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11562 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11563 bd->changes.pos = 1;
11565 else if (bd->shade.dir == E_DIRECTION_LEFT)
11566 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11567 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11569 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11570 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11571 bd->changes.pos = 1;
11574 if ((bd->shaped) || (bd->client.shaped))
11576 bd->need_shape_merge = 1;
11577 bd->need_shape_export = 1;
11579 if (bd->shaped_input)
11581 bd->need_shape_merge = 1;
11583 bd->changes.size = 1;
11589 E_Event_Border_Resize *ev;
11592 bd->shaded = !(bd->shaded);
11593 bd->changes.size = 1;
11594 bd->changes.shaded = 1;
11595 bd->changes.shading = 1;
11597 bd->shade.anim = NULL;
11600 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11602 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11603 edje_object_message_signal_process(bd->bg_object);
11604 e_border_frame_recalc(bd);
11606 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11607 ev = E_NEW(E_Event_Border_Resize, 1);
11609 e_object_ref(E_OBJECT(bd));
11610 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11611 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11612 return ECORE_CALLBACK_CANCEL;
11614 return ECORE_CALLBACK_RENEW;
11618 _e_border_event_border_resize_free(void *data __UNUSED__,
11621 E_Event_Border_Resize *e;
11624 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11625 e_object_unref(E_OBJECT(e->border));
11630 _e_border_event_border_move_free(void *data __UNUSED__,
11633 E_Event_Border_Move *e;
11636 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11637 e_object_unref(E_OBJECT(e->border));
11642 _e_border_event_border_add_free(void *data __UNUSED__,
11645 E_Event_Border_Add *e;
11648 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11649 e_object_unref(E_OBJECT(e->border));
11654 _e_border_event_border_remove_free(void *data __UNUSED__,
11657 E_Event_Border_Remove *e;
11660 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11661 e_object_unref(E_OBJECT(e->border));
11666 _e_border_event_border_show_free(void *data __UNUSED__,
11669 E_Event_Border_Show *e;
11672 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11673 e_object_unref(E_OBJECT(e->border));
11678 _e_border_event_border_hide_free(void *data __UNUSED__,
11681 E_Event_Border_Hide *e;
11684 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11685 e_object_unref(E_OBJECT(e->border));
11690 _e_border_event_border_iconify_free(void *data __UNUSED__,
11693 E_Event_Border_Iconify *e;
11696 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11697 e_object_unref(E_OBJECT(e->border));
11702 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11705 E_Event_Border_Uniconify *e;
11708 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11709 e_object_unref(E_OBJECT(e->border));
11714 _e_border_event_border_stick_free(void *data __UNUSED__,
11717 E_Event_Border_Stick *e;
11720 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11721 e_object_unref(E_OBJECT(e->border));
11726 _e_border_event_border_unstick_free(void *data __UNUSED__,
11729 E_Event_Border_Unstick *e;
11732 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11733 e_object_unref(E_OBJECT(e->border));
11738 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11741 E_Event_Border_Zone_Set *e;
11744 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11745 e_object_unref(E_OBJECT(e->border));
11746 e_object_unref(E_OBJECT(e->zone));
11751 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11754 E_Event_Border_Desk_Set *e;
11757 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11758 e_object_unref(E_OBJECT(e->border));
11759 e_object_unref(E_OBJECT(e->desk));
11764 _e_border_event_border_stack_free(void *data __UNUSED__,
11767 E_Event_Border_Stack *e;
11770 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11771 e_object_unref(E_OBJECT(e->border));
11774 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11775 e_object_unref(E_OBJECT(e->stack));
11781 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11784 E_Event_Border_Icon_Change *e;
11787 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11788 e_object_unref(E_OBJECT(e->border));
11793 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11796 E_Event_Border_Urgent_Change *e;
11799 e_object_unref(E_OBJECT(e->border));
11804 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11807 E_Event_Border_Focus_In *e;
11810 e_object_unref(E_OBJECT(e->border));
11815 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11818 E_Event_Border_Focus_Out *e;
11821 e_object_unref(E_OBJECT(e->border));
11826 _e_border_event_border_property_free(void *data __UNUSED__,
11829 E_Event_Border_Property *e;
11832 e_object_unref(E_OBJECT(e->border));
11837 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11840 E_Event_Border_Fullscreen *e;
11843 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11844 e_object_unref(E_OBJECT(e->border));
11849 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
11852 E_Event_Border_Unfullscreen *e;
11855 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
11856 e_object_unref(E_OBJECT(e->border));
11860 #ifdef _F_ZONE_WINDOW_ROTATION_
11862 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
11865 E_Event_Border_Rotation_Change_Begin *e;
11867 e_object_unref(E_OBJECT(e->border));
11872 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
11875 E_Event_Border_Rotation_Change_Cancel *e;
11877 e_object_unref(E_OBJECT(e->border));
11882 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
11885 E_Event_Border_Rotation_Change_End *e;
11887 e_object_unref(E_OBJECT(e->border));
11892 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
11894 E_Event_Border_Rotation_Change_Begin *ev = NULL;
11895 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
11899 e_object_ref(E_OBJECT(bd));
11900 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
11902 _e_border_event_border_rotation_change_begin_free,
11909 _e_border_zone_update(E_Border *bd)
11915 /* still within old zone - leave it there */
11916 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11917 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
11918 #if _F_BORDER_CLIP_TO_ZONE_
11920 _e_border_shape_input_clip_to_zone(bd);
11925 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11926 /* find a new zone */
11927 con = bd->zone->container;
11928 EINA_LIST_FOREACH(con->zones, l, zone)
11930 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11931 zone->x, zone->y, zone->w, zone->h))
11933 e_border_zone_set(bd, zone);
11934 #if _F_BORDER_CLIP_TO_ZONE_
11935 _e_border_shape_input_clip_to_zone(bd);
11936 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11943 _e_border_resize_begin(E_Border *bd)
11945 if (!bd->lock_user_stacking)
11947 if (e_config->border_raise_on_mouse_action)
11948 e_border_raise(bd);
11950 if ((bd->shaded) || (bd->shading) ||
11951 (bd->fullscreen) || (bd->lock_user_size))
11954 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11960 if (bd->client.netwm.sync.request)
11962 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11963 bd->client.netwm.sync.serial = 1;
11964 bd->client.netwm.sync.wait = 0;
11965 bd->client.netwm.sync.send_time = ecore_loop_time_get();
11968 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
11975 _e_border_resize_end(E_Border *bd)
11979 e_grabinput_release(bd->win, bd->win);
11982 if (bd->client.netwm.sync.alarm)
11984 E_Border_Pending_Move_Resize *pnd;
11986 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11987 bd->client.netwm.sync.alarm = 0;
11988 /* resize to last geometry if sync alarm for it was not yet handled */
11989 if (bd->pending_move_resize)
11992 bd->changes.pos = 1;
11993 bd->changes.size = 1;
11994 _e_border_client_move_resize_send(bd);
11997 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12001 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12005 /* If this border was maximized, we need to unset Maximized state or
12006 * on restart, E still thinks it's maximized */
12007 if (bd->maximized != E_MAXIMIZE_NONE)
12008 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12009 bd->maximized & E_MAXIMIZE_NONE);
12014 _e_border_resize_update(E_Border *bd)
12016 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12020 _e_border_move_begin(E_Border *bd)
12022 if (!bd->lock_user_stacking)
12024 if (e_config->border_raise_on_mouse_action)
12025 e_border_raise(bd);
12027 if ((bd->fullscreen) || (bd->lock_user_location))
12030 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
12036 if (bd->client.netwm.sync.request)
12038 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12039 bd->client.netwm.sync.serial = 0;
12040 bd->client.netwm.sync.wait = 0;
12041 bd->client.netwm.sync.time = ecore_loop_time_get();
12044 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12051 _e_border_move_end(E_Border *bd)
12055 e_grabinput_release(bd->win, bd->win);
12059 if (bd->client.netwm.sync.alarm)
12061 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12062 bd->client.netwm.sync.alarm = 0;
12065 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12072 _e_border_move_update(E_Border *bd)
12074 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12078 _e_border_cb_ping_poller(void *data)
12088 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12089 if (bd->kill_timer)
12091 ecore_timer_del(bd->kill_timer);
12092 bd->kill_timer = NULL;
12098 /* if time between last ping and now is greater
12099 * than half the ping interval... */
12100 if ((ecore_loop_time_get() - bd->ping) >
12101 ((e_config->ping_clients_interval *
12102 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12107 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12108 /* FIXME: if below dialog is up - hide it now */
12110 if (bd->delete_requested)
12112 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12113 e_border_act_kill_begin(bd);
12117 bd->ping_poller = NULL;
12119 return ECORE_CALLBACK_CANCEL;
12123 _e_border_cb_kill_timer(void *data)
12128 // dont wait until it's hung -
12131 if (bd->client.netwm.pid > 1)
12132 kill(bd->client.netwm.pid, SIGKILL);
12134 bd->kill_timer = NULL;
12135 return ECORE_CALLBACK_CANCEL;
12139 _e_border_pointer_resize_begin(E_Border *bd)
12141 switch (bd->resize_mode)
12144 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12148 e_pointer_type_push(bd->pointer, bd, "resize_t");
12152 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12156 e_pointer_type_push(bd->pointer, bd, "resize_r");
12160 e_pointer_type_push(bd->pointer, bd, "resize_br");
12164 e_pointer_type_push(bd->pointer, bd, "resize_b");
12168 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12172 e_pointer_type_push(bd->pointer, bd, "resize_l");
12178 _e_border_pointer_resize_end(E_Border *bd)
12180 switch (bd->resize_mode)
12183 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12187 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12191 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12195 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12199 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12203 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12207 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12211 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12217 _e_border_pointer_move_begin(E_Border *bd)
12219 e_pointer_type_push(bd->pointer, bd, "move");
12223 _e_border_pointer_move_end(E_Border *bd)
12225 e_pointer_type_pop(bd->pointer, bd, "move");
12228 static Eina_List *_e_border_hooks = NULL;
12229 static int _e_border_hooks_delete = 0;
12230 static int _e_border_hooks_walking = 0;
12233 _e_border_hooks_clean(void)
12238 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12242 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12249 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12255 _e_border_hooks_walking++;
12256 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12258 if (bh->delete_me) continue;
12259 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12261 _e_border_hooks_walking--;
12262 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12263 _e_border_hooks_clean();
12266 EAPI E_Border_Hook *
12267 e_border_hook_add(E_Border_Hook_Point hookpoint,
12268 void (*func)(void *data,
12274 bh = E_NEW(E_Border_Hook, 1);
12275 if (!bh) return NULL;
12276 bh->hookpoint = hookpoint;
12279 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12284 e_border_hook_del(E_Border_Hook *bh)
12287 if (_e_border_hooks_walking == 0)
12289 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12293 _e_border_hooks_delete++;
12297 e_border_focus_track_freeze(void)
12299 focus_track_frozen++;
12303 e_border_focus_track_thaw(void)
12305 focus_track_frozen--;
12309 e_border_under_pointer_get(E_Desk *desk,
12312 E_Border *bd = NULL, *cbd;
12316 /* We need to ensure that we can get the container window for the
12317 * zone of either the given desk or the desk of the excluded
12318 * window, so return if neither is given */
12320 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12322 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12326 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12328 if (!cbd) continue;
12329 /* If a border was specified which should be excluded from the list
12330 * (because it will be closed shortly for example), skip */
12331 if ((exclude) && (cbd == exclude)) continue;
12332 if ((desk) && (cbd->desk != desk)) continue;
12333 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12335 /* If the layer is higher, the position of the window is higher
12336 * (always on top vs always below) */
12337 if (!bd || (cbd->layer > bd->layer))
12347 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12354 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12355 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12356 (y - warp_y) > 5 || (y - warp_y) < -5)
12358 /* User moved the mouse, so stop warping */
12363 /* We just use the same warp speed as configured
12364 * for the windowlist */
12365 spd = e_config->winlist_warp_speed;
12368 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12369 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12370 if (warp_x == x && warp_y == y)
12372 warp_x = warp_to_x;
12373 warp_y = warp_to_y;
12377 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12378 return ECORE_CALLBACK_RENEW;
12381 ecore_timer_del(warp_timer);
12383 return ECORE_CALLBACK_CANCEL;
12387 e_border_pointer_warp_to_center(E_Border *bd)
12391 /* Do not slide pointer when disabled (probably breaks focus
12392 * on sloppy/mouse focus but requested by users). */
12393 if (!e_config->pointer_slide) return 0;
12394 /* Only warp the pointer if it is not already in the area of
12395 * the given border */
12396 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12397 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12398 (y >= bd->y) && (y <= (bd->y + bd->h)))
12401 warp_to_x = bd->x + (bd->w / 2);
12402 if (warp_to_x < (bd->zone->x + 1))
12403 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12404 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12405 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12407 warp_to_y = bd->y + (bd->h / 2);
12408 if (warp_to_y < (bd->zone->y + 1))
12409 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12410 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12411 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12414 warp_to_win = bd->zone->container->win;
12415 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12417 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12422 e_border_comp_hidden_set(E_Border *bd,
12428 E_OBJECT_CHECK(bd);
12429 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12431 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12434 ecore_x_window_hide(tmp->win);
12436 ecore_x_window_show(tmp->win);
12439 if (bd->comp_hidden == hidden) return;
12441 bd->comp_hidden = hidden;
12443 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12445 ecore_x_composite_window_events_disable(bd->win);
12446 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12450 _e_border_shape_input_rectangle_set(bd);
12451 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12456 e_border_tmp_input_hidden_push(E_Border *bd)
12461 E_OBJECT_CHECK(bd);
12462 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12464 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12465 e_border_tmp_input_hidden_push(tmp);
12467 bd->tmp_input_hidden++;
12468 if (bd->tmp_input_hidden != 1) return;
12470 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12472 ecore_x_composite_window_events_disable(bd->win);
12473 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12477 _e_border_shape_input_rectangle_set(bd);
12478 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12483 e_border_tmp_input_hidden_pop(E_Border *bd)
12488 E_OBJECT_CHECK(bd);
12489 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12491 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12492 e_border_tmp_input_hidden_pop(tmp);
12494 bd->tmp_input_hidden--;
12495 if (bd->tmp_input_hidden != 0) return;
12497 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12499 ecore_x_composite_window_events_disable(bd->win);
12500 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12504 _e_border_shape_input_rectangle_set(bd);
12505 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12510 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12512 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12514 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12515 ((bd->parent->focused) &&
12516 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12521 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12522 e_desk_show(bd->desk);
12524 if (!bd->lock_user_iconify)
12525 e_border_uniconify(bd);
12527 if ((!bd->iconic) && (!bd->sticky))
12528 e_desk_show(bd->desk);
12529 if (!bd->lock_user_stacking) e_border_raise(bd);
12530 if (!bd->lock_focus_out)
12532 /* XXX ooffice does send this request for
12533 config dialogs when the main window gets focus.
12534 causing the pointer to jump back and forth. */
12535 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12536 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12537 ecore_x_pointer_warp(bd->zone->container->win,
12538 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12539 e_border_focus_set(bd, 1, 1);
12543 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/