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(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_zone_prediction_check(E_Zone *zone);
174 static Eina_Bool _e_border_rotation_vkbd_transient_for_check(E_Border *bd);
175 static Eina_Bool _e_border_rotation_transient_for_check(E_Border *bd, int ang);
176 static Eina_Bool _e_border_cb_window_configure(void *data,
179 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
180 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
181 static void _e_border_vkbd_show(E_Border *bd);
182 static void _e_border_vkbd_hide(E_Border *bd);
184 static void _e_border_move_resize_internal(E_Border *bd,
189 Eina_Bool without_border,
192 static void _e_border_eval(E_Border *bd);
193 static void _e_border_eval0(E_Border *bd);
194 static void _e_border_container_layout_hook(E_Container *con);
196 static void _e_border_moveinfo_gather(E_Border *bd,
198 static void _e_border_resize_handle(E_Border *bd);
200 static Eina_Bool _e_border_shade_animator(void *data);
202 static void _e_border_event_border_add_free(void *data,
204 static void _e_border_event_border_remove_free(void *data,
206 static void _e_border_event_border_zone_set_free(void *data,
208 static void _e_border_event_border_desk_set_free(void *data,
210 static void _e_border_event_border_stack_free(void *data,
212 static void _e_border_event_border_icon_change_free(void *data,
214 static void _e_border_event_border_urgent_change_free(void *data,
216 static void _e_border_event_border_focus_in_free(void *data,
218 static void _e_border_event_border_focus_out_free(void *data,
220 static void _e_border_event_border_resize_free(void *data,
222 static void _e_border_event_border_move_free(void *data,
224 static void _e_border_event_border_show_free(void *data,
226 static void _e_border_event_border_hide_free(void *data,
228 static void _e_border_event_border_iconify_free(void *data,
230 static void _e_border_event_border_uniconify_free(void *data,
232 static void _e_border_event_border_stick_free(void *data,
234 static void _e_border_event_border_unstick_free(void *data,
236 static void _e_border_event_border_property_free(void *data,
238 static void _e_border_event_border_fullscreen_free(void *data,
240 static void _e_border_event_border_unfullscreen_free(void *data,
242 #ifdef _F_ZONE_WINDOW_ROTATION_
243 static void _e_border_event_border_rotation_free(void *data,
247 static void _e_border_zone_update(E_Border *bd);
249 static int _e_border_resize_begin(E_Border *bd);
250 static int _e_border_resize_end(E_Border *bd);
251 static void _e_border_resize_update(E_Border *bd);
253 static int _e_border_move_begin(E_Border *bd);
254 static int _e_border_move_end(E_Border *bd);
255 static void _e_border_move_update(E_Border *bd);
257 static Eina_Bool _e_border_cb_ping_poller(void *data);
258 static Eina_Bool _e_border_cb_kill_timer(void *data);
260 static void _e_border_pointer_resize_begin(E_Border *bd);
261 static void _e_border_pointer_resize_end(E_Border *bd);
262 static void _e_border_pointer_move_begin(E_Border *bd);
263 static void _e_border_pointer_move_end(E_Border *bd);
265 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
268 static void _e_border_client_move_resize_send(E_Border *bd);
270 static void _e_border_frame_replace(E_Border *bd,
273 static void _e_border_shape_input_rectangle_set(E_Border* bd);
274 static void _e_border_show(E_Border *bd);
275 static void _e_border_hide(E_Border *bd);
278 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
279 static void _e_border_latest_stacked_focus (E_Border* bd);
280 static void _e_border_check_stack (E_Border *bd);
281 static void _e_border_focus_top_stack_set (E_Border* bd);
283 #if _F_BORDER_CLIP_TO_ZONE_
284 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
285 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
286 /* local subsystem globals */
287 static Eina_List *handlers = NULL;
288 static Eina_List *borders = NULL;
289 static Eina_Hash *borders_hash = NULL;
290 static E_Border *focused = NULL;
291 static E_Border *focusing = NULL;
292 static Eina_List *focus_next = NULL;
293 static Ecore_X_Time focus_time = 0;
295 static E_Border *bdresize = NULL;
296 static E_Border *bdmove = NULL;
297 static E_Drag *drag_border = NULL;
299 static int grabbed = 0;
301 static Eina_List *focus_stack = NULL;
302 static Eina_List *raise_stack = NULL;
304 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
305 static int screen_size_index = -1;
307 static int focus_track_frozen = 0;
309 static int warp_to = 0;
310 static int warp_to_x = 0;
311 static int warp_to_y = 0;
312 static int warp_x = 0;
313 static int warp_y = 0;
314 static Ecore_X_Window warp_to_win;
315 static Ecore_Timer *warp_timer = NULL;
317 #ifdef _F_ZONE_WINDOW_ROTATION_
318 typedef struct _E_Border_Rotation E_Border_Rotation;
319 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
321 struct _E_Border_Rotation
325 Eina_Bool wait_prepare_done;
326 Ecore_Timer *prepare_timer;
327 Ecore_Timer *done_timer;
329 Ecore_X_Window vkbd_ctrl_win;
331 E_Border *vkbd_prediction;
333 /* vkbd show/hide preprare */
334 Eina_Bool vkbd_show_prepare_done;
335 Ecore_Timer *vkbd_show_prepare_timer;
336 Ecore_Timer *vkbd_show_timer;
338 Eina_Bool vkbd_hide_prepare_done;
339 Ecore_Timer *vkbd_hide_prepare_timer;
340 Ecore_Timer *vkbd_hide_timer;
346 struct _E_Border_Rotation_Info
351 Eina_Bool win_resize;
354 static E_Border_Rotation rot =
374 EAPI int E_EVENT_BORDER_ADD = 0;
375 EAPI int E_EVENT_BORDER_REMOVE = 0;
376 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
377 EAPI int E_EVENT_BORDER_DESK_SET = 0;
378 EAPI int E_EVENT_BORDER_RESIZE = 0;
379 EAPI int E_EVENT_BORDER_MOVE = 0;
380 EAPI int E_EVENT_BORDER_SHOW = 0;
381 EAPI int E_EVENT_BORDER_HIDE = 0;
382 EAPI int E_EVENT_BORDER_ICONIFY = 0;
383 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
384 EAPI int E_EVENT_BORDER_STICK = 0;
385 EAPI int E_EVENT_BORDER_UNSTICK = 0;
386 EAPI int E_EVENT_BORDER_STACK = 0;
387 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
388 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
389 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
390 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
391 EAPI int E_EVENT_BORDER_PROPERTY = 0;
392 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
393 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
394 #ifdef _F_ZONE_WINDOW_ROTATION_
395 EAPI int E_EVENT_BORDER_ROTATION = 0;
398 #define GRAV_SET(bd, grav) \
399 ecore_x_window_gravity_set(bd->bg_win, grav); \
400 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
401 ecore_x_window_gravity_set(bd->client.win, grav);
404 _e_border_sub_borders_new(E_Border *bd)
406 Eina_List *list = NULL, *l;
410 EINA_LIST_FOREACH(bd->transients, l, child)
412 if (!eina_list_data_find(list, child))
413 list = eina_list_append(list, child);
415 bl = e_container_border_list_first(bd->zone->container);
416 while ((child = e_container_border_list_next(bl)))
418 if (e_object_is_del(E_OBJECT(child))) continue;
419 if (child == bd) continue;
421 if ((bd->client.icccm.client_leader) &&
422 (child->client.icccm.client_leader ==
423 bd->client.icccm.client_leader))
425 printf("bd %s in group with %s\n",
426 e_border_name_get(child),
427 e_border_name_get(bd));
428 if (!eina_list_data_find(list, child))
429 list = eina_list_append(list, child);
433 e_container_border_list_free(bl);
437 /* externally accessible functions */
441 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
442 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
443 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
444 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
445 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
446 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
447 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
448 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
449 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
450 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
451 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
452 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
453 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
454 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
459 #ifdef _F_ZONE_WINDOW_ROTATION_
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
463 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
465 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
469 #ifdef _F_USE_DESK_WINDOW_PROFILE_
470 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
472 #ifdef _F_ZONE_WINDOW_ROTATION_
473 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE, _e_border_cb_zone_rotation_change, NULL));
476 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
478 E_EVENT_BORDER_ADD = ecore_event_type_new();
479 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
480 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
481 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
482 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
483 E_EVENT_BORDER_MOVE = ecore_event_type_new();
484 E_EVENT_BORDER_SHOW = ecore_event_type_new();
485 E_EVENT_BORDER_HIDE = ecore_event_type_new();
486 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
487 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
488 E_EVENT_BORDER_STICK = ecore_event_type_new();
489 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
490 E_EVENT_BORDER_STACK = ecore_event_type_new();
491 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
492 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
493 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
494 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
495 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
496 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
497 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
498 #ifdef _F_ZONE_WINDOW_ROTATION_
499 E_EVENT_BORDER_ROTATION = ecore_event_type_new();
508 e_border_shutdown(void)
510 E_FREE_LIST(handlers, ecore_event_handler_del);
512 if (borders_hash) eina_hash_free(borders_hash);
514 e_int_border_menu_hooks_clear();
520 e_border_new(E_Container *con,
526 Ecore_X_Window_Attributes *att;
527 unsigned int managed, desk[2];
530 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
531 if (!bd) return NULL;
532 ecore_x_window_shadow_tree_flush();
533 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
537 /* FIXME: ewww - round trip */
538 bd->client.argb = ecore_x_window_argb_get(win);
540 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
543 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
544 ecore_x_window_shape_events_select(bd->win, 1);
546 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
547 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
549 bd->bg_ecore_evas = e_canvas_new(bd->win,
550 0, 0, bd->w, bd->h, 1, 0,
552 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
553 e_canvas_add(bd->bg_ecore_evas);
554 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
555 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
556 ecore_x_window_shape_events_select(bd->bg_win, 1);
557 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
558 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
560 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
562 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
563 ecore_x_window_container_manage(bd->client.shell_win);
564 if (!internal) ecore_x_window_client_manage(win);
565 /* FIXME: Round trip. XCB */
566 /* fetch needed to avoid grabbing the server as window may vanish */
567 att = &bd->client.initial_attributes;
568 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
570 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
571 e_canvas_del(bd->bg_ecore_evas);
572 ecore_evas_free(bd->bg_ecore_evas);
573 ecore_x_window_free(bd->client.shell_win);
574 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
575 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
576 ecore_x_window_free(bd->win);
581 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
582 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
584 /* FIXME: if first_map is 1 then we should ignore the first hide event
585 * or ensure the window is already hidden and events flushed before we
586 * create a border for it */
589 // printf("##- FIRST MAP\n");
594 // needed to be 1 for internal windw and on restart.
595 // bd->ignore_first_unmap = 2;
598 bd->client.win = win;
599 bd->zone = e_zone_current_get(con);
601 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
603 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
604 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
605 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
606 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
607 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
608 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
610 bd->client.icccm.title = NULL;
611 bd->client.icccm.name = NULL;
612 bd->client.icccm.class = NULL;
613 bd->client.icccm.icon_name = NULL;
614 bd->client.icccm.machine = NULL;
615 bd->client.icccm.min_w = 1;
616 bd->client.icccm.min_h = 1;
617 bd->client.icccm.max_w = 32767;
618 bd->client.icccm.max_h = 32767;
619 bd->client.icccm.base_w = 0;
620 bd->client.icccm.base_h = 0;
621 bd->client.icccm.step_w = -1;
622 bd->client.icccm.step_h = -1;
623 bd->client.icccm.min_aspect = 0.0;
624 bd->client.icccm.max_aspect = 0.0;
625 bd->client.icccm.accepts_focus = 1;
627 bd->client.netwm.pid = 0;
628 bd->client.netwm.name = NULL;
629 bd->client.netwm.icon_name = NULL;
630 bd->client.netwm.desktop = 0;
631 bd->client.netwm.state.modal = 0;
632 bd->client.netwm.state.sticky = 0;
633 bd->client.netwm.state.shaded = 0;
634 bd->client.netwm.state.hidden = 0;
635 bd->client.netwm.state.maximized_v = 0;
636 bd->client.netwm.state.maximized_h = 0;
637 bd->client.netwm.state.skip_taskbar = 0;
638 bd->client.netwm.state.skip_pager = 0;
639 bd->client.netwm.state.fullscreen = 0;
640 bd->client.netwm.state.stacking = E_STACKING_NONE;
641 bd->client.netwm.action.move = 0;
642 bd->client.netwm.action.resize = 0;
643 bd->client.netwm.action.minimize = 0;
644 bd->client.netwm.action.shade = 0;
645 bd->client.netwm.action.stick = 0;
646 bd->client.netwm.action.maximized_h = 0;
647 bd->client.netwm.action.maximized_v = 0;
648 bd->client.netwm.action.fullscreen = 0;
649 bd->client.netwm.action.change_desktop = 0;
650 bd->client.netwm.action.close = 0;
651 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
657 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
658 bd->client.icccm.fetch.command = 1;
661 Eina_Bool video_parent = EINA_FALSE;
662 Eina_Bool video_position = EINA_FALSE;
665 for (i = 0; i < at_num; i++)
667 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
668 bd->client.icccm.fetch.title = 1;
669 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
670 bd->client.icccm.fetch.name_class = 1;
671 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
672 bd->client.icccm.fetch.icon_name = 1;
673 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
674 bd->client.icccm.fetch.machine = 1;
675 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
676 bd->client.icccm.fetch.hints = 1;
677 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
678 bd->client.icccm.fetch.size_pos_hints = 1;
679 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
680 bd->client.icccm.fetch.protocol = 1;
681 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
682 bd->client.mwm.fetch.hints = 1;
683 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
685 bd->client.icccm.fetch.transient_for = 1;
686 bd->client.netwm.fetch.type = 1;
688 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
689 bd->client.icccm.fetch.client_leader = 1;
690 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
691 bd->client.icccm.fetch.window_role = 1;
692 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
693 bd->client.icccm.fetch.state = 1;
695 /* netwm, loop again, netwm will ignore some icccm, so we
696 * have to be sure that netwm is checked after */
697 for (i = 0; i < at_num; i++)
699 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
702 bd->client.icccm.fetch.title = 0;
703 bd->client.netwm.fetch.name = 1;
705 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
708 bd->client.icccm.fetch.icon_name = 0;
709 bd->client.netwm.fetch.icon_name = 1;
711 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
713 bd->client.netwm.fetch.icon = 1;
715 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
717 bd->client.netwm.fetch.user_time = 1;
719 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
721 DBG("ECORE_X_ATOM_NET_WM_STRUT");
722 bd->client.netwm.fetch.strut = 1;
724 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
726 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
727 bd->client.netwm.fetch.strut = 1;
729 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
732 bd->client.mwm.fetch.hints = 0;
734 bd->client.netwm.fetch.type = 1;
736 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
738 bd->client.netwm.fetch.state = 1;
741 /* other misc atoms */
742 for (i = 0; i < at_num; i++)
744 /* loop to check for own atoms */
745 if (atoms[i] == E_ATOM_WINDOW_STATE)
747 bd->client.e.fetch.state = 1;
749 /* loop to check for qtopia atoms */
750 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
751 bd->client.qtopia.fetch.soft_menu = 1;
752 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
753 bd->client.qtopia.fetch.soft_menus = 1;
754 /* loop to check for vkbd atoms */
755 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
756 bd->client.vkbd.fetch.state = 1;
757 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
758 bd->client.vkbd.fetch.vkbd = 1;
759 /* loop to check for illume atoms */
760 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
761 bd->client.illume.conformant.fetch.conformant = 1;
762 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
763 bd->client.illume.quickpanel.fetch.state = 1;
764 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
765 bd->client.illume.quickpanel.fetch.quickpanel = 1;
766 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
767 bd->client.illume.quickpanel.fetch.priority.major = 1;
768 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
769 bd->client.illume.quickpanel.fetch.priority.minor = 1;
770 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
771 bd->client.illume.quickpanel.fetch.zone = 1;
772 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
773 bd->client.illume.drag.fetch.locked = 1;
774 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
775 bd->client.illume.drag.fetch.drag = 1;
776 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
777 bd->client.illume.win_state.fetch.state = 1;
778 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
779 video_parent = EINA_TRUE;
780 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
781 video_position = EINA_TRUE;
782 #ifdef _F_USE_DESK_WINDOW_PROFILE_
783 /* loop to check for window profile list atom */
784 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
785 bd->client.e.fetch.profile_list = 1;
787 #ifdef _F_ZONE_WINDOW_ROTATION_
788 /* loop to check for wm rotation */
789 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
791 if (e_config->wm_win_rotation)
792 bd->client.e.fetch.rot.support = 1;
794 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
795 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
796 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
797 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
799 if (e_config->wm_win_rotation)
800 bd->client.e.fetch.rot.geom_hint = 1;
802 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
804 if (e_config->wm_win_rotation)
805 bd->client.e.fetch.rot.app_set = 1;
807 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
809 if (e_config->wm_win_rotation)
810 bd->client.e.fetch.rot.preferred_rot = 1;
812 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
814 if (e_config->wm_win_rotation)
815 bd->client.e.fetch.rot.available_rots = 1;
818 #ifdef _F_DEICONIFY_APPROVE_
819 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
821 bd->client.e.state.deiconify_approve.support = 1;
825 if (video_position && video_parent)
827 bd->client.e.state.video = 1;
828 bd->client.e.fetch.video_parent = 1;
829 bd->client.e.fetch.video_position = 1;
830 ecore_x_window_lower(bd->win);
831 ecore_x_composite_window_events_disable(bd->win);
832 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
833 fprintf(stderr, "We found a video window \\o/ %x\n", win);
838 bd->client.border.changed = 1;
840 bd->client.w = att->w;
841 bd->client.h = att->h;
843 bd->w = bd->client.w;
844 bd->h = bd->client.h;
846 bd->resize_mode = RESIZE_NONE;
848 bd->saved.layer = bd->layer;
849 bd->changes.icon = 1;
850 bd->changes.size = 1;
851 bd->changes.shape = 1;
852 bd->changes.shape_input = 1;
854 bd->offer_resistance = 1;
856 /* just to friggin make java happy - we're DELAYING the reparent until
859 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
860 bd->need_reparent = 1;
862 ecore_x_window_border_width_set(win, 0);
863 ecore_x_window_show(bd->event_win);
864 ecore_x_window_show(bd->client.shell_win);
865 bd->shape = e_container_shape_add(con);
870 #ifdef _F_ZONE_WINDOW_ROTATION_
871 bd->client.e.state.rot.preferred_rot = -1;
874 // bd->zone = e_zone_current_get(con);
875 bd->desk = e_desk_current_get(bd->zone);
876 e_container_border_add(bd);
877 borders = eina_list_append(borders, bd);
878 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
882 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
883 "optimisations failing due to bizarre client behavior. will\n"
885 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
886 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
889 ELBF(ELBT_BD, 0, bd->client.win,
890 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
891 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
893 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
894 printf("optimisations failing due to bizarre client behavior. will\n");
895 printf("work around.\n");
896 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
897 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
900 ELBF(ELBT_BD, 0, bd->client.win,
901 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
902 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
905 #ifdef _F_ZONE_WINDOW_ROTATION_
906 if ((rot.vkbd) && (rot.vkbd == bd2))
908 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
909 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
910 rot.vkbd_hide_prepare_done);
912 if (rot.vkbd_hide_prepare_timer)
914 ecore_timer_del(rot.vkbd_hide_prepare_timer);
915 rot.vkbd_hide_prepare_timer = NULL;
917 e_object_unref(E_OBJECT(bd2));
920 _e_border_vkbd_hide(rot.vkbd);
922 if (rot.vkbd_ctrl_win)
924 ELB(ELBT_BD, "SET KBD_OFF", 0);
925 ecore_x_e_virtual_keyboard_state_set
926 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
928 rot.vkbd_hide_prepare_done = EINA_FALSE;
930 if (rot.vkbd_hide_timer)
931 ecore_timer_del(rot.vkbd_hide_timer);
932 rot.vkbd_hide_timer = NULL;
934 rot.vkbd_show_prepare_done = EINA_FALSE;
935 if (rot.vkbd_show_prepare_timer)
936 ecore_timer_del(rot.vkbd_show_prepare_timer);
937 rot.vkbd_show_prepare_timer = NULL;
938 if (rot.vkbd_show_timer)
939 ecore_timer_del(rot.vkbd_show_timer);
940 rot.vkbd_show_timer = NULL;
945 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
946 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
947 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
949 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
950 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
951 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
953 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
954 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
955 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
957 unsigned int zgeom[4];
959 zgeom[0] = bd->zone->x;
960 zgeom[1] = bd->zone->y;
961 zgeom[2] = bd->zone->w;
962 zgeom[3] = bd->zone->h;
963 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
965 e_desk_xy_get(bd->desk, &deskx, &desky);
968 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
969 #ifdef _F_USE_DESK_WINDOW_PROFILE_
970 if (strcmp(bd->desk->window_profile,
971 e_config->desktop_default_window_profile) != 0)
973 ecore_x_e_window_profile_set(bd->client.win,
974 bd->desk->window_profile);
978 focus_stack = eina_list_append(focus_stack, bd);
980 bd->pointer = e_pointer_window_new(bd->win, 0);
985 e_border_res_change_geometry_save(E_Border *bd)
988 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
990 if (bd->pre_res_change.valid) return;
991 bd->pre_res_change.valid = 1;
992 bd->pre_res_change.x = bd->x;
993 bd->pre_res_change.y = bd->y;
994 bd->pre_res_change.w = bd->w;
995 bd->pre_res_change.h = bd->h;
996 bd->pre_res_change.saved.x = bd->saved.x;
997 bd->pre_res_change.saved.y = bd->saved.y;
998 bd->pre_res_change.saved.w = bd->saved.w;
999 bd->pre_res_change.saved.h = bd->saved.h;
1003 e_border_res_change_geometry_restore(E_Border *bd)
1007 unsigned char valid : 1;
1016 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1017 if (!bd->pre_res_change.valid) return;
1018 if (bd->new_client) return;
1020 ecore_x_window_shadow_tree_flush();
1021 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1025 e_border_unfullscreen(bd);
1026 e_border_fullscreen(bd, e_config->fullscreen_policy);
1028 else if (bd->maximized != E_MAXIMIZE_NONE)
1032 max = bd->maximized;
1033 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1034 e_border_maximize(bd, max);
1038 int x, y, w, h, zx, zy, zw, zh;
1040 bd->saved.x = bd->pre_res_change.saved.x;
1041 bd->saved.y = bd->pre_res_change.saved.y;
1042 bd->saved.w = bd->pre_res_change.saved.w;
1043 bd->saved.h = bd->pre_res_change.saved.h;
1045 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1047 if (bd->saved.w > zw)
1049 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1050 bd->saved.x = zx + zw - bd->saved.w;
1052 if (bd->saved.h > zh)
1054 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1055 bd->saved.y = zy + zh - bd->saved.h;
1057 x = bd->pre_res_change.x;
1058 y = bd->pre_res_change.y;
1059 w = bd->pre_res_change.w;
1060 h = bd->pre_res_change.h;
1065 if ((x + w) > (zx + zw))
1067 if ((y + h) > (zy + zh))
1069 e_border_move_resize(bd, x, y, w, h);
1071 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1075 e_border_zone_set(E_Border *bd,
1078 E_Event_Border_Zone_Set *ev;
1081 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1082 E_OBJECT_CHECK(zone);
1083 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1085 if (bd->zone == zone) return;
1087 /* if the window does not lie in the new zone, move it so that it does */
1088 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1091 /* first guess -- get offset from old zone, and apply to new zone */
1092 x = zone->x + (bd->x - bd->zone->x);
1093 y = zone->y + (bd->y - bd->zone->y);
1095 /* keep window from hanging off bottom and left */
1096 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1097 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1099 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1100 if (x < zone->x) x = zone->x;
1101 if (y < zone->y) y = zone->y;
1103 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1105 /* still not in zone at all, so just move it to closest edge */
1106 if (x < zone->x) x = zone->x;
1107 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1108 if (y < zone->y) y = zone->y;
1109 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1111 e_border_move(bd, x, y);
1116 if (bd->desk->zone != bd->zone)
1117 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1119 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1121 e_object_ref(E_OBJECT(bd));
1122 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1124 e_object_ref(E_OBJECT(zone));
1126 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1128 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1129 // XXXXXXXXXXXXXXXXXXXXXXXXX
1130 // XXX ZZZZZZZZZZZZZZZZZZZzz
1131 // need to adjust this if zone pos/size changes
1133 unsigned int zgeom[4];
1135 zgeom[0] = bd->zone->x;
1136 zgeom[1] = bd->zone->y;
1137 zgeom[2] = bd->zone->w;
1138 zgeom[3] = bd->zone->h;
1139 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1141 e_remember_update(bd);
1145 e_border_desk_set(E_Border *bd,
1148 E_Event_Border_Desk_Set *ev;
1152 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1153 E_OBJECT_CHECK(desk);
1154 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1155 if (bd->desk == desk) return;
1156 ecore_x_window_shadow_tree_flush();
1159 bd->desk->fullscreen_borders--;
1160 desk->fullscreen_borders++;
1162 old_desk = bd->desk;
1164 e_border_zone_set(bd, desk->zone);
1166 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1167 e_hints_window_desktop_set(bd);
1169 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1171 e_object_ref(E_OBJECT(bd));
1172 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1173 ev->desk = old_desk;
1174 e_object_ref(E_OBJECT(old_desk));
1175 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1177 if (bd->ignore_first_unmap != 1)
1179 if ((bd->desk->visible) || (bd->sticky))
1182 e_border_hide(bd, 1);
1185 if (e_config->transient.desktop)
1189 Eina_List *list = _e_border_sub_borders_new(bd);
1191 EINA_LIST_FOREACH(list, l, child)
1193 e_border_desk_set(child, bd->desk);
1195 eina_list_free(list);
1197 e_remember_update(bd);
1200 #ifdef _F_ZONE_WINDOW_ROTATION_
1202 _e_border_vkbd_state_check(E_Border *bd,
1205 Eina_Bool res = EINA_TRUE;
1206 if (!e_config->wm_win_rotation) return EINA_FALSE;
1207 if ((rot.vkbd) && (rot.vkbd == bd))
1211 if ((rot.vkbd_hide_prepare_done) ||
1212 (rot.vkbd_hide_prepare_timer))
1217 if ((rot.vkbd_show_prepare_done) ||
1218 (rot.vkbd_show_prepare_timer))
1226 _e_border_vkbd_show_timeout(void *data)
1228 E_Border *bd = data;
1229 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1230 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1232 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1234 if (rot.vkbd_ctrl_win)
1236 ELB(ELBT_BD, "SET KBD_ON", 0);
1237 ecore_x_e_virtual_keyboard_state_set
1238 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1243 rot.vkbd_show_prepare_done = EINA_FALSE;
1245 if (rot.vkbd_show_prepare_timer)
1246 ecore_timer_del(rot.vkbd_show_prepare_timer);
1247 rot.vkbd_show_prepare_timer = NULL;
1249 if (rot.vkbd_show_timer)
1250 ecore_timer_del(rot.vkbd_show_timer);
1251 rot.vkbd_show_timer = NULL;
1253 return ECORE_CALLBACK_CANCEL;
1257 _e_border_vkbd_hide_timeout(void *data)
1259 E_Border *bd = data;
1260 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1261 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1263 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1265 if (rot.vkbd_ctrl_win)
1267 ELB(ELBT_BD, "SET KBD_OFF", 0);
1268 ecore_x_e_virtual_keyboard_state_set
1269 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1272 e_object_unref(E_OBJECT(bd));
1275 rot.vkbd_hide_prepare_done = EINA_FALSE;
1277 if (rot.vkbd_hide_prepare_timer)
1278 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1279 rot.vkbd_hide_prepare_timer = NULL;
1281 if (rot.vkbd_hide_timer)
1282 ecore_timer_del(rot.vkbd_hide_timer);
1283 rot.vkbd_hide_timer = NULL;
1285 return ECORE_CALLBACK_CANCEL;
1289 _e_border_vkbd_show(E_Border *bd)
1291 if (!e_config->wm_win_rotation) return;
1292 rot.vkbd_show_prepare_done = EINA_TRUE;
1293 if (rot.vkbd_show_prepare_timer)
1294 ecore_timer_del(rot.vkbd_show_prepare_timer);
1295 rot.vkbd_show_prepare_timer = NULL;
1296 if (rot.vkbd_show_timer)
1297 ecore_timer_del(rot.vkbd_show_timer);
1298 rot.vkbd_show_timer = NULL;
1299 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1302 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1307 _e_border_vkbd_hide(E_Border *bd)
1309 if (!e_config->wm_win_rotation) return;
1310 rot.vkbd_hide_prepare_done = EINA_TRUE;
1311 if (rot.vkbd_hide_prepare_timer)
1312 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1313 rot.vkbd_hide_prepare_timer = NULL;
1314 if (rot.vkbd_hide_timer)
1315 ecore_timer_del(rot.vkbd_hide_timer);
1316 rot.vkbd_hide_timer = NULL;
1317 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1319 e_border_hide(bd, 0);
1320 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1325 _e_border_vkbd_show_prepare_timeout(void *data)
1327 E_Border *bd = data;
1328 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1329 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1331 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1332 _e_border_vkbd_show(bd);
1334 return ECORE_CALLBACK_CANCEL;
1338 _e_border_vkbd_hide_prepare_timeout(void *data)
1340 E_Border *bd = data;
1341 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1342 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1344 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1345 _e_border_vkbd_hide(bd);
1347 return ECORE_CALLBACK_CANCEL;
1352 e_border_show(E_Border *bd)
1354 E_Event_Border_Show *ev;
1355 unsigned int visible;
1358 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1359 if (bd->visible) return;
1360 #ifdef _F_ZONE_WINDOW_ROTATION_
1361 if ((e_config->wm_win_rotation) &&
1362 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1364 (!rot.vkbd_show_prepare_done))
1366 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1367 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1368 if (rot.vkbd_show_prepare_timer)
1369 ecore_timer_del(rot.vkbd_show_prepare_timer);
1370 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1371 _e_border_vkbd_show_prepare_timeout,
1375 ELB(ELBT_BD, "SHOW", bd->client.win);
1377 ecore_x_window_shadow_tree_flush();
1378 e_container_shape_show(bd->shape);
1379 if (!bd->need_reparent)
1380 ecore_x_window_show(bd->client.win);
1381 e_hints_window_visible_set(bd);
1384 bd->changes.visible = 1;
1387 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1388 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1390 ev = E_NEW(E_Event_Border_Show, 1);
1392 e_object_ref(E_OBJECT(bd));
1393 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1394 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1396 #ifdef _F_ZONE_WINDOW_ROTATION_
1397 if ((e_config->wm_win_rotation) &&
1398 ((bd->client.e.state.rot.support) ||
1399 (bd->client.e.state.rot.app_set)))
1401 ELB(ELBT_ROT, "CHECK", bd->client.win);
1402 _e_border_rotation_check(bd);
1408 e_border_hide(E_Border *bd,
1411 unsigned int visible;
1414 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1416 #ifdef _F_ZONE_WINDOW_ROTATION_
1417 if ((e_config->wm_win_rotation) &&
1418 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1420 (!rot.vkbd_hide_prepare_done) &&
1423 Eina_Bool need_prepare = EINA_TRUE;
1424 E_Border *child = NULL;
1427 if (e_object_is_del(E_OBJECT(bd->parent)))
1428 need_prepare = EINA_FALSE;
1431 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1432 if (bd->parent->modal == bd)
1434 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1435 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1436 bd->parent->lock_close = 0;
1437 bd->parent->saved.event_mask = 0;
1438 bd->parent->modal = NULL;
1444 need_prepare = EINA_FALSE;
1446 EINA_LIST_FREE(bd->transients, child)
1448 child->parent = NULL;
1451 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1455 e_object_ref(E_OBJECT(bd));
1456 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1457 if (rot.vkbd_hide_prepare_timer)
1458 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1459 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1460 _e_border_vkbd_hide_prepare_timeout,
1466 e_object_ref(E_OBJECT(bd));
1468 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1469 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1471 /* cleanup code from _e_border_vkbd_hide() */
1472 rot.vkbd_hide_prepare_done = EINA_TRUE;
1473 if (rot.vkbd_hide_prepare_timer)
1474 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1475 rot.vkbd_hide_prepare_timer = NULL;
1476 if (rot.vkbd_hide_timer)
1477 ecore_timer_del(rot.vkbd_hide_timer);
1478 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1481 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1483 if (!bd->visible) goto send_event;
1484 ecore_x_window_shadow_tree_flush();
1486 _e_border_move_end(bd);
1487 if (bd->resize_mode != RESIZE_NONE)
1489 _e_border_pointer_resize_end(bd);
1490 bd->resize_mode = RESIZE_NONE;
1491 _e_border_resize_end(bd);
1494 e_container_shape_hide(bd->shape);
1495 if (!bd->iconic) e_hints_window_hidden_set(bd);
1498 bd->changes.visible = 1;
1500 if (!bd->need_reparent)
1502 if ((bd->focused) ||
1503 (e_grabinput_last_focus_win_get() == bd->client.win))
1505 e_border_focus_set(bd, 0, 1);
1513 con = e_container_current_get(e_manager_current_get());
1514 zone = e_zone_current_get(con);
1515 desk = e_desk_current_get(zone);
1518 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1519 e_border_focus_set(bd->parent, 1, 1);
1520 else if (e_config->focus_revert_on_hide_or_close)
1522 /* When using pointer focus, the border under the
1523 * pointer (if any) gets focused, in sloppy/click
1524 * focus the last focused window on the current
1525 * desk gets focus */
1526 if (e_config->focus_policy == E_FOCUS_MOUSE)
1528 pbd = e_border_under_pointer_get(desk, bd);
1530 e_border_focus_set(pbd, 1, 1);
1532 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1533 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1534 (e_config->focus_policy == E_FOCUS_CLICK))
1535 _e_border_latest_stacked_focus(bd);
1539 e_desk_last_focused_focus(desk);
1549 /* Make sure that this border isn't deleted */
1550 bd->await_hide_event++;
1552 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1553 ecore_x_window_hide(bd->client.win);
1558 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1560 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1567 E_Event_Border_Hide *ev;
1569 ev = E_NEW(E_Event_Border_Hide, 1);
1571 e_object_ref(E_OBJECT(bd));
1572 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1573 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1578 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1582 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1583 setpriority(PRIO_PROCESS, pid, newpri);
1584 // shouldnt need to do this as default ionice class is "none" (0), and
1585 // this inherits io priority FROM nice level
1586 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1587 // IOPRIO_PRIO_VALUE(2, 5));
1591 char *file, buf[PATH_MAX];
1595 // yes - this is /proc specific... so this may not work on some
1596 // os's - works on linux. too bad for others.
1597 files = ecore_file_ls("/proc");
1598 EINA_LIST_FREE(files, file)
1600 if (isdigit(file[0]))
1602 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1603 f = fopen(buf, "r");
1608 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1614 _pri_adj(pid2, set, adj, EINA_TRUE,
1615 adj_children, do_children);
1617 _pri_adj(pid2, set, adj, use_adj,
1618 adj_children, do_children);
1630 _e_border_pri_raise(E_Border *bd)
1632 if (bd->client.netwm.pid <= 0) return;
1633 if (bd->client.netwm.pid == getpid()) return;
1634 _pri_adj(bd->client.netwm.pid,
1635 e_config->priority - 1, -1, EINA_FALSE,
1636 // EINA_TRUE, EINA_TRUE);
1637 EINA_TRUE, EINA_FALSE);
1638 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1639 // bd->client.netwm.pid, e_border_name_get(bd));
1643 _e_border_pri_norm(E_Border *bd)
1645 if (bd->client.netwm.pid <= 0) return;
1646 if (bd->client.netwm.pid == getpid()) return;
1647 _pri_adj(bd->client.netwm.pid,
1648 e_config->priority, 1, EINA_FALSE,
1649 // EINA_TRUE, EINA_TRUE);
1650 EINA_TRUE, EINA_FALSE);
1651 // printf("WIN: pid %i, title %s (NORMAL)\n",
1652 // bd->client.netwm.pid, e_border_name_get(bd));
1656 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1659 Ecore_Evas *bg_ecore_evas;
1665 bg_ecore_evas = bd->bg_ecore_evas;
1667 /* unregister old frame window */
1668 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1669 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1671 e_focus_setdown(bd);
1672 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1673 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1675 if (bd->icon_object)
1676 evas_object_del(bd->icon_object);
1678 evas_object_del(bd->bg_object);
1679 e_canvas_del(bg_ecore_evas);
1680 ecore_evas_free(bg_ecore_evas);
1683 e_object_del(E_OBJECT(bd->pointer));
1685 /* create new frame */
1687 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1688 bd->x, bd->y, bd->w, bd->h);
1691 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1692 bd->x, bd->y, bd->w, bd->h);
1693 ecore_x_window_shape_events_select(bd->win, 1);
1696 ecore_x_window_configure(bd->win,
1697 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1698 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1700 win, ECORE_X_WINDOW_STACK_BELOW);
1702 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1703 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1706 bd->bg_ecore_evas = e_canvas_new(bd->win,
1707 0, 0, bd->w, bd->h, 1, 0,
1710 e_canvas_add(bd->bg_ecore_evas);
1711 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1713 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1714 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1715 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1717 ecore_x_window_shape_events_select(bd->bg_win, 1);
1719 /* move client with shell win over to new frame */
1720 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1721 bd->client_inset.l, bd->client_inset.t);
1723 bd->pointer = e_pointer_window_new(bd->win, 0);
1725 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1726 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1733 ecore_evas_show(bd->bg_ecore_evas);
1734 ecore_x_window_show(bd->win);
1736 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1737 ecore_x_window_show(tmp->win);
1740 bd->bg_object = edje_object_add(bd->bg_evas);
1741 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1742 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1744 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1746 /* cleanup old frame */
1747 ecore_x_window_free(win);
1751 _e_border_client_move_resize_send(E_Border *bd)
1753 if (bd->internal_ecore_evas)
1754 ecore_evas_managed_move(bd->internal_ecore_evas,
1755 bd->x + bd->fx.x + bd->client_inset.l,
1756 bd->y + bd->fx.y + bd->client_inset.t);
1758 ecore_x_icccm_move_resize_send(bd->client.win,
1759 bd->x + bd->fx.x + bd->client_inset.l,
1760 bd->y + bd->fx.y + bd->client_inset.t,
1766 _e_border_pending_move_resize_add(E_Border *bd,
1773 Eina_Bool without_border,
1774 unsigned int serial)
1776 E_Border_Pending_Move_Resize *pnd;
1778 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1780 pnd->resize = resize;
1782 pnd->without_border = without_border;
1787 pnd->serial = serial;
1788 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1792 _e_border_move_internal(E_Border *bd,
1795 Eina_Bool without_border)
1797 E_Event_Border_Move *ev;
1800 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1802 ecore_x_window_shadow_tree_flush();
1805 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1811 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1813 if (e_config->allow_manip)
1816 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1821 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1826 else if (e_config->allow_manip)
1834 x -= bd->client_inset.l;
1835 y -= bd->client_inset.t;
1837 if (bd->move_intercept_cb)
1840 px = bd->x, py = bd->y;
1841 bd->move_intercept_cb(bd, x, y);
1842 if ((bd->x == px) && (bd->y == py)) return;
1844 else if ((x == bd->x) && (y == bd->y)) return;
1845 bd->pre_res_change.valid = 0;
1849 bd->changes.pos = 1;
1851 if (bd->client.netwm.sync.request)
1853 bd->client.netwm.sync.wait++;
1854 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1857 _e_border_client_move_resize_send(bd);
1858 _e_border_move_update(bd);
1859 ev = E_NEW(E_Event_Border_Move, 1);
1861 e_object_ref(E_OBJECT(bd));
1862 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1863 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1864 _e_border_zone_update(bd);
1868 * Move window to coordinates that already account border decorations.
1870 * This call will consider given position already accounts border
1871 * decorations, so it will not be considered later. This will just
1872 * work properly with borders that have being evaluated and border
1873 * decorations are known (border->client_inset).
1875 * @parm x horizontal position to place window.
1876 * @parm y vertical position to place window.
1878 * @see e_border_move_without_border()
1881 e_border_move(E_Border *bd,
1888 _e_border_move_internal(bd, x, y, 0);
1893 * Set a callback which will be called just prior to updating the
1894 * move coordinates for a border
1897 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1899 bd->move_intercept_cb = cb;
1903 * Move window to coordinates that do not account border decorations yet.
1905 * This call will consider given position does not account border
1906 * decoration, so these values (border->client_inset) will be
1907 * accounted automatically. This is specially useful when it is a new
1908 * client and has not be evaluated yet, in this case
1909 * border->client_inset will be zeroed and no information is known. It
1910 * will mark pending requests so border will be accounted on
1911 * evalutation phase.
1913 * @parm x horizontal position to place window.
1914 * @parm y vertical position to place window.
1916 * @see e_border_move()
1919 e_border_move_without_border(E_Border *bd,
1926 _e_border_move_internal(bd, x, y, 1);
1930 e_border_center(E_Border *bd)
1934 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1936 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1937 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1941 e_border_center_pos_get(E_Border *bd,
1947 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1949 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1950 if (x) *x = zx + (zw - bd->w) / 2;
1951 if (y) *y = zy + (zh - bd->h) / 2;
1955 e_border_fx_offset(E_Border *bd,
1960 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1962 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
1966 bd->changes.pos = 1;
1969 if (bd->moving) _e_border_move_update(bd);
1973 _e_border_move_resize_internal(E_Border *bd,
1978 Eina_Bool without_border,
1981 E_Event_Border_Move *mev;
1982 E_Event_Border_Resize *rev;
1985 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1987 ecore_x_window_shadow_tree_flush();
1991 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
1997 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1999 if (e_config->allow_manip)
2002 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2008 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2015 if (e_config->allow_manip)
2023 x -= bd->client_inset.l;
2024 y -= bd->client_inset.t;
2025 w += (bd->client_inset.l + bd->client_inset.r);
2026 h += (bd->client_inset.t + bd->client_inset.b);
2029 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2030 (w == bd->w) && (h == bd->h))
2033 bd->pre_res_change.valid = 0;
2036 bd->changes.pos = 1;
2042 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2043 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2045 if ((bd->shaped) || (bd->client.shaped))
2047 bd->need_shape_merge = 1;
2048 bd->need_shape_export = 1;
2050 if (bd->shaped_input)
2052 bd->need_shape_merge = 1;
2055 if (bd->internal_ecore_evas)
2058 bd->changes.size = 1;
2062 if (bdresize && bd->client.netwm.sync.request)
2064 bd->client.netwm.sync.wait++;
2065 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2066 * when no move is intended. The border geometry is set above anyways.
2068 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2069 bd->client.netwm.sync.serial);
2070 ecore_x_netwm_sync_request_send(bd->client.win,
2071 bd->client.netwm.sync.serial++);
2076 bd->changes.size = 1;
2080 _e_border_client_move_resize_send(bd);
2082 _e_border_resize_update(bd);
2085 mev = E_NEW(E_Event_Border_Move, 1);
2087 e_object_ref(E_OBJECT(bd));
2088 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2089 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2092 rev = E_NEW(E_Event_Border_Resize, 1);
2094 e_object_ref(E_OBJECT(bd));
2095 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2096 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2097 _e_border_zone_update(bd);
2101 * Move and resize window to values that already account border decorations.
2103 * This call will consider given values already accounts border
2104 * decorations, so it will not be considered later. This will just
2105 * work properly with borders that have being evaluated and border
2106 * decorations are known (border->client_inset).
2108 * @parm x horizontal position to place window.
2109 * @parm y vertical position to place window.
2110 * @parm w horizontal window size.
2111 * @parm h vertical window size.
2113 * @see e_border_move_resize_without_border()
2116 e_border_move_resize(E_Border *bd,
2125 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2129 * Move and resize window to values that do not account border decorations yet.
2131 * This call will consider given values already accounts border
2132 * decorations, so it will not be considered later. This will just
2133 * work properly with borders that have being evaluated and border
2134 * decorations are known (border->client_inset).
2136 * @parm x horizontal position to place window.
2137 * @parm y vertical position to place window.
2138 * @parm w horizontal window size.
2139 * @parm h vertical window size.
2141 * @see e_border_move_resize()
2144 e_border_move_resize_without_border(E_Border *bd,
2153 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2157 * Resize window to values that already account border decorations.
2159 * This call will consider given size already accounts border
2160 * decorations, so it will not be considered later. This will just
2161 * work properly with borders that have being evaluated and border
2162 * decorations are known (border->client_inset).
2164 * @parm w horizontal window size.
2165 * @parm h vertical window size.
2167 * @see e_border_resize_without_border()
2170 e_border_resize(E_Border *bd,
2177 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2181 * Resize window to values that do not account border decorations yet.
2183 * This call will consider given size does not account border
2184 * decoration, so these values (border->client_inset) will be
2185 * accounted automatically. This is specially useful when it is a new
2186 * client and has not be evaluated yet, in this case
2187 * border->client_inset will be zeroed and no information is known. It
2188 * will mark pending requests so border will be accounted on
2189 * evalutation phase.
2191 * @parm w horizontal window size.
2192 * @parm h vertical window size.
2194 * @see e_border_resize()
2197 e_border_resize_without_border(E_Border *bd,
2204 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2208 e_border_layer_set(E_Border *bd,
2214 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2216 ecore_x_window_shadow_tree_flush();
2218 oldraise = e_config->transient.raise;
2222 bd->saved.layer = layer;
2226 if (e_config->transient.layer)
2230 Eina_List *list = _e_border_sub_borders_new(bd);
2232 /* We need to set raise to one, else the child wont
2233 * follow to the new layer. It should be like this,
2234 * even if the user usually doesn't want to raise
2237 e_config->transient.raise = 1;
2238 EINA_LIST_FOREACH(list, l, child)
2240 e_border_layer_set(child, layer);
2244 e_config->transient.raise = oldraise;
2248 e_border_raise(E_Border *bd)
2250 E_Event_Border_Stack *ev;
2251 E_Border *last = NULL, *child;
2255 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2257 ecore_x_window_shadow_tree_flush();
2259 if (e_config->transient.raise)
2261 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2262 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2265 Eina_List *list = _e_border_sub_borders_new(bd);
2267 EINA_LIST_REVERSE_FOREACH(list, l, child)
2269 /* Don't stack iconic transients. If the user wants these shown,
2270 * thats another option.
2275 e_border_stack_below(child, last);
2280 /* First raise the border to find out which border we will end up above */
2281 above = e_container_border_raise(child);
2285 /* We ended up above a border, now we must stack this border to
2286 * generate the stacking event, and to check if this transient
2287 * has other transients etc.
2289 e_border_stack_above(child, above);
2293 /* If we didn't end up above any border, we are on the bottom! */
2294 e_border_lower(child);
2300 eina_list_free(list);
2301 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2305 EINA_LIST_FOREACH(bd->transients, l, child)
2307 /* Don't stack iconic transients. If the user wants these shown,
2308 * thats another option.
2312 child->layer = bd->layer;
2313 if (!last) last = child;
2314 e_border_raise (child);
2321 ev = E_NEW(E_Event_Border_Stack, 1);
2323 e_object_ref(E_OBJECT(bd));
2327 e_container_border_stack_below(bd, last);
2329 e_object_ref(E_OBJECT(last));
2330 ev->type = E_STACKING_BELOW;
2336 /* If we don't have any children, raise this border */
2337 above = e_container_border_raise(bd);
2338 e_border_raise_latest_set(bd);
2341 /* We ended up above a border */
2343 e_object_ref(E_OBJECT(above));
2344 ev->type = E_STACKING_ABOVE;
2348 /* No border to raise above, same as a lower! */
2350 ev->type = E_STACKING_ABOVE;
2354 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2355 e_remember_update(bd);
2359 e_border_lower(E_Border *bd)
2361 E_Event_Border_Stack *ev;
2362 E_Border *last = NULL, *child;
2366 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2368 ecore_x_window_shadow_tree_flush();
2370 if (e_config->transient.lower)
2372 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2373 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2376 Eina_List *list = _e_border_sub_borders_new(bd);
2378 EINA_LIST_REVERSE_FOREACH(list, l, child)
2380 /* Don't stack iconic transients. If the user wants these shown,
2381 * thats another option.
2386 e_border_stack_below(child, last);
2391 /* First lower the border to find out which border we will end up below */
2392 below = e_container_border_lower(child);
2396 /* We ended up below a border, now we must stack this border to
2397 * generate the stacking event, and to check if this transient
2398 * has other transients etc.
2400 e_border_stack_below(child, below);
2404 /* If we didn't end up below any border, we are on top! */
2405 e_border_raise(child);
2411 eina_list_free(list);
2413 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2417 EINA_LIST_FOREACH(bd->transients, l, child)
2419 /* Don't stack iconic transients. If the user wants these shown,
2420 * thats another option.
2424 child->layer = bd->layer;
2425 e_border_lower (child);
2433 ev = E_NEW(E_Event_Border_Stack, 1);
2435 e_object_ref(E_OBJECT(bd));
2439 e_container_border_stack_below(bd, last);
2441 e_object_ref(E_OBJECT(last));
2442 ev->type = E_STACKING_BELOW;
2448 /* If we don't have any children, lower this border */
2449 below = e_container_border_lower(bd);
2452 /* We ended up below a border */
2454 e_object_ref(E_OBJECT(below));
2455 ev->type = E_STACKING_BELOW;
2459 /* No border to hide under, same as a raise! */
2461 ev->type = E_STACKING_BELOW;
2465 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2466 e_remember_update(bd);
2470 e_border_stack_above(E_Border *bd,
2473 /* TODO: Should stack above allow the border to change level */
2474 E_Event_Border_Stack *ev;
2475 E_Border *last = NULL, *child;
2479 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2481 ecore_x_window_shadow_tree_flush();
2483 if (e_config->transient.raise)
2485 Eina_List *list = _e_border_sub_borders_new(bd);
2487 EINA_LIST_REVERSE_FOREACH(list, l, child)
2489 /* Don't stack iconic transients. If the user wants these shown,
2490 * thats another option.
2495 e_border_stack_below(child, last);
2497 e_border_stack_above(child, above);
2501 eina_list_free(list);
2504 ev = E_NEW(E_Event_Border_Stack, 1);
2506 e_object_ref(E_OBJECT(bd));
2510 e_container_border_stack_below(bd, last);
2512 e_object_ref(E_OBJECT(last));
2513 ev->type = E_STACKING_BELOW;
2517 e_container_border_stack_above(bd, above);
2519 e_object_ref(E_OBJECT(above));
2520 ev->type = E_STACKING_ABOVE;
2523 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2524 e_remember_update(bd);
2528 e_border_stack_below(E_Border *bd,
2531 /* TODO: Should stack below allow the border to change level */
2532 E_Event_Border_Stack *ev;
2533 E_Border *last = NULL, *child;
2537 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2539 ecore_x_window_shadow_tree_flush();
2541 if (e_config->transient.lower)
2543 Eina_List *list = _e_border_sub_borders_new(bd);
2545 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2547 /* Don't stack iconic transients. If the user wants these shown,
2548 * thats another option.
2553 e_border_stack_below(child, last);
2555 e_border_stack_below(child, below);
2559 eina_list_free(list);
2562 ev = E_NEW(E_Event_Border_Stack, 1);
2564 e_object_ref(E_OBJECT(bd));
2568 e_container_border_stack_below(bd, last);
2570 e_object_ref(E_OBJECT(last));
2571 ev->type = E_STACKING_BELOW;
2575 e_container_border_stack_below(bd, below);
2577 e_object_ref(E_OBJECT(below));
2578 ev->type = E_STACKING_BELOW;
2581 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2582 e_remember_update(bd);
2586 e_border_focus_latest_set(E_Border *bd)
2588 focus_stack = eina_list_remove(focus_stack, bd);
2589 focus_stack = eina_list_prepend(focus_stack, bd);
2593 e_border_raise_latest_set(E_Border *bd)
2595 raise_stack = eina_list_remove(raise_stack, bd);
2596 raise_stack = eina_list_prepend(raise_stack, bd);
2600 * Sets the focus to the given border if necessary
2601 * There are 3 cases of different focus_policy-configurations:
2603 * - E_FOCUS_CLICK: just set the focus, the most simple one
2605 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2606 * warp the pointer to the window. If this fails (because
2607 * the pointer is already in the window), just set the focus.
2609 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2610 * last window which was focused, if the mouse is on the
2611 * desktop. So, we need to look if there is another window
2612 * under the pointer and warp to pointer to the right
2613 * one if so (also, we set the focus afterwards). In case
2614 * there is no window under pointer, the pointer is on the
2615 * desktop and so we just set the focus.
2618 * This function is to be called when setting the focus was not
2619 * explicitly triggered by the user (by moving the mouse or
2620 * clicking for example), but implicitly (by closing a window,
2621 * the last focused window should get focus).
2625 e_border_focus_set_with_pointer(E_Border *bd)
2627 #ifdef PRINT_LOTS_OF_DEBUG
2628 E_PRINT_BORDER_INFO(bd);
2630 /* note: this is here as it seems there are enough apps that do not even
2631 * expect us to emulate a look of focus but not actually set x input
2632 * focus as we do - so simply abort any focuse set on such windows */
2633 /* be strict about accepting focus hint */
2634 if ((!bd->client.icccm.accepts_focus) &&
2635 (!bd->client.icccm.take_focus)) return;
2636 if (bd->lock_focus_out) return;
2638 e_border_focus_set(bd, 1, 1);
2640 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2641 if (!bd->visible) return;
2643 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2645 if (!e_border_under_pointer_get(bd->desk, bd))
2647 e_border_pointer_warp_to_center(bd);
2652 e_border_pointer_warp_to_center(bd);
2657 e_border_focus_set(E_Border *bd,
2661 E_Border *bd_unfocus = NULL;
2662 Eina_Bool focus_changed = EINA_FALSE;
2665 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2666 /* note: this is here as it seems there are enough apps that do not even
2667 * expect us to emulate a look of focus but not actually set x input
2668 * focus as we do - so simply abort any focuse set on such windows */
2669 /* be strict about accepting focus hint */
2670 if ((!bd->client.icccm.accepts_focus) &&
2671 (!bd->client.icccm.take_focus))
2673 if ((set) && (focus) && (bd->lock_focus_out)) return;
2675 /* dont focus an iconified window. that's silly! */
2680 e_border_uniconify(bd);
2681 if (!focus_track_frozen)
2682 e_border_focus_latest_set(bd);
2685 else if (!bd->visible)
2689 /* FIXME: hack for deskflip animation:
2690 * dont update focus when sliding previous desk */
2691 else if ((!bd->sticky) &&
2692 (bd->desk != e_desk_current_get(bd->desk->zone)))
2698 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2700 e_border_focus_set(bd->modal, focus, set);
2703 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2705 e_border_focus_set(bd->leader->modal, focus, set);
2713 if (bd->visible && bd->changes.visible)
2718 else if ((!bd->focused) ||
2719 (focus_next && (bd != eina_list_data_get(focus_next))))
2723 if ((l = eina_list_data_find_list(focus_next, bd)))
2724 focus_next = eina_list_promote_list(focus_next, l);
2726 focus_next = eina_list_prepend(focus_next, bd);
2728 if ((bd->client.icccm.take_focus) &&
2729 (bd->client.icccm.accepts_focus))
2731 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2732 /* TODO what if the client didn't take focus ? */
2734 else if (!bd->client.icccm.accepts_focus)
2736 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2738 else if (!bd->client.icccm.take_focus)
2740 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2741 /* e_border_focus_set(bd, 1, 0); */
2751 if (focused) bd_unfocus = focused;
2752 if (focusing == bd) focusing = NULL;
2757 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2759 if ((bd2->fullscreen) &&
2761 (bd2->zone == bd->zone) &&
2762 ((bd2->desk == bd->desk) ||
2763 (bd2->sticky) || (bd->sticky)))
2765 Eina_Bool unfocus_is_parent = EINA_FALSE;
2766 E_Border *bd_parent;
2768 bd_parent = bd->parent;
2771 if (bd_parent == bd2)
2773 unfocus_is_parent = EINA_TRUE;
2776 bd_parent = bd->parent;
2778 if ((!unfocus_is_parent) &&
2779 (!e_config->allow_above_fullscreen))
2781 e_border_iconify(bd2);
2786 focus_changed = EINA_TRUE;
2792 focus_next = eina_list_remove(focus_next, bd);
2793 if (bd == focusing) focusing = NULL;
2795 if ((bd->focused) &&
2796 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2798 Eina_Bool wasfocused = EINA_FALSE;
2801 /* should always be the case. anyway */
2805 wasfocused = EINA_TRUE;
2808 if ((set) && (!focus_next) && (!focusing))
2810 e_grabinput_focus(bd->zone->container->bg_win,
2811 E_FOCUS_METHOD_PASSIVE);
2813 if ((bd->fullscreen) && (wasfocused))
2815 Eina_Bool have_vis_child = EINA_FALSE;
2819 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2822 (bd2->zone == bd->zone) &&
2823 ((bd2->desk == bd->desk) ||
2824 (bd2->sticky) || (bd->sticky)))
2826 if (bd2->parent == bd)
2828 have_vis_child = EINA_TRUE;
2833 if ((!have_vis_child) &&
2834 (!e_config->allow_above_fullscreen))
2835 e_border_iconify(bd);
2841 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2842 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2844 E_Event_Border_Focus_Out *ev;
2846 bd_unfocus->focused = 0;
2847 e_focus_event_focus_out(bd_unfocus);
2849 if (bd_unfocus->raise_timer)
2850 ecore_timer_del(bd_unfocus->raise_timer);
2851 bd_unfocus->raise_timer = NULL;
2853 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2854 if (bd_unfocus->icon_object)
2855 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2857 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2858 ev->border = bd_unfocus;
2859 e_object_ref(E_OBJECT(bd_unfocus));
2861 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2862 _e_border_event_border_focus_out_free, NULL);
2863 if ((bd_unfocus->fullscreen) &&
2864 (bd != bd_unfocus) &&
2865 (bd->zone == bd_unfocus->zone) &&
2866 ((bd->desk == bd_unfocus->desk) ||
2867 (bd->sticky) || (bd_unfocus->sticky)))
2869 Eina_Bool unfocus_is_parent = EINA_FALSE;
2870 E_Border *bd_parent;
2872 bd_parent = bd->parent;
2875 if (bd_parent == bd_unfocus)
2877 unfocus_is_parent = EINA_TRUE;
2880 bd_parent = bd->parent;
2882 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2884 e_border_iconify(bd_unfocus);
2891 E_Event_Border_Focus_In *ev;
2893 e_focus_event_focus_in(bd);
2895 if (!focus_track_frozen)
2896 e_border_focus_latest_set(bd);
2898 e_hints_active_window_set(bd->zone->container->manager, bd);
2900 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2901 if (bd->icon_object)
2902 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2904 ev = E_NEW(E_Event_Border_Focus_In, 1);
2906 e_object_ref(E_OBJECT(bd));
2908 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2909 _e_border_event_border_focus_in_free, NULL);
2914 e_border_shade(E_Border *bd,
2917 E_Event_Border_Resize *ev;
2922 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2923 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2924 ((bd->maximized) && (!e_config->allow_manip))) return;
2925 if ((bd->client.border.name) &&
2926 (!strcmp("borderless", bd->client.border.name))) return;
2928 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2929 ecore_x_window_hide(tmp->win);
2931 ecore_x_window_shadow_tree_flush();
2933 bd->shade.x = bd->x;
2934 bd->shade.y = bd->y;
2935 bd->shade.dir = dir;
2937 e_hints_window_shaded_set(bd, 1);
2938 e_hints_window_shade_direction_set(bd, dir);
2940 if (e_config->border_shade_animate)
2942 bd->shade.start = ecore_loop_time_get();
2944 bd->changes.shading = 1;
2947 if (bd->shade.dir == E_DIRECTION_UP ||
2948 bd->shade.dir == E_DIRECTION_LEFT)
2949 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2951 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2953 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2954 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2958 if (bd->shade.dir == E_DIRECTION_UP)
2960 bd->h = bd->client_inset.t + bd->client_inset.b;
2962 else if (bd->shade.dir == E_DIRECTION_DOWN)
2964 bd->h = bd->client_inset.t + bd->client_inset.b;
2965 bd->y = bd->y + bd->client.h;
2966 bd->changes.pos = 1;
2968 else if (bd->shade.dir == E_DIRECTION_LEFT)
2970 bd->w = bd->client_inset.l + bd->client_inset.r;
2972 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2974 bd->w = bd->client_inset.l + bd->client_inset.r;
2975 bd->x = bd->x + bd->client.w;
2976 bd->changes.pos = 1;
2979 if ((bd->shaped) || (bd->client.shaped))
2981 bd->need_shape_merge = 1;
2982 bd->need_shape_export = 1;
2984 if (bd->shaped_input)
2986 bd->need_shape_merge = 1;
2989 bd->changes.size = 1;
2991 bd->changes.shaded = 1;
2993 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
2994 e_border_frame_recalc(bd);
2995 ev = E_NEW(E_Event_Border_Resize, 1);
2997 /* The resize is added in the animator when animation complete */
2998 /* For non-animated, we add it immediately with the new size */
2999 e_object_ref(E_OBJECT(bd));
3000 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3001 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3004 e_remember_update(bd);
3008 e_border_unshade(E_Border *bd,
3011 E_Event_Border_Resize *ev;
3016 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3017 if ((!bd->shaded) || (bd->shading))
3020 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3021 ecore_x_window_show(tmp->win);
3023 ecore_x_window_shadow_tree_flush();
3025 bd->shade.dir = dir;
3027 e_hints_window_shaded_set(bd, 0);
3028 e_hints_window_shade_direction_set(bd, dir);
3030 if (bd->shade.dir == E_DIRECTION_UP ||
3031 bd->shade.dir == E_DIRECTION_LEFT)
3033 bd->shade.x = bd->x;
3034 bd->shade.y = bd->y;
3038 bd->shade.x = bd->x - bd->client.w;
3039 bd->shade.y = bd->y - bd->client.h;
3041 if (e_config->border_shade_animate)
3043 bd->shade.start = ecore_loop_time_get();
3045 bd->changes.shading = 1;
3048 if (bd->shade.dir == E_DIRECTION_UP)
3050 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3051 ecore_x_window_move_resize(bd->client.win, 0,
3052 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3054 bd->client.w, bd->client.h);
3056 else if (bd->shade.dir == E_DIRECTION_LEFT)
3058 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3059 ecore_x_window_move_resize(bd->client.win,
3060 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3062 0, bd->client.w, bd->client.h);
3065 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3067 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3068 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3072 if (bd->shade.dir == E_DIRECTION_UP)
3074 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3076 else if (bd->shade.dir == E_DIRECTION_DOWN)
3078 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3079 bd->y = bd->y - bd->client.h;
3080 bd->changes.pos = 1;
3082 else if (bd->shade.dir == E_DIRECTION_LEFT)
3084 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3086 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3088 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3089 bd->x = bd->x - bd->client.w;
3090 bd->changes.pos = 1;
3092 if ((bd->shaped) || (bd->client.shaped))
3094 bd->need_shape_merge = 1;
3095 bd->need_shape_export = 1;
3097 if (bd->shaped_input)
3099 bd->need_shape_merge = 1;
3102 bd->changes.size = 1;
3104 bd->changes.shaded = 1;
3106 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3107 e_border_frame_recalc(bd);
3108 ev = E_NEW(E_Event_Border_Resize, 1);
3110 /* The resize is added in the animator when animation complete */
3111 /* For non-animated, we add it immediately with the new size */
3112 e_object_ref(E_OBJECT(bd));
3113 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3114 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3117 e_remember_update(bd);
3121 _e_border_client_inset_calc(E_Border *bd)
3124 Evas_Coord cx, cy, cw, ch;
3128 evas_object_resize(bd->bg_object, 1000, 1000);
3129 edje_object_message_signal_process(bd->bg_object);
3130 edje_object_calc_force(bd->bg_object);
3131 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3132 bd->client_inset.l = cx;
3133 bd->client_inset.r = 1000 - (cx + cw);
3134 bd->client_inset.t = cy;
3135 bd->client_inset.b = 1000 - (cy + ch);
3139 bd->client_inset.l = 0;
3140 bd->client_inset.r = 0;
3141 bd->client_inset.t = 0;
3142 bd->client_inset.b = 0;
3145 ecore_x_netwm_frame_size_set(bd->client.win,
3146 bd->client_inset.l, bd->client_inset.r,
3147 bd->client_inset.t, bd->client_inset.b);
3148 ecore_x_e_frame_size_set(bd->client.win,
3149 bd->client_inset.l, bd->client_inset.r,
3150 bd->client_inset.t, bd->client_inset.b);
3154 _e_border_maximize(E_Border *bd, E_Maximize max)
3156 int x1, yy1, x2, y2;
3159 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3163 zx = zy = zw = zh = 0;
3165 switch (max & E_MAXIMIZE_TYPE)
3167 case E_MAXIMIZE_NONE:
3171 case E_MAXIMIZE_FULLSCREEN:
3177 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3178 _e_border_client_inset_calc(bd);
3180 e_border_resize_limit(bd, &w, &h);
3181 /* center x-direction */
3182 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3183 /* center y-direction */
3184 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3186 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3187 cy = bd->zone->y + (bd->zone->h / 2);
3190 switch (max & E_MAXIMIZE_DIRECTION)
3192 case E_MAXIMIZE_BOTH:
3193 e_border_move_resize(bd, x1, yy1, w, h);
3196 case E_MAXIMIZE_VERTICAL:
3197 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3200 case E_MAXIMIZE_HORIZONTAL:
3201 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3204 case E_MAXIMIZE_LEFT:
3205 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3208 case E_MAXIMIZE_RIGHT:
3209 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3211 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3212 case E_MAXIMIZE_TOP:
3213 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3215 case E_MAXIMIZE_BOTTOM:
3216 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3222 case E_MAXIMIZE_SMART:
3223 case E_MAXIMIZE_EXPAND:
3225 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3237 if (bd->x < zx) // window left not useful coordinates
3239 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3240 x1 = zx + zw - bd->w;
3241 else // window normal position
3244 if (bd->y < zy) // window top not useful coordinates
3246 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3247 yy1 = zy + zh - bd->h;
3248 else // window normal position
3251 switch (max & E_MAXIMIZE_DIRECTION)
3253 case E_MAXIMIZE_BOTH:
3254 e_border_move_resize(bd, zx, zy, zw, zh);
3257 case E_MAXIMIZE_VERTICAL:
3258 e_border_move_resize(bd, x1, zy, w, zh);
3261 case E_MAXIMIZE_HORIZONTAL:
3262 e_border_move_resize(bd, zx, yy1, zw, h);
3265 case E_MAXIMIZE_LEFT:
3266 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3269 case E_MAXIMIZE_RIGHT:
3270 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3274 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3277 case E_MAXIMIZE_FILL:
3280 x2 = bd->zone->x + bd->zone->w;
3281 y2 = bd->zone->y + bd->zone->h;
3283 /* walk through all shelves */
3284 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3286 /* walk through all windows */
3287 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3293 e_border_resize_limit(bd, &w, &h);
3294 /* center x-direction */
3295 x1 = x1 + (pw - w) / 2;
3296 /* center y-direction */
3297 yy1 = yy1 + (ph - h) / 2;
3299 switch (max & E_MAXIMIZE_DIRECTION)
3301 case E_MAXIMIZE_BOTH:
3302 e_border_move_resize(bd, x1, yy1, w, h);
3305 case E_MAXIMIZE_VERTICAL:
3306 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3309 case E_MAXIMIZE_HORIZONTAL:
3310 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3313 case E_MAXIMIZE_LEFT:
3314 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3317 case E_MAXIMIZE_RIGHT:
3318 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3326 e_border_maximize(E_Border *bd,
3330 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3332 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3334 if ((bd->shaded) || (bd->shading)) return;
3335 ecore_x_window_shadow_tree_flush();
3337 e_border_unfullscreen(bd);
3338 /* Only allow changes in vertical/ horizontal maximization */
3339 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3340 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3343 bd->need_maximize = 1;
3344 bd->maximized &= ~E_MAXIMIZE_TYPE;
3345 bd->maximized |= max;
3349 bd->pre_res_change.valid = 0;
3350 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3352 /* Horizontal hasn't been set */
3353 bd->saved.x = bd->x - bd->zone->x;
3354 bd->saved.w = bd->w;
3356 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3358 /* Vertical hasn't been set */
3359 bd->saved.y = bd->y - bd->zone->y;
3360 bd->saved.h = bd->h;
3363 bd->saved.zone = bd->zone->num;
3364 e_hints_window_size_set(bd);
3368 _e_border_maximize(bd, max);
3371 /* Remove previous type */
3372 bd->maximized &= ~E_MAXIMIZE_TYPE;
3373 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3374 bd->maximized |= max;
3376 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3377 bd->maximized & E_MAXIMIZE_VERTICAL);
3378 e_remember_update(bd);
3382 e_border_unmaximize(E_Border *bd,
3386 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3387 if (!(max & E_MAXIMIZE_DIRECTION))
3389 CRI("BUG: Unmaximize call without direction!");
3393 if ((bd->shaded) || (bd->shading)) return;
3394 ecore_x_window_shadow_tree_flush();
3395 /* Remove directions not used */
3396 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3397 /* Can only remove existing maximization directions */
3399 if (bd->maximized & E_MAXIMIZE_TYPE)
3401 bd->pre_res_change.valid = 0;
3402 bd->need_maximize = 0;
3404 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3408 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3409 _e_border_client_inset_calc(bd);
3412 bd->maximized = E_MAXIMIZE_NONE;
3413 _e_border_move_resize_internal(bd,
3414 bd->zone->x + bd->saved.x,
3415 bd->zone->y + bd->saved.y,
3416 bd->saved.w, bd->saved.h, 0, 1);
3417 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3418 e_hints_window_size_unset(bd);
3429 if (max & E_MAXIMIZE_VERTICAL)
3431 /* Remove vertical */
3433 y = bd->saved.y + bd->zone->y;
3434 bd->saved.h = bd->saved.y = 0;
3435 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3436 bd->maximized &= ~E_MAXIMIZE_LEFT;
3437 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3439 if (max & E_MAXIMIZE_HORIZONTAL)
3441 /* Remove horizontal */
3443 x = bd->saved.x + bd->zone->x;
3444 bd->saved.w = bd->saved.x = 0;
3445 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3448 e_border_resize_limit(bd, &w, &h);
3450 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3452 bd->maximized = E_MAXIMIZE_NONE;
3453 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3454 e_hints_window_size_unset(bd);
3455 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3459 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3460 e_hints_window_size_set(bd);
3463 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3464 bd->maximized & E_MAXIMIZE_VERTICAL);
3466 e_remember_update(bd);
3470 e_border_fullscreen(E_Border *bd,
3471 E_Fullscreen policy)
3473 E_Event_Border_Fullscreen *ev;
3476 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3478 if ((bd->shaded) || (bd->shading)) return;
3479 ecore_x_window_shadow_tree_flush();
3482 bd->need_fullscreen = 1;
3485 if (!bd->fullscreen)
3487 bd->pre_res_change.valid = 0;
3489 bd->saved.x = bd->x - bd->zone->x;
3490 bd->saved.y = bd->y - bd->zone->y;
3491 bd->saved.w = bd->client.w;
3492 bd->saved.h = bd->client.h;
3493 bd->saved.maximized = bd->maximized;
3494 bd->saved.zone = bd->zone->num;
3497 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3498 e_hints_window_size_set(bd);
3500 bd->client_inset.l = 0;
3501 bd->client_inset.r = 0;
3502 bd->client_inset.t = 0;
3503 bd->client_inset.b = 0;
3505 bd->desk->fullscreen_borders++;
3507 /* e_zone_fullscreen_set(bd->zone, 1); */
3508 bd->saved.layer = bd->layer;
3509 if (!e_config->allow_above_fullscreen)
3510 e_border_layer_set(bd, 250);
3512 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3513 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3515 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3517 else if (policy == E_FULLSCREEN_ZOOM)
3519 Ecore_X_Randr_Screen_Size_MM *sizes;
3520 int num_sizes, i, best_size_index = 0;
3522 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3524 &screen_size.height,
3526 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3530 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3531 int best_dist = INT_MAX, dist;
3533 for (i = 0; i < num_sizes; i++)
3535 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3537 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3538 if (dist < best_dist)
3540 best_size.width = sizes[i].width;
3541 best_size.height = sizes[i].height;
3543 best_size_index = i;
3547 if (((best_size.width != -1) && (best_size.height != -1)) &&
3548 ((best_size.width != screen_size.width) ||
3549 (best_size.height != screen_size.height)))
3551 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3553 screen_size_index = best_size_index;
3554 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3558 screen_size.width = -1;
3559 screen_size.height = -1;
3560 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3565 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3569 e_hints_window_fullscreen_set(bd, 1);
3570 e_hints_window_size_unset(bd);
3571 bd->client.border.changed = 1;
3574 bd->fullscreen_policy = policy;
3576 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3578 e_object_ref(E_OBJECT(bd));
3579 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3580 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3582 e_remember_update(bd);
3586 e_border_unfullscreen(E_Border *bd)
3588 E_Event_Border_Unfullscreen *ev;
3591 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3592 if ((bd->shaded) || (bd->shading)) return;
3593 ecore_x_window_shadow_tree_flush();
3596 bd->pre_res_change.valid = 0;
3598 bd->need_fullscreen = 0;
3599 bd->desk->fullscreen_borders--;
3601 if ((screen_size.width != -1) && (screen_size.height != -1))
3603 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3605 screen_size.width = -1;
3606 screen_size.height = -1;
3608 e_border_move_resize(bd,
3609 bd->saved.x + bd->zone->x,
3610 bd->saved.y + bd->zone->y,
3611 bd->saved.w, bd->saved.h);
3613 if (bd->saved.maximized)
3614 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3615 bd->saved.maximized);
3617 e_border_layer_set(bd, bd->saved.layer);
3619 e_hints_window_fullscreen_set(bd, 0);
3620 bd->client.border.changed = 1;
3623 bd->fullscreen_policy = 0;
3625 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3627 e_object_ref(E_OBJECT(bd));
3628 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3629 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3631 e_remember_update(bd);
3635 e_border_iconify(E_Border *bd)
3637 E_Event_Border_Iconify *ev;
3638 unsigned int iconic;
3641 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3642 if (bd->shading) return;
3643 ecore_x_window_shadow_tree_flush();
3647 e_border_hide(bd, 1);
3648 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3649 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3652 e_hints_window_iconic_set(bd);
3653 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3655 ev = E_NEW(E_Event_Border_Iconify, 1);
3657 e_object_ref(E_OBJECT(bd));
3658 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3659 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3661 if (e_config->transient.iconify)
3665 Eina_List *list = _e_border_sub_borders_new(bd);
3667 EINA_LIST_FOREACH(list, l, child)
3669 e_border_iconify(child);
3671 eina_list_free(list);
3673 e_remember_update(bd);
3676 #ifdef _F_DEICONIFY_APPROVE_
3678 _e_border_uniconify_timeout(void *data)
3683 if (!e_object_is_del(E_OBJECT(bd)))
3685 bd->client.e.state.deiconify_approve.render_done = 1;
3686 e_border_uniconify(bd);
3687 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3690 return ECORE_CALLBACK_CANCEL;
3695 e_border_uniconify(E_Border *bd)
3698 E_Event_Border_Uniconify *ev;
3699 unsigned int iconic;
3702 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3704 #ifdef _F_DEICONIFY_APPROVE_
3705 if (e_config->deiconify_approve)
3707 if (bd->client.e.state.deiconify_approve.support)
3709 if (bd->client.e.state.deiconify_approve.wait_timer) return;
3710 if (bd->client.e.state.deiconify_approve.render_done == 0)
3712 ecore_x_client_message32_send(bd->client.win,
3713 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3714 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3715 bd->client.win, 0, 0, 0, 0);
3716 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3721 bd->client.e.state.deiconify_approve.render_done = 0;
3725 #if _F_ZONE_WINDOW_ROTATION_
3726 if (!bd->client.win)
3728 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3733 if (bd->shading) return;
3734 ecore_x_window_shadow_tree_flush();
3739 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3740 desk = e_desk_current_get(bd->desk->zone);
3741 #ifdef _F_USE_EXTENDED_ICONIFY_
3742 if (e_manager_comp_evas_get(bd->zone->container->manager))
3744 if (bd->await_hide_event > 0)
3745 bd->await_hide_event--;
3748 e_border_desk_set(bd, desk);
3750 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3753 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3755 ev = E_NEW(E_Event_Border_Uniconify, 1);
3757 e_object_ref(E_OBJECT(bd));
3758 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3759 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3761 if (e_config->transient.iconify)
3765 Eina_List *list = _e_border_sub_borders_new(bd);
3767 EINA_LIST_FOREACH(list, l, child)
3769 e_border_uniconify(child);
3771 eina_list_free(list);
3773 e_remember_update(bd);
3777 e_border_stick(E_Border *bd)
3779 E_Event_Border_Stick *ev;
3782 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3783 if (bd->sticky) return;
3785 e_hints_window_sticky_set(bd, 1);
3788 if (e_config->transient.desktop)
3792 Eina_List *list = _e_border_sub_borders_new(bd);
3794 EINA_LIST_FOREACH(list, l, child)
3797 e_hints_window_sticky_set(child, 1);
3798 e_border_show(child);
3800 eina_list_free(list);
3803 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3804 ev = E_NEW(E_Event_Border_Stick, 1);
3806 e_object_ref(E_OBJECT(bd));
3807 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3808 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3809 e_remember_update(bd);
3813 e_border_unstick(E_Border *bd)
3815 E_Event_Border_Unstick *ev;
3818 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3819 /* Set the desk before we unstick the border */
3820 if (!bd->sticky) return;
3822 e_hints_window_sticky_set(bd, 0);
3824 if (e_config->transient.desktop)
3828 Eina_List *list = _e_border_sub_borders_new(bd);
3830 EINA_LIST_FOREACH(list, l, child)
3833 e_hints_window_sticky_set(child, 0);
3835 eina_list_free(list);
3838 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3839 ev = E_NEW(E_Event_Border_Unstick, 1);
3841 e_object_ref(E_OBJECT(bd));
3842 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3843 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3845 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3846 e_remember_update(bd);
3850 e_border_pinned_set(E_Border *bd,
3858 bd->borderless = set;
3859 bd->user_skip_winlist = set;
3863 stacking = E_STACKING_BELOW;
3868 stacking = E_STACKING_NONE;
3871 e_border_layer_set(bd, layer);
3872 e_hints_window_stacking_set(bd, stacking);
3874 bd->client.border.changed = 1;
3880 e_border_find_by_client_window(Ecore_X_Window win)
3884 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3885 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3886 (bd->client.win == win))
3892 e_border_find_all_by_client_window(Ecore_X_Window win)
3896 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3897 if ((bd) && (bd->client.win == win))
3903 e_border_find_by_frame_window(Ecore_X_Window win)
3907 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3908 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3909 (bd->bg_win == win))
3915 e_border_find_by_window(Ecore_X_Window win)
3919 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3920 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3927 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
3932 EINA_LIST_FOREACH(borders, l, bd)
3934 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3935 (bd->client.netwm.sync.alarm == al))
3942 e_border_focused_get(void)
3948 _e_border_shape_input_rectangle_set(E_Border* bd)
3952 if ((bd->visible) && (bd->shaped_input))
3954 Ecore_X_Rectangle rects[4];
3955 Ecore_X_Window twin, twin2;
3958 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
3959 0, 0, bd->w, bd->h);
3962 rects[0].width = bd->w;
3963 rects[0].height = bd->client_inset.t;
3965 rects[1].y = bd->client_inset.t;
3966 rects[1].width = bd->client_inset.l;
3967 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3968 rects[2].x = bd->w - bd->client_inset.r;
3969 rects[2].y = bd->client_inset.t;
3970 rects[2].width = bd->client_inset.r;
3971 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3973 rects[3].y = bd->h - bd->client_inset.b;
3974 rects[3].width = bd->w;
3975 rects[3].height = bd->client_inset.b;
3976 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
3978 twin2 = ecore_x_window_override_new
3979 (bd->zone->container->scratch_win, 0, 0,
3980 bd->w - bd->client_inset.l - bd->client_inset.r,
3981 bd->h - bd->client_inset.t - bd->client_inset.b);
3984 if ((bd->shading) || (bd->shaded))
3986 if (bd->shade.dir == E_DIRECTION_UP)
3987 y = bd->h - bd->client_inset.t - bd->client_inset.b -
3989 else if (bd->shade.dir == E_DIRECTION_LEFT)
3990 x = bd->w - bd->client_inset.l - bd->client_inset.r -
3993 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
3995 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
3996 bd->w - bd->client_inset.l - bd->client_inset.r,
3997 bd->h - bd->client_inset.t - bd->client_inset.b);
3998 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4000 bd->client_inset.t);
4001 ecore_x_window_shape_input_window_set(bd->win, twin);
4002 ecore_x_window_free(twin2);
4003 ecore_x_window_free(twin);
4007 if (bd->visible) // not shaped input
4009 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4010 ecore_x_composite_window_events_enable(bd->win);
4012 ecore_x_composite_window_events_disable(bd->win);
4016 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4017 ecore_x_composite_window_events_enable(bd->win);
4019 ecore_x_composite_window_events_disable(bd->win);
4025 e_border_idler_before(void)
4034 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4036 EINA_LIST_FOREACH(man->containers, cl, con)
4041 // pass 1 - eval0. fetch properties on new or on change and
4042 // call hooks to decide what to do - maybe move/resize
4043 bl = e_container_border_list_last(con);
4044 while ((bd = e_container_border_list_prev(bl)))
4046 if (bd->changed) _e_border_eval0(bd);
4048 e_container_border_list_free(bl);
4050 // layout hook - this is where a hook gets to figure out what to
4052 _e_border_container_layout_hook(con);
4054 // pass 2 - show windows needing show
4055 bl = e_container_border_list_last(con);
4056 while ((bd = e_container_border_list_prev(bl)))
4058 if ((bd->changes.visible) && (bd->visible) &&
4059 (!bd->new_client) && (!bd->changes.pos) &&
4060 (!bd->changes.size))
4063 bd->changes.visible = 0;
4066 e_container_border_list_free(bl);
4068 // pass 3 - hide windows needing hide and eval (main eval)
4069 bl = e_container_border_list_first(con);
4070 while ((bd = e_container_border_list_next(bl)))
4072 if (e_object_is_del(E_OBJECT(bd))) continue;
4074 if ((bd->changes.visible) && (!bd->visible))
4077 bd->changes.visible = 0;
4080 if (bd->changed) _e_border_eval(bd);
4082 if ((bd->changes.visible) && (bd->visible))
4085 bd->changes.visible = 0;
4088 e_container_border_list_free(bl);
4094 E_Border *bd = NULL, *bd2;
4096 EINA_LIST_FREE(focus_next, bd2)
4097 if ((!bd) && (bd2->visible)) bd = bd2;
4101 /* TODO revert focus when lost here ? */
4107 /* already focused. but anyway dont be so strict, this
4108 fcks up illume setting focus on internal windows */
4113 focus_time = ecore_x_current_time_get();
4117 if ((bd->client.icccm.take_focus) &&
4118 (bd->client.icccm.accepts_focus))
4120 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4121 /* TODO what if the client didn't take focus ? */
4123 else if (!bd->client.icccm.accepts_focus)
4125 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4127 else if (!bd->client.icccm.take_focus)
4129 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4130 /* e_border_focus_set(bd, 1, 0); */
4134 #ifdef _F_ZONE_WINDOW_ROTATION_
4135 if ((e_config->wm_win_rotation) &&
4138 Ecore_X_Event_Client_Message *msg = NULL;
4140 EINA_LIST_FREE(rot.msgs, msg)
4142 t = msg->message_type;
4143 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4145 if ((rot.vkbd_ctrl_win) &&
4146 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4149 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4150 if (rot.vkbd_show_prepare_timer)
4151 _e_border_vkbd_show(rot.vkbd);
4153 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4156 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4158 if ((rot.vkbd_ctrl_win) &&
4159 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4162 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4163 if (rot.vkbd_hide_prepare_timer)
4165 _e_border_vkbd_hide(rot.vkbd);
4166 rot.vkbd_hide_prepare_timer = NULL;
4167 e_object_unref(E_OBJECT(rot.vkbd));
4170 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4173 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4175 rot.vkbd_ctrl_win = msg->data.l[0];
4176 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4178 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4180 if ((rot.vkbd_ctrl_win) &&
4181 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4183 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4184 E_Manager *m = e_manager_current_get();
4185 E_Zone *zone = NULL;
4186 if (m) zone = e_util_zone_current_get(m);
4187 if ((zone) && (rot.wait_prepare_done))
4189 if (_e_border_rotation_list_add(zone, EINA_FALSE))
4190 _e_border_rotation_change_request(zone);
4193 if (rot.prepare_timer)
4194 ecore_timer_del(rot.prepare_timer);
4195 rot.prepare_timer = NULL;
4196 rot.wait_prepare_done = EINA_FALSE;
4204 rot.fetch = EINA_FALSE;
4210 e_border_client_list(void)
4212 /* FIXME: This should be a somewhat ordered list */
4216 static Ecore_X_Window action_input_win = 0;
4217 static E_Border *action_border = NULL;
4218 static Ecore_Event_Handler *action_handler_key = NULL;
4219 static Ecore_Event_Handler *action_handler_mouse = NULL;
4220 static Ecore_Timer *action_timer = NULL;
4221 static Ecore_X_Rectangle action_orig;
4224 _e_border_show(E_Border *bd)
4229 ecore_evas_show(bd->bg_ecore_evas);
4237 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4239 _e_border_shape_input_rectangle_set(bd);
4241 // ecore_x_composite_window_events_enable(bd->win);
4242 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4245 ecore_x_window_show(bd->win);
4247 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4248 ecore_x_window_show(tmp->win);
4252 _e_border_hide(E_Border *bd)
4257 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4259 ecore_x_window_hide(bd->win);
4260 ecore_evas_hide(bd->bg_ecore_evas);
4262 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4263 ecore_x_window_hide(tmp->win);
4267 ecore_x_composite_window_events_disable(bd->win);
4268 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4273 _e_border_action_input_win_del(void)
4275 if (!action_input_win)
4278 e_grabinput_release(action_input_win, action_input_win);
4279 ecore_x_window_free(action_input_win);
4280 action_input_win = 0;
4285 _e_border_action_input_win_new(E_Border *bd)
4287 if (!action_input_win)
4289 Ecore_X_Window parent = bd->zone->container->win;
4290 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4291 if (!action_input_win)
4295 ecore_x_window_show(action_input_win);
4296 if (e_grabinput_get(action_input_win, 0, action_input_win))
4299 _e_border_action_input_win_del();
4304 _e_border_action_finish(void)
4306 _e_border_action_input_win_del();
4310 ecore_timer_del(action_timer);
4311 action_timer = NULL;
4314 if (action_handler_key)
4316 ecore_event_handler_del(action_handler_key);
4317 action_handler_key = NULL;
4320 if (action_handler_mouse)
4322 ecore_event_handler_del(action_handler_mouse);
4323 action_handler_mouse = NULL;
4326 action_border = NULL;
4330 _e_border_action_init(E_Border *bd)
4332 action_orig.x = bd->x;
4333 action_orig.y = bd->y;
4334 action_orig.width = bd->w;
4335 action_orig.height = bd->h;
4341 _e_border_action_restore_orig(E_Border *bd)
4343 if (action_border != bd)
4346 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4350 _e_border_key_down_modifier_apply(int modifier,
4353 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4355 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4368 _e_border_action_move_timeout(void *data __UNUSED__)
4370 _e_border_move_end(action_border);
4371 _e_border_action_finish();
4372 return ECORE_CALLBACK_CANCEL;
4376 _e_border_action_move_timeout_add(void)
4379 ecore_timer_del(action_timer);
4380 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4384 _e_border_move_key_down(void *data __UNUSED__,
4385 int type __UNUSED__,
4388 Ecore_Event_Key *ev = event;
4391 if (ev->event_window != action_input_win)
4392 return ECORE_CALLBACK_PASS_ON;
4395 fputs("ERROR: no action_border!\n", stderr);
4399 x = action_border->x;
4400 y = action_border->y;
4402 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4403 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4404 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4405 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4406 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4407 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4408 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4409 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4410 else if (strcmp(ev->key, "Return") == 0)
4412 else if (strcmp(ev->key, "Escape") == 0)
4414 _e_border_action_restore_orig(action_border);
4417 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4418 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4421 e_border_move(action_border, x, y);
4422 _e_border_action_move_timeout_add();
4424 return ECORE_CALLBACK_PASS_ON;
4427 _e_border_move_end(action_border);
4428 _e_border_action_finish();
4429 return ECORE_CALLBACK_DONE;
4433 _e_border_move_mouse_down(void *data __UNUSED__,
4434 int type __UNUSED__,
4437 Ecore_Event_Mouse_Button *ev = event;
4439 if (ev->event_window != action_input_win)
4440 return ECORE_CALLBACK_PASS_ON;
4443 fputs("ERROR: no action_border!\n", stderr);
4445 _e_border_move_end(action_border);
4446 _e_border_action_finish();
4447 return ECORE_CALLBACK_DONE;
4451 e_border_act_move_keyboard(E_Border *bd)
4456 if (!_e_border_move_begin(bd))
4459 if (!_e_border_action_input_win_new(bd))
4461 _e_border_move_end(bd);
4465 _e_border_action_init(bd);
4466 _e_border_action_move_timeout_add();
4467 _e_border_move_update(bd);
4469 if (action_handler_key)
4470 ecore_event_handler_del(action_handler_key);
4471 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4473 if (action_handler_mouse)
4474 ecore_event_handler_del(action_handler_mouse);
4475 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4479 _e_border_action_resize_timeout(void *data __UNUSED__)
4481 _e_border_resize_end(action_border);
4482 _e_border_action_finish();
4483 return ECORE_CALLBACK_CANCEL;
4487 _e_border_action_resize_timeout_add(void)
4490 ecore_timer_del(action_timer);
4491 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4495 _e_border_resize_key_down(void *data __UNUSED__,
4496 int type __UNUSED__,
4499 Ecore_Event_Key *ev = event;
4502 if (ev->event_window != action_input_win)
4503 return ECORE_CALLBACK_PASS_ON;
4506 fputs("ERROR: no action_border!\n", stderr);
4510 w = action_border->w;
4511 h = action_border->h;
4513 dx = e_config->border_keyboard.resize.dx;
4514 if (dx < action_border->client.icccm.step_w)
4515 dx = action_border->client.icccm.step_w;
4516 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4517 if (dx < action_border->client.icccm.step_w)
4518 dx = action_border->client.icccm.step_w;
4520 dy = e_config->border_keyboard.resize.dy;
4521 if (dy < action_border->client.icccm.step_h)
4522 dy = action_border->client.icccm.step_h;
4523 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4524 if (dy < action_border->client.icccm.step_h)
4525 dy = action_border->client.icccm.step_h;
4527 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4529 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4531 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4533 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
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_resize_limit(action_border, &w, &h);
4547 e_border_resize(action_border, w, h);
4548 _e_border_action_resize_timeout_add();
4550 return ECORE_CALLBACK_PASS_ON;
4553 _e_border_resize_end(action_border);
4554 _e_border_action_finish();
4555 return ECORE_CALLBACK_DONE;
4559 _e_border_resize_mouse_down(void *data __UNUSED__,
4560 int type __UNUSED__,
4563 Ecore_Event_Mouse_Button *ev = event;
4565 if (ev->event_window != action_input_win)
4566 return ECORE_CALLBACK_PASS_ON;
4569 fputs("ERROR: no action_border!\n", stderr);
4571 _e_border_resize_end(action_border);
4572 _e_border_action_finish();
4573 return ECORE_CALLBACK_DONE;
4577 e_border_act_resize_keyboard(E_Border *bd)
4582 if (!_e_border_resize_begin(bd))
4585 if (!_e_border_action_input_win_new(bd))
4587 _e_border_resize_end(bd);
4591 _e_border_action_init(bd);
4592 _e_border_action_resize_timeout_add();
4593 _e_border_resize_update(bd);
4595 if (action_handler_key)
4596 ecore_event_handler_del(action_handler_key);
4597 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4599 if (action_handler_mouse)
4600 ecore_event_handler_del(action_handler_mouse);
4601 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4605 e_border_act_move_begin(E_Border *bd,
4606 Ecore_Event_Mouse_Button *ev)
4609 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4610 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4611 if (!_e_border_move_begin(bd))
4614 e_zone_edge_disable();
4616 _e_border_pointer_move_begin(bd);
4621 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4622 _e_border_moveinfo_gather(bd, source);
4627 e_border_act_move_end(E_Border *bd,
4628 Ecore_Event_Mouse_Button *ev __UNUSED__)
4631 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4632 if (!bd->moving) return;
4634 _e_border_pointer_move_end(bd);
4635 e_zone_edge_enable();
4636 _e_border_move_end(bd);
4637 e_zone_flip_coords_handle(bd->zone, -1, -1);
4641 e_border_act_resize_begin(E_Border *bd,
4642 Ecore_Event_Mouse_Button *ev)
4645 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4646 if (bd->lock_user_size) return;
4647 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4648 if (!_e_border_resize_begin(bd))
4650 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4652 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4654 bd->resize_mode = RESIZE_TL;
4655 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4659 bd->resize_mode = RESIZE_BL;
4660 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4665 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4667 bd->resize_mode = RESIZE_TR;
4668 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4672 bd->resize_mode = RESIZE_BR;
4673 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4676 _e_border_pointer_resize_begin(bd);
4681 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4682 _e_border_moveinfo_gather(bd, source);
4687 e_border_act_resize_end(E_Border *bd,
4688 Ecore_Event_Mouse_Button *ev __UNUSED__)
4691 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4692 if (bd->resize_mode != RESIZE_NONE)
4694 _e_border_pointer_resize_end(bd);
4695 bd->resize_mode = RESIZE_NONE;
4696 _e_border_resize_end(bd);
4697 bd->changes.reset_gravity = 1;
4703 e_border_act_menu_begin(E_Border *bd,
4704 Ecore_Event_Mouse_Button *ev,
4708 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4711 e_int_border_menu_show(bd,
4712 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4713 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4720 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4721 e_int_border_menu_show(bd, x, y, key, 0);
4726 e_border_act_close_begin(E_Border *bd)
4729 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4730 if (bd->lock_close) return;
4731 if (bd->client.icccm.delete_request)
4733 bd->delete_requested = 1;
4734 ecore_x_window_delete_request_send(bd->client.win);
4735 if (bd->client.netwm.ping)
4738 else if (e_config->kill_if_close_not_possible)
4740 e_border_act_kill_begin(bd);
4745 e_border_act_kill_begin(E_Border *bd)
4748 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4749 if (bd->internal) return;
4750 if (bd->lock_close) return;
4751 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4753 kill(bd->client.netwm.pid, SIGINT);
4754 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4755 _e_border_cb_kill_timer, bd);
4759 if (!bd->internal) ecore_x_kill(bd->client.win);
4764 e_border_icon_add(E_Border *bd,
4769 E_OBJECT_CHECK_RETURN(bd, NULL);
4770 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4775 if (!bd->internal_icon)
4777 o = e_icon_add(evas);
4778 e_util_icon_theme_set(o, "enlightenment");
4782 if (!bd->internal_icon_key)
4786 ext = strrchr(bd->internal_icon, '.');
4787 if ((ext) && ((!strcmp(ext, ".edj"))))
4789 o = edje_object_add(evas);
4790 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4791 e_util_icon_theme_set(o, "enlightenment");
4795 o = e_icon_add(evas);
4796 e_icon_file_set(o, bd->internal_icon);
4800 o = e_icon_add(evas);
4801 if (!e_util_icon_theme_set(o, bd->internal_icon))
4802 e_util_icon_theme_set(o, "enlightenment");
4807 o = edje_object_add(evas);
4808 edje_object_file_set(o, bd->internal_icon,
4809 bd->internal_icon_key);
4814 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4816 if (bd->client.netwm.icons)
4818 o = e_icon_add(evas);
4819 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4820 bd->client.netwm.icons[0].width,
4821 bd->client.netwm.icons[0].height);
4822 e_icon_alpha_set(o, 1);
4828 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4830 o = e_icon_add(evas);
4833 e_icon_fdo_icon_set(o, bd->desktop->icon);
4837 else if (bd->client.netwm.icons)
4839 o = e_icon_add(evas);
4840 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4841 bd->client.netwm.icons[0].width,
4842 bd->client.netwm.icons[0].height);
4843 e_icon_alpha_set(o, 1);
4848 o = e_icon_add(evas);
4849 e_util_icon_theme_set(o, "unknown");
4854 e_border_button_bindings_ungrab_all(void)
4859 EINA_LIST_FOREACH(borders, l, bd)
4861 e_focus_setdown(bd);
4862 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4863 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4868 e_border_button_bindings_grab_all(void)
4873 EINA_LIST_FOREACH(borders, l, bd)
4875 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
4876 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
4882 e_border_focus_stack_get(void)
4888 e_border_raise_stack_get(void)
4894 e_border_lost_windows_get(E_Zone *zone)
4896 Eina_List *list = NULL, *l;
4898 int loss_overlap = 5;
4900 E_OBJECT_CHECK_RETURN(zone, NULL);
4901 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
4902 EINA_LIST_FOREACH(borders, l, bd)
4907 if ((bd->zone != zone) ||
4908 (bd->zone->container != zone->container))
4911 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
4912 bd->zone->y + loss_overlap,
4913 bd->zone->w - (2 * loss_overlap),
4914 bd->zone->h - (2 * loss_overlap),
4915 bd->x, bd->y, bd->w, bd->h))
4917 list = eina_list_append(list, bd);
4919 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
4920 bd->zone->w, bd->zone->h,
4921 bd->x, bd->y, bd->w, bd->h)) &&
4924 Ecore_X_Rectangle *rect;
4927 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
4933 for (i = 0; i < num; i++)
4935 if (E_INTERSECTS(bd->zone->x + loss_overlap,
4936 bd->zone->y + loss_overlap,
4937 bd->zone->w - (2 * loss_overlap),
4938 bd->zone->h - (2 * loss_overlap),
4939 rect[i].x, rect[i].y,
4940 (int)rect[i].width, (int)rect[i].height))
4948 list = eina_list_append(list, bd);
4956 e_border_ping(E_Border *bd)
4959 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4960 if (!e_config->ping_clients) return;
4962 ecore_x_netwm_ping_send(bd->client.win);
4963 bd->ping = ecore_loop_time_get();
4964 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
4965 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
4966 e_config->ping_clients_interval,
4967 _e_border_cb_ping_poller, bd);
4971 e_border_move_cancel(void)
4975 if (bdmove->cur_mouse_action)
4980 e_object_ref(E_OBJECT(bd));
4981 if (bd->cur_mouse_action->func.end_mouse)
4982 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
4983 else if (bd->cur_mouse_action->func.end)
4984 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
4985 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4986 bd->cur_mouse_action = NULL;
4987 e_object_unref(E_OBJECT(bd));
4990 _e_border_move_end(bdmove);
4995 e_border_resize_cancel(void)
4999 if (bdresize->cur_mouse_action)
5004 e_object_ref(E_OBJECT(bd));
5005 if (bd->cur_mouse_action->func.end_mouse)
5006 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5007 else if (bd->cur_mouse_action->func.end)
5008 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5009 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5010 bd->cur_mouse_action = NULL;
5011 e_object_unref(E_OBJECT(bd));
5015 bdresize->resize_mode = RESIZE_NONE;
5016 _e_border_resize_end(bdresize);
5022 e_border_frame_recalc(E_Border *bd)
5024 if (!bd->bg_object) return;
5026 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5027 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5029 _e_border_client_inset_calc(bd);
5031 bd->w += (bd->client_inset.l + bd->client_inset.r);
5032 bd->h += (bd->client_inset.t + bd->client_inset.b);
5035 bd->changes.size = 1;
5036 if ((bd->shaped) || (bd->client.shaped))
5038 bd->need_shape_merge = 1;
5039 bd->need_shape_export = 1;
5041 if (bd->shaped_input)
5043 bd->need_shape_merge = 1;
5045 _e_border_client_move_resize_send(bd);
5049 e_border_immortal_windows_get(void)
5051 Eina_List *list = NULL, *l;
5054 EINA_LIST_FOREACH(borders, l, bd)
5057 list = eina_list_append(list, bd);
5063 e_border_name_get(const E_Border *bd)
5065 E_OBJECT_CHECK_RETURN(bd, "");
5066 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5067 if (bd->client.netwm.name)
5068 return bd->client.netwm.name;
5069 else if (bd->client.icccm.title)
5070 return bd->client.icccm.title;
5075 e_border_signal_move_begin(E_Border *bd,
5077 const char *src __UNUSED__)
5080 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5082 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5083 if (!_e_border_move_begin(bd)) return;
5085 _e_border_pointer_move_begin(bd);
5086 e_zone_edge_disable();
5087 _e_border_moveinfo_gather(bd, sig);
5088 if (bd->cur_mouse_action)
5090 if ((!bd->cur_mouse_action->func.end_mouse) &&
5091 (!bd->cur_mouse_action->func.end))
5092 bd->cur_mouse_action = NULL;
5094 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5096 bd->cur_mouse_action = e_action_find("window_move");
5097 if (bd->cur_mouse_action)
5098 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5102 e_border_signal_move_end(E_Border *bd,
5103 const char *sig __UNUSED__,
5104 const char *src __UNUSED__)
5107 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5108 if (!bd->moving) return;
5110 _e_border_pointer_move_end(bd);
5111 e_zone_edge_enable();
5112 _e_border_move_end(bd);
5113 e_zone_flip_coords_handle(bd->zone, -1, -1);
5117 e_border_resizing_get(E_Border *bd)
5119 E_OBJECT_CHECK_RETURN(bd, 0);
5120 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5121 if (bd->resize_mode == RESIZE_NONE) return 0;
5126 e_border_signal_resize_begin(E_Border *bd,
5129 const char *src __UNUSED__)
5131 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5132 int resize_mode = RESIZE_BR;
5135 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5137 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5138 if (!_e_border_resize_begin(bd))
5140 if (!strcmp(dir, "tl"))
5142 resize_mode = RESIZE_TL;
5143 grav = ECORE_X_GRAVITY_SE;
5145 else if (!strcmp(dir, "t"))
5147 resize_mode = RESIZE_T;
5148 grav = ECORE_X_GRAVITY_S;
5150 else if (!strcmp(dir, "tr"))
5152 resize_mode = RESIZE_TR;
5153 grav = ECORE_X_GRAVITY_SW;
5155 else if (!strcmp(dir, "r"))
5157 resize_mode = RESIZE_R;
5158 grav = ECORE_X_GRAVITY_W;
5160 else if (!strcmp(dir, "br"))
5162 resize_mode = RESIZE_BR;
5163 grav = ECORE_X_GRAVITY_NW;
5165 else if (!strcmp(dir, "b"))
5167 resize_mode = RESIZE_B;
5168 grav = ECORE_X_GRAVITY_N;
5170 else if (!strcmp(dir, "bl"))
5172 resize_mode = RESIZE_BL;
5173 grav = ECORE_X_GRAVITY_NE;
5175 else if (!strcmp(dir, "l"))
5177 resize_mode = RESIZE_L;
5178 grav = ECORE_X_GRAVITY_E;
5180 bd->resize_mode = resize_mode;
5181 _e_border_pointer_resize_begin(bd);
5182 _e_border_moveinfo_gather(bd, sig);
5184 if (bd->cur_mouse_action)
5186 if ((!bd->cur_mouse_action->func.end_mouse) &&
5187 (!bd->cur_mouse_action->func.end))
5188 bd->cur_mouse_action = NULL;
5190 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5192 bd->cur_mouse_action = e_action_find("window_resize");
5193 if (bd->cur_mouse_action)
5194 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5198 e_border_signal_resize_end(E_Border *bd,
5199 const char *dir __UNUSED__,
5200 const char *sig __UNUSED__,
5201 const char *src __UNUSED__)
5204 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5205 if (bd->resize_mode == RESIZE_NONE) return;
5206 _e_border_resize_handle(bd);
5207 _e_border_pointer_resize_end(bd);
5208 bd->resize_mode = RESIZE_NONE;
5209 _e_border_resize_end(bd);
5210 bd->changes.reset_gravity = 1;
5215 e_border_resize_limit(E_Border *bd,
5222 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5223 *w -= bd->client_inset.l + bd->client_inset.r;
5224 *h -= bd->client_inset.t + bd->client_inset.b;
5227 if ((bd->client.icccm.base_w >= 0) &&
5228 (bd->client.icccm.base_h >= 0))
5232 tw = *w - bd->client.icccm.base_w;
5233 th = *h - bd->client.icccm.base_h;
5236 a = (double)(tw) / (double)(th);
5237 if ((bd->client.icccm.min_aspect != 0.0) &&
5238 (a < bd->client.icccm.min_aspect))
5240 th = tw / bd->client.icccm.max_aspect;
5241 *h = th + bd->client.icccm.base_h;
5243 else if ((bd->client.icccm.max_aspect != 0.0) &&
5244 (a > bd->client.icccm.max_aspect))
5246 tw = th * bd->client.icccm.max_aspect;
5247 *w = tw + bd->client.icccm.base_w;
5252 a = (double)*w / (double)*h;
5253 if ((bd->client.icccm.min_aspect != 0.0) &&
5254 (a < bd->client.icccm.min_aspect))
5255 *h = *w / bd->client.icccm.min_aspect;
5256 else if ((bd->client.icccm.max_aspect != 0.0) &&
5257 (a > bd->client.icccm.max_aspect))
5258 *w = *h * bd->client.icccm.max_aspect;
5260 if (bd->client.icccm.step_w > 0)
5262 if (bd->client.icccm.base_w >= 0)
5263 *w = bd->client.icccm.base_w +
5264 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5265 bd->client.icccm.step_w);
5267 *w = bd->client.icccm.min_w +
5268 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5269 bd->client.icccm.step_w);
5271 if (bd->client.icccm.step_h > 0)
5273 if (bd->client.icccm.base_h >= 0)
5274 *h = bd->client.icccm.base_h +
5275 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5276 bd->client.icccm.step_h);
5278 *h = bd->client.icccm.min_h +
5279 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5280 bd->client.icccm.step_h);
5286 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5287 else if (*w < bd->client.icccm.min_w)
5288 *w = bd->client.icccm.min_w;
5289 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5290 else if (*h < bd->client.icccm.min_h)
5291 *h = bd->client.icccm.min_h;
5293 *w += bd->client_inset.l + bd->client_inset.r;
5294 *h += bd->client_inset.t + bd->client_inset.b;
5297 /* local subsystem functions */
5299 _e_border_free(E_Border *bd)
5301 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5304 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5306 bd->client.e.state.video_parent_border->client.e.state.video_child =
5308 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5311 if (bd->client.e.state.video_child)
5315 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5317 tmp->client.e.state.video_parent_border = NULL;
5322 efreet_desktop_free(bd->desktop);
5327 ecore_idle_enterer_del(bd->post_job);
5328 bd->post_job = NULL;
5332 e_object_del(E_OBJECT(bd->pointer));
5336 _e_border_resize_end(bd);
5338 _e_border_move_end(bd);
5339 /* TODO: Other states to end before dying? */
5341 if (bd->cur_mouse_action)
5343 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5344 bd->cur_mouse_action = NULL;
5347 E_FREE(bd->shape_rects);
5348 bd->shape_rects_num = 0;
5350 if (bd->dangling_ref_check)
5352 ecore_timer_del(bd->dangling_ref_check);
5353 bd->dangling_ref_check = NULL;
5358 ecore_timer_del(bd->kill_timer);
5359 bd->kill_timer = NULL;
5361 if (bd->ping_poller)
5363 ecore_poller_del(bd->ping_poller);
5364 bd->ping_poller = NULL;
5366 E_FREE_LIST(bd->pending_move_resize, free);
5368 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5369 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5371 if (bd->border_locks_dialog)
5373 e_object_del(E_OBJECT(bd->border_locks_dialog));
5374 bd->border_locks_dialog = NULL;
5376 if (bd->border_remember_dialog)
5378 e_object_del(E_OBJECT(bd->border_remember_dialog));
5379 bd->border_remember_dialog = NULL;
5381 if (bd->border_border_dialog)
5383 e_object_del(E_OBJECT(bd->border_border_dialog));
5384 bd->border_border_dialog = NULL;
5386 if (bd->border_prop_dialog)
5388 e_object_del(E_OBJECT(bd->border_prop_dialog));
5389 bd->border_prop_dialog = NULL;
5392 e_int_border_menu_del(bd);
5397 focus_next = eina_list_remove(focus_next, bd);
5399 if ((focused == bd) ||
5400 (e_grabinput_last_focus_win_get() == bd->client.win))
5402 if ((!focus_next) && (!focusing))
5404 e_grabinput_focus(bd->zone->container->bg_win,
5405 E_FOCUS_METHOD_PASSIVE);
5406 e_hints_active_window_set(bd->zone->container->manager, NULL);
5411 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5417 bd->remember = NULL;
5418 e_remember_unuse(rem);
5420 if (!bd->already_unparented)
5422 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5423 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5424 ecore_x_window_save_set_del(bd->client.win);
5425 bd->already_unparented = 1;
5427 if (bd->group) eina_list_free(bd->group);
5428 if (bd->transients) eina_list_free(bd->transients);
5429 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5430 if (bd->client.netwm.icons)
5433 for (i = 0; i < bd->client.netwm.num_icons; i++)
5434 free(bd->client.netwm.icons[i].data);
5435 free(bd->client.netwm.icons);
5437 if (bd->client.netwm.extra_types)
5438 free(bd->client.netwm.extra_types);
5439 if (bd->client.border.name)
5440 eina_stringshare_del(bd->client.border.name);
5442 eina_stringshare_del(bd->bordername);
5443 if (bd->client.icccm.name)
5444 eina_stringshare_del(bd->client.icccm.name);
5445 if (bd->client.icccm.class)
5447 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5448 e_bindings_mapping_change_enable(EINA_TRUE);
5449 eina_stringshare_del(bd->client.icccm.class);
5451 if (bd->client.icccm.title)
5452 eina_stringshare_del(bd->client.icccm.title);
5453 if (bd->client.icccm.icon_name)
5454 eina_stringshare_del(bd->client.icccm.icon_name);
5455 if (bd->client.icccm.machine)
5456 eina_stringshare_del(bd->client.icccm.machine);
5457 if (bd->client.icccm.window_role)
5458 eina_stringshare_del(bd->client.icccm.window_role);
5460 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5464 for (i = 0; i < bd->client.icccm.command.argc; i++)
5465 free(bd->client.icccm.command.argv[i]);
5466 free(bd->client.icccm.command.argv);
5468 if (bd->client.netwm.name)
5469 eina_stringshare_del(bd->client.netwm.name);
5470 if (bd->client.netwm.icon_name)
5471 eina_stringshare_del(bd->client.netwm.icon_name);
5472 e_object_del(E_OBJECT(bd->shape));
5473 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5474 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5475 if (bd->icon_object) evas_object_del(bd->icon_object);
5476 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5477 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5479 if (str) eina_stringshare_del(str);
5481 bd->client.e.state.profiles = NULL;
5482 if (bd->client.e.state.profile)
5483 eina_stringshare_del(bd->client.e.state.profile);
5484 bd->client.e.state.profile = NULL;
5486 #ifdef _F_ZONE_WINDOW_ROTATION_
5487 if (e_config->wm_win_rotation)
5489 bd->client.e.fetch.rot.app_set = 0;
5490 bd->client.e.state.rot.preferred_rot = -1;
5492 if (bd->client.e.state.rot.available_rots)
5493 E_FREE(bd->client.e.state.rot.available_rots);
5495 _e_border_rotation_list_remove(bd);
5496 if ((rot.vkbd) && (rot.vkbd == bd))
5498 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5500 if (rot.vkbd_ctrl_win)
5502 ELB(ELBT_BD, "SET KBD_OFF", 0);
5503 ecore_x_e_virtual_keyboard_state_set
5504 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5507 rot.vkbd_hide_prepare_done = EINA_FALSE;
5508 if (rot.vkbd_hide_prepare_timer)
5509 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5510 rot.vkbd_hide_prepare_timer = NULL;
5511 if (rot.vkbd_hide_timer)
5512 ecore_timer_del(rot.vkbd_hide_timer);
5513 rot.vkbd_hide_timer = NULL;
5515 rot.vkbd_show_prepare_done = EINA_FALSE;
5516 if (rot.vkbd_show_prepare_timer)
5517 ecore_timer_del(rot.vkbd_show_prepare_timer);
5518 rot.vkbd_show_prepare_timer = NULL;
5519 if (rot.vkbd_show_timer)
5520 ecore_timer_del(rot.vkbd_show_timer);
5521 rot.vkbd_show_timer = NULL;
5523 else if ((rot.vkbd_prediction) &&
5524 (rot.vkbd_prediction == bd))
5525 rot.vkbd_prediction = NULL;
5528 evas_object_del(bd->bg_object);
5529 e_canvas_del(bd->bg_ecore_evas);
5530 ecore_evas_free(bd->bg_ecore_evas);
5531 ecore_x_window_free(bd->client.shell_win);
5532 e_focus_setdown(bd);
5533 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5534 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5535 ecore_x_window_free(bd->win);
5537 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5538 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5539 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5540 borders = eina_list_remove(borders, bd);
5541 focus_stack = eina_list_remove(focus_stack, bd);
5542 raise_stack = eina_list_remove(raise_stack, bd);
5544 e_container_border_remove(bd);
5550 _e_border_del_dangling_ref_check(void *data)
5556 printf("EEK EEK border still around 1 second after being deleted!\n");
5557 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5558 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5559 bd->client.icccm.name, bd->client.icccm.class);
5560 // e_object_breadcrumb_debug(E_OBJECT(bd));
5567 _e_border_del(E_Border *bd)
5569 E_Event_Border_Remove *ev;
5572 #ifdef _F_BORDER_HOOK_PATCH_
5573 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5584 focus_next = eina_list_remove(focus_next, bd);
5586 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5588 if ((drag_border) && (drag_border->data == bd))
5590 e_object_del(E_OBJECT(drag_border));
5593 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5595 if (bd->border_locks_dialog)
5597 e_object_del(E_OBJECT(bd->border_locks_dialog));
5598 bd->border_locks_dialog = NULL;
5600 if (bd->border_remember_dialog)
5602 e_object_del(E_OBJECT(bd->border_remember_dialog));
5603 bd->border_remember_dialog = NULL;
5605 if (bd->border_border_dialog)
5607 e_object_del(E_OBJECT(bd->border_border_dialog));
5608 bd->border_border_dialog = NULL;
5610 if (bd->border_prop_dialog)
5612 e_object_del(E_OBJECT(bd->border_prop_dialog));
5613 bd->border_prop_dialog = NULL;
5616 e_int_border_menu_del(bd);
5618 if (bd->raise_timer)
5620 ecore_timer_del(bd->raise_timer);
5621 bd->raise_timer = NULL;
5623 if (!bd->already_unparented)
5625 ecore_x_window_reparent(bd->client.win,
5626 bd->zone->container->manager->root,
5627 bd->x + bd->client_inset.l,
5628 bd->y + bd->client_inset.t);
5629 ecore_x_window_save_set_del(bd->client.win);
5630 bd->already_unparented = 1;
5631 // bd->client.win = 0;
5633 bd->already_unparented = 1;
5635 if ((!bd->new_client) && (!stopping))
5637 ev = E_NEW(E_Event_Border_Remove, 1);
5639 e_object_ref(E_OBJECT(bd));
5640 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5641 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5644 #ifdef _F_DEICONIFY_APPROVE_
5645 if (bd->client.e.state.deiconify_approve.wait_timer)
5647 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5648 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5654 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5655 if (bd->parent->modal == bd)
5657 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5658 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5659 bd->parent->lock_close = 0;
5660 bd->parent->saved.event_mask = 0;
5661 bd->parent->modal = NULL;
5665 EINA_LIST_FREE(bd->transients, child)
5667 child->parent = NULL;
5672 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5673 if (bd->leader->modal == bd)
5674 bd->leader->modal = NULL;
5677 EINA_LIST_FREE(bd->group, child)
5679 child->leader = NULL;
5683 #ifdef PRINT_LOTS_OF_DEBUG
5685 _e_border_print(E_Border *bd,
5694 "\tBorderless: %s\n",
5695 bd, bd->client.icccm.name, bd->client.icccm.title,
5696 bd->borderless ? "TRUE" : "FALSE");
5702 _e_border_cb_window_show_request(void *data __UNUSED__,
5703 int ev_type __UNUSED__,
5707 Ecore_X_Event_Window_Show_Request *e;
5710 bd = e_border_find_by_client_window(e->win);
5711 if (!bd) return ECORE_CALLBACK_PASS_ON;
5714 if (!bd->lock_client_iconify)
5715 e_border_uniconify(bd);
5719 /* FIXME: make border "urgent" for a bit - it wants attention */
5720 /* e_border_show(bd); */
5721 if (!bd->lock_client_stacking)
5724 return ECORE_CALLBACK_PASS_ON;
5728 _e_border_cb_window_destroy(void *data __UNUSED__,
5729 int ev_type __UNUSED__,
5733 Ecore_X_Event_Window_Destroy *e;
5736 bd = e_border_find_by_client_window(e->win);
5737 if (!bd) return ECORE_CALLBACK_PASS_ON;
5738 e_border_hide(bd, 0);
5739 e_object_del(E_OBJECT(bd));
5740 return ECORE_CALLBACK_PASS_ON;
5744 _e_border_cb_window_hide(void *data __UNUSED__,
5745 int ev_type __UNUSED__,
5748 E_Border *bd = NULL;
5749 Ecore_X_Event_Window_Hide *e;
5752 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5753 // not interested in hide events from windows other than the window in question
5754 if (e->win != e->event_win)
5756 bd = e_border_find_by_client_window(e->win);
5757 if (!bd) return ECORE_CALLBACK_PASS_ON;
5758 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5762 (bd->zone->container->manager->root == e->event_win)))
5763 return ECORE_CALLBACK_PASS_ON;
5766 if (!bd) bd = e_border_find_by_client_window(e->win);
5767 // printf(" bd = %p\n", bd);
5770 if (ecore_x_window_visible_get(e->win))
5772 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5773 ecore_x_window_hide(e->win);
5775 return ECORE_CALLBACK_PASS_ON;
5778 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5779 if (bd->ignore_first_unmap > 0)
5781 bd->ignore_first_unmap--;
5782 return ECORE_CALLBACK_PASS_ON;
5784 /* Don't delete hidden or iconified windows */
5785 #ifdef _F_USE_EXTENDED_ICONIFY_
5786 if (bd->await_hide_event > 0)
5788 if ((bd->iconic) || (bd->await_hide_event > 0))
5791 // printf(" Don't delete hidden or iconified windows\n");
5792 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
5793 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
5794 if (bd->await_hide_event > 0)
5796 bd->await_hide_event--;
5800 // printf(" hide really\n");
5801 /* Only hide the border if it is visible */
5802 if (bd->visible) e_border_hide(bd, 1);
5807 // printf(" hide2\n");
5808 #ifdef _F_USE_EXTENDED_ICONIFY_
5815 e_border_hide(bd, 0);
5816 e_object_del(E_OBJECT(bd));
5818 return ECORE_CALLBACK_PASS_ON;
5822 _e_border_cb_window_reparent(void *data __UNUSED__,
5823 int ev_type __UNUSED__,
5824 void *ev __UNUSED__)
5828 Ecore_X_Event_Window_Reparent *e;
5831 bd = e_border_find_by_client_window(e->win);
5833 if (e->parent == bd->client.shell_win) return 1;
5834 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
5838 e_border_hide(bd, 0);
5839 e_object_del(E_OBJECT(bd));
5841 return ECORE_CALLBACK_PASS_ON;
5845 _e_border_cb_window_configure_request(void *data __UNUSED__,
5846 int ev_type __UNUSED__,
5850 Ecore_X_Event_Window_Configure_Request *e;
5853 bd = e_border_find_by_client_window(e->win);
5856 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
5857 if (!e_util_container_window_find(e->win))
5858 ecore_x_window_configure(e->win, e->value_mask,
5859 e->x, e->y, e->w, e->h, e->border,
5860 e->abovewin, e->detail);
5861 return ECORE_CALLBACK_PASS_ON;
5864 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
5865 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
5871 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
5873 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
5875 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
5876 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
5882 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
5883 w = e->w + bd->client_inset.l + bd->client_inset.r;
5884 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
5885 h = e->h + bd->client_inset.t + bd->client_inset.b;
5886 if ((!bd->lock_client_location) && (!bd->lock_client_size))
5888 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5890 bd->saved.x = x - bd->zone->x;
5891 bd->saved.y = y - bd->zone->y;
5896 e_border_move_resize(bd, x, y, w, h);
5898 else if (!bd->lock_client_location)
5900 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5902 bd->saved.x = x - bd->zone->x;
5903 bd->saved.y = y - bd->zone->y;
5906 e_border_move(bd, x, y);
5908 else if (!bd->lock_client_size)
5910 if ((bd->shaded) || (bd->shading))
5916 if ((bd->shade.dir == E_DIRECTION_UP) ||
5917 (bd->shade.dir == E_DIRECTION_DOWN))
5919 e_border_resize(bd, w, bd->h);
5924 e_border_resize(bd, bd->w, h);
5930 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5936 e_border_resize(bd, w, h);
5942 if (!bd->lock_client_location)
5944 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5946 bd->saved.x = x - bd->zone->x;
5947 bd->saved.y = y - bd->zone->y;
5950 e_border_move(bd, x, y);
5954 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
5955 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
5961 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
5962 w = e->w + bd->client_inset.l + bd->client_inset.r;
5963 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
5964 h = e->h + bd->client_inset.t + bd->client_inset.b;
5965 #ifdef _F_ZONE_WINDOW_ROTATION_
5966 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
5968 if (!bd->lock_client_size)
5970 if ((bd->shaded) || (bd->shading))
5976 if ((bd->shade.dir == E_DIRECTION_UP) ||
5977 (bd->shade.dir == E_DIRECTION_DOWN))
5979 e_border_resize(bd, w, bd->h);
5984 e_border_resize(bd, bd->w, h);
5990 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
5995 zx = zy = zw = zh = 0;
5998 * This code does resize and move a window on a
5999 * X configure request into an useful geometry.
6000 * This is really useful for size jumping file dialogs.
6005 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6007 if (e_config->geometry_auto_resize_limit == 1)
6016 e_border_resize(bd, w, h);
6018 if (e_config->geometry_auto_move == 1)
6020 /* z{x,y,w,h} are only set here; FIXME! */
6023 // move window horizontal if resize to not useful geometry
6024 if (bd->x + bd->w > zx + zw)
6025 rx = zx + zw - bd->w;
6026 else if (bd->x < zx)
6029 // move window vertical if resize to not useful geometry
6030 if (bd->y + bd->h > zy + zh)
6031 ry = zy + zh - bd->h;
6032 else if (bd->y < zy)
6035 e_border_move(bd, rx, ry);
6041 if (!bd->lock_client_stacking)
6043 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6044 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6048 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6050 obd = e_border_find_by_client_window(e->abovewin);
6053 e_border_stack_above(bd, obd);
6057 ecore_x_window_configure(bd->win,
6058 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6059 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6061 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6062 /* FIXME: need to rebuiuld border list from current stacking */
6065 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6067 obd = e_border_find_by_client_window(e->abovewin);
6070 e_border_stack_below(bd, obd);
6074 ecore_x_window_configure(bd->win,
6075 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6076 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6078 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6079 /* FIXME: need to rebuiuld border list from current stacking */
6082 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6086 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6090 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6095 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6097 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6101 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6105 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6109 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6113 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6120 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6121 _e_border_client_move_resize_send(bd);
6122 return ECORE_CALLBACK_PASS_ON;
6126 _e_border_cb_window_resize_request(void *data __UNUSED__,
6127 int ev_type __UNUSED__,
6131 Ecore_X_Event_Window_Resize_Request *e;
6134 bd = e_border_find_by_client_window(e->win);
6137 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6138 ecore_x_window_resize(e->win, e->w, e->h);
6139 return ECORE_CALLBACK_PASS_ON;
6144 w = e->w + bd->client_inset.l + bd->client_inset.r;
6145 h = e->h + bd->client_inset.t + bd->client_inset.b;
6146 if ((bd->shaded) || (bd->shading))
6152 if ((bd->shade.dir == E_DIRECTION_UP) ||
6153 (bd->shade.dir == E_DIRECTION_DOWN))
6155 e_border_resize(bd, w, bd->h);
6160 e_border_resize(bd, bd->w, h);
6165 e_border_resize(bd, w, h);
6168 _e_border_client_move_resize_send(bd);
6169 return ECORE_CALLBACK_PASS_ON;
6173 _e_border_cb_window_gravity(void *data __UNUSED__,
6174 int ev_type __UNUSED__,
6175 void *ev __UNUSED__)
6178 // Ecore_X_Event_Window_Gravity *e;
6181 // bd = e_border_find_by_client_window(e->win);
6182 // if (!bd) return 1;
6187 _e_border_cb_window_stack_request(void *data __UNUSED__,
6188 int ev_type __UNUSED__,
6192 Ecore_X_Event_Window_Stack_Request *e;
6195 bd = e_border_find_by_client_window(e->win);
6198 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6199 if (!e_util_container_window_find(e->win))
6201 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6202 ecore_x_window_raise(e->win);
6203 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6204 ecore_x_window_lower(e->win);
6206 return ECORE_CALLBACK_PASS_ON;
6208 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6210 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6212 return ECORE_CALLBACK_PASS_ON;
6216 _e_border_cb_window_property(void *data __UNUSED__,
6217 int ev_type __UNUSED__,
6221 Ecore_X_Event_Window_Property *e;
6224 bd = e_border_find_by_client_window(e->win);
6225 if (!bd) return ECORE_CALLBACK_PASS_ON;
6226 if (e->atom == ECORE_X_ATOM_WM_NAME)
6228 if ((!bd->client.netwm.name) &&
6229 (!bd->client.netwm.fetch.name))
6231 bd->client.icccm.fetch.title = 1;
6235 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6237 bd->client.netwm.fetch.name = 1;
6240 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6242 bd->client.icccm.fetch.name_class = 1;
6245 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6247 if ((!bd->client.netwm.icon_name) &&
6248 (!bd->client.netwm.fetch.icon_name))
6250 bd->client.icccm.fetch.icon_name = 1;
6254 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6256 bd->client.netwm.fetch.icon_name = 1;
6259 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6261 bd->client.icccm.fetch.machine = 1;
6264 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6266 bd->client.icccm.fetch.protocol = 1;
6269 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6271 bd->client.icccm.fetch.hints = 1;
6274 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6276 bd->client.icccm.fetch.size_pos_hints = 1;
6279 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6282 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6283 (!bd->client.netwm.fetch.type))
6286 bd->client.mwm.fetch.hints = 1;
6292 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6294 bd->client.icccm.fetch.transient_for = 1;
6297 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6299 bd->client.icccm.fetch.client_leader = 1;
6302 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6304 bd->client.icccm.fetch.window_role = 1;
6307 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6309 bd->client.netwm.fetch.icon = 1;
6312 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6314 bd->client.qtopia.fetch.soft_menu = 1;
6317 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6319 bd->client.qtopia.fetch.soft_menus = 1;
6322 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6324 bd->client.vkbd.fetch.state = 1;
6327 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6329 bd->client.vkbd.fetch.vkbd = 1;
6332 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6334 bd->client.illume.conformant.fetch.conformant = 1;
6337 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6339 bd->client.illume.quickpanel.fetch.state = 1;
6342 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6344 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6347 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6349 bd->client.illume.quickpanel.fetch.priority.major = 1;
6352 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6354 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6357 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6359 bd->client.illume.quickpanel.fetch.zone = 1;
6362 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6364 bd->client.illume.drag.fetch.locked = 1;
6367 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6369 bd->client.illume.drag.fetch.drag = 1;
6372 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6374 bd->client.illume.win_state.fetch.state = 1;
6378 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6380 bd->client.netwm.fetch.user_time = 1;
6383 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6385 bd->client.netwm.fetch.strut = 1;
6388 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6390 bd->client.netwm.fetch.strut = 1;
6394 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6396 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6398 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6400 bd->client.e.fetch.video_position = 1;
6403 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6405 bd->client.e.fetch.video_parent = 1;
6408 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6410 bd->client.netwm.fetch.state = 1;
6413 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6414 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6416 bd->client.e.fetch.profile_list = 1;
6420 #ifdef _F_ZONE_WINDOW_ROTATION_
6421 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6423 if (e_config->wm_win_rotation)
6425 bd->client.e.fetch.rot.support = 1;
6429 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6430 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6431 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6432 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6434 if (e_config->wm_win_rotation)
6436 bd->client.e.fetch.rot.geom_hint = 1;
6440 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6442 if (e_config->wm_win_rotation)
6444 bd->client.e.fetch.rot.app_set = 1;
6448 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6450 if (e_config->wm_win_rotation)
6452 bd->client.e.fetch.rot.preferred_rot = 1;
6456 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6458 if (e_config->wm_win_rotation)
6460 bd->client.e.fetch.rot.available_rots = 1;
6466 return ECORE_CALLBACK_PASS_ON;
6470 _e_border_cb_window_colormap(void *data __UNUSED__,
6471 int ev_type __UNUSED__,
6475 Ecore_X_Event_Window_Colormap *e;
6478 bd = e_border_find_by_client_window(e->win);
6479 if (!bd) return ECORE_CALLBACK_PASS_ON;
6480 return ECORE_CALLBACK_PASS_ON;
6484 _e_border_cb_window_shape(void *data __UNUSED__,
6485 int ev_type __UNUSED__,
6489 Ecore_X_Event_Window_Shape *e;
6492 bd = e_border_find_by_client_window(e->win);
6494 if (e->type == ECORE_X_SHAPE_INPUT)
6498 bd->need_shape_merge = 1;
6499 // YYY bd->shaped_input = 1;
6500 bd->changes.shape_input = 1;
6504 return ECORE_CALLBACK_PASS_ON;
6509 bd->changes.shape = 1;
6511 return ECORE_CALLBACK_PASS_ON;
6513 bd = e_border_find_by_window(e->win);
6516 bd->need_shape_export = 1;
6518 return ECORE_CALLBACK_PASS_ON;
6520 bd = e_border_find_by_frame_window(e->win);
6523 bd->need_shape_merge = 1;
6525 return ECORE_CALLBACK_PASS_ON;
6527 return ECORE_CALLBACK_PASS_ON;
6531 _e_border_cb_window_focus_in(void *data __UNUSED__,
6532 int ev_type __UNUSED__,
6536 Ecore_X_Event_Window_Focus_In *e;
6539 bd = e_border_find_by_client_window(e->win);
6540 if (!bd) return ECORE_CALLBACK_PASS_ON;
6541 #ifdef INOUTDEBUG_FOCUS
6546 const char *modes[] = {
6548 "MODE_WHILE_GRABBED",
6552 const char *details[] = {
6556 "DETAIL_NON_LINEAR",
6557 "DETAIL_NON_LINEAR_VIRTUAL",
6559 "DETAIL_POINTER_ROOT",
6560 "DETAIL_DETAIL_NONE"
6564 ct[strlen(ct) - 1] = 0;
6565 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6570 details[e->detail]);
6572 DBG("%s cb focus in %d %d\n",
6573 e_border_name_get(bd),
6574 bd->client.icccm.accepts_focus,
6575 bd->client.icccm.take_focus);
6578 _e_border_pri_raise(bd);
6579 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6581 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6583 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6585 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6588 /* ignore focus in from !take_focus windows, we just gave it em */
6589 /* if (!bd->client.icccm.take_focus)
6590 * return ECORE_CALLBACK_PASS_ON; */
6592 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6593 if (e->time >= focus_time)
6594 e_border_focus_set(bd, 1, 0);
6595 return ECORE_CALLBACK_PASS_ON;
6599 _e_border_cb_window_focus_out(void *data __UNUSED__,
6600 int ev_type __UNUSED__,
6604 Ecore_X_Event_Window_Focus_Out *e;
6607 bd = e_border_find_by_client_window(e->win);
6608 if (!bd) return ECORE_CALLBACK_PASS_ON;
6609 #ifdef INOUTDEBUG_FOCUS
6614 const char *modes[] = {
6616 "MODE_WHILE_GRABBED",
6620 const char *details[] = {
6624 "DETAIL_NON_LINEAR",
6625 "DETAIL_NON_LINEAR_VIRTUAL",
6627 "DETAIL_POINTER_ROOT",
6628 "DETAIL_DETAIL_NONE"
6632 ct[strlen(ct) - 1] = 0;
6633 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6638 details[e->detail]);
6640 DBG("%s cb focus out %d %d",
6641 e_border_name_get(bd),
6642 bd->client.icccm.accepts_focus,
6643 bd->client.icccm.take_focus);
6646 _e_border_pri_norm(bd);
6647 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6649 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6650 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6651 return ECORE_CALLBACK_PASS_ON;
6652 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6653 return ECORE_CALLBACK_PASS_ON;
6655 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6657 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6658 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6659 return ECORE_CALLBACK_PASS_ON;
6660 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6661 return ECORE_CALLBACK_PASS_ON;
6662 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6663 return ECORE_CALLBACK_PASS_ON;
6664 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6665 return ECORE_CALLBACK_PASS_ON;
6667 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6669 /* for firefox/thunderbird (xul) menu walking */
6670 /* NB: why did i disable this before? */
6671 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6672 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6673 return ECORE_CALLBACK_PASS_ON;
6675 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6677 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6678 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6679 return ECORE_CALLBACK_PASS_ON;
6681 e_border_focus_set(bd, 0, 0);
6682 return ECORE_CALLBACK_PASS_ON;
6685 #if _F_BORDER_CLIP_TO_ZONE_
6687 _e_border_shape_input_clip_to_zone(E_Border *bd)
6689 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6693 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6694 bd->zone->w, bd->zone->h,
6695 bd->x, bd->y, bd->w, bd->h)))
6698 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6699 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6700 bd->zone->x, bd->zone->y,
6701 bd->zone->w, bd->zone->h);
6704 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6705 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6709 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6710 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6713 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6716 _e_border_cb_client_message(void *data __UNUSED__,
6717 int ev_type __UNUSED__,
6720 Ecore_X_Event_Client_Message *e;
6724 #ifdef _F_DEICONIFY_APPROVE_
6725 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6727 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6729 bd = e_border_find_by_client_window(e->win);
6732 if (bd->client.e.state.deiconify_approve.support)
6734 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6735 if (bd->client.e.state.deiconify_approve.wait_timer)
6737 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
6738 bd->client.e.state.deiconify_approve.wait_timer = NULL;
6740 bd->client.e.state.deiconify_approve.render_done = 1;
6741 e_border_uniconify(bd);
6744 return ECORE_CALLBACK_PASS_ON;
6748 #ifdef _F_ZONE_WINDOW_ROTATION_
6749 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
6751 bd = e_border_find_by_client_window(e->win);
6754 if (e_config->wm_win_rotation)
6756 Ecore_X_Event_Client_Message *msg = NULL;
6757 Ecore_X_Atom t = e->message_type;
6758 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
6759 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
6760 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
6761 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
6763 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
6764 if (!msg) return ECORE_CALLBACK_PASS_ON;
6767 msg->message_type = e->message_type;
6768 msg->data.l[0] = e->data.l[0];
6769 msg->data.l[1] = e->data.l[1];
6770 msg->data.l[2] = e->data.l[2];
6771 msg->data.l[3] = e->data.l[3];
6772 msg->data.l[4] = e->data.l[4];
6773 rot.msgs = eina_list_append(rot.msgs, msg);
6775 rot.fetch = EINA_TRUE;
6778 return ECORE_CALLBACK_PASS_ON;
6781 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
6783 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
6784 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
6786 if (e_config->wm_win_rotation)
6788 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
6789 _e_border_rotation_list_remove(bd);
6793 return ECORE_CALLBACK_PASS_ON;
6797 _e_border_cb_window_state_request(void *data __UNUSED__,
6798 int ev_type __UNUSED__,
6802 Ecore_X_Event_Window_State_Request *e;
6806 bd = e_border_find_by_client_window(e->win);
6807 if (!bd) return ECORE_CALLBACK_PASS_ON;
6809 for (i = 0; i < 2; i++)
6810 e_hints_window_state_update(bd, e->state[i], e->action);
6812 return ECORE_CALLBACK_PASS_ON;
6816 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
6817 int ev_type __UNUSED__,
6821 Ecore_X_Event_Window_Move_Resize_Request *e;
6824 bd = e_border_find_by_client_window(e->win);
6825 if (!bd) return ECORE_CALLBACK_PASS_ON;
6827 if ((bd->shaded) || (bd->shading) ||
6828 (bd->fullscreen) || (bd->moving) ||
6829 (bd->resize_mode != RESIZE_NONE))
6830 return ECORE_CALLBACK_PASS_ON;
6832 if ((e->button >= 1) && (e->button <= 3))
6834 bd->mouse.last_down[e->button - 1].mx = e->x;
6835 bd->mouse.last_down[e->button - 1].my = e->y;
6836 bd->mouse.last_down[e->button - 1].x = bd->x;
6837 bd->mouse.last_down[e->button - 1].y = bd->y;
6838 bd->mouse.last_down[e->button - 1].w = bd->w;
6839 bd->mouse.last_down[e->button - 1].h = bd->h;
6843 bd->moveinfo.down.x = bd->x;
6844 bd->moveinfo.down.y = bd->y;
6845 bd->moveinfo.down.w = bd->w;
6846 bd->moveinfo.down.h = bd->h;
6848 bd->mouse.current.mx = e->x;
6849 bd->mouse.current.my = e->y;
6850 bd->moveinfo.down.button = e->button;
6851 bd->moveinfo.down.mx = e->x;
6852 bd->moveinfo.down.my = e->y;
6855 if (!bd->lock_user_stacking)
6858 if (e->direction == MOVE)
6860 bd->cur_mouse_action = e_action_find("window_move");
6861 if (bd->cur_mouse_action)
6863 if ((!bd->cur_mouse_action->func.end_mouse) &&
6864 (!bd->cur_mouse_action->func.end))
6865 bd->cur_mouse_action = NULL;
6866 if (bd->cur_mouse_action)
6868 e_object_ref(E_OBJECT(bd->cur_mouse_action));
6869 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
6872 return ECORE_CALLBACK_PASS_ON;
6875 if (!_e_border_resize_begin(bd))
6876 return ECORE_CALLBACK_PASS_ON;
6878 switch (e->direction)
6881 bd->resize_mode = RESIZE_TL;
6882 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
6886 bd->resize_mode = RESIZE_T;
6887 GRAV_SET(bd, ECORE_X_GRAVITY_S);
6891 bd->resize_mode = RESIZE_TR;
6892 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
6896 bd->resize_mode = RESIZE_R;
6897 GRAV_SET(bd, ECORE_X_GRAVITY_W);
6901 bd->resize_mode = RESIZE_BR;
6902 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
6906 bd->resize_mode = RESIZE_B;
6907 GRAV_SET(bd, ECORE_X_GRAVITY_N);
6911 bd->resize_mode = RESIZE_BL;
6912 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
6916 bd->resize_mode = RESIZE_L;
6917 GRAV_SET(bd, ECORE_X_GRAVITY_E);
6921 return ECORE_CALLBACK_PASS_ON;
6924 bd->cur_mouse_action = e_action_find("window_resize");
6925 if (bd->cur_mouse_action)
6927 if ((!bd->cur_mouse_action->func.end_mouse) &&
6928 (!bd->cur_mouse_action->func.end))
6929 bd->cur_mouse_action = NULL;
6931 if (bd->cur_mouse_action)
6932 e_object_ref(E_OBJECT(bd->cur_mouse_action));
6934 return ECORE_CALLBACK_PASS_ON;
6938 _e_border_cb_desktop_change(void *data __UNUSED__,
6939 int ev_type __UNUSED__,
6943 Ecore_X_Event_Desktop_Change *e;
6946 bd = e_border_find_by_client_window(e->win);
6949 if (e->desk == 0xffffffff)
6951 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
6955 desk = e_desk_at_pos_get(bd->zone, e->desk);
6957 e_border_desk_set(bd, desk);
6962 ecore_x_netwm_desktop_set(e->win, e->desk);
6964 return ECORE_CALLBACK_PASS_ON;
6968 _e_border_cb_sync_alarm(void *data __UNUSED__,
6969 int ev_type __UNUSED__,
6973 Ecore_X_Event_Sync_Alarm *e;
6974 unsigned int serial;
6977 bd = e_border_find_by_alarm(e->alarm);
6978 if (!bd) return ECORE_CALLBACK_PASS_ON;
6980 if (bd->client.netwm.sync.wait)
6981 bd->client.netwm.sync.wait--;
6983 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
6985 E_Border_Pending_Move_Resize *pnd = NULL;
6987 /* skip pending for which we didn't get a reply */
6988 while (bd->pending_move_resize)
6990 pnd = bd->pending_move_resize->data;
6991 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
6993 if (serial == pnd->serial)
7005 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7006 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7011 bd->changes.size = 1;
7012 bd->changes.pos = 1;
7015 evas_render(bd->bg_evas);
7017 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7018 &bd->mouse.current.mx,
7019 &bd->mouse.current.my);
7021 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7022 _e_border_resize_handle(bd);
7024 return ECORE_CALLBACK_PASS_ON;
7028 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7029 int ev_type __UNUSED__,
7030 void *ev __UNUSED__)
7035 /* mark all borders for desktop/icon updates */
7036 EINA_LIST_FOREACH(borders, l, bd)
7040 efreet_desktop_free(bd->desktop);
7043 bd->changes.icon = 1;
7047 e_init_status_set(_("Desktop files scan done"));
7050 return ECORE_CALLBACK_PASS_ON;
7054 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7055 int ev_type __UNUSED__,
7056 void *ev __UNUSED__)
7061 /* mark all borders for desktop/icon updates */
7062 EINA_LIST_FOREACH(borders, l, bd)
7064 bd->changes.icon = 1;
7067 return ECORE_CALLBACK_PASS_ON;
7071 _e_border_cb_pointer_warp(void *data __UNUSED__,
7072 int ev_type __UNUSED__,
7075 E_Event_Pointer_Warp *e;
7078 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7079 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7080 return ECORE_CALLBACK_PASS_ON;
7084 _e_border_cb_signal_bind(void *data,
7085 Evas_Object *obj __UNUSED__,
7086 const char *emission,
7092 if (e_dnd_active()) return;
7093 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7098 _e_border_cb_mouse_in(void *data,
7099 int type __UNUSED__,
7102 Ecore_X_Event_Mouse_In *ev;
7107 #ifdef INOUTDEBUG_MOUSE
7112 const char *modes[] = {
7114 "MODE_WHILE_GRABBED",
7118 const char *details[] = {
7122 "DETAIL_NON_LINEAR",
7123 "DETAIL_NON_LINEAR_VIRTUAL",
7125 "DETAIL_POINTER_ROOT",
7126 "DETAIL_DETAIL_NONE"
7130 ct[strlen(ct) - 1] = 0;
7131 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7132 ev->win, ev->event_win,
7135 details[ev->detail]);
7138 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7139 if (ev->event_win == bd->win)
7141 e_focus_event_mouse_in(bd);
7144 if ((ev->win != bd->win) &&
7145 (ev->win != bd->event_win) &&
7146 (ev->event_win != bd->win) &&
7147 (ev->event_win != bd->event_win))
7148 return ECORE_CALLBACK_PASS_ON;
7150 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7152 bd->mouse.current.mx = ev->root.x;
7153 bd->mouse.current.my = ev->root.y;
7154 if (!bd->bg_evas_in)
7156 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7157 bd->bg_evas_in = EINA_TRUE;
7159 return ECORE_CALLBACK_PASS_ON;
7163 _e_border_cb_mouse_out(void *data,
7164 int type __UNUSED__,
7167 Ecore_X_Event_Mouse_Out *ev;
7172 #ifdef INOUTDEBUG_MOUSE
7177 const char *modes[] = {
7179 "MODE_WHILE_GRABBED",
7183 const char *details[] = {
7187 "DETAIL_NON_LINEAR",
7188 "DETAIL_NON_LINEAR_VIRTUAL",
7190 "DETAIL_POINTER_ROOT",
7191 "DETAIL_DETAIL_NONE"
7195 ct[strlen(ct) - 1] = 0;
7196 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7197 ev->win, ev->event_win,
7200 details[ev->detail]);
7203 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7204 if (ev->event_win == bd->win)
7207 return ECORE_CALLBACK_PASS_ON;
7208 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7209 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7210 return ECORE_CALLBACK_PASS_ON;
7211 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7212 return ECORE_CALLBACK_PASS_ON;
7213 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7214 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7215 return ECORE_CALLBACK_PASS_ON;
7216 e_focus_event_mouse_out(bd);
7219 if ((ev->win != bd->win) &&
7220 (ev->win != bd->event_win) &&
7221 (ev->event_win != bd->win) &&
7222 (ev->event_win != bd->event_win))
7223 return ECORE_CALLBACK_PASS_ON;
7225 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7227 bd->mouse.current.mx = ev->root.x;
7228 bd->mouse.current.my = ev->root.y;
7231 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7232 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7233 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7235 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7236 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7237 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7238 bd->bg_evas_in = EINA_FALSE;
7241 return ECORE_CALLBACK_PASS_ON;
7245 _e_border_cb_mouse_wheel(void *data,
7246 int type __UNUSED__,
7249 Ecore_Event_Mouse_Wheel *ev;
7254 if ((ev->event_window == bd->win) ||
7255 (ev->event_window == bd->event_win))
7257 bd->mouse.current.mx = ev->root.x;
7258 bd->mouse.current.my = ev->root.y;
7259 if (!bd->cur_mouse_action)
7260 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7263 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7264 return ECORE_CALLBACK_PASS_ON;
7268 _e_border_cb_mouse_down(void *data,
7269 int type __UNUSED__,
7272 Ecore_Event_Mouse_Button *ev;
7277 if ((ev->event_window == bd->win) ||
7278 (ev->event_window == bd->event_win))
7280 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7282 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7283 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7284 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7285 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7286 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7287 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7291 bd->moveinfo.down.x = bd->x + bd->fx.x;
7292 bd->moveinfo.down.y = bd->y + bd->fx.y;
7293 bd->moveinfo.down.w = bd->w;
7294 bd->moveinfo.down.h = bd->h;
7296 bd->mouse.current.mx = ev->root.x;
7297 bd->mouse.current.my = ev->root.y;
7298 if (!bd->cur_mouse_action)
7300 bd->cur_mouse_action =
7301 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7303 if (bd->cur_mouse_action)
7305 if ((!bd->cur_mouse_action->func.end_mouse) &&
7306 (!bd->cur_mouse_action->func.end))
7307 bd->cur_mouse_action = NULL;
7308 if (bd->cur_mouse_action)
7309 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7312 e_focus_event_mouse_down(bd);
7314 if (ev->window != ev->event_window)
7318 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7322 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7324 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7325 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7326 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7327 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7328 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7329 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7333 bd->moveinfo.down.x = bd->x + bd->fx.x;
7334 bd->moveinfo.down.y = bd->y + bd->fx.y;
7335 bd->moveinfo.down.w = bd->w;
7336 bd->moveinfo.down.h = bd->h;
7338 bd->mouse.current.mx = ev->root.x;
7339 bd->mouse.current.my = ev->root.y;
7344 else if (bd->resize_mode != RESIZE_NONE)
7350 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7352 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7353 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7354 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7356 return ECORE_CALLBACK_PASS_ON;
7360 _e_border_cb_mouse_up(void *data,
7361 int type __UNUSED__,
7364 Ecore_Event_Mouse_Button *ev;
7369 if ((ev->event_window == bd->win) ||
7370 (ev->event_window == bd->event_win))
7372 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7374 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7375 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7376 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7377 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7379 bd->mouse.current.mx = ev->root.x;
7380 bd->mouse.current.my = ev->root.y;
7381 /* also we dont pass the same params that went in - then again that */
7382 /* should be ok as we are just ending the action if it has an end */
7383 if (bd->cur_mouse_action)
7385 if (bd->cur_mouse_action->func.end_mouse)
7386 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7387 else if (bd->cur_mouse_action->func.end)
7388 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7389 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7390 bd->cur_mouse_action = NULL;
7394 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7395 e_focus_event_mouse_up(bd);
7398 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7399 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7401 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7402 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7403 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7404 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7406 bd->mouse.current.mx = ev->root.x;
7407 bd->mouse.current.my = ev->root.y;
7411 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7412 return ECORE_CALLBACK_PASS_ON;
7416 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7418 #ifdef _F_BORDER_CLIP_TO_ZONE_
7419 int new_x_max, new_y_max;
7420 int new_x_min, new_y_min;
7421 int margin_x, margin_y;
7423 margin_x = bd->w - 100;
7424 margin_y = bd->h - 100;
7426 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7427 new_x_min = bd->zone->x - margin_x;
7428 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7429 new_y_min = bd->zone->y - margin_y;
7431 if (x >= new_x_max) *new_x = new_x_max;
7432 else if (x <= new_x_min) *new_x = new_x_min;
7434 if (y >= new_y_max) *new_y = new_y_max;
7435 else if (y <= new_y_min) *new_y = new_y_min;
7440 _e_border_cb_mouse_move(void *data,
7441 int type __UNUSED__,
7444 Ecore_Event_Mouse_Move *ev;
7449 if ((ev->window != bd->event_win) &&
7450 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7451 bd->mouse.current.mx = ev->root.x;
7452 bd->mouse.current.my = ev->root.y;
7455 int x, y, new_x, new_y;
7457 Eina_List *skiplist = NULL;
7459 // FIXME: remove? sync what for when only moving?
7460 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7461 bd->client.netwm.sync.wait = 0;
7462 if ((bd->client.netwm.sync.request) &&
7463 (bd->client.netwm.sync.alarm) &&
7464 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7466 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7468 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7469 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7470 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7471 (bd->mouse.current.my - bd->moveinfo.down.my);
7475 x = bd->moveinfo.down.x +
7476 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7477 y = bd->moveinfo.down.y +
7478 (bd->mouse.current.my - bd->moveinfo.down.my);
7483 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7484 skiplist = eina_list_append(skiplist, bd);
7485 e_resist_container_border_position(bd->zone->container, skiplist,
7486 bd->x, bd->y, bd->w, bd->h,
7488 &new_x, &new_y, &new_w, &new_h);
7489 eina_list_free(skiplist);
7491 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7493 /* if (e_config->window_out_of_vscreen_limits_partly) */
7495 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7498 skiplist = eina_list_append(skiplist, bd);
7499 e_resist_container_border_position(bd->zone->container, skiplist,
7500 bd->x, bd->y, bd->w, bd->h,
7502 &new_x, &new_y, &new_w, &new_h);
7503 eina_list_free(skiplist);
7506 bd->shelf_fix.x = 0;
7507 bd->shelf_fix.y = 0;
7508 bd->shelf_fix.modified = 0;
7509 e_border_move(bd, new_x, new_y);
7510 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7512 else if (bd->resize_mode != RESIZE_NONE)
7514 if ((bd->client.netwm.sync.request) &&
7515 (bd->client.netwm.sync.alarm))
7517 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7519 E_Border_Pending_Move_Resize *pnd;
7521 if (bd->pending_move_resize)
7523 bd->changes.pos = 1;
7524 bd->changes.size = 1;
7526 _e_border_client_move_resize_send(bd);
7528 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7531 bd->client.netwm.sync.wait = 0;
7533 /* sync.wait is incremented when resize_handle sends
7534 * sync-request and decremented by sync-alarm cb. so
7535 * we resize here either on initial resize, timeout or
7536 * when no new resize-request was added by sync-alarm cb.
7538 if (!bd->client.netwm.sync.wait)
7539 _e_border_resize_handle(bd);
7542 _e_border_resize_handle(bd);
7548 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7550 bd->drag.x = ev->root.x;
7551 bd->drag.y = ev->root.y;
7557 dx = bd->drag.x - ev->root.x;
7558 dy = bd->drag.y - ev->root.y;
7559 if (((dx * dx) + (dy * dy)) >
7560 (e_config->drag_resist * e_config->drag_resist))
7563 if (bd->icon_object)
7565 Evas_Object *o = NULL;
7566 Evas_Coord x, y, w, h;
7567 const char *drag_types[] = { "enlightenment/border" };
7569 e_object_ref(E_OBJECT(bd));
7570 evas_object_geometry_get(bd->icon_object,
7572 drag_border = e_drag_new(bd->zone->container,
7573 bd->x + bd->fx.x + x,
7574 bd->y + bd->fx.y + y,
7575 drag_types, 1, bd, -1,
7577 _e_border_cb_drag_finished);
7578 o = e_border_icon_add(bd, drag_border->evas);
7581 /* FIXME: fallback icon for drag */
7582 o = evas_object_rectangle_add(drag_border->evas);
7583 evas_object_color_set(o, 255, 255, 255, 255);
7585 e_drag_object_set(drag_border, o);
7587 e_drag_resize(drag_border, w, h);
7588 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7594 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7596 return ECORE_CALLBACK_PASS_ON;
7600 _e_border_cb_grab_replay(void *data __UNUSED__,
7604 Ecore_Event_Mouse_Button *ev;
7606 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7608 if ((e_config->pass_click_on)
7609 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7610 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7615 bd = e_border_find_by_window(ev->event_window);
7618 if (bd->cur_mouse_action)
7619 return ECORE_CALLBACK_DONE;
7620 if (ev->event_window == bd->win)
7622 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7623 E_OBJECT(bd), ev, NULL))
7624 return ECORE_CALLBACK_PASS_ON;
7628 return ECORE_CALLBACK_DONE;
7632 _e_border_cb_drag_finished(E_Drag *drag,
7633 int dropped __UNUSED__)
7638 e_object_unref(E_OBJECT(bd));
7642 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7644 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7645 int ev_type __UNUSED__,
7648 E_Event_Desk_Window_Profile_Change *e;
7653 EINA_LIST_FOREACH(borders, l, bd)
7655 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7657 bd->client.e.fetch.profile_list = 1;
7661 return ECORE_CALLBACK_PASS_ON;
7665 #ifdef _F_ZONE_WINDOW_ROTATION_
7667 _e_border_cb_zone_rotation_change(void *data __UNUSED__,
7668 int ev_type __UNUSED__,
7671 E_Event_Zone_Rotation_Change *e = ev;
7672 Eina_Bool res = EINA_FALSE;
7674 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7675 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7677 res = _e_border_rotation_zone_check(e->zone);
7678 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: result:%d (%d)", res, e->zone->rot.curr);
7681 e_manager_comp_screen_lock(e_manager_current_get());
7682 res = _e_border_rotation_zone_vkbd_check(e->zone);
7683 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd result:%d (%d)", res, e->zone->rot.curr);
7686 res = _e_border_rotation_transient_for_check(rot.vkbd,
7688 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd transient_for result:%d (%d)", res, e->zone->rot.curr);
7693 if (rot.prepare_timer)
7694 ecore_timer_del(rot.prepare_timer);
7695 rot.prepare_timer = NULL;
7698 ecore_timer_del(rot.done_timer);
7699 rot.done_timer = NULL;
7701 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
7702 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
7705 rot.prepare_timer = ecore_timer_add(4.0f,
7706 _e_border_rotation_change_prepare_timeout,
7708 rot.wait_prepare_done = EINA_TRUE;
7712 _e_border_rotation_list_add(e->zone, EINA_TRUE);
7713 _e_border_rotation_change_request(e->zone);
7718 /* there is no border which supports window manager rotation */
7719 e_zone_rotation_update_cancel(e->zone);
7721 return ECORE_CALLBACK_PASS_ON;
7725 _e_border_rotation_change_prepare_timeout(void *data)
7727 E_Zone *zone = data;
7728 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7730 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
7732 if ((rot.wait_prepare_done) &&
7734 (_e_border_rotation_list_add(zone, EINA_FALSE)))
7736 _e_border_rotation_change_request(zone);
7740 if (rot.prepare_timer)
7741 ecore_timer_del(rot.prepare_timer);
7742 rot.prepare_timer = NULL;
7743 rot.wait_prepare_done = EINA_FALSE;
7745 return ECORE_CALLBACK_CANCEL;
7749 _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
7751 Eina_List *l = NULL;
7752 E_Border_Rotation_Info *info = NULL;
7754 if (!e_config->wm_win_rotation) return;
7755 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
7756 rot.prepare_timer = NULL;
7757 rot.wait_prepare_done = EINA_FALSE;
7759 EINA_LIST_FOREACH(rot.list, l, info)
7761 ELBF(ELBT_ROT, 1, info->bd->client.win,
7762 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
7763 info->ang, info->win_resize, info->w, info->h);
7765 ecore_x_e_window_rotation_change_prepare_send
7766 (info->bd->client.win, info->ang,
7767 info->win_resize, info->w, info->h);
7769 if (!info->bd->client.e.state.rot.pending_change_request)
7771 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
7772 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
7778 ecore_timer_del(rot.done_timer);
7779 rot.done_timer = ecore_timer_add(4.0f,
7780 _e_border_rotation_change_done_timeout,
7785 _e_border_rotation_list_remove(E_Border *bd)
7787 Eina_List *l = NULL;
7788 E_Border_Rotation_Info *info = NULL;
7789 if (!e_config->wm_win_rotation) return;
7791 EINA_LIST_FOREACH(rot.list, l, info)
7795 rot.list = eina_list_remove(rot.list, info);
7800 if (bd->client.e.state.rot.wait_for_done)
7802 bd->client.e.state.rot.wait_for_done = 0;
7803 if (eina_list_count(rot.list) == 0)
7805 _e_border_rotation_change_done();
7811 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
7813 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7814 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
7815 _e_border_rotation_change_done();
7816 return ECORE_CALLBACK_CANCEL;
7820 _e_border_rotation_change_done(void)
7822 E_Manager *m = NULL;
7823 E_Border_Rotation_Info *info = NULL;
7825 if (!e_config->wm_win_rotation) return;
7827 if (rot.prepare_timer)
7828 ecore_timer_del(rot.prepare_timer);
7829 rot.prepare_timer = NULL;
7831 rot.wait_prepare_done = EINA_FALSE;
7834 ecore_timer_del(rot.done_timer);
7835 rot.done_timer = NULL;
7837 EINA_LIST_FREE(rot.list, info)
7841 info->bd->client.e.state.rot.wait_for_done = 0;
7842 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
7849 m = e_manager_current_get();
7850 e_manager_comp_screen_unlock(m);
7851 e_zone_rotation_update_done(e_util_zone_current_get(m));
7855 _prev_angle_get(Ecore_X_Window win)
7857 int ret, count = 0, ang = -1;
7858 unsigned char* data = NULL;
7860 ret = ecore_x_window_prop_property_get
7861 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
7862 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
7864 if ((ret) && (data) && (count))
7865 ang = ((int *)data)[0];
7866 if (data) free(data);
7870 /* get proper rotation value using preferred rotation and list of available rotations */
7872 _e_border_rotation_get(E_Border *bd,
7876 int current_ang = bd->client.e.state.rot.curr;
7878 Eina_Bool found = EINA_FALSE;
7879 Eina_Bool found_curr_ang = EINA_FALSE;
7881 if (!e_config->wm_win_rotation) return ang;
7882 if (!bd->client.e.state.rot.app_set) return ang;
7884 if (bd->client.e.state.rot.preferred_rot != -1)
7886 ang = bd->client.e.state.rot.preferred_rot;
7887 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
7889 else if ((bd->client.e.state.rot.available_rots) &&
7890 (bd->client.e.state.rot.count))
7892 for (i = 0; i < bd->client.e.state.rot.count; i++)
7894 if (bd->client.e.state.rot.available_rots[i] == base_ang)
7900 if (bd->client.e.state.rot.available_rots[i] == current_ang)
7901 found_curr_ang = EINA_TRUE;
7904 /* do nothing. this window wants to maintain current state.
7905 * for example, window's available_rots: 0, 90, 270,
7906 * current zone rotation request: 180. the WM does nothing
7911 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
7912 ang = bd->client.e.state.rot.curr;
7914 ang = bd->client.e.state.rot.available_rots[0];
7919 /* In this case, border doesn't have a list of
7920 * available rotations, thus WM should request
7921 * rotation with '0' degree to the application.
7929 #define REGION_EQUAL_TO_ZONE(a, z) \
7930 ((((a)->x) == ((z)->x)) && \
7931 (((a)->y) == ((z)->y)) && \
7932 (((a)->w) == ((z)->w)) && \
7933 (((a)->h) == ((z)->h)))
7936 _e_border_rotation_check(E_Border *bd)
7938 E_Zone *zone = bd->zone;
7939 int x, y, w, h, ang = 0;
7940 int diff = 0, _ang = 0;
7941 Eina_Bool resize = EINA_TRUE;
7942 Eina_Bool hint = EINA_FALSE;
7943 Eina_Bool move = EINA_TRUE;
7945 if (!e_config->wm_win_rotation) return EINA_FALSE;
7947 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
7949 ang = zone->rot.curr;
7951 if (((rot.vkbd) && (rot.vkbd == bd)) ||
7952 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
7954 ELBF(ELBT_ROT, 1, bd->client.win,
7955 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
7956 (rot.vkbd == bd) ? "vkbd" : "prediction",
7957 bd->parent ? bd->parent->client.win : 0,
7958 bd->parent ? bd->parent->client.e.state.rot.support : -1,
7959 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
7960 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
7964 ang = bd->parent->client.e.state.rot.curr;
7965 if ((!bd->parent->client.e.state.rot.support) &&
7966 (!bd->parent->client.e.state.rot.app_set))
7973 if ((!bd->client.e.state.rot.app_set) &&
7974 (!bd->client.e.state.rot.support))
7976 /* hack for magnifier and keyboard popup */
7977 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
7978 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
7980 ELB(ELBT_BD, "MAG", bd->client.win);
7982 if ((rot.vkbd) && (rot.vkbd->visible))
7983 ang = rot.vkbd->client.e.state.rot.curr;
7984 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
7987 ELBF(ELBT_ROT, 1, bd->client.win, "MAG %d,%d %dx%d m:%d", x, y, w, h, move);
7988 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
7994 if (bd->client.e.state.rot.app_set)
7996 /* utility type window should be rotated according to
7997 * rotation of the transient_for window.
8000 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8002 ang = bd->parent->client.e.state.rot.curr;
8003 if ((!bd->parent->client.e.state.rot.support) &&
8004 (!bd->parent->client.e.state.rot.app_set))
8006 /* if transient_for window doesn't support rotation feature,
8007 * then this window should't be rotated.
8008 * TODO: need to check whether window supports '0' degree or not.
8011 ELBF(ELBT_ROT, 0, bd->client.win,
8012 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8013 ang, bd->parent->client.win);
8017 ang = _e_border_rotation_get(bd->parent, ang);
8018 ELBF(ELBT_ROT, 0, bd->client.win,
8019 "GET ROT ang:%d Transient_For:0x%08x",
8020 ang, bd->parent->client.win);
8025 ang = _e_border_rotation_get(bd, ang);
8026 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8027 ang, bd->parent ? bd->parent->client.win : 0,
8028 bd->client.netwm.type);
8032 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8034 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8036 /* need to check previous rotation angle, this may be because
8037 * the window was unmapped with non-0 rotation degree.
8038 * and now, the window wants to show on the 0 degree zone,
8039 * thus the wm should request to rotate the window to 0 degree.
8043 _ang = _prev_angle_get(bd->client.win);
8045 bd->client.e.state.rot.curr = _ang;
8046 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8049 if (bd->client.e.state.rot.curr != ang)
8051 Eina_Bool is_screen_locked = EINA_FALSE;
8053 if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) &&
8054 /* check whether virtual keyboard is visible on the zone */
8055 (_e_border_rotation_zone_vkbd_check(bd->zone)) &&
8056 /* check whether virtual keyboard belongs to this border (transient_for) */
8057 (_e_border_rotation_vkbd_transient_for_check(bd)) &&
8058 /* check rotation of the virtual keyboard */
8059 (((rot.vkbd) && (rot.vkbd->client.e.state.rot.curr != ang)) ||
8060 ((rot.vkbd_prediction) && (rot.vkbd_prediction->client.e.state.rot.curr != ang))) &&
8061 (!rot.wait_prepare_done))
8063 ELB(ELBT_ROT, "DO VKBD ROT", bd->client.win);
8064 e_manager_comp_screen_lock(e_manager_current_get());
8065 is_screen_locked = EINA_TRUE;
8067 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8068 rot.prepare_timer = NULL;
8070 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8071 rot.done_timer = NULL;
8073 ELB(ELBT_ROT, "send rot_change_prepare", rot.vkbd_ctrl_win);
8074 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8077 rot.prepare_timer = ecore_timer_add(4.0f,
8078 _e_border_rotation_change_prepare_timeout,
8080 rot.wait_prepare_done = EINA_TRUE;
8083 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8084 bd->client.e.state.rot.curr = ang;
8085 bd->client.e.state.rot.wait_for_done = 1;
8087 diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8088 if ((diff == 180) || (diff == -180))
8089 resize = EINA_FALSE;
8091 /* Check if it has size hint, full size or not, and needs to resize.
8092 * Under the below condition, replace width value with height.
8094 if ((!hint) && (!REGION_EQUAL_TO_ZONE(bd, bd->zone)) && (resize))
8096 x = bd->x; y = bd->y;
8097 w = bd->w; h = bd->h;
8100 resize = EINA_FALSE;
8106 _e_border_move_resize_internal(bd, x, y, w, h,
8107 EINA_TRUE, EINA_FALSE);
8112 if (bd->client.e.state.rot.app_set) resize = EINA_FALSE;
8114 E_Border_Rotation_Info *info = NULL;
8115 info = E_NEW(E_Border_Rotation_Info, 1);
8118 if (!is_screen_locked)
8119 e_manager_comp_screen_lock(e_manager_current_get());
8123 info->x = x; info->y = y;
8124 info->w = w; info->h = h;
8125 info->win_resize = resize;
8126 rot.list = eina_list_append(rot.list, info);
8128 if (info->win_resize)
8129 bd->client.e.state.rot.pending_change_request = 1;
8131 ELBF(ELBT_ROT, 1, info->bd->client.win,
8132 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8133 info->ang, info->win_resize, info->w, info->h);
8135 ecore_x_e_window_rotation_change_prepare_send
8136 (info->bd->client.win, info->ang,
8137 info->win_resize, info->w, info->h);
8139 if (!info->bd->client.e.state.rot.pending_change_request)
8141 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8142 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8147 ecore_timer_del(rot.done_timer);
8148 rot.done_timer = ecore_timer_add(4.0f,
8149 _e_border_rotation_change_done_timeout,
8157 _e_border_rotation_zone_check(E_Zone *zone)
8159 Eina_Bool wait = EINA_FALSE;
8160 E_Border_List *l = NULL;
8161 E_Border *bd = NULL;
8163 if (!e_config->wm_win_rotation) return EINA_FALSE;
8165 l = e_container_border_list_last(zone->container);
8166 if (!l) return EINA_FALSE;
8167 while ((bd = e_container_border_list_prev(l)))
8169 if ((!bd) || (e_object_is_del(E_OBJECT(bd))) ||
8170 (!bd->visible) || (bd->zone != zone) ||
8171 (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8172 bd->x, bd->y, bd->w, bd->h))) continue;
8174 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8175 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)) ||
8176 ((REGION_EQUAL_TO_ZONE(bd, zone)) &&
8177 (bd->client.e.state.rot.preferred_rot != -1))) continue;
8179 if (_e_border_rotation_border_check(bd, zone->rot.curr))
8185 if (l) e_container_border_list_free(l);
8190 // check if border is rotatable in ang.
8192 _e_border_rotation_border_check(E_Border *bd, int ang)
8194 Eina_Bool wait = EINA_FALSE;
8196 if (!bd) return wait;
8198 if (((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8199 /* basically WM allows only fullscreen window to rotate */
8200 ((REGION_EQUAL_TO_ZONE(bd, bd->zone)) ||
8201 /* we don't like this kind of code.
8202 * it means that the WM also allows non-fullscreen window to rotate if it sets geom hint.
8203 * such as large editable window.
8205 ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE) && (bd->client.e.state.rot.geom_hint)) ||
8206 /* and floating mode window is also rotatable */
8207 (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) &&
8208 (bd->client.e.state.rot.preferred_rot == -1))
8212 if (bd->client.e.state.rot.app_set)
8214 if (bd->client.e.state.rot.available_rots &&
8215 bd->client.e.state.rot.count)
8217 Eina_Bool found = EINA_FALSE;
8218 for (i = 0; i < bd->client.e.state.rot.count; i++)
8220 if (bd->client.e.state.rot.available_rots[i] == ang)
8225 if ((found) && (ang != bd->client.e.state.rot.curr))
8231 ELB(ELBT_ROT, "ROT CANCEL for preferred rot", bd->client.win);
8238 ELB(ELBT_ROT, "DO ROT", 0);
8246 /* check whether virtual keyboard is visible on the zone */
8248 _e_border_rotation_zone_vkbd_check(E_Zone *zone)
8250 if (!e_config->wm_win_rotation) return EINA_FALSE;
8252 if ((rot.vkbd_ctrl_win) &&
8254 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8255 (rot.vkbd->visible) &&
8256 (rot.vkbd->zone == zone) &&
8257 (E_INTERSECTS(zone->x, zone->y,
8259 rot.vkbd->x, rot.vkbd->y,
8260 rot.vkbd->w, rot.vkbd->h)))
8267 /* check whether prediction keyboard is visible on the zone */
8269 _e_border_rotation_zone_prediction_check(E_Zone *zone)
8271 if (!e_config->wm_win_rotation) return EINA_FALSE;
8273 if ((rot.vkbd_ctrl_win) &&
8274 (rot.vkbd_prediction) &&
8275 (!e_object_is_del(E_OBJECT(rot.vkbd_prediction))) &&
8276 (rot.vkbd_prediction->visible) &&
8277 (rot.vkbd_prediction->zone == zone) &&
8278 (E_INTERSECTS(zone->x, zone->y,
8280 rot.vkbd_prediction->x, rot.vkbd_prediction->y,
8281 rot.vkbd_prediction->w, rot.vkbd_prediction->h)))
8288 /* check whether border is parent of the virtual keyboard */
8290 _e_border_rotation_vkbd_transient_for_check(E_Border *bd)
8292 if (!e_config->wm_win_rotation) return EINA_FALSE;
8294 if (rot.vkbd_ctrl_win)
8296 if ((rot.vkbd) && (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8299 if (rot.vkbd->parent == bd)
8303 if ((rot.vkbd_prediction) && (!e_object_is_del(E_OBJECT(rot.vkbd_prediction))) &&
8304 (rot.vkbd_prediction != bd))
8306 /* bug! but i can't fix it */
8307 if (rot.vkbd_prediction == bd)
8315 // check if bd's parent is rotatable.
8317 _e_border_rotation_transient_for_check(E_Border *bd, int ang)
8319 Eina_Bool ret = EINA_FALSE;
8321 if (!e_config->wm_win_rotation) return EINA_FALSE;
8322 if (!bd) return EINA_FALSE;
8324 if (!bd->parent) ret = EINA_TRUE;
8327 if (_e_border_rotation_border_check(bd->parent, ang))
8335 _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
8337 Eina_Bool wait = EINA_FALSE;
8338 E_Border_List *l = NULL;
8339 Eina_List *nl = NULL;
8340 E_Border *bd = NULL;
8341 E_Border_Rotation_Info *info = NULL;
8343 if (!e_config->wm_win_rotation) return EINA_FALSE;
8345 l = e_container_border_list_last(zone->container);
8346 if (!l) return EINA_FALSE;
8347 while ((bd = e_container_border_list_prev(l)))
8349 if ((!bd) || (e_object_is_del(E_OBJECT(bd)))) continue;
8351 if ((without_vkbd) &&
8352 (((rot.vkbd) && (rot.vkbd == bd)) ||
8353 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))) continue;
8355 if ((bd->visible) &&
8356 ((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8357 (bd->zone == zone) &&
8358 (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8359 bd->x, bd->y, bd->w, bd->h)))
8361 // check if this window is available to be rotate.
8362 if ((bd->client.e.state.rot.app_set) &&
8363 (bd->client.e.state.rot.preferred_rot != -1)) continue;
8365 /* check list of available rotations */
8366 int ang = zone->rot.curr;
8367 if (bd->client.e.state.rot.app_set)
8369 ang = _e_border_rotation_get(bd, ang);
8370 ELBF(ELBT_ROT, 0, bd->client.win, "returned ang:%d", ang);
8373 /* skip same angle */
8374 if (bd->client.e.state.rot.curr == ang)
8376 ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang);
8381 ELBF(ELBT_ROT, 0, bd->client.win, "ADD ROT_LIST curr:%d != ang:%d",
8382 bd->client.e.state.rot.curr, ang);
8385 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8386 bd->client.e.state.rot.curr = ang;
8387 bd->client.e.state.rot.wait_for_done = 1;
8389 info = E_NEW(E_Border_Rotation_Info, 1);
8394 info->x = bd->x; info->y = bd->y;
8395 info->w = bd->w; info->h = bd->h;
8396 info->win_resize = EINA_FALSE;
8397 nl = eina_list_append(nl, info);
8400 if (REGION_EQUAL_TO_ZONE(bd, zone))
8402 wait = EINA_TRUE; // for the maximized window
8406 int diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8408 Eina_Bool resize = EINA_TRUE;
8409 if ((diff == 180) || (diff == -180))
8410 resize = EINA_FALSE;
8412 Eina_Bool move = EINA_TRUE;
8413 Eina_Bool hint = EINA_FALSE;
8414 hint = _e_border_rotation_geom_get(bd, zone, zone->rot.curr, &x, &y, &w, &h, &move);
8416 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8419 x = bd->x; y = bd->y;
8420 w = bd->w; h = bd->h;
8424 resize = EINA_FALSE;
8427 // swap width and height and resize border
8431 _e_border_move_resize_internal(bd, x, y, w, h,
8432 EINA_TRUE, EINA_TRUE);
8439 info->x = x; info->y = y;
8440 info->w = w; info->h = h;
8441 info->win_resize = resize;
8445 bd->client.e.state.rot.pending_change_request = 1;
8450 /* support for rotating prediction window without virtual keyboard */
8453 if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) &&
8454 /* check whether prediction is visible on the zone */
8455 (_e_border_rotation_zone_prediction_check(bd->zone)) &&
8456 /* check whether prediction window belongs to this border (transient_for) */
8457 (rot.vkbd_prediction->parent == bd) &&
8458 /* check rotation of prediction window */
8459 (rot.vkbd_prediction->client.e.state.rot.curr != bd->client.e.state.rot.curr) &&
8460 (!rot.wait_prepare_done))
8462 E_Border *pbd = rot.vkbd_prediction;
8463 ang = bd->client.e.state.rot.curr;
8465 ELBF(ELBT_ROT, 0, pbd->client.win, "ADD ROT_LIST curr:%d != ang:%d (PREDICTION)",
8466 pbd->client.e.state.rot.curr, ang);
8468 pbd->client.e.state.rot.prev = pbd->client.e.state.rot.curr;
8469 pbd->client.e.state.rot.curr = ang;
8470 pbd->client.e.state.rot.wait_for_done = 1;
8472 info = E_NEW(E_Border_Rotation_Info, 1);
8477 info->x = pbd->x; info->y = pbd->y;
8478 info->w = pbd->w; info->h = pbd->h;
8479 info->win_resize = EINA_FALSE;
8480 nl = eina_list_append(nl, info);
8484 Eina_Bool move = EINA_TRUE;
8485 Eina_Bool hint = EINA_FALSE;
8486 hint = _e_border_rotation_geom_get(pbd, zone, zone->rot.curr, &x, &y, &w, &h, &move);
8488 _e_border_move_resize_internal(pbd, x, y, w, h, EINA_TRUE, move);
8492 info->x = x; info->y = y;
8493 info->w = w; info->h = h;
8494 info->win_resize = EINA_TRUE;
8497 pbd->client.e.state.rot.pending_change_request = 1;
8503 if (l) e_container_border_list_free(l);
8507 // clear previous list
8508 EINA_LIST_FREE(rot.list, info)
8519 _e_border_cb_window_configure(void *data __UNUSED__,
8520 int ev_type __UNUSED__,
8523 Ecore_X_Event_Window_Configure *e = ev;
8524 if (!e) return ECORE_CALLBACK_PASS_ON;
8525 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8527 E_Border *bd = e_border_find_by_client_window(e->win);
8528 if (!bd) return ECORE_CALLBACK_PASS_ON;
8530 if (bd->client.e.state.rot.pending_change_request)
8532 if ((e->w == bd->w) && (e->h == bd->h))
8534 ELBF(ELBT_ROT, 0, bd->client.win,
8535 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8536 bd->client.e.state.rot.curr,
8539 bd->client.e.state.rot.pending_change_request = 0;
8541 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8542 bd->client.e.state.rot.curr);
8545 return ECORE_CALLBACK_PASS_ON;
8549 _e_border_rotation_geom_get(E_Border *bd,
8558 if (!e_config->wm_win_rotation) return EINA_FALSE;
8560 Eina_Bool res = EINA_FALSE;
8561 Eina_Bool _move = EINA_TRUE;
8571 if (move) *move = EINA_TRUE;
8573 if (bd->client.e.state.rot.geom_hint)
8578 _w = bd->client.e.state.rot.geom[0].w;
8579 _h = bd->client.e.state.rot.geom[0].h;
8580 if (_w == 0) _w = bd->w;
8581 if (_h == 0) _h = bd->h;
8582 _x = 0; _y = zone->h - _h;
8585 _w = bd->client.e.state.rot.geom[1].w;
8586 _h = bd->client.e.state.rot.geom[1].h;
8587 if (_w == 0) _w = bd->w;
8588 if (_h == 0) _h = bd->h;
8589 _x = zone->w - _w; _y = 0;
8592 _w = bd->client.e.state.rot.geom[2].w;
8593 _h = bd->client.e.state.rot.geom[2].h;
8594 if (_w == 0) _w = bd->w;
8595 if (_h == 0) _h = bd->h;
8599 _w = bd->client.e.state.rot.geom[3].w;
8600 _h = bd->client.e.state.rot.geom[3].h;
8601 if (_w == 0) _w = bd->w;
8602 if (_h == 0) _h = bd->h;
8612 if (!((rot.vkbd) && (rot.vkbd == bd)))
8616 if (move) *move = EINA_FALSE;
8624 _x = 0; _y = 0; _w = 0; _h = 0;
8629 if (move) _move = *move;
8631 ELBF(ELBT_ROT, 1, bd->client.win,
8632 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8633 ang, _x, _y, _w, _h, _move);
8641 _e_border_post_move_resize_job(void *data)
8645 bd = (E_Border *)data;
8651 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8652 ecore_x_window_move(tmp->win,
8654 bd->client_inset.l +
8656 tmp->client.e.state.video_position.x,
8658 bd->client_inset.t +
8660 tmp->client.e.state.video_position.y);
8662 if (bd->client.e.state.video)
8666 parent = bd->client.e.state.video_parent_border;
8667 ecore_x_window_move(bd->win,
8669 parent->client_inset.l +
8671 bd->client.e.state.video_position.x,
8673 parent->client_inset.t +
8675 bd->client.e.state.video_position.y);
8677 else if ((bd->post_move) && (bd->post_resize))
8679 ecore_x_window_move_resize(bd->win,
8684 else if (bd->post_move)
8686 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
8688 else if (bd->post_resize)
8690 ecore_x_window_resize(bd->win, bd->w, bd->h);
8693 if (bd->client.e.state.video)
8695 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
8697 bd->client.e.state.video_parent_border->x +
8698 bd->client.e.state.video_parent_border->client_inset.l +
8699 bd->client.e.state.video_parent_border->fx.x +
8700 bd->client.e.state.video_position.x,
8701 bd->client.e.state.video_parent_border->y +
8702 bd->client.e.state.video_parent_border->client_inset.t +
8703 bd->client.e.state.video_parent_border->fx.y +
8704 bd->client.e.state.video_position.y,
8712 bd->post_job = NULL;
8718 bd->post_resize = 0;
8719 bd->post_job = NULL;
8720 return ECORE_CALLBACK_CANCEL;
8724 _e_border_container_layout_hook(E_Container *con)
8726 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
8730 _e_border_eval0(E_Border *bd)
8732 int change_urgent = 0;
8734 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8735 Eina_Bool need_desk_set = EINA_FALSE;
8737 #ifdef _F_ZONE_WINDOW_ROTATION_
8738 Eina_Bool need_rotation_set = EINA_FALSE;
8740 if ((e_config->wm_win_rotation) &&
8741 (bd->client.icccm.fetch.transient_for))
8743 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8744 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
8746 need_rotation_set = EINA_TRUE;
8747 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
8752 if (e_object_is_del(E_OBJECT(bd)))
8754 CRI("_e_border_eval(%p) with deleted border!\n", bd);
8759 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
8761 bd->changes.border = 0;
8763 /* fetch any info queued to be fetched */
8764 if (bd->client.netwm.fetch.state)
8766 e_hints_window_state_get(bd);
8767 bd->client.netwm.fetch.state = 0;
8770 if (bd->client.icccm.fetch.client_leader)
8772 /* TODO: What do to if the client leader isn't mapped yet? */
8773 E_Border *bd_leader = NULL;
8775 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
8776 if (bd->client.icccm.client_leader)
8777 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
8780 if (bd->leader != bd_leader)
8782 bd->leader->group = eina_list_remove(bd->leader->group, bd);
8783 if (bd->leader->modal == bd) bd->leader->modal = NULL;
8789 /* If this border is the leader of the group, don't register itself */
8790 if ((bd_leader) && (bd_leader != bd))
8792 bd_leader->group = eina_list_append(bd_leader->group, bd);
8793 bd->leader = bd_leader;
8794 /* Only set the window modal to the leader it there is no parent */
8795 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
8796 ((!bd->parent) || (bd->parent->modal != bd)))
8798 bd->leader->modal = bd;
8799 if (bd->leader->focused)
8800 e_border_focus_set(bd, 1, 1);
8806 EINA_LIST_FOREACH(bd->leader->group, l, child)
8808 if ((child != bd) && (child->focused))
8809 e_border_focus_set(bd, 1, 1);
8814 bd->client.icccm.fetch.client_leader = 0;
8817 if (bd->client.icccm.fetch.title)
8819 char *title = ecore_x_icccm_title_get(bd->client.win);
8820 eina_stringshare_replace(&bd->client.icccm.title, title);
8821 if (title) free(title);
8824 edje_object_part_text_set(bd->bg_object, "e.text.title",
8825 bd->client.icccm.title);
8826 bd->client.icccm.fetch.title = 0;
8829 if (bd->client.netwm.fetch.name)
8832 ecore_x_netwm_name_get(bd->client.win, &name);
8833 eina_stringshare_replace(&bd->client.netwm.name, name);
8834 if (name) free(name);
8837 edje_object_part_text_set(bd->bg_object, "e.text.title",
8838 bd->client.netwm.name);
8839 bd->client.netwm.fetch.name = 0;
8842 if (bd->client.icccm.fetch.name_class)
8844 const char *pname, *pclass;
8845 char *nname, *nclass;
8847 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
8848 pname = bd->client.icccm.name;
8849 pclass = bd->client.icccm.class;
8850 bd->client.icccm.name = eina_stringshare_add(nname);
8851 bd->client.icccm.class = eina_stringshare_add(nclass);
8852 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
8853 e_bindings_mapping_change_enable(EINA_FALSE);
8854 #ifdef _F_ZONE_WINDOW_ROTATION_
8855 if (e_config->wm_win_rotation)
8857 if ((bd->client.icccm.name) && (bd->client.icccm.class))
8859 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
8860 (!strcmp(bd->client.icccm.class, "ISF")))
8862 ELB(ELBT_BD, "SET VKBD", bd->client.win);
8863 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
8866 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
8867 (!strcmp(bd->client.icccm.class, "ISF")))
8869 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
8870 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
8871 rot.vkbd_prediction = bd;
8873 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
8874 (!strcmp(bd->client.icccm.class, "ISF")))
8876 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
8877 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
8879 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
8880 (!strcmp(bd->client.icccm.class, "ISF")))
8882 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
8883 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
8888 if (nname) free(nname);
8889 if (nclass) free(nclass);
8891 if (!((bd->client.icccm.name == pname) &&
8892 (bd->client.icccm.class == pclass)))
8893 bd->changes.icon = 1;
8895 if (pname) eina_stringshare_del(pname);
8896 if (pclass) eina_stringshare_del(pclass);
8897 bd->client.icccm.fetch.name_class = 0;
8898 bd->changes.icon = 1;
8901 if (bd->client.icccm.fetch.state)
8903 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
8904 bd->client.icccm.fetch.state = 0;
8907 if (bd->client.e.fetch.state)
8909 e_hints_window_e_state_get(bd);
8910 bd->client.e.fetch.state = 0;
8913 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8914 if (bd->client.e.fetch.profile_list)
8916 const char **profiles = NULL;
8920 if (bd->client.e.state.profile)
8921 eina_stringshare_del(bd->client.e.state.profile);
8922 EINA_LIST_FREE(bd->client.e.state.profiles, str)
8924 if (str) eina_stringshare_del(str);
8926 bd->client.e.state.profile = NULL;
8927 bd->client.e.state.profiles = NULL;
8928 bd->client.e.state.profile_list = 0;
8930 if (ecore_x_e_window_profile_list_get(bd->client.win,
8933 bd->client.e.state.profile_list = 1;
8934 for (i = 0; i < num; i++)
8936 str = eina_stringshare_add(profiles[i]);
8937 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
8940 /* We should set desk to contain given border after creating E_BORDER_ADD event.
8941 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
8943 need_desk_set = EINA_TRUE;
8947 if (strcmp(bd->desk->window_profile,
8948 e_config->desktop_default_window_profile) != 0)
8950 ecore_x_e_window_profile_set(bd->client.win,
8951 bd->desk->window_profile);
8958 bd->client.e.fetch.profile_list = 0;
8961 #ifdef _F_ZONE_WINDOW_ROTATION_
8962 if ((e_config->wm_win_rotation) &&
8963 (bd->client.e.fetch.rot.support))
8966 unsigned int support = 0;
8968 ret = ecore_x_window_prop_card32_get
8970 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
8973 bd->client.e.state.rot.support = 0;
8974 if ((ret == 1) && (support == 1))
8975 bd->client.e.state.rot.support = 1;
8977 if (bd->client.e.state.rot.support)
8978 need_rotation_set = EINA_TRUE;
8980 bd->client.e.fetch.rot.support = 0;
8982 if ((e_config->wm_win_rotation) &&
8983 (bd->client.e.fetch.rot.geom_hint))
8985 Eina_Rectangle r[4];
8987 bd->client.e.state.rot.geom_hint = 0;
8988 for (i = 0; i < 4; i++)
8990 r[i].x = bd->client.e.state.rot.geom[i].x;
8991 r[i].y = bd->client.e.state.rot.geom[i].y;
8992 r[i].w = bd->client.e.state.rot.geom[i].w;
8993 r[i].h = bd->client.e.state.rot.geom[i].h;
8995 bd->client.e.state.rot.geom[i].x = 0;
8996 bd->client.e.state.rot.geom[i].y = 0;
8997 bd->client.e.state.rot.geom[i].w = 0;
8998 bd->client.e.state.rot.geom[i].h = 0;
9001 for (i = 0; i < 4; i++)
9003 x = 0; y = 0; w = 0; h = 0;
9004 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9006 bd->client.e.state.rot.geom_hint = 1;
9007 bd->client.e.state.rot.geom[i].x = x;
9008 bd->client.e.state.rot.geom[i].y = y;
9009 bd->client.e.state.rot.geom[i].w = w;
9010 bd->client.e.state.rot.geom[i].h = h;
9012 if (!((r[i].x == x) && (r[i].y == y) &&
9013 (r[i].w == w) && (r[i].h == h)))
9015 need_rotation_set = EINA_TRUE;
9019 bd->client.e.fetch.rot.geom_hint = 0;
9021 if ((e_config->wm_win_rotation) &&
9022 (bd->client.e.fetch.rot.app_set))
9024 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9025 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9026 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9028 if (_prev_app_set != bd->client.e.state.rot.app_set)
9029 need_rotation_set = EINA_TRUE;
9031 bd->client.e.fetch.rot.app_set = 0;
9033 if ((e_config->wm_win_rotation) &&
9034 (bd->client.e.fetch.rot.preferred_rot))
9036 int r = 0, _prev_preferred_rot;
9037 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9038 bd->client.e.state.rot.preferred_rot = -1;
9039 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9041 bd->client.e.state.rot.preferred_rot = r;
9042 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9046 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9049 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9050 need_rotation_set = EINA_TRUE;
9052 bd->client.e.fetch.rot.preferred_rot = 0;
9054 if ((e_config->wm_win_rotation) &&
9055 (bd->client.e.fetch.rot.available_rots))
9057 Eina_Bool res, diff = EINA_FALSE;
9059 unsigned int count = 0, i = 0;
9060 int _prev_rots[4] = { -1, };
9062 if (bd->client.e.state.rot.available_rots)
9065 bd->client.e.state.rot.available_rots,
9066 (sizeof(int) * bd->client.e.state.rot.count));
9068 E_FREE(bd->client.e.state.rot.available_rots);
9071 bd->client.e.state.rot.count = 0;
9073 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9075 if ((res) && (count > 0) && (rots))
9077 bd->client.e.state.rot.available_rots = rots;
9078 bd->client.e.state.rot.count = count;
9080 for (i = 0; i < count; i++)
9082 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9083 if ((!diff) && (_prev_rots[i] != rots[i]))
9085 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9086 count, i, _prev_rots[i], rots[i]);
9093 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9097 if (diff) need_rotation_set = EINA_TRUE;
9098 bd->client.e.fetch.rot.available_rots = 0;
9101 if (bd->client.netwm.fetch.type)
9103 e_hints_window_type_get(bd);
9104 if ((!bd->lock_border) || (!bd->client.border.name))
9105 bd->client.border.changed = 1;
9107 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9109 if (!bd->client.netwm.state.skip_pager)
9111 bd->client.netwm.state.skip_pager = 1;
9112 bd->client.netwm.update.state = 1;
9114 if (!bd->client.netwm.state.skip_taskbar)
9116 bd->client.netwm.state.skip_taskbar = 1;
9117 bd->client.netwm.update.state = 1;
9120 bd->client.netwm.fetch.type = 0;
9122 if (bd->client.icccm.fetch.machine)
9124 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9126 if ((!machine) && (bd->client.icccm.client_leader))
9127 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9129 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9130 if (machine) free(machine);
9132 bd->client.icccm.fetch.machine = 0;
9135 if (bd->client.icccm.fetch.command)
9137 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9141 for (i = 0; i < bd->client.icccm.command.argc; i++)
9142 free(bd->client.icccm.command.argv[i]);
9143 free(bd->client.icccm.command.argv);
9145 bd->client.icccm.command.argc = 0;
9146 bd->client.icccm.command.argv = NULL;
9147 ecore_x_icccm_command_get(bd->client.win,
9148 &(bd->client.icccm.command.argc),
9149 &(bd->client.icccm.command.argv));
9150 if ((bd->client.icccm.client_leader) &&
9151 (!bd->client.icccm.command.argv))
9152 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9153 &(bd->client.icccm.command.argc),
9154 &(bd->client.icccm.command.argv));
9155 bd->client.icccm.fetch.command = 0;
9158 if (bd->client.icccm.fetch.hints)
9160 Eina_Bool accepts_focus, is_urgent;
9162 accepts_focus = EINA_TRUE;
9163 is_urgent = EINA_FALSE;
9164 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9165 if (ecore_x_icccm_hints_get(bd->client.win,
9167 &bd->client.icccm.initial_state,
9168 &bd->client.icccm.icon_pixmap,
9169 &bd->client.icccm.icon_mask,
9170 &bd->client.icccm.icon_window,
9171 &bd->client.icccm.window_group,
9174 bd->client.icccm.accepts_focus = accepts_focus;
9175 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9177 bd->client.icccm.urgent = is_urgent;
9179 /* If this is a new window, set the state as requested. */
9180 if ((bd->new_client) &&
9181 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9183 e_border_iconify(bd);
9184 e_border_hide(bd, 1);
9187 bd->client.icccm.fetch.hints = 0;
9190 if (bd->client.icccm.fetch.size_pos_hints)
9192 Eina_Bool request_pos;
9194 request_pos = EINA_FALSE;
9195 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9197 &bd->client.icccm.gravity,
9198 &bd->client.icccm.min_w,
9199 &bd->client.icccm.min_h,
9200 &bd->client.icccm.max_w,
9201 &bd->client.icccm.max_h,
9202 &bd->client.icccm.base_w,
9203 &bd->client.icccm.base_h,
9204 &bd->client.icccm.step_w,
9205 &bd->client.icccm.step_h,
9206 &bd->client.icccm.min_aspect,
9207 &bd->client.icccm.max_aspect))
9209 bd->client.icccm.request_pos = request_pos;
9214 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9215 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9216 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9217 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9218 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9219 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9220 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9221 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9222 // if doing a resize, fix it up
9223 if (bd->resize_mode != RESIZE_NONE)
9225 int x, y, w, h, new_w, new_h;
9233 e_border_resize_limit(bd, &new_w, &new_h);
9234 if ((bd->resize_mode == RESIZE_TL) ||
9235 (bd->resize_mode == RESIZE_L) ||
9236 (bd->resize_mode == RESIZE_BL))
9238 if ((bd->resize_mode == RESIZE_TL) ||
9239 (bd->resize_mode == RESIZE_T) ||
9240 (bd->resize_mode == RESIZE_TR))
9242 e_border_move_resize(bd, x, y, new_w, new_h);
9244 bd->client.icccm.fetch.size_pos_hints = 0;
9247 if (bd->client.icccm.fetch.protocol)
9250 Ecore_X_WM_Protocol *proto;
9252 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9255 for (i = 0; i < num; i++)
9257 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9258 bd->client.icccm.delete_request = 1;
9259 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9260 bd->client.icccm.take_focus = 1;
9261 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9262 bd->client.netwm.ping = 1;
9263 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9265 bd->client.netwm.sync.request = 1;
9266 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9267 &bd->client.netwm.sync.counter))
9268 bd->client.netwm.sync.request = 0;
9273 if (bd->client.netwm.ping)
9277 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9278 bd->ping_poller = NULL;
9280 bd->client.icccm.fetch.protocol = 0;
9282 if (bd->client.icccm.fetch.transient_for)
9284 /* TODO: What do to if the transient for isn't mapped yet? */
9285 E_Border *bd_parent = NULL;
9287 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9288 if (bd->client.icccm.transient_for)
9289 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9290 /* If we already have a parent, remove it */
9293 if (bd_parent != bd->parent)
9295 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9296 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9302 if ((bd_parent) && (bd_parent != bd) &&
9303 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9305 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9306 bd->parent = bd_parent;
9310 e_border_layer_set(bd, bd->parent->layer);
9311 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9313 Ecore_X_Window_Attributes attr;
9314 bd->parent->modal = bd;
9315 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9316 bd->parent->saved.event_mask = attr.event_mask.mine;
9317 bd->parent->lock_close = 1;
9318 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9319 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9322 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9323 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9326 bd->client.icccm.fetch.transient_for = 0;
9329 if (bd->client.icccm.fetch.window_role)
9331 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9332 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9333 if (role) free(role);
9335 bd->client.icccm.fetch.window_role = 0;
9338 if (bd->client.icccm.fetch.icon_name)
9340 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9341 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9342 if (icon_name) free(icon_name);
9344 bd->client.icccm.fetch.icon_name = 0;
9347 if (bd->client.netwm.fetch.icon_name)
9350 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9351 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9352 if (icon_name) free(icon_name);
9354 bd->client.netwm.fetch.icon_name = 0;
9357 if (bd->client.netwm.fetch.icon)
9360 if (bd->client.netwm.icons)
9362 for (i = 0; i < bd->client.netwm.num_icons; i++)
9364 free(bd->client.netwm.icons[i].data);
9365 bd->client.netwm.icons[i].data = NULL;
9367 free(bd->client.netwm.icons);
9369 bd->client.netwm.icons = NULL;
9370 bd->client.netwm.num_icons = 0;
9371 if (ecore_x_netwm_icons_get(bd->client.win,
9372 &bd->client.netwm.icons,
9373 &bd->client.netwm.num_icons))
9375 // unless the rest of e17 uses border icons OTHER than icon #0
9376 // then free the rest that we don't need anymore.
9377 for (i = 1; i < bd->client.netwm.num_icons; i++)
9379 free(bd->client.netwm.icons[i].data);
9380 bd->client.netwm.icons[i].data = NULL;
9382 bd->client.netwm.num_icons = 1;
9383 bd->changes.icon = 1;
9385 bd->client.netwm.fetch.icon = 0;
9387 if (bd->client.netwm.fetch.user_time)
9389 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9390 bd->client.netwm.fetch.user_time = 0;
9392 if (bd->client.netwm.fetch.strut)
9394 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9395 &bd->client.netwm.strut.left,
9396 &bd->client.netwm.strut.right,
9397 &bd->client.netwm.strut.top,
9398 &bd->client.netwm.strut.bottom,
9399 &bd->client.netwm.strut.left_start_y,
9400 &bd->client.netwm.strut.left_end_y,
9401 &bd->client.netwm.strut.right_start_y,
9402 &bd->client.netwm.strut.right_end_y,
9403 &bd->client.netwm.strut.top_start_x,
9404 &bd->client.netwm.strut.top_end_x,
9405 &bd->client.netwm.strut.bottom_start_x,
9406 &bd->client.netwm.strut.bottom_end_x))
9408 ecore_x_netwm_strut_get(bd->client.win,
9409 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9410 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9412 bd->client.netwm.strut.left_start_y = 0;
9413 bd->client.netwm.strut.left_end_y = 0;
9414 bd->client.netwm.strut.right_start_y = 0;
9415 bd->client.netwm.strut.right_end_y = 0;
9416 bd->client.netwm.strut.top_start_x = 0;
9417 bd->client.netwm.strut.top_end_x = 0;
9418 bd->client.netwm.strut.bottom_start_x = 0;
9419 bd->client.netwm.strut.bottom_end_x = 0;
9421 bd->client.netwm.fetch.strut = 0;
9423 if (bd->client.qtopia.fetch.soft_menu)
9425 e_hints_window_qtopia_soft_menu_get(bd);
9426 bd->client.qtopia.fetch.soft_menu = 0;
9429 if (bd->client.qtopia.fetch.soft_menus)
9431 e_hints_window_qtopia_soft_menus_get(bd);
9432 bd->client.qtopia.fetch.soft_menus = 0;
9435 if (bd->client.vkbd.fetch.state)
9437 e_hints_window_virtual_keyboard_state_get(bd);
9438 bd->client.vkbd.fetch.state = 0;
9441 if (bd->client.vkbd.fetch.vkbd)
9443 e_hints_window_virtual_keyboard_get(bd);
9444 bd->client.vkbd.fetch.vkbd = 0;
9447 if (bd->client.illume.conformant.fetch.conformant)
9449 bd->client.illume.conformant.conformant =
9450 ecore_x_e_illume_conformant_get(bd->client.win);
9451 bd->client.illume.conformant.fetch.conformant = 0;
9453 if (bd->client.illume.quickpanel.fetch.state)
9455 bd->client.illume.quickpanel.state =
9456 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9457 bd->client.illume.quickpanel.fetch.state = 0;
9459 if (bd->client.illume.quickpanel.fetch.quickpanel)
9461 bd->client.illume.quickpanel.quickpanel =
9462 ecore_x_e_illume_quickpanel_get(bd->client.win);
9463 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9465 if (bd->client.illume.quickpanel.fetch.priority.major)
9467 bd->client.illume.quickpanel.priority.major =
9468 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9469 bd->client.illume.quickpanel.fetch.priority.major = 0;
9471 if (bd->client.illume.quickpanel.fetch.priority.minor)
9473 bd->client.illume.quickpanel.priority.minor =
9474 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9475 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9477 if (bd->client.illume.quickpanel.fetch.zone)
9479 bd->client.illume.quickpanel.zone =
9480 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9481 bd->client.illume.quickpanel.fetch.zone = 0;
9483 if (bd->client.illume.drag.fetch.drag)
9485 bd->client.illume.drag.drag =
9486 ecore_x_e_illume_drag_get(bd->client.win);
9487 bd->client.illume.drag.fetch.drag = 0;
9489 if (bd->client.illume.drag.fetch.locked)
9491 bd->client.illume.drag.locked =
9492 ecore_x_e_illume_drag_locked_get(bd->client.win);
9493 bd->client.illume.drag.fetch.locked = 0;
9495 if (bd->client.illume.win_state.fetch.state)
9497 bd->client.illume.win_state.state =
9498 ecore_x_e_illume_window_state_get(bd->client.win);
9499 bd->client.illume.win_state.fetch.state = 0;
9501 if (bd->changes.shape)
9503 Ecore_X_Rectangle *rects;
9506 bd->changes.shape = 0;
9507 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9512 /* This doesn't fix the race, but makes it smaller. we detect
9513 * this and if cw and ch != client w/h then mark this as needing
9514 * a shape change again to fixup next event loop.
9516 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9517 if ((cw != bd->client.w) || (ch != bd->client.h))
9518 bd->changes.shape = 1;
9520 (rects[0].x == 0) &&
9521 (rects[0].y == 0) &&
9522 ((int)rects[0].width == cw) &&
9523 ((int)rects[0].height == ch))
9525 if (bd->client.shaped)
9527 bd->client.shaped = 0;
9528 if (!bd->bordername)
9529 bd->client.border.changed = 1;
9534 if (!bd->client.shaped)
9536 bd->client.shaped = 1;
9537 if (!bd->bordername)
9538 bd->client.border.changed = 1;
9545 // FIXME: no rects i think can mean... totally empty window
9546 bd->client.shaped = 0;
9547 if (!bd->bordername)
9548 bd->client.border.changed = 1;
9550 bd->need_shape_merge = 1;
9552 if (bd->changes.shape_input)
9554 Ecore_X_Rectangle *rects;
9557 bd->changes.shape_input = 0;
9558 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9563 /* This doesn't fix the race, but makes it smaller. we detect
9564 * this and if cw and ch != client w/h then mark this as needing
9565 * a shape change again to fixup next event loop.
9567 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9568 if ((cw != bd->client.w) || (ch != bd->client.h))
9569 bd->changes.shape_input = 1;
9571 (rects[0].x == 0) &&
9572 (rects[0].y == 0) &&
9573 ((int)rects[0].width == cw) &&
9574 ((int)rects[0].height == ch))
9576 if (bd->shaped_input)
9578 bd->shaped_input = 0;
9579 if (!bd->bordername)
9580 bd->client.border.changed = 1;
9585 if (!bd->shaped_input)
9587 bd->shaped_input = 1;
9588 if (!bd->bordername)
9589 bd->client.border.changed = 1;
9596 bd->shaped_input = 1;
9597 if (!bd->bordername)
9598 bd->client.border.changed = 1;
9600 bd->need_shape_merge = 1;
9602 if (bd->client.mwm.fetch.hints)
9606 bd->client.mwm.exists =
9607 ecore_x_mwm_hints_get(bd->client.win,
9608 &bd->client.mwm.func,
9609 &bd->client.mwm.decor,
9610 &bd->client.mwm.input);
9611 pb = bd->client.mwm.borderless;
9612 bd->client.mwm.borderless = 0;
9613 if (bd->client.mwm.exists)
9615 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9616 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9617 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9618 bd->client.mwm.borderless = 1;
9620 if (bd->client.mwm.borderless != pb)
9622 if ((!bd->lock_border) || (!bd->client.border.name))
9623 bd->client.border.changed = 1;
9625 bd->client.mwm.fetch.hints = 0;
9628 if (bd->client.e.fetch.video_parent)
9630 /* unlinking child/parent */
9631 if (bd->client.e.state.video_parent_border != NULL)
9633 bd->client.e.state.video_parent_border->client.e.state.video_child =
9635 (bd->client.e.state.video_parent_border->client.e.state.video_child,
9639 ecore_x_window_prop_card32_get(bd->client.win,
9640 ECORE_X_ATOM_E_VIDEO_PARENT,
9641 &bd->client.e.state.video_parent,
9644 /* linking child/parent */
9645 if (bd->client.e.state.video_parent != 0)
9650 EINA_LIST_FOREACH(borders, l, tmp)
9651 if (tmp->client.win == bd->client.e.state.video_parent)
9653 /* fprintf(stderr, "child added to parent \\o/\n"); */
9654 bd->client.e.state.video_parent_border = tmp;
9655 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
9657 if (bd->desk != tmp->desk)
9658 e_border_desk_set(bd, tmp->desk);
9663 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
9665 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
9668 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
9672 ecore_x_window_prop_card32_get(bd->client.win,
9673 ECORE_X_ATOM_E_VIDEO_POSITION,
9676 bd->client.e.state.video_position.x = xy[0];
9677 bd->client.e.state.video_position.y = xy[1];
9678 bd->client.e.state.video_position.updated = 1;
9679 bd->client.e.fetch.video_position = 0;
9680 bd->x = bd->client.e.state.video_position.x;
9681 bd->y = bd->client.e.state.video_position.y;
9683 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
9685 if (bd->client.netwm.update.state)
9687 e_hints_window_state_set(bd);
9688 /* Some stats might change the border, like modal */
9689 if (((!bd->lock_border) || (!bd->client.border.name)) &&
9690 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9692 bd->client.border.changed = 1;
9696 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9698 bd->parent->modal = bd;
9699 if (bd->parent->focused)
9700 e_border_focus_set(bd, 1, 1);
9703 else if (bd->leader)
9705 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9707 bd->leader->modal = bd;
9708 if (bd->leader->focused)
9709 e_border_focus_set(bd, 1, 1);
9715 EINA_LIST_FOREACH(bd->leader->group, l, child)
9717 if ((child != bd) && (child->focused))
9718 e_border_focus_set(bd, 1, 1);
9723 bd->client.netwm.update.state = 0;
9728 E_Event_Border_Add *ev;
9729 E_Exec_Instance *inst;
9731 ev = E_NEW(E_Event_Border_Add, 1);
9733 e_object_ref(E_OBJECT(bd));
9734 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
9735 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
9737 if ((!bd->lock_border) || (!bd->client.border.name))
9738 bd->client.border.changed = 1;
9743 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
9744 ((bd->client.icccm.client_leader > 0) &&
9745 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
9748 if (!strncmp(str, "E_START|", 8))
9753 if (id > 0) bd->client.netwm.startup_id = id;
9758 /* It's ok not to have fetch flag, should only be set on startup
9759 * * and not changed. */
9760 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
9762 if (bd->client.icccm.client_leader)
9764 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
9765 bd->client.netwm.pid = -1;
9768 bd->client.netwm.pid = -1;
9773 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
9774 bd->client.netwm.pid);
9775 if ((inst) && (inst->used == 0))
9781 zone = e_container_zone_number_get(bd->zone->container,
9783 if (zone) e_border_zone_set(bd, zone);
9784 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
9786 if (desk) e_border_desk_set(bd, desk);
9787 e_exec_instance_found(inst);
9790 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
9792 E_Border *bdl = NULL;
9797 if (bd->leader) bdl = bd->leader;
9804 bl = e_container_border_list_first(bd->zone->container);
9805 while ((child = e_container_border_list_next(bl)))
9807 if (child == bd) continue;
9808 if (e_object_is_del(E_OBJECT(child))) continue;
9809 if ((bd->client.icccm.client_leader) &&
9810 (child->client.icccm.client_leader ==
9811 bd->client.icccm.client_leader))
9817 e_container_border_list_free(bl);
9822 e_border_zone_set(bd, bdl->zone);
9824 e_border_desk_set(bd, bdl->desk);
9832 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9835 E_Container *con = bd->zone->container;
9836 E_Desk *desk = NULL;
9839 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
9841 desk = e_container_desk_window_profile_get(con, str);
9844 if (bd->desk != desk)
9846 bd->client.e.state.profile = eina_stringshare_add(str);
9847 if (bd->zone != desk->zone)
9848 e_border_zone_set(bd, desk->zone);
9849 e_border_desk_set(bd, desk);
9856 #ifdef _F_ZONE_WINDOW_ROTATION_
9857 if ((e_config->wm_win_rotation) &&
9858 (need_rotation_set))
9860 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
9861 _e_border_rotation_check(bd);
9865 /* PRE_POST_FETCH calls e_remember apply for new client */
9866 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
9867 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
9868 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
9870 if (bd->need_reparent)
9873 ecore_x_window_save_set_add(bd->client.win);
9874 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
9877 if ((bd->new_client) && (bd->internal) &&
9878 (bd->internal_ecore_evas))
9879 ecore_evas_show(bd->internal_ecore_evas);
9880 ecore_x_window_show(bd->client.win);
9882 bd->need_reparent = 0;
9885 if ((bd->client.border.changed) && (!bd->shaded) &&
9886 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9888 const char *bordername;
9891 bordername = "borderless";
9892 else if (bd->bordername)
9893 bordername = bd->bordername;
9894 else if ((bd->client.mwm.borderless) || (bd->borderless))
9895 bordername = "borderless";
9896 else if (((bd->client.icccm.transient_for != 0) ||
9897 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
9898 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
9899 (bd->client.icccm.min_h == bd->client.icccm.max_h))
9900 bordername = "noresize_dialog";
9901 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
9902 (bd->client.icccm.min_h == bd->client.icccm.max_h))
9903 bordername = "noresize";
9904 else if (bd->client.shaped)
9905 bordername = "shaped";
9906 else if ((!bd->client.icccm.accepts_focus) &&
9907 (!bd->client.icccm.take_focus))
9908 bordername = "nofocus";
9909 else if (bd->client.icccm.urgent)
9910 bordername = "urgent";
9911 else if ((bd->client.icccm.transient_for != 0) ||
9912 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
9913 bordername = "dialog";
9914 else if (bd->client.netwm.state.modal)
9915 bordername = "modal";
9916 else if ((bd->client.netwm.state.skip_taskbar) ||
9917 (bd->client.netwm.state.skip_pager))
9918 bordername = "skipped";
9919 else if ((bd->internal) && (bd->client.icccm.class) &&
9920 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
9921 bordername = "internal_fileman";
9923 bordername = e_config->theme_default_border_style;
9924 if (!bordername) bordername = "default";
9926 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
9932 bd->changes.border = 1;
9933 eina_stringshare_replace(&bd->client.border.name, bordername);
9937 bd->w -= (bd->client_inset.l + bd->client_inset.r);
9938 bd->h -= (bd->client_inset.t + bd->client_inset.b);
9939 bd->changes.size = 1;
9940 evas_object_del(bd->bg_object);
9942 o = edje_object_add(bd->bg_evas);
9943 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
9944 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
9945 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
9947 if (bd->client.border.name != e_config->theme_default_border_style)
9949 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
9950 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
9954 ok = e_theme_edje_object_set(o, "base/theme/borders",
9955 "e/widgets/border/default/border");
9958 /* Reset default border style to default */
9959 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
9960 e_config_save_queue();
9968 const char *shape_option, *argb_option;
9973 if ((e_config->use_composite) && (!bd->client.argb))
9975 argb_option = edje_object_data_get(o, "argb");
9976 if ((argb_option) && (!strcmp(argb_option, "1")))
9979 if (use_argb != bd->argb)
9980 _e_border_frame_replace(bd, use_argb);
9987 shape_option = edje_object_data_get(o, "shaped");
9988 if ((shape_option) && (!strcmp(shape_option, "1")))
9992 if (bd->client.netwm.name)
9993 edje_object_part_text_set(o, "e.text.title",
9994 bd->client.netwm.name);
9995 else if (bd->client.icccm.title)
9996 edje_object_part_text_set(o, "e.text.title",
9997 bd->client.icccm.title);
10001 evas_object_del(o);
10002 bd->bg_object = NULL;
10005 _e_border_client_inset_calc(bd);
10007 bd->w += (bd->client_inset.l + bd->client_inset.r);
10008 bd->h += (bd->client_inset.t + bd->client_inset.b);
10009 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10010 bd->changes.size = 1;
10011 /* really needed ? */
10012 ecore_x_window_move(bd->client.shell_win,
10013 bd->client_inset.l,
10014 bd->client_inset.t);
10016 if (bd->maximized != E_MAXIMIZE_NONE)
10018 E_Maximize maximized = bd->maximized;
10020 /* to force possible resizes */
10021 bd->maximized = E_MAXIMIZE_NONE;
10023 _e_border_maximize(bd, maximized);
10025 /* restore maximized state */
10026 bd->maximized = maximized;
10028 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10029 bd->maximized & E_MAXIMIZE_VERTICAL);
10033 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10034 _e_border_cb_signal_bind, bd);
10037 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10038 if (bd->icon_object)
10039 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10042 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10044 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10046 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10047 // FIXME: in eval -do differently
10048 // edje_object_message_signal_process(bd->bg_object);
10049 // e_border_frame_recalc(bd);
10051 evas_object_move(bd->bg_object, 0, 0);
10052 evas_object_resize(bd->bg_object, bd->w, bd->h);
10053 evas_object_show(bd->bg_object);
10056 bd->client.border.changed = 0;
10058 if (bd->icon_object)
10062 evas_object_show(bd->icon_object);
10063 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10066 evas_object_hide(bd->icon_object);
10070 if (rem_change) e_remember_update(bd);
10074 E_Event_Border_Urgent_Change *ev;
10076 if (bd->client.icccm.urgent)
10077 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10079 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10081 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10083 e_object_ref(E_OBJECT(bd));
10084 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10085 _e_border_event_border_urgent_change_free, NULL);
10088 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10091 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10093 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10095 E_Border* temp_bd = NULL;
10096 E_Border* top_focusable_bd = NULL;
10097 Eina_Bool is_fully_obscured = EINA_FALSE;
10098 Ecore_X_XRegion *visible_region = NULL;
10099 Ecore_X_XRegion *win_region = NULL;
10100 Ecore_X_Rectangle visible_rect, win_rect;
10103 // set the entire visible region as a root geometry
10104 visible_rect.x = bd->zone->x;
10105 visible_rect.y = bd->zone->y;
10106 visible_rect.width = bd->zone->w;
10107 visible_rect.height = bd->zone->h;
10109 visible_region = ecore_x_xregion_new();
10110 if (!visible_region) return;
10112 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10114 bl = e_container_border_list_last(bd->zone->container);
10115 while ((temp_bd = e_container_border_list_prev(bl)))
10117 if (temp_bd == bd) break;
10119 if (temp_bd == focused) continue;
10120 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10121 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10122 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10123 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10124 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10125 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10126 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10127 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10128 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10130 if (!top_focusable_bd)
10132 top_focusable_bd = temp_bd;
10135 win_rect.x = temp_bd->x;
10136 win_rect.y = temp_bd->y;
10137 win_rect.width = temp_bd->w;
10138 win_rect.height = temp_bd->h;
10140 // if it stick out or is bigger than the entire visible region,
10141 // clip it by the entire visible's geometry.
10142 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10143 win_rect.width, win_rect.height,
10144 visible_rect.x, visible_rect.y,
10145 (int)(visible_rect.width), (int)(visible_rect.height));
10147 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10149 win_region = ecore_x_xregion_new();
10152 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10153 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10154 ecore_x_xregion_free(win_region);
10157 if (ecore_x_xregion_is_empty(visible_region))
10159 is_fully_obscured = EINA_TRUE;
10167 if (is_fully_obscured == EINA_TRUE)
10169 e_border_focus_set(top_focusable_bd, 1, 1);
10173 e_border_focus_set(bd, 1, 1);
10176 if (visible_region) ecore_x_xregion_free(visible_region);
10177 e_container_border_list_free(bl);
10181 _e_border_latest_stacked_focus(E_Border *bd)
10184 int root_w, root_h;
10186 root_w = bd->zone->w;
10187 root_h = bd->zone->h;
10190 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10192 if (bd == temp_bd) continue;
10193 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10194 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10196 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10197 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10198 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10199 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10200 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10201 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10202 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10204 _e_border_latest_stacked_focus_check_set(temp_bd);
10211 _e_border_check_stack (E_Border *bd)
10213 E_Border* temp_bd = NULL;
10214 E_Border* top_bd = NULL;
10215 int passed_focus = 0;
10217 int root_w = bd->zone->w;
10218 int root_h = bd->zone->h;
10221 bl = e_container_border_list_last(bd->zone->container);
10222 while ((temp_bd = e_container_border_list_prev(bl)))
10224 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10225 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10226 if ((temp_bd != bd) &&
10227 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10229 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10230 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10231 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10232 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10233 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10234 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10235 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10241 e_border_focus_set_with_pointer(bd);
10248 e_border_focus_set_with_pointer(top_bd);
10257 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10259 if (!bd->lock_focus_out)
10261 e_border_focus_latest_set(bd);
10273 if (temp_bd == focused)
10279 e_container_border_list_free(bl);
10283 _e_border_focus_top_stack_set(E_Border* bd)
10286 int root_w, root_h;
10288 root_w = bd->zone->w;
10289 root_h = bd->zone->h;
10292 bl = e_container_border_list_last(bd->zone->container);
10293 while ((temp_bd = e_container_border_list_prev(bl)))
10295 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10296 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10297 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10299 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10300 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10301 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10302 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10303 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10304 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10305 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10307 if (!temp_bd->focused)
10309 /* this border is the top of the latest stack */
10310 e_border_focus_set (temp_bd, 1, 1);
10315 e_container_border_list_free(bl);
10320 _e_border_eval(E_Border *bd)
10322 E_Event_Border_Property *event;
10323 E_Border_Pending_Move_Resize *pnd;
10324 int rem_change = 0;
10325 int send_event = 1;
10327 if (e_object_is_del(E_OBJECT(bd)))
10329 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10334 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10336 if (bd->new_client)
10338 int zx = 0, zy = 0, zw = 0, zh = 0;
10341 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10344 * Limit maximum size of windows to useful geometry
10346 // TODO: temoporary limited maximize algorithm
10358 if ((rw != bd->w) || (rh != bd->h))
10362 e_border_resize (bd, bd->w, bd->h);
10368 bd->x -= bd->client_inset.l;
10369 bd->y -= bd->client_inset.t;
10370 bd->changes.pos = 1;
10373 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10376 Ecore_X_Window_Attributes *att;
10379 att = &bd->client.initial_attributes;
10380 bw = att->border * 2;
10381 switch (bd->client.icccm.gravity)
10383 case ECORE_X_GRAVITY_N:
10384 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10388 case ECORE_X_GRAVITY_NE:
10389 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10393 case ECORE_X_GRAVITY_E:
10394 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10395 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10398 case ECORE_X_GRAVITY_SE:
10399 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10400 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10403 case ECORE_X_GRAVITY_S:
10404 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10405 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10408 case ECORE_X_GRAVITY_SW:
10410 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10413 case ECORE_X_GRAVITY_W:
10415 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10418 case ECORE_X_GRAVITY_CENTER:
10419 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10420 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10423 case ECORE_X_GRAVITY_NW:
10430 * This ensures that windows that like to open with a x/y
10431 * position smaller than returned by e_zone_useful_geometry_get()
10432 * are moved to useful positions.
10435 if (e_config->geometry_auto_move)
10443 if (bd->x + bd->w > zx + zw)
10444 bd->x = zx + zw - bd->w;
10446 if (bd->y + bd->h > zy + zh)
10447 bd->y = zy + zh - bd->h;
10450 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10452 bd->changes.pos = 1;
10458 bd->changes.pos = 1;
10464 /* FIXME: special placement for dialogs etc. etc. etc goes
10466 /* FIXME: what if parent is not on this desktop - or zone? */
10467 if ((bd->parent) && (bd->parent->visible))
10469 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10470 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10471 bd->changes.pos = 1;
10475 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10477 /* TODO: Place in center of group */
10480 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10482 bd->x = zx + ((zw - bd->w) / 2);
10483 bd->y = zy + ((zh - bd->h) / 2);
10484 bd->changes.pos = 1;
10490 Eina_List *skiplist = NULL;
10494 new_x = zx + (rand() % (zw - bd->w));
10498 new_y = zy + (rand() % (zh - bd->h));
10502 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10504 skiplist = eina_list_append(skiplist, bd);
10506 e_place_desk_region_smart(bd->desk, skiplist,
10507 bd->x, bd->y, bd->w, bd->h,
10510 e_place_zone_region_smart(bd->zone, skiplist,
10511 bd->x, bd->y, bd->w, bd->h,
10513 eina_list_free(skiplist);
10515 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10517 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10522 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10523 bd->client_inset.t, &new_x, &new_y);
10527 bd->changes.pos = 1;
10530 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10532 if ((!bd->lock_client_location) && (pnd->move))
10536 bd->changes.pos = 1;
10538 if (pnd->without_border)
10540 bd->x -= bd->client_inset.l;
10541 bd->y -= bd->client_inset.t;
10544 if ((!bd->lock_client_size) && (pnd->resize))
10546 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10547 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10548 bd->client.w = pnd->w;
10549 bd->client.h = pnd->h;
10550 bd->changes.size = 1;
10556 /* Recreate state */
10557 e_hints_window_init(bd);
10558 if ((bd->client.e.state.centered) &&
10559 ((!bd->remember) ||
10560 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10562 bd->x = zx + (zw - bd->w) / 2;
10563 bd->y = zy + (zh - bd->h) / 2;
10564 bd->changes.pos = 1;
10568 _e_border_client_move_resize_send(bd);
10570 /* if the explicit geometry request asks for the app to be
10571 * in another zone - well move it there */
10575 zone = e_container_zone_at_point_get(bd->zone->container,
10576 bd->x + (bd->w / 2),
10577 bd->y + (bd->h / 2));
10579 zone = e_container_zone_at_point_get(bd->zone->container,
10583 zone = e_container_zone_at_point_get(bd->zone->container,
10587 zone = e_container_zone_at_point_get(bd->zone->container,
10589 bd->y + bd->h - 1);
10591 zone = e_container_zone_at_point_get(bd->zone->container,
10593 bd->y + bd->h - 1);
10594 if ((zone) && (zone != bd->zone))
10595 e_border_zone_set(bd, zone);
10599 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10601 /* effect changes to the window border itself */
10602 if ((bd->changes.shading))
10604 /* show at start of unshade (but don't hide until end of shade) */
10606 ecore_x_window_raise(bd->client.shell_win);
10607 bd->changes.shading = 0;
10610 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
10613 ecore_x_window_lower(bd->client.shell_win);
10615 ecore_x_window_raise(bd->client.shell_win);
10616 bd->changes.shaded = 0;
10619 else if ((bd->changes.shaded) && (bd->changes.pos))
10622 ecore_x_window_lower(bd->client.shell_win);
10624 ecore_x_window_raise(bd->client.shell_win);
10625 bd->changes.size = 1;
10626 bd->changes.shaded = 0;
10629 else if ((bd->changes.shaded) && (bd->changes.size))
10632 ecore_x_window_lower(bd->client.shell_win);
10634 ecore_x_window_raise(bd->client.shell_win);
10635 bd->changes.shaded = 0;
10638 else if (bd->changes.shaded)
10641 ecore_x_window_lower(bd->client.shell_win);
10643 ecore_x_window_raise(bd->client.shell_win);
10644 bd->changes.size = 1;
10645 bd->changes.shaded = 0;
10649 if (bd->changes.size)
10651 int x = 0, y = 0, xx = 0, yy = 0;
10653 if ((bd->shaded) && (!bd->shading))
10655 evas_obscured_clear(bd->bg_evas);
10659 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
10660 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
10662 evas_obscured_clear(bd->bg_evas);
10663 evas_obscured_rectangle_add(bd->bg_evas,
10664 bd->client_inset.l, bd->client_inset.t, xx, yy);
10668 if (bd->shade.dir == E_DIRECTION_UP)
10670 y = yy - bd->client.h;
10672 else if (bd->shade.dir == E_DIRECTION_LEFT)
10674 x = xx - bd->client.w;
10679 if (bd->client.e.state.video)
10681 if (bd->client.e.state.video_position.updated)
10683 ecore_x_window_move(bd->win,
10684 bd->client.e.state.video_parent_border->x +
10685 bd->client.e.state.video_parent_border->client_inset.l +
10686 bd->client.e.state.video_parent_border->fx.x +
10687 bd->client.e.state.video_position.x,
10688 bd->client.e.state.video_parent_border->y +
10689 bd->client.e.state.video_parent_border->client_inset.t +
10690 bd->client.e.state.video_parent_border->fx.y +
10691 bd->client.e.state.video_position.y);
10692 bd->client.e.state.video_position.updated = 0;
10695 else if (!bd->changes.pos)
10697 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10698 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10699 bd->post_resize = 1;
10706 ecore_x_window_move_resize(bd->win,
10711 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
10712 ecore_x_window_move(tmp->win,
10713 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
10714 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
10717 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
10719 if ((!bd->shaded) || (bd->shading))
10720 ecore_x_window_move_resize(bd->client.shell_win,
10721 bd->client_inset.l, bd->client_inset.t, xx, yy);
10723 if (bd->internal_ecore_evas)
10724 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
10725 else if (!bd->client.e.state.video)
10726 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
10728 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
10729 evas_object_resize(bd->bg_object, bd->w, bd->h);
10730 e_container_shape_resize(bd->shape, bd->w, bd->h);
10731 if (bd->changes.pos)
10732 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10734 _e_border_client_move_resize_send(bd);
10736 bd->changes.pos = 0;
10737 bd->changes.size = 0;
10740 else if (bd->changes.pos)
10742 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10743 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10746 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10748 _e_border_client_move_resize_send(bd);
10750 bd->changes.pos = 0;
10754 if (bd->changes.reset_gravity)
10756 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
10757 bd->changes.reset_gravity = 0;
10761 if (bd->need_shape_merge)
10763 _e_border_shape_input_rectangle_set(bd);
10764 if ((bd->shaped) || (bd->client.shaped))
10766 Ecore_X_Window twin, twin2;
10769 twin = ecore_x_window_override_new
10770 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
10772 ecore_x_window_shape_window_set(twin, bd->bg_win);
10775 Ecore_X_Rectangle rects[4];
10779 rects[0].width = bd->w;
10780 rects[0].height = bd->client_inset.t;
10782 rects[1].y = bd->client_inset.t;
10783 rects[1].width = bd->client_inset.l;
10784 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
10785 rects[2].x = bd->w - bd->client_inset.r;
10786 rects[2].y = bd->client_inset.t;
10787 rects[2].width = bd->client_inset.r;
10788 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
10790 rects[3].y = bd->h - bd->client_inset.b;
10791 rects[3].width = bd->w;
10792 rects[3].height = bd->client_inset.b;
10793 ecore_x_window_shape_rectangles_set(twin, rects, 4);
10795 twin2 = ecore_x_window_override_new
10796 (bd->zone->container->scratch_win, 0, 0,
10797 bd->w - bd->client_inset.l - bd->client_inset.r,
10798 bd->h - bd->client_inset.t - bd->client_inset.b);
10801 if ((bd->shading) || (bd->shaded))
10803 if (bd->shade.dir == E_DIRECTION_UP)
10804 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
10805 else if (bd->shade.dir == E_DIRECTION_LEFT)
10806 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
10808 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
10810 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
10811 bd->w - bd->client_inset.l - bd->client_inset.r,
10812 bd->h - bd->client_inset.t - bd->client_inset.b);
10813 ecore_x_window_shape_window_add_xy(twin, twin2,
10814 bd->client_inset.l,
10815 bd->client_inset.t);
10816 ecore_x_window_free(twin2);
10817 ecore_x_window_shape_window_set(bd->win, twin);
10818 ecore_x_window_free(twin);
10821 ecore_x_window_shape_mask_set(bd->win, 0);
10822 // bd->need_shape_export = 1;
10823 bd->need_shape_merge = 0;
10826 if (bd->need_shape_export)
10828 Ecore_X_Rectangle *rects, *orects;
10831 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
10837 if ((num == bd->shape_rects_num) && (bd->shape_rects))
10841 orects = bd->shape_rects;
10843 for (i = 0; i < num; i++)
10845 if (rects[i].x < 0)
10847 rects[i].width -= rects[i].x;
10850 if ((rects[i].x + (int)rects[i].width) > bd->w)
10851 rects[i].width = rects[i].width - rects[i].x;
10852 if (rects[i].y < 0)
10854 rects[i].height -= rects[i].y;
10857 if ((rects[i].y + (int)rects[i].height) > bd->h)
10858 rects[i].height = rects[i].height - rects[i].y;
10860 if ((orects[i].x != rects[i].x) ||
10861 (orects[i].y != rects[i].y) ||
10862 (orects[i].width != rects[i].width) ||
10863 (orects[i].height != rects[i].height))
10872 if (bd->client.shaped)
10873 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
10875 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
10876 E_FREE(bd->shape_rects);
10877 bd->shape_rects = rects;
10878 bd->shape_rects_num = num;
10879 e_container_shape_rects_set(bd->shape, rects, num);
10886 E_FREE(bd->shape_rects);
10887 bd->shape_rects = NULL;
10888 bd->shape_rects_num = 0;
10889 e_container_shape_rects_set(bd->shape, NULL, 0);
10891 bd->need_shape_export = 0;
10894 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
10898 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
10899 if ((!bd->placed) && (!bd->re_manage) &&
10900 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
10901 (!((bd->client.icccm.transient_for != 0) ||
10902 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
10903 (!bdmove) && (!bdresize))
10905 /* Set this window into moving state */
10907 bd->cur_mouse_action = e_action_find("window_move");
10908 if (bd->cur_mouse_action)
10910 if ((!bd->cur_mouse_action->func.end_mouse) &&
10911 (!bd->cur_mouse_action->func.end))
10912 bd->cur_mouse_action = NULL;
10913 if (bd->cur_mouse_action)
10915 bd->x = x - (bd->w >> 1);
10916 bd->y = y - (bd->client_inset.t >> 1);
10918 bd->changes.pos = 1;
10920 _e_border_client_move_resize_send(bd);
10925 _e_border_show(bd);
10927 if (bd->cur_mouse_action)
10929 bd->moveinfo.down.x = bd->x + bd->fx.x;
10930 bd->moveinfo.down.y = bd->y + bd->fx.y;
10931 bd->moveinfo.down.w = bd->w;
10932 bd->moveinfo.down.h = bd->h;
10933 bd->mouse.current.mx = x;
10934 bd->mouse.current.my = y;
10935 bd->moveinfo.down.button = 0;
10936 bd->moveinfo.down.mx = x;
10937 bd->moveinfo.down.my = y;
10940 e_object_ref(E_OBJECT(bd->cur_mouse_action));
10941 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
10942 if (e_config->border_raise_on_mouse_action)
10943 e_border_raise(bd);
10944 e_border_focus_set(bd, 1, 1);
10946 bd->changes.visible = 0;
10950 if (bd->changes.icon)
10954 efreet_desktop_free(bd->desktop);
10955 bd->desktop = NULL;
10957 if (bd->icon_object)
10959 evas_object_del(bd->icon_object);
10960 bd->icon_object = NULL;
10962 if (bd->remember && bd->remember->prop.desktop_file)
10964 const char *desktop = bd->remember->prop.desktop_file;
10966 bd->desktop = efreet_desktop_get(desktop);
10968 bd->desktop = efreet_util_desktop_name_find(desktop);
10972 if ((bd->client.icccm.name) && (bd->client.icccm.class))
10973 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
10974 bd->client.icccm.class);
10978 /* libreoffice and maybe others match window class
10979 with .desktop file name */
10980 if (bd->client.icccm.class)
10983 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
10984 bd->desktop = efreet_util_desktop_file_id_find(buf);
10989 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
10990 bd->client.netwm.pid);
10991 if (bd->desktop) efreet_desktop_ref(bd->desktop);
10993 if (!bd->desktop && bd->client.icccm.name)
10995 /* this works for most cases as fallback. useful when app is
10996 run from a shell */
10997 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
10999 if (!bd->desktop && bd->client.icccm.transient_for)
11001 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11002 if (bd2 && bd2->desktop)
11004 efreet_desktop_ref(bd2->desktop);
11005 bd->desktop = bd2->desktop;
11010 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11011 bd->desktop->orig_path);
11014 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11015 if ((bd->focused) && (bd->icon_object))
11016 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11019 evas_object_show(bd->icon_object);
11020 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11023 evas_object_hide(bd->icon_object);
11026 E_Event_Border_Icon_Change *ev;
11028 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11030 e_object_ref(E_OBJECT(bd));
11031 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11032 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11033 _e_border_event_border_icon_change_free, NULL);
11035 bd->changes.icon = 0;
11038 bd->new_client = 0;
11040 bd->changes.stack = 0;
11041 bd->changes.prop = 0;
11043 if ((bd->take_focus) || (bd->want_focus))
11045 bd->take_focus = 0;
11046 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11047 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11048 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11051 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11054 bd->want_focus = 0;
11055 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11056 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11057 _e_border_check_stack(bd);
11060 e_border_focus_set_with_pointer(bd);
11062 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11064 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11065 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11066 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11067 e_border_focused_get())))
11069 e_border_focus_set_with_pointer(bd);
11074 /* focus window by default when it is the only one on desk */
11075 E_Border *bd2 = NULL;
11077 EINA_LIST_FOREACH(focus_stack, l, bd2)
11079 if (bd == bd2) continue;
11080 if ((!bd2->iconic) && (bd2->visible) &&
11081 ((bd->desk == bd2->desk) || bd2->sticky))
11087 e_border_focus_set_with_pointer(bd);
11092 if (bd->need_maximize)
11095 max = bd->maximized;
11096 bd->maximized = E_MAXIMIZE_NONE;
11097 e_border_maximize(bd, max);
11098 bd->need_maximize = 0;
11101 if (bd->need_fullscreen)
11103 e_border_fullscreen(bd, e_config->fullscreen_policy);
11104 bd->need_fullscreen = 0;
11108 e_remember_update(bd);
11110 if (send_event) // FIXME: send only if a property changed - above need to
11111 { // check on that. for now - always send.
11112 event = E_NEW(E_Event_Border_Property, 1);
11113 event->border = bd;
11114 e_object_ref(E_OBJECT(bd));
11115 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11117 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11121 _e_border_moveinfo_gather(E_Border *bd,
11122 const char *source)
11124 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11125 else if (e_util_glob_match(source, "mouse,*,2"))
11126 bd->moveinfo.down.button = 2;
11127 else if (e_util_glob_match(source, "mouse,*,3"))
11128 bd->moveinfo.down.button = 3;
11129 else bd->moveinfo.down.button = 0;
11130 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11132 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11133 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11137 bd->moveinfo.down.mx = bd->mouse.current.mx;
11138 bd->moveinfo.down.my = bd->mouse.current.my;
11143 _e_border_resize_handle(E_Border *bd)
11146 int new_x, new_y, new_w, new_h;
11148 Eina_List *skiplist = NULL;
11155 if ((bd->resize_mode == RESIZE_TR) ||
11156 (bd->resize_mode == RESIZE_R) ||
11157 (bd->resize_mode == RESIZE_BR))
11159 if ((bd->moveinfo.down.button >= 1) &&
11160 (bd->moveinfo.down.button <= 3))
11161 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11162 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11164 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11166 else if ((bd->resize_mode == RESIZE_TL) ||
11167 (bd->resize_mode == RESIZE_L) ||
11168 (bd->resize_mode == RESIZE_BL))
11170 if ((bd->moveinfo.down.button >= 1) &&
11171 (bd->moveinfo.down.button <= 3))
11172 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11173 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11175 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11178 if ((bd->resize_mode == RESIZE_TL) ||
11179 (bd->resize_mode == RESIZE_T) ||
11180 (bd->resize_mode == RESIZE_TR))
11182 if ((bd->moveinfo.down.button >= 1) &&
11183 (bd->moveinfo.down.button <= 3))
11184 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11185 (bd->mouse.current.my - bd->moveinfo.down.my);
11187 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11189 else if ((bd->resize_mode == RESIZE_BL) ||
11190 (bd->resize_mode == RESIZE_B) ||
11191 (bd->resize_mode == RESIZE_BR))
11193 if ((bd->moveinfo.down.button >= 1) &&
11194 (bd->moveinfo.down.button <= 3))
11195 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11196 (bd->mouse.current.my - bd->moveinfo.down.my);
11198 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11204 if ((bd->resize_mode == RESIZE_TL) ||
11205 (bd->resize_mode == RESIZE_L) ||
11206 (bd->resize_mode == RESIZE_BL))
11208 if ((bd->resize_mode == RESIZE_TL) ||
11209 (bd->resize_mode == RESIZE_T) ||
11210 (bd->resize_mode == RESIZE_TR))
11213 skiplist = eina_list_append(skiplist, bd);
11214 e_resist_container_border_position(bd->zone->container, skiplist,
11215 bd->x, bd->y, bd->w, bd->h,
11217 &new_x, &new_y, &new_w, &new_h);
11218 eina_list_free(skiplist);
11222 e_border_resize_limit(bd, &new_w, &new_h);
11223 if ((bd->resize_mode == RESIZE_TL) ||
11224 (bd->resize_mode == RESIZE_L) ||
11225 (bd->resize_mode == RESIZE_BL))
11226 new_x += (w - new_w);
11227 if ((bd->resize_mode == RESIZE_TL) ||
11228 (bd->resize_mode == RESIZE_T) ||
11229 (bd->resize_mode == RESIZE_TR))
11230 new_y += (h - new_h);
11232 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11236 _e_border_shade_animator(void *data)
11238 E_Border *bd = data;
11240 double dur = bd->client.h / e_config->border_shade_speed;
11242 dt = ecore_loop_time_get() - bd->shade.start;
11245 if (val < 0.0) val = 0.0;
11246 else if (val > 1.0) val = 1.0;
11248 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11251 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11252 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11254 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11257 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11258 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11260 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11263 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11264 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11266 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11269 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11270 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11272 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11275 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11276 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11278 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11281 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11282 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11284 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11287 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11288 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11290 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11293 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11294 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11296 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11299 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11300 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11305 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11306 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11309 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11310 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11311 else if (bd->shade.val > .999)
11312 bd->shade.val = 1.0;
11314 if (bd->shade.dir == E_DIRECTION_UP)
11315 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11316 else if (bd->shade.dir == E_DIRECTION_DOWN)
11318 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11319 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11320 bd->changes.pos = 1;
11322 else if (bd->shade.dir == E_DIRECTION_LEFT)
11323 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11324 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11326 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11327 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11328 bd->changes.pos = 1;
11331 if ((bd->shaped) || (bd->client.shaped))
11333 bd->need_shape_merge = 1;
11334 bd->need_shape_export = 1;
11336 if (bd->shaped_input)
11338 bd->need_shape_merge = 1;
11340 bd->changes.size = 1;
11346 E_Event_Border_Resize *ev;
11349 bd->shaded = !(bd->shaded);
11350 bd->changes.size = 1;
11351 bd->changes.shaded = 1;
11352 bd->changes.shading = 1;
11354 bd->shade.anim = NULL;
11357 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11359 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11360 edje_object_message_signal_process(bd->bg_object);
11361 e_border_frame_recalc(bd);
11363 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11364 ev = E_NEW(E_Event_Border_Resize, 1);
11366 e_object_ref(E_OBJECT(bd));
11367 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11368 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11369 return ECORE_CALLBACK_CANCEL;
11371 return ECORE_CALLBACK_RENEW;
11375 _e_border_event_border_resize_free(void *data __UNUSED__,
11378 E_Event_Border_Resize *e;
11381 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11382 e_object_unref(E_OBJECT(e->border));
11387 _e_border_event_border_move_free(void *data __UNUSED__,
11390 E_Event_Border_Move *e;
11393 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11394 e_object_unref(E_OBJECT(e->border));
11399 _e_border_event_border_add_free(void *data __UNUSED__,
11402 E_Event_Border_Add *e;
11405 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11406 e_object_unref(E_OBJECT(e->border));
11411 _e_border_event_border_remove_free(void *data __UNUSED__,
11414 E_Event_Border_Remove *e;
11417 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11418 e_object_unref(E_OBJECT(e->border));
11423 _e_border_event_border_show_free(void *data __UNUSED__,
11426 E_Event_Border_Show *e;
11429 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11430 e_object_unref(E_OBJECT(e->border));
11435 _e_border_event_border_hide_free(void *data __UNUSED__,
11438 E_Event_Border_Hide *e;
11441 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11442 e_object_unref(E_OBJECT(e->border));
11447 _e_border_event_border_iconify_free(void *data __UNUSED__,
11450 E_Event_Border_Iconify *e;
11453 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11454 e_object_unref(E_OBJECT(e->border));
11459 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11462 E_Event_Border_Uniconify *e;
11465 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11466 e_object_unref(E_OBJECT(e->border));
11471 _e_border_event_border_stick_free(void *data __UNUSED__,
11474 E_Event_Border_Stick *e;
11477 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11478 e_object_unref(E_OBJECT(e->border));
11483 _e_border_event_border_unstick_free(void *data __UNUSED__,
11486 E_Event_Border_Unstick *e;
11489 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11490 e_object_unref(E_OBJECT(e->border));
11495 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11498 E_Event_Border_Zone_Set *e;
11501 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11502 e_object_unref(E_OBJECT(e->border));
11503 e_object_unref(E_OBJECT(e->zone));
11508 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11511 E_Event_Border_Desk_Set *e;
11514 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11515 e_object_unref(E_OBJECT(e->border));
11516 e_object_unref(E_OBJECT(e->desk));
11521 _e_border_event_border_stack_free(void *data __UNUSED__,
11524 E_Event_Border_Stack *e;
11527 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11528 e_object_unref(E_OBJECT(e->border));
11531 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11532 e_object_unref(E_OBJECT(e->stack));
11538 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11541 E_Event_Border_Icon_Change *e;
11544 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11545 e_object_unref(E_OBJECT(e->border));
11550 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11553 E_Event_Border_Urgent_Change *e;
11556 e_object_unref(E_OBJECT(e->border));
11561 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11564 E_Event_Border_Focus_In *e;
11567 e_object_unref(E_OBJECT(e->border));
11572 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11575 E_Event_Border_Focus_Out *e;
11578 e_object_unref(E_OBJECT(e->border));
11583 _e_border_event_border_property_free(void *data __UNUSED__,
11586 E_Event_Border_Property *e;
11589 e_object_unref(E_OBJECT(e->border));
11594 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11597 E_Event_Border_Fullscreen *e;
11600 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11601 e_object_unref(E_OBJECT(e->border));
11606 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
11609 E_Event_Border_Unfullscreen *e;
11612 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
11613 e_object_unref(E_OBJECT(e->border));
11617 #ifdef _F_ZONE_WINDOW_ROTATION_
11619 _e_border_event_border_rotation_free(void *data __UNUSED__,
11622 E_Event_Border_Rotation *e;
11625 e_object_unref(E_OBJECT(e->border));
11631 _e_border_zone_update(E_Border *bd)
11637 /* still within old zone - leave it there */
11638 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11639 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
11640 #if _F_BORDER_CLIP_TO_ZONE_
11642 _e_border_shape_input_clip_to_zone(bd);
11647 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11648 /* find a new zone */
11649 con = bd->zone->container;
11650 EINA_LIST_FOREACH(con->zones, l, zone)
11652 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11653 zone->x, zone->y, zone->w, zone->h))
11655 e_border_zone_set(bd, zone);
11656 #if _F_BORDER_CLIP_TO_ZONE_
11657 _e_border_shape_input_clip_to_zone(bd);
11658 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11665 _e_border_resize_begin(E_Border *bd)
11667 if (!bd->lock_user_stacking)
11669 if (e_config->border_raise_on_mouse_action)
11670 e_border_raise(bd);
11672 if ((bd->shaded) || (bd->shading) ||
11673 (bd->fullscreen) || (bd->lock_user_size))
11676 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11682 if (bd->client.netwm.sync.request)
11684 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11685 bd->client.netwm.sync.serial = 1;
11686 bd->client.netwm.sync.wait = 0;
11687 bd->client.netwm.sync.send_time = ecore_loop_time_get();
11690 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
11697 _e_border_resize_end(E_Border *bd)
11701 e_grabinput_release(bd->win, bd->win);
11704 if (bd->client.netwm.sync.alarm)
11706 E_Border_Pending_Move_Resize *pnd;
11708 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11709 bd->client.netwm.sync.alarm = 0;
11710 /* resize to last geometry if sync alarm for it was not yet handled */
11711 if (bd->pending_move_resize)
11714 bd->changes.pos = 1;
11715 bd->changes.size = 1;
11716 _e_border_client_move_resize_send(bd);
11719 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11723 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
11727 /* If this border was maximized, we need to unset Maximized state or
11728 * on restart, E still thinks it's maximized */
11729 if (bd->maximized != E_MAXIMIZE_NONE)
11730 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
11731 bd->maximized & E_MAXIMIZE_NONE);
11736 _e_border_resize_update(E_Border *bd)
11738 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
11742 _e_border_move_begin(E_Border *bd)
11744 if (!bd->lock_user_stacking)
11746 if (e_config->border_raise_on_mouse_action)
11747 e_border_raise(bd);
11749 if ((bd->fullscreen) || (bd->lock_user_location))
11752 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11758 if (bd->client.netwm.sync.request)
11760 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11761 bd->client.netwm.sync.serial = 0;
11762 bd->client.netwm.sync.wait = 0;
11763 bd->client.netwm.sync.time = ecore_loop_time_get();
11766 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
11773 _e_border_move_end(E_Border *bd)
11777 e_grabinput_release(bd->win, bd->win);
11781 if (bd->client.netwm.sync.alarm)
11783 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11784 bd->client.netwm.sync.alarm = 0;
11787 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
11794 _e_border_move_update(E_Border *bd)
11796 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
11800 _e_border_cb_ping_poller(void *data)
11810 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
11811 if (bd->kill_timer)
11813 ecore_timer_del(bd->kill_timer);
11814 bd->kill_timer = NULL;
11820 /* if time between last ping and now is greater
11821 * than half the ping interval... */
11822 if ((ecore_loop_time_get() - bd->ping) >
11823 ((e_config->ping_clients_interval *
11824 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
11829 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
11830 /* FIXME: if below dialog is up - hide it now */
11832 if (bd->delete_requested)
11834 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
11835 e_border_act_kill_begin(bd);
11839 bd->ping_poller = NULL;
11841 return ECORE_CALLBACK_CANCEL;
11845 _e_border_cb_kill_timer(void *data)
11850 // dont wait until it's hung -
11853 if (bd->client.netwm.pid > 1)
11854 kill(bd->client.netwm.pid, SIGKILL);
11856 bd->kill_timer = NULL;
11857 return ECORE_CALLBACK_CANCEL;
11861 _e_border_pointer_resize_begin(E_Border *bd)
11863 switch (bd->resize_mode)
11866 e_pointer_type_push(bd->pointer, bd, "resize_tl");
11870 e_pointer_type_push(bd->pointer, bd, "resize_t");
11874 e_pointer_type_push(bd->pointer, bd, "resize_tr");
11878 e_pointer_type_push(bd->pointer, bd, "resize_r");
11882 e_pointer_type_push(bd->pointer, bd, "resize_br");
11886 e_pointer_type_push(bd->pointer, bd, "resize_b");
11890 e_pointer_type_push(bd->pointer, bd, "resize_bl");
11894 e_pointer_type_push(bd->pointer, bd, "resize_l");
11900 _e_border_pointer_resize_end(E_Border *bd)
11902 switch (bd->resize_mode)
11905 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
11909 e_pointer_type_pop(bd->pointer, bd, "resize_t");
11913 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
11917 e_pointer_type_pop(bd->pointer, bd, "resize_r");
11921 e_pointer_type_pop(bd->pointer, bd, "resize_br");
11925 e_pointer_type_pop(bd->pointer, bd, "resize_b");
11929 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
11933 e_pointer_type_pop(bd->pointer, bd, "resize_l");
11939 _e_border_pointer_move_begin(E_Border *bd)
11941 e_pointer_type_push(bd->pointer, bd, "move");
11945 _e_border_pointer_move_end(E_Border *bd)
11947 e_pointer_type_pop(bd->pointer, bd, "move");
11950 static Eina_List *_e_border_hooks = NULL;
11951 static int _e_border_hooks_delete = 0;
11952 static int _e_border_hooks_walking = 0;
11955 _e_border_hooks_clean(void)
11960 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
11964 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
11971 _e_border_hook_call(E_Border_Hook_Point hookpoint,
11977 _e_border_hooks_walking++;
11978 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
11980 if (bh->delete_me) continue;
11981 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
11983 _e_border_hooks_walking--;
11984 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
11985 _e_border_hooks_clean();
11988 EAPI E_Border_Hook *
11989 e_border_hook_add(E_Border_Hook_Point hookpoint,
11990 void (*func)(void *data,
11996 bh = E_NEW(E_Border_Hook, 1);
11997 if (!bh) return NULL;
11998 bh->hookpoint = hookpoint;
12001 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12006 e_border_hook_del(E_Border_Hook *bh)
12009 if (_e_border_hooks_walking == 0)
12011 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12015 _e_border_hooks_delete++;
12019 e_border_focus_track_freeze(void)
12021 focus_track_frozen++;
12025 e_border_focus_track_thaw(void)
12027 focus_track_frozen--;
12031 e_border_under_pointer_get(E_Desk *desk,
12034 E_Border *bd = NULL, *cbd;
12038 /* We need to ensure that we can get the container window for the
12039 * zone of either the given desk or the desk of the excluded
12040 * window, so return if neither is given */
12042 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12044 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12048 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12050 if (!cbd) continue;
12051 /* If a border was specified which should be excluded from the list
12052 * (because it will be closed shortly for example), skip */
12053 if ((exclude) && (cbd == exclude)) continue;
12054 if ((desk) && (cbd->desk != desk)) continue;
12055 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12057 /* If the layer is higher, the position of the window is higher
12058 * (always on top vs always below) */
12059 if (!bd || (cbd->layer > bd->layer))
12069 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12076 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12077 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12078 (y - warp_y) > 5 || (y - warp_y) < -5)
12080 /* User moved the mouse, so stop warping */
12085 /* We just use the same warp speed as configured
12086 * for the windowlist */
12087 spd = e_config->winlist_warp_speed;
12090 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12091 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12092 if (warp_x == x && warp_y == y)
12094 warp_x = warp_to_x;
12095 warp_y = warp_to_y;
12099 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12100 return ECORE_CALLBACK_RENEW;
12103 ecore_timer_del(warp_timer);
12105 return ECORE_CALLBACK_CANCEL;
12109 e_border_pointer_warp_to_center(E_Border *bd)
12113 /* Do not slide pointer when disabled (probably breaks focus
12114 * on sloppy/mouse focus but requested by users). */
12115 if (!e_config->pointer_slide) return 0;
12116 /* Only warp the pointer if it is not already in the area of
12117 * the given border */
12118 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12119 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12120 (y >= bd->y) && (y <= (bd->y + bd->h)))
12123 warp_to_x = bd->x + (bd->w / 2);
12124 if (warp_to_x < (bd->zone->x + 1))
12125 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12126 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12127 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12129 warp_to_y = bd->y + (bd->h / 2);
12130 if (warp_to_y < (bd->zone->y + 1))
12131 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12132 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12133 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12136 warp_to_win = bd->zone->container->win;
12137 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12139 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12144 e_border_comp_hidden_set(E_Border *bd,
12150 E_OBJECT_CHECK(bd);
12151 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12153 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12156 ecore_x_window_hide(tmp->win);
12158 ecore_x_window_show(tmp->win);
12161 if (bd->comp_hidden == hidden) return;
12163 bd->comp_hidden = hidden;
12165 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12167 ecore_x_composite_window_events_disable(bd->win);
12168 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12172 _e_border_shape_input_rectangle_set(bd);
12173 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12178 e_border_tmp_input_hidden_push(E_Border *bd)
12183 E_OBJECT_CHECK(bd);
12184 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12186 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12187 e_border_tmp_input_hidden_push(tmp);
12189 bd->tmp_input_hidden++;
12190 if (bd->tmp_input_hidden != 1) return;
12192 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12194 ecore_x_composite_window_events_disable(bd->win);
12195 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12199 _e_border_shape_input_rectangle_set(bd);
12200 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12205 e_border_tmp_input_hidden_pop(E_Border *bd)
12210 E_OBJECT_CHECK(bd);
12211 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12213 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12214 e_border_tmp_input_hidden_pop(tmp);
12216 bd->tmp_input_hidden--;
12217 if (bd->tmp_input_hidden != 0) return;
12219 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12221 ecore_x_composite_window_events_disable(bd->win);
12222 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12226 _e_border_shape_input_rectangle_set(bd);
12227 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12232 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12234 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12236 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12237 ((bd->parent->focused) &&
12238 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12243 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12244 e_desk_show(bd->desk);
12246 if (!bd->lock_user_iconify)
12247 e_border_uniconify(bd);
12249 if ((!bd->iconic) && (!bd->sticky))
12250 e_desk_show(bd->desk);
12251 if (!bd->lock_user_stacking) e_border_raise(bd);
12252 if (!bd->lock_focus_out)
12254 /* XXX ooffice does send this request for
12255 config dialogs when the main window gets focus.
12256 causing the pointer to jump back and forth. */
12257 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12258 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12259 ecore_x_pointer_warp(bd->zone->container->win,
12260 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12261 e_border_focus_set(bd, 1, 1);
12265 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/