2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the COPYING file for the original copyright owner and
22 //#define INOUTDEBUG_MOUSE 1
23 //#define INOUTDEBUG_FOCUS 1
25 /* These are compatible with netwm */
35 #define RESIZE_NONE 11
37 /* local subsystem functions */
38 static void _e_border_pri_raise(E_Border *bd);
39 static void _e_border_pri_norm(E_Border *bd);
40 static void _e_border_free(E_Border *bd);
41 static void _e_border_del(E_Border *bd);
43 #ifdef PRINT_LOTS_OF_DEBUG
44 #define E_PRINT_BORDER_INFO(X) \
45 _e_border_print(X, __PRETTY_FUNC__)
47 static void _e_border_print(E_Border *bd,
51 /* FIXME: these likely belong in a separate icccm/client handler */
52 /* and the border needs to become a dumb object that just does what its */
54 static Eina_Bool _e_border_cb_window_show_request(void *data,
57 static Eina_Bool _e_border_cb_window_destroy(void *data,
60 static Eina_Bool _e_border_cb_window_hide(void *data,
63 static Eina_Bool _e_border_cb_window_reparent(void *data,
66 static Eina_Bool _e_border_cb_window_configure_request(void *data,
69 static Eina_Bool _e_border_cb_window_resize_request(void *data,
72 static Eina_Bool _e_border_cb_window_gravity(void *data,
75 static Eina_Bool _e_border_cb_window_stack_request(void *data,
78 static Eina_Bool _e_border_cb_window_property(void *data,
81 static Eina_Bool _e_border_cb_window_colormap(void *data,
84 static Eina_Bool _e_border_cb_window_shape(void *data,
87 static Eina_Bool _e_border_cb_window_focus_in(void *data,
90 static Eina_Bool _e_border_cb_window_focus_out(void *data,
93 static Eina_Bool _e_border_cb_client_message(void *data,
97 static Eina_Bool _e_border_cb_window_state_request(void *data,
100 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
103 static Eina_Bool _e_border_cb_desktop_change(void *data,
106 static Eina_Bool _e_border_cb_sync_alarm(void *data,
109 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
112 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
116 static Eina_Bool _e_border_cb_pointer_warp(void *data,
119 static void _e_border_cb_signal_bind(void *data,
121 const char *emission,
123 static Eina_Bool _e_border_cb_mouse_in(void *data,
126 static Eina_Bool _e_border_cb_mouse_out(void *data,
129 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
132 static Eina_Bool _e_border_cb_mouse_down(void *data,
135 static Eina_Bool _e_border_cb_mouse_up(void *data,
138 static Eina_Bool _e_border_cb_mouse_move(void *data,
141 static Eina_Bool _e_border_cb_grab_replay(void *data,
144 static void _e_border_cb_drag_finished(E_Drag *drag,
146 #ifdef _F_USE_DESK_WINDOW_PROFILE_
147 static Eina_Bool _e_border_cb_desk_window_profile_change(void *data,
151 #ifdef _F_ZONE_WINDOW_ROTATION_
152 static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data,
155 static void _e_border_cb_rotation_sync_job(void *data);
156 static void _e_border_cb_rotation_async_job(void *data);
157 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
158 static void _e_border_rotation_change_request(E_Zone *zone);
159 static void _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush);
160 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
161 static void _e_border_rotation_change_done(void);
162 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
170 static void _e_border_rotation_list_remove(E_Border *bd);
171 static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h);
172 static int _e_border_rotation_angle_get(E_Border *bd);
173 static Eina_Bool _e_border_rotation_zone_set(E_Zone *zone);
174 static Eina_Bool _e_border_rotatable_check(E_Border *bd, int ang);
175 static Eina_Bool _e_border_is_vkbd(E_Border *bd);
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_change_begin_free(void *data,
245 static void _e_border_event_border_rotation_change_cancel_free(void *data,
247 static void _e_border_event_border_rotation_change_end_free(void *data,
249 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
252 static void _e_border_zone_update(E_Border *bd);
254 static int _e_border_resize_begin(E_Border *bd);
255 static int _e_border_resize_end(E_Border *bd);
256 static void _e_border_resize_update(E_Border *bd);
258 static int _e_border_move_begin(E_Border *bd);
259 static int _e_border_move_end(E_Border *bd);
260 static void _e_border_move_update(E_Border *bd);
262 static Eina_Bool _e_border_cb_ping_poller(void *data);
263 static Eina_Bool _e_border_cb_kill_timer(void *data);
265 static void _e_border_pointer_resize_begin(E_Border *bd);
266 static void _e_border_pointer_resize_end(E_Border *bd);
267 static void _e_border_pointer_move_begin(E_Border *bd);
268 static void _e_border_pointer_move_end(E_Border *bd);
270 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
273 static void _e_border_client_move_resize_send(E_Border *bd);
275 static void _e_border_frame_replace(E_Border *bd,
278 static void _e_border_shape_input_rectangle_set(E_Border* bd);
279 static void _e_border_show(E_Border *bd);
280 static void _e_border_hide(E_Border *bd);
283 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
284 static void _e_border_latest_stacked_focus (E_Border* bd);
285 static void _e_border_check_stack (E_Border *bd);
286 static void _e_border_focus_top_stack_set (E_Border* bd);
288 #if _F_BORDER_CLIP_TO_ZONE_
289 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
290 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
291 /* local subsystem globals */
292 static Eina_List *handlers = NULL;
293 static Eina_List *borders = NULL;
294 static Eina_Hash *borders_hash = NULL;
295 static E_Border *focused = NULL;
296 static E_Border *focusing = NULL;
297 static Eina_List *focus_next = NULL;
298 static Ecore_X_Time focus_time = 0;
300 static E_Border *bdresize = NULL;
301 static E_Border *bdmove = NULL;
302 static E_Drag *drag_border = NULL;
304 static int grabbed = 0;
306 static Eina_List *focus_stack = NULL;
307 static Eina_List *raise_stack = NULL;
309 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
310 static int screen_size_index = -1;
312 static int focus_track_frozen = 0;
314 static int warp_to = 0;
315 static int warp_to_x = 0;
316 static int warp_to_y = 0;
317 static int warp_x = 0;
318 static int warp_y = 0;
319 static Ecore_X_Window warp_to_win;
320 static Ecore_Timer *warp_timer = NULL;
322 #ifdef _F_ZONE_WINDOW_ROTATION_
323 typedef struct _E_Border_Rotation E_Border_Rotation;
324 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
326 struct _E_Border_Rotation
329 Eina_List *async_list;
331 Eina_Bool wait_prepare_done;
332 Ecore_Timer *prepare_timer;
333 Ecore_Timer *done_timer;
335 Ecore_Job *async_job;
337 Ecore_X_Window vkbd_ctrl_win;
339 E_Border *vkbd_prediction;
341 /* vkbd show/hide preprare */
342 Eina_Bool vkbd_show_prepare_done;
343 Ecore_Timer *vkbd_show_prepare_timer;
344 Ecore_Timer *vkbd_show_timer;
346 Eina_Bool vkbd_hide_prepare_done;
347 Ecore_Timer *vkbd_hide_prepare_timer;
348 Ecore_Timer *vkbd_hide_timer;
354 struct _E_Border_Rotation_Info
359 Eina_Bool win_resize;
362 static E_Border_Rotation rot =
385 EAPI int E_EVENT_BORDER_ADD = 0;
386 EAPI int E_EVENT_BORDER_REMOVE = 0;
387 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
388 EAPI int E_EVENT_BORDER_DESK_SET = 0;
389 EAPI int E_EVENT_BORDER_RESIZE = 0;
390 EAPI int E_EVENT_BORDER_MOVE = 0;
391 EAPI int E_EVENT_BORDER_SHOW = 0;
392 EAPI int E_EVENT_BORDER_HIDE = 0;
393 EAPI int E_EVENT_BORDER_ICONIFY = 0;
394 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
395 EAPI int E_EVENT_BORDER_STICK = 0;
396 EAPI int E_EVENT_BORDER_UNSTICK = 0;
397 EAPI int E_EVENT_BORDER_STACK = 0;
398 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
399 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
400 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
401 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
402 EAPI int E_EVENT_BORDER_PROPERTY = 0;
403 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
404 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
405 #ifdef _F_ZONE_WINDOW_ROTATION_
406 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
407 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
408 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
409 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
412 #define GRAV_SET(bd, grav) \
413 ecore_x_window_gravity_set(bd->bg_win, grav); \
414 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
415 ecore_x_window_gravity_set(bd->client.win, grav);
418 _e_border_sub_borders_new(E_Border *bd)
420 Eina_List *list = NULL, *l;
424 EINA_LIST_FOREACH(bd->transients, l, child)
426 if (!eina_list_data_find(list, child))
427 list = eina_list_append(list, child);
429 bl = e_container_border_list_first(bd->zone->container);
430 while ((child = e_container_border_list_next(bl)))
432 if (e_object_is_del(E_OBJECT(child))) continue;
433 if (child == bd) continue;
435 if ((bd->client.icccm.client_leader) &&
436 (child->client.icccm.client_leader ==
437 bd->client.icccm.client_leader))
439 printf("bd %s in group with %s\n",
440 e_border_name_get(child),
441 e_border_name_get(bd));
442 if (!eina_list_data_find(list, child))
443 list = eina_list_append(list, child);
447 e_container_border_list_free(bl);
451 /* externally accessible functions */
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
473 #ifdef _F_ZONE_WINDOW_ROTATION_
474 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
477 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
479 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
480 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
483 #ifdef _F_USE_DESK_WINDOW_PROFILE_
484 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
486 #ifdef _F_ZONE_WINDOW_ROTATION_
487 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
490 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
492 E_EVENT_BORDER_ADD = ecore_event_type_new();
493 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
494 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
495 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
496 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
497 E_EVENT_BORDER_MOVE = ecore_event_type_new();
498 E_EVENT_BORDER_SHOW = ecore_event_type_new();
499 E_EVENT_BORDER_HIDE = ecore_event_type_new();
500 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
501 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
502 E_EVENT_BORDER_STICK = ecore_event_type_new();
503 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
504 E_EVENT_BORDER_STACK = ecore_event_type_new();
505 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
506 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
507 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
508 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
509 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
510 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
511 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
512 #ifdef _F_ZONE_WINDOW_ROTATION_
513 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
514 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
515 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
516 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
525 e_border_shutdown(void)
527 E_FREE_LIST(handlers, ecore_event_handler_del);
529 if (borders_hash) eina_hash_free(borders_hash);
531 e_int_border_menu_hooks_clear();
537 e_border_new(E_Container *con,
543 Ecore_X_Window_Attributes *att;
544 unsigned int managed, desk[2];
547 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
548 if (!bd) return NULL;
549 ecore_x_window_shadow_tree_flush();
550 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
554 /* FIXME: ewww - round trip */
555 bd->client.argb = ecore_x_window_argb_get(win);
557 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
560 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
561 ecore_x_window_shape_events_select(bd->win, 1);
563 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
564 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
566 bd->bg_ecore_evas = e_canvas_new(bd->win,
567 0, 0, bd->w, bd->h, 1, 0,
569 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
570 e_canvas_add(bd->bg_ecore_evas);
571 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
572 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
573 ecore_x_window_shape_events_select(bd->bg_win, 1);
574 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
575 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
577 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
579 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
580 ecore_x_window_container_manage(bd->client.shell_win);
581 if (!internal) ecore_x_window_client_manage(win);
582 /* FIXME: Round trip. XCB */
583 /* fetch needed to avoid grabbing the server as window may vanish */
584 att = &bd->client.initial_attributes;
585 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
587 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
588 e_canvas_del(bd->bg_ecore_evas);
589 ecore_evas_free(bd->bg_ecore_evas);
590 ecore_x_window_free(bd->client.shell_win);
591 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
592 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
593 ecore_x_window_free(bd->win);
598 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
599 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
601 /* FIXME: if first_map is 1 then we should ignore the first hide event
602 * or ensure the window is already hidden and events flushed before we
603 * create a border for it */
606 // printf("##- FIRST MAP\n");
611 // needed to be 1 for internal windw and on restart.
612 // bd->ignore_first_unmap = 2;
615 bd->client.win = win;
616 bd->zone = e_zone_current_get(con);
618 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
620 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
621 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
622 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
623 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
624 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
625 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
627 bd->client.icccm.title = NULL;
628 bd->client.icccm.name = NULL;
629 bd->client.icccm.class = NULL;
630 bd->client.icccm.icon_name = NULL;
631 bd->client.icccm.machine = NULL;
632 bd->client.icccm.min_w = 1;
633 bd->client.icccm.min_h = 1;
634 bd->client.icccm.max_w = 32767;
635 bd->client.icccm.max_h = 32767;
636 bd->client.icccm.base_w = 0;
637 bd->client.icccm.base_h = 0;
638 bd->client.icccm.step_w = -1;
639 bd->client.icccm.step_h = -1;
640 bd->client.icccm.min_aspect = 0.0;
641 bd->client.icccm.max_aspect = 0.0;
642 bd->client.icccm.accepts_focus = 1;
644 bd->client.netwm.pid = 0;
645 bd->client.netwm.name = NULL;
646 bd->client.netwm.icon_name = NULL;
647 bd->client.netwm.desktop = 0;
648 bd->client.netwm.state.modal = 0;
649 bd->client.netwm.state.sticky = 0;
650 bd->client.netwm.state.shaded = 0;
651 bd->client.netwm.state.hidden = 0;
652 bd->client.netwm.state.maximized_v = 0;
653 bd->client.netwm.state.maximized_h = 0;
654 bd->client.netwm.state.skip_taskbar = 0;
655 bd->client.netwm.state.skip_pager = 0;
656 bd->client.netwm.state.fullscreen = 0;
657 bd->client.netwm.state.stacking = E_STACKING_NONE;
658 bd->client.netwm.action.move = 0;
659 bd->client.netwm.action.resize = 0;
660 bd->client.netwm.action.minimize = 0;
661 bd->client.netwm.action.shade = 0;
662 bd->client.netwm.action.stick = 0;
663 bd->client.netwm.action.maximized_h = 0;
664 bd->client.netwm.action.maximized_v = 0;
665 bd->client.netwm.action.fullscreen = 0;
666 bd->client.netwm.action.change_desktop = 0;
667 bd->client.netwm.action.close = 0;
668 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
674 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
675 bd->client.icccm.fetch.command = 1;
678 Eina_Bool video_parent = EINA_FALSE;
679 Eina_Bool video_position = EINA_FALSE;
682 for (i = 0; i < at_num; i++)
684 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
685 bd->client.icccm.fetch.title = 1;
686 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
687 bd->client.icccm.fetch.name_class = 1;
688 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
689 bd->client.icccm.fetch.icon_name = 1;
690 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
691 bd->client.icccm.fetch.machine = 1;
692 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
693 bd->client.icccm.fetch.hints = 1;
694 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
695 bd->client.icccm.fetch.size_pos_hints = 1;
696 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
697 bd->client.icccm.fetch.protocol = 1;
698 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
699 bd->client.mwm.fetch.hints = 1;
700 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
702 bd->client.icccm.fetch.transient_for = 1;
703 bd->client.netwm.fetch.type = 1;
705 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
706 bd->client.icccm.fetch.client_leader = 1;
707 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
708 bd->client.icccm.fetch.window_role = 1;
709 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
710 bd->client.icccm.fetch.state = 1;
712 /* netwm, loop again, netwm will ignore some icccm, so we
713 * have to be sure that netwm is checked after */
714 for (i = 0; i < at_num; i++)
716 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
719 bd->client.icccm.fetch.title = 0;
720 bd->client.netwm.fetch.name = 1;
722 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
725 bd->client.icccm.fetch.icon_name = 0;
726 bd->client.netwm.fetch.icon_name = 1;
728 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
730 bd->client.netwm.fetch.icon = 1;
732 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
734 bd->client.netwm.fetch.user_time = 1;
736 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
738 DBG("ECORE_X_ATOM_NET_WM_STRUT");
739 bd->client.netwm.fetch.strut = 1;
741 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
743 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
744 bd->client.netwm.fetch.strut = 1;
746 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
749 bd->client.mwm.fetch.hints = 0;
751 bd->client.netwm.fetch.type = 1;
753 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
755 bd->client.netwm.fetch.state = 1;
758 /* other misc atoms */
759 for (i = 0; i < at_num; i++)
761 /* loop to check for own atoms */
762 if (atoms[i] == E_ATOM_WINDOW_STATE)
764 bd->client.e.fetch.state = 1;
766 /* loop to check for qtopia atoms */
767 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
768 bd->client.qtopia.fetch.soft_menu = 1;
769 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
770 bd->client.qtopia.fetch.soft_menus = 1;
771 /* loop to check for vkbd atoms */
772 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
773 bd->client.vkbd.fetch.state = 1;
774 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
775 bd->client.vkbd.fetch.vkbd = 1;
776 /* loop to check for illume atoms */
777 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
778 bd->client.illume.conformant.fetch.conformant = 1;
779 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
780 bd->client.illume.quickpanel.fetch.state = 1;
781 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
782 bd->client.illume.quickpanel.fetch.quickpanel = 1;
783 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
784 bd->client.illume.quickpanel.fetch.priority.major = 1;
785 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
786 bd->client.illume.quickpanel.fetch.priority.minor = 1;
787 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
788 bd->client.illume.quickpanel.fetch.zone = 1;
789 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
790 bd->client.illume.drag.fetch.locked = 1;
791 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
792 bd->client.illume.drag.fetch.drag = 1;
793 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
794 bd->client.illume.win_state.fetch.state = 1;
795 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
796 video_parent = EINA_TRUE;
797 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
798 video_position = EINA_TRUE;
799 #ifdef _F_USE_DESK_WINDOW_PROFILE_
800 /* loop to check for window profile list atom */
801 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
802 bd->client.e.fetch.profile_list = 1;
804 #ifdef _F_ZONE_WINDOW_ROTATION_
805 /* loop to check for wm rotation */
806 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
808 if (e_config->wm_win_rotation)
809 bd->client.e.fetch.rot.support = 1;
811 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
812 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
813 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
814 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
816 if (e_config->wm_win_rotation)
817 bd->client.e.fetch.rot.geom_hint = 1;
819 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
821 if (e_config->wm_win_rotation)
822 bd->client.e.fetch.rot.app_set = 1;
824 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
826 if (e_config->wm_win_rotation)
827 bd->client.e.fetch.rot.preferred_rot = 1;
829 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
831 if (e_config->wm_win_rotation)
832 bd->client.e.fetch.rot.available_rots = 1;
835 #ifdef _F_DEICONIFY_APPROVE_
836 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
838 bd->client.e.state.deiconify_approve.support = 1;
842 if (video_position && video_parent)
844 bd->client.e.state.video = 1;
845 bd->client.e.fetch.video_parent = 1;
846 bd->client.e.fetch.video_position = 1;
847 ecore_x_window_lower(bd->win);
848 ecore_x_composite_window_events_disable(bd->win);
849 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
850 fprintf(stderr, "We found a video window \\o/ %x\n", win);
855 bd->client.border.changed = 1;
857 bd->client.w = att->w;
858 bd->client.h = att->h;
860 bd->w = bd->client.w;
861 bd->h = bd->client.h;
863 bd->resize_mode = RESIZE_NONE;
865 bd->saved.layer = bd->layer;
866 bd->changes.icon = 1;
867 bd->changes.size = 1;
868 bd->changes.shape = 1;
869 bd->changes.shape_input = 1;
871 bd->offer_resistance = 1;
873 /* just to friggin make java happy - we're DELAYING the reparent until
876 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
877 bd->need_reparent = 1;
879 ecore_x_window_border_width_set(win, 0);
880 ecore_x_window_show(bd->event_win);
881 ecore_x_window_show(bd->client.shell_win);
882 bd->shape = e_container_shape_add(con);
887 #ifdef _F_ZONE_WINDOW_ROTATION_
888 bd->client.e.state.rot.preferred_rot = -1;
889 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
890 bd->client.e.state.rot.changes = -1;
891 bd->client.e.state.rot.pending_show = 0;
892 bd->client.e.state.rot.curr = 0;
893 bd->client.e.state.rot.prev = 0;
896 // bd->zone = e_zone_current_get(con);
897 bd->desk = e_desk_current_get(bd->zone);
898 e_container_border_add(bd);
899 borders = eina_list_append(borders, bd);
900 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
904 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
905 "optimisations failing due to bizarre client behavior. will\n"
907 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
908 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
911 ELBF(ELBT_BD, 0, bd->client.win,
912 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
913 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
915 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
916 printf("optimisations failing due to bizarre client behavior. will\n");
917 printf("work around.\n");
918 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
919 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
922 ELBF(ELBT_BD, 0, bd->client.win,
923 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
924 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
927 #ifdef _F_ZONE_WINDOW_ROTATION_
928 if ((rot.vkbd) && (rot.vkbd == bd2))
930 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
931 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
932 rot.vkbd_hide_prepare_done);
934 if (rot.vkbd_hide_prepare_timer)
936 ecore_timer_del(rot.vkbd_hide_prepare_timer);
937 rot.vkbd_hide_prepare_timer = NULL;
939 e_object_unref(E_OBJECT(bd2));
942 _e_border_vkbd_hide(rot.vkbd);
944 if (rot.vkbd_ctrl_win)
946 ELB(ELBT_BD, "SET KBD_OFF", 0);
947 ecore_x_e_virtual_keyboard_state_set
948 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
950 rot.vkbd_hide_prepare_done = EINA_FALSE;
952 if (rot.vkbd_hide_timer)
953 ecore_timer_del(rot.vkbd_hide_timer);
954 rot.vkbd_hide_timer = NULL;
956 rot.vkbd_show_prepare_done = EINA_FALSE;
957 if (rot.vkbd_show_prepare_timer)
958 ecore_timer_del(rot.vkbd_show_prepare_timer);
959 rot.vkbd_show_prepare_timer = NULL;
960 if (rot.vkbd_show_timer)
961 ecore_timer_del(rot.vkbd_show_timer);
962 rot.vkbd_show_timer = NULL;
967 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
968 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
969 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
971 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
972 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
973 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
975 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
976 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
977 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
979 unsigned int zgeom[4];
981 zgeom[0] = bd->zone->x;
982 zgeom[1] = bd->zone->y;
983 zgeom[2] = bd->zone->w;
984 zgeom[3] = bd->zone->h;
985 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
987 e_desk_xy_get(bd->desk, &deskx, &desky);
990 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
991 #ifdef _F_USE_DESK_WINDOW_PROFILE_
992 if (strcmp(bd->desk->window_profile,
993 e_config->desktop_default_window_profile) != 0)
995 ecore_x_e_window_profile_set(bd->client.win,
996 bd->desk->window_profile);
1000 focus_stack = eina_list_append(focus_stack, bd);
1002 bd->pointer = e_pointer_window_new(bd->win, 0);
1007 e_border_res_change_geometry_save(E_Border *bd)
1010 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1012 if (bd->pre_res_change.valid) return;
1013 bd->pre_res_change.valid = 1;
1014 bd->pre_res_change.x = bd->x;
1015 bd->pre_res_change.y = bd->y;
1016 bd->pre_res_change.w = bd->w;
1017 bd->pre_res_change.h = bd->h;
1018 bd->pre_res_change.saved.x = bd->saved.x;
1019 bd->pre_res_change.saved.y = bd->saved.y;
1020 bd->pre_res_change.saved.w = bd->saved.w;
1021 bd->pre_res_change.saved.h = bd->saved.h;
1025 e_border_res_change_geometry_restore(E_Border *bd)
1029 unsigned char valid : 1;
1038 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1039 if (!bd->pre_res_change.valid) return;
1040 if (bd->new_client) return;
1042 ecore_x_window_shadow_tree_flush();
1043 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1047 e_border_unfullscreen(bd);
1048 e_border_fullscreen(bd, e_config->fullscreen_policy);
1050 else if (bd->maximized != E_MAXIMIZE_NONE)
1054 max = bd->maximized;
1055 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1056 e_border_maximize(bd, max);
1060 int x, y, w, h, zx, zy, zw, zh;
1062 bd->saved.x = bd->pre_res_change.saved.x;
1063 bd->saved.y = bd->pre_res_change.saved.y;
1064 bd->saved.w = bd->pre_res_change.saved.w;
1065 bd->saved.h = bd->pre_res_change.saved.h;
1067 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1069 if (bd->saved.w > zw)
1071 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1072 bd->saved.x = zx + zw - bd->saved.w;
1074 if (bd->saved.h > zh)
1076 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1077 bd->saved.y = zy + zh - bd->saved.h;
1079 x = bd->pre_res_change.x;
1080 y = bd->pre_res_change.y;
1081 w = bd->pre_res_change.w;
1082 h = bd->pre_res_change.h;
1087 if ((x + w) > (zx + zw))
1089 if ((y + h) > (zy + zh))
1091 e_border_move_resize(bd, x, y, w, h);
1093 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1097 e_border_zone_set(E_Border *bd,
1100 E_Event_Border_Zone_Set *ev;
1103 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1104 E_OBJECT_CHECK(zone);
1105 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1107 if (bd->zone == zone) return;
1109 /* if the window does not lie in the new zone, move it so that it does */
1110 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1113 /* first guess -- get offset from old zone, and apply to new zone */
1114 x = zone->x + (bd->x - bd->zone->x);
1115 y = zone->y + (bd->y - bd->zone->y);
1117 /* keep window from hanging off bottom and left */
1118 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1119 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1121 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1122 if (x < zone->x) x = zone->x;
1123 if (y < zone->y) y = zone->y;
1125 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1127 /* still not in zone at all, so just move it to closest edge */
1128 if (x < zone->x) x = zone->x;
1129 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1130 if (y < zone->y) y = zone->y;
1131 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1133 e_border_move(bd, x, y);
1138 if (bd->desk->zone != bd->zone)
1139 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1141 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1143 e_object_ref(E_OBJECT(bd));
1144 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1146 e_object_ref(E_OBJECT(zone));
1148 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1150 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1151 // XXXXXXXXXXXXXXXXXXXXXXXXX
1152 // XXX ZZZZZZZZZZZZZZZZZZZzz
1153 // need to adjust this if zone pos/size changes
1155 unsigned int zgeom[4];
1157 zgeom[0] = bd->zone->x;
1158 zgeom[1] = bd->zone->y;
1159 zgeom[2] = bd->zone->w;
1160 zgeom[3] = bd->zone->h;
1161 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1163 e_remember_update(bd);
1167 e_border_desk_set(E_Border *bd,
1170 E_Event_Border_Desk_Set *ev;
1174 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1175 E_OBJECT_CHECK(desk);
1176 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1177 if (bd->desk == desk) return;
1178 ecore_x_window_shadow_tree_flush();
1181 bd->desk->fullscreen_borders--;
1182 desk->fullscreen_borders++;
1184 old_desk = bd->desk;
1186 e_border_zone_set(bd, desk->zone);
1188 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1189 e_hints_window_desktop_set(bd);
1191 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1193 e_object_ref(E_OBJECT(bd));
1194 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1195 ev->desk = old_desk;
1196 e_object_ref(E_OBJECT(old_desk));
1197 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1199 if (bd->ignore_first_unmap != 1)
1201 if ((bd->desk->visible) || (bd->sticky))
1204 e_border_hide(bd, 1);
1207 if (e_config->transient.desktop)
1211 Eina_List *list = _e_border_sub_borders_new(bd);
1213 EINA_LIST_FOREACH(list, l, child)
1215 e_border_desk_set(child, bd->desk);
1217 eina_list_free(list);
1219 e_remember_update(bd);
1222 #ifdef _F_ZONE_WINDOW_ROTATION_
1224 _e_border_vkbd_state_check(E_Border *bd,
1227 Eina_Bool res = EINA_TRUE;
1228 if (!e_config->wm_win_rotation) return EINA_FALSE;
1229 if ((rot.vkbd) && (rot.vkbd == bd))
1233 if ((rot.vkbd_hide_prepare_done) ||
1234 (rot.vkbd_hide_prepare_timer))
1239 if ((rot.vkbd_show_prepare_done) ||
1240 (rot.vkbd_show_prepare_timer))
1248 _e_border_vkbd_show_timeout(void *data)
1250 E_Border *bd = data;
1251 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1252 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1254 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1256 if (rot.vkbd_ctrl_win)
1258 ELB(ELBT_BD, "SET KBD_ON", 0);
1259 ecore_x_e_virtual_keyboard_state_set
1260 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1265 rot.vkbd_show_prepare_done = EINA_FALSE;
1267 if (rot.vkbd_show_prepare_timer)
1268 ecore_timer_del(rot.vkbd_show_prepare_timer);
1269 rot.vkbd_show_prepare_timer = NULL;
1271 if (rot.vkbd_show_timer)
1272 ecore_timer_del(rot.vkbd_show_timer);
1273 rot.vkbd_show_timer = NULL;
1275 return ECORE_CALLBACK_CANCEL;
1279 _e_border_vkbd_hide_timeout(void *data)
1281 E_Border *bd = data;
1282 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1283 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1285 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1287 if (rot.vkbd_ctrl_win)
1289 ELB(ELBT_BD, "SET KBD_OFF", 0);
1290 ecore_x_e_virtual_keyboard_state_set
1291 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1294 e_object_unref(E_OBJECT(bd));
1297 rot.vkbd_hide_prepare_done = EINA_FALSE;
1299 if (rot.vkbd_hide_prepare_timer)
1300 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1301 rot.vkbd_hide_prepare_timer = NULL;
1303 if (rot.vkbd_hide_timer)
1304 ecore_timer_del(rot.vkbd_hide_timer);
1305 rot.vkbd_hide_timer = NULL;
1307 return ECORE_CALLBACK_CANCEL;
1311 _e_border_vkbd_show(E_Border *bd)
1313 if (!e_config->wm_win_rotation) return;
1314 rot.vkbd_show_prepare_done = EINA_TRUE;
1315 if (rot.vkbd_show_prepare_timer)
1316 ecore_timer_del(rot.vkbd_show_prepare_timer);
1317 rot.vkbd_show_prepare_timer = NULL;
1318 if (rot.vkbd_show_timer)
1319 ecore_timer_del(rot.vkbd_show_timer);
1320 rot.vkbd_show_timer = NULL;
1321 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1324 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1329 _e_border_vkbd_hide(E_Border *bd)
1331 if (!e_config->wm_win_rotation) return;
1332 rot.vkbd_hide_prepare_done = EINA_TRUE;
1333 if (rot.vkbd_hide_prepare_timer)
1334 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1335 rot.vkbd_hide_prepare_timer = NULL;
1336 if (rot.vkbd_hide_timer)
1337 ecore_timer_del(rot.vkbd_hide_timer);
1338 rot.vkbd_hide_timer = NULL;
1339 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1341 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1342 e_border_hide(bd, 0);
1343 if (!e_object_is_del(E_OBJECT(bd)))
1345 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1346 e_object_del(E_OBJECT(bd));
1348 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1353 _e_border_vkbd_show_prepare_timeout(void *data)
1355 E_Border *bd = data;
1356 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1357 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1359 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1360 _e_border_vkbd_show(bd);
1362 return ECORE_CALLBACK_CANCEL;
1366 _e_border_vkbd_hide_prepare_timeout(void *data)
1368 E_Border *bd = data;
1369 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1370 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1372 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1373 _e_border_vkbd_hide(bd);
1375 return ECORE_CALLBACK_CANCEL;
1380 e_border_show(E_Border *bd)
1382 E_Event_Border_Show *ev;
1383 unsigned int visible;
1386 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1387 if (bd->visible) return;
1388 #ifdef _F_ZONE_WINDOW_ROTATION_
1389 if ((bd->new_client) &&
1390 (bd->client.e.state.rot.changes != -1))
1392 // newly created window that has to be rotated will be show after rotation done.
1393 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1394 bd->client.e.state.rot.pending_show = 1;
1397 if ((e_config->wm_win_rotation) &&
1398 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1400 (!rot.vkbd_show_prepare_done))
1402 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1403 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1404 if (rot.vkbd_show_prepare_timer)
1405 ecore_timer_del(rot.vkbd_show_prepare_timer);
1406 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1407 _e_border_vkbd_show_prepare_timeout,
1411 ELB(ELBT_BD, "SHOW", bd->client.win);
1413 ecore_x_window_shadow_tree_flush();
1414 e_container_shape_show(bd->shape);
1415 if (!bd->need_reparent)
1416 ecore_x_window_show(bd->client.win);
1417 e_hints_window_visible_set(bd);
1420 bd->changes.visible = 1;
1423 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1424 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1426 ev = E_NEW(E_Event_Border_Show, 1);
1428 e_object_ref(E_OBJECT(bd));
1429 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1430 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1432 #ifdef _F_ZONE_WINDOW_ROTATION_
1433 if ((e_config->wm_win_rotation) &&
1434 ((bd->client.e.state.rot.support) ||
1435 (bd->client.e.state.rot.app_set)))
1437 ELB(ELBT_ROT, "CHECK", bd->client.win);
1438 int rotation = _e_border_rotation_angle_get(bd);
1439 if (rotation != -1) e_border_rotation_set(bd, rotation);
1445 e_border_hide(E_Border *bd,
1448 unsigned int visible;
1451 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1453 #ifdef _F_ZONE_WINDOW_ROTATION_
1454 if ((e_config->wm_win_rotation) &&
1455 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1457 (!rot.vkbd_hide_prepare_done) &&
1460 Eina_Bool need_prepare = EINA_TRUE;
1461 E_Border *child = NULL;
1464 if (e_object_is_del(E_OBJECT(bd->parent)))
1465 need_prepare = EINA_FALSE;
1468 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1469 if (bd->parent->modal == bd)
1471 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1472 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1473 bd->parent->lock_close = 0;
1474 bd->parent->saved.event_mask = 0;
1475 bd->parent->modal = NULL;
1481 need_prepare = EINA_FALSE;
1483 EINA_LIST_FREE(bd->transients, child)
1485 child->parent = NULL;
1488 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1492 e_object_ref(E_OBJECT(bd));
1493 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1494 if (rot.vkbd_hide_prepare_timer)
1495 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1496 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1497 _e_border_vkbd_hide_prepare_timeout,
1503 e_object_ref(E_OBJECT(bd));
1505 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1506 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1508 /* cleanup code from _e_border_vkbd_hide() */
1509 rot.vkbd_hide_prepare_done = EINA_TRUE;
1510 if (rot.vkbd_hide_prepare_timer)
1511 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1512 rot.vkbd_hide_prepare_timer = NULL;
1513 if (rot.vkbd_hide_timer)
1514 ecore_timer_del(rot.vkbd_hide_timer);
1515 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1518 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1520 if (!bd->visible) goto send_event;
1521 ecore_x_window_shadow_tree_flush();
1523 _e_border_move_end(bd);
1524 if (bd->resize_mode != RESIZE_NONE)
1526 _e_border_pointer_resize_end(bd);
1527 bd->resize_mode = RESIZE_NONE;
1528 _e_border_resize_end(bd);
1531 e_container_shape_hide(bd->shape);
1532 if (!bd->iconic) e_hints_window_hidden_set(bd);
1535 bd->changes.visible = 1;
1537 if (!bd->need_reparent)
1539 if ((bd->focused) ||
1540 (e_grabinput_last_focus_win_get() == bd->client.win))
1542 e_border_focus_set(bd, 0, 1);
1550 con = e_container_current_get(e_manager_current_get());
1551 zone = e_zone_current_get(con);
1552 desk = e_desk_current_get(zone);
1555 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1556 e_border_focus_set(bd->parent, 1, 1);
1557 else if (e_config->focus_revert_on_hide_or_close)
1559 /* When using pointer focus, the border under the
1560 * pointer (if any) gets focused, in sloppy/click
1561 * focus the last focused window on the current
1562 * desk gets focus */
1563 if (e_config->focus_policy == E_FOCUS_MOUSE)
1565 pbd = e_border_under_pointer_get(desk, bd);
1567 e_border_focus_set(pbd, 1, 1);
1569 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1570 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1571 (e_config->focus_policy == E_FOCUS_CLICK))
1572 _e_border_latest_stacked_focus(bd);
1576 e_desk_last_focused_focus(desk);
1586 /* Make sure that this border isn't deleted */
1587 bd->await_hide_event++;
1589 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1590 ecore_x_window_hide(bd->client.win);
1595 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1597 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1604 #ifdef _F_ZONE_WINDOW_ROTATION_
1605 _e_border_rotation_list_remove(bd);
1608 E_Event_Border_Hide *ev;
1610 ev = E_NEW(E_Event_Border_Hide, 1);
1612 e_object_ref(E_OBJECT(bd));
1613 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1614 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1619 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1623 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1624 setpriority(PRIO_PROCESS, pid, newpri);
1625 // shouldnt need to do this as default ionice class is "none" (0), and
1626 // this inherits io priority FROM nice level
1627 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1628 // IOPRIO_PRIO_VALUE(2, 5));
1632 char *file, buf[PATH_MAX];
1636 // yes - this is /proc specific... so this may not work on some
1637 // os's - works on linux. too bad for others.
1638 files = ecore_file_ls("/proc");
1639 EINA_LIST_FREE(files, file)
1641 if (isdigit(file[0]))
1643 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1644 f = fopen(buf, "r");
1649 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1655 _pri_adj(pid2, set, adj, EINA_TRUE,
1656 adj_children, do_children);
1658 _pri_adj(pid2, set, adj, use_adj,
1659 adj_children, do_children);
1671 _e_border_pri_raise(E_Border *bd)
1673 if (bd->client.netwm.pid <= 0) return;
1674 if (bd->client.netwm.pid == getpid()) return;
1675 _pri_adj(bd->client.netwm.pid,
1676 e_config->priority - 1, -1, EINA_FALSE,
1677 // EINA_TRUE, EINA_TRUE);
1678 EINA_TRUE, EINA_FALSE);
1679 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1680 // bd->client.netwm.pid, e_border_name_get(bd));
1684 _e_border_pri_norm(E_Border *bd)
1686 if (bd->client.netwm.pid <= 0) return;
1687 if (bd->client.netwm.pid == getpid()) return;
1688 _pri_adj(bd->client.netwm.pid,
1689 e_config->priority, 1, EINA_FALSE,
1690 // EINA_TRUE, EINA_TRUE);
1691 EINA_TRUE, EINA_FALSE);
1692 // printf("WIN: pid %i, title %s (NORMAL)\n",
1693 // bd->client.netwm.pid, e_border_name_get(bd));
1697 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1700 Ecore_Evas *bg_ecore_evas;
1706 bg_ecore_evas = bd->bg_ecore_evas;
1708 /* unregister old frame window */
1709 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1710 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1712 e_focus_setdown(bd);
1713 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1714 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1716 if (bd->icon_object)
1717 evas_object_del(bd->icon_object);
1719 evas_object_del(bd->bg_object);
1720 e_canvas_del(bg_ecore_evas);
1721 ecore_evas_free(bg_ecore_evas);
1724 e_object_del(E_OBJECT(bd->pointer));
1726 /* create new frame */
1728 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1729 bd->x, bd->y, bd->w, bd->h);
1732 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1733 bd->x, bd->y, bd->w, bd->h);
1734 ecore_x_window_shape_events_select(bd->win, 1);
1737 ecore_x_window_configure(bd->win,
1738 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1739 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1741 win, ECORE_X_WINDOW_STACK_BELOW);
1743 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1744 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1747 bd->bg_ecore_evas = e_canvas_new(bd->win,
1748 0, 0, bd->w, bd->h, 1, 0,
1751 e_canvas_add(bd->bg_ecore_evas);
1752 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1754 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1755 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1756 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1758 ecore_x_window_shape_events_select(bd->bg_win, 1);
1760 /* move client with shell win over to new frame */
1761 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1762 bd->client_inset.l, bd->client_inset.t);
1764 bd->pointer = e_pointer_window_new(bd->win, 0);
1766 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1767 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1774 ecore_evas_show(bd->bg_ecore_evas);
1775 ecore_x_window_show(bd->win);
1777 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1778 ecore_x_window_show(tmp->win);
1781 bd->bg_object = edje_object_add(bd->bg_evas);
1782 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1783 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1785 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1787 /* cleanup old frame */
1788 ecore_x_window_free(win);
1792 _e_border_client_move_resize_send(E_Border *bd)
1794 if (bd->internal_ecore_evas)
1795 ecore_evas_managed_move(bd->internal_ecore_evas,
1796 bd->x + bd->fx.x + bd->client_inset.l,
1797 bd->y + bd->fx.y + bd->client_inset.t);
1799 ecore_x_icccm_move_resize_send(bd->client.win,
1800 bd->x + bd->fx.x + bd->client_inset.l,
1801 bd->y + bd->fx.y + bd->client_inset.t,
1807 _e_border_pending_move_resize_add(E_Border *bd,
1814 Eina_Bool without_border,
1815 unsigned int serial)
1817 E_Border_Pending_Move_Resize *pnd;
1819 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1821 pnd->resize = resize;
1823 pnd->without_border = without_border;
1828 pnd->serial = serial;
1829 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1833 _e_border_move_internal(E_Border *bd,
1836 Eina_Bool without_border)
1838 E_Event_Border_Move *ev;
1841 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1843 ecore_x_window_shadow_tree_flush();
1846 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1852 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1854 if (e_config->allow_manip)
1857 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1862 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1867 else if (e_config->allow_manip)
1875 x -= bd->client_inset.l;
1876 y -= bd->client_inset.t;
1878 if (bd->move_intercept_cb)
1881 px = bd->x, py = bd->y;
1882 bd->move_intercept_cb(bd, x, y);
1883 if ((bd->x == px) && (bd->y == py)) return;
1885 else if ((x == bd->x) && (y == bd->y)) return;
1886 bd->pre_res_change.valid = 0;
1890 bd->changes.pos = 1;
1892 if (bd->client.netwm.sync.request)
1894 bd->client.netwm.sync.wait++;
1895 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1898 _e_border_client_move_resize_send(bd);
1899 _e_border_move_update(bd);
1900 ev = E_NEW(E_Event_Border_Move, 1);
1902 e_object_ref(E_OBJECT(bd));
1903 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1904 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1905 _e_border_zone_update(bd);
1909 * Move window to coordinates that already account border decorations.
1911 * This call will consider given position already accounts border
1912 * decorations, so it will not be considered later. This will just
1913 * work properly with borders that have being evaluated and border
1914 * decorations are known (border->client_inset).
1916 * @parm x horizontal position to place window.
1917 * @parm y vertical position to place window.
1919 * @see e_border_move_without_border()
1922 e_border_move(E_Border *bd,
1929 _e_border_move_internal(bd, x, y, 0);
1934 * Set a callback which will be called just prior to updating the
1935 * move coordinates for a border
1938 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1940 bd->move_intercept_cb = cb;
1944 * Move window to coordinates that do not account border decorations yet.
1946 * This call will consider given position does not account border
1947 * decoration, so these values (border->client_inset) will be
1948 * accounted automatically. This is specially useful when it is a new
1949 * client and has not be evaluated yet, in this case
1950 * border->client_inset will be zeroed and no information is known. It
1951 * will mark pending requests so border will be accounted on
1952 * evalutation phase.
1954 * @parm x horizontal position to place window.
1955 * @parm y vertical position to place window.
1957 * @see e_border_move()
1960 e_border_move_without_border(E_Border *bd,
1967 _e_border_move_internal(bd, x, y, 1);
1971 e_border_center(E_Border *bd)
1975 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1977 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1978 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1982 e_border_center_pos_get(E_Border *bd,
1988 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1990 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1991 if (x) *x = zx + (zw - bd->w) / 2;
1992 if (y) *y = zy + (zh - bd->h) / 2;
1996 e_border_fx_offset(E_Border *bd,
2001 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2003 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2007 bd->changes.pos = 1;
2010 if (bd->moving) _e_border_move_update(bd);
2014 _e_border_move_resize_internal(E_Border *bd,
2019 Eina_Bool without_border,
2022 E_Event_Border_Move *mev;
2023 E_Event_Border_Resize *rev;
2026 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2028 ecore_x_window_shadow_tree_flush();
2032 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2038 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2040 if (e_config->allow_manip)
2043 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2049 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2056 if (e_config->allow_manip)
2064 x -= bd->client_inset.l;
2065 y -= bd->client_inset.t;
2066 w += (bd->client_inset.l + bd->client_inset.r);
2067 h += (bd->client_inset.t + bd->client_inset.b);
2070 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2071 (w == bd->w) && (h == bd->h))
2074 bd->pre_res_change.valid = 0;
2077 bd->changes.pos = 1;
2083 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2084 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2086 if ((bd->shaped) || (bd->client.shaped))
2088 bd->need_shape_merge = 1;
2089 bd->need_shape_export = 1;
2091 if (bd->shaped_input)
2093 bd->need_shape_merge = 1;
2096 if (bd->internal_ecore_evas)
2099 bd->changes.size = 1;
2103 if (bdresize && bd->client.netwm.sync.request)
2105 bd->client.netwm.sync.wait++;
2106 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2107 * when no move is intended. The border geometry is set above anyways.
2109 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2110 bd->client.netwm.sync.serial);
2111 ecore_x_netwm_sync_request_send(bd->client.win,
2112 bd->client.netwm.sync.serial++);
2117 bd->changes.size = 1;
2121 _e_border_client_move_resize_send(bd);
2123 _e_border_resize_update(bd);
2126 mev = E_NEW(E_Event_Border_Move, 1);
2128 e_object_ref(E_OBJECT(bd));
2129 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2130 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2133 rev = E_NEW(E_Event_Border_Resize, 1);
2135 e_object_ref(E_OBJECT(bd));
2136 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2137 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2138 _e_border_zone_update(bd);
2142 * Move and resize window to values that already account border decorations.
2144 * This call will consider given values already accounts border
2145 * decorations, so it will not be considered later. This will just
2146 * work properly with borders that have being evaluated and border
2147 * decorations are known (border->client_inset).
2149 * @parm x horizontal position to place window.
2150 * @parm y vertical position to place window.
2151 * @parm w horizontal window size.
2152 * @parm h vertical window size.
2154 * @see e_border_move_resize_without_border()
2157 e_border_move_resize(E_Border *bd,
2166 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2170 * Move and resize window to values that do not account border decorations yet.
2172 * This call will consider given values already accounts border
2173 * decorations, so it will not be considered later. This will just
2174 * work properly with borders that have being evaluated and border
2175 * decorations are known (border->client_inset).
2177 * @parm x horizontal position to place window.
2178 * @parm y vertical position to place window.
2179 * @parm w horizontal window size.
2180 * @parm h vertical window size.
2182 * @see e_border_move_resize()
2185 e_border_move_resize_without_border(E_Border *bd,
2194 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2198 * Resize window to values that already account border decorations.
2200 * This call will consider given size already accounts border
2201 * decorations, so it will not be considered later. This will just
2202 * work properly with borders that have being evaluated and border
2203 * decorations are known (border->client_inset).
2205 * @parm w horizontal window size.
2206 * @parm h vertical window size.
2208 * @see e_border_resize_without_border()
2211 e_border_resize(E_Border *bd,
2218 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2222 * Resize window to values that do not account border decorations yet.
2224 * This call will consider given size does not account border
2225 * decoration, so these values (border->client_inset) will be
2226 * accounted automatically. This is specially useful when it is a new
2227 * client and has not be evaluated yet, in this case
2228 * border->client_inset will be zeroed and no information is known. It
2229 * will mark pending requests so border will be accounted on
2230 * evalutation phase.
2232 * @parm w horizontal window size.
2233 * @parm h vertical window size.
2235 * @see e_border_resize()
2238 e_border_resize_without_border(E_Border *bd,
2245 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2249 e_border_layer_set(E_Border *bd,
2255 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2257 ecore_x_window_shadow_tree_flush();
2259 oldraise = e_config->transient.raise;
2263 bd->saved.layer = layer;
2267 if (e_config->transient.layer)
2271 Eina_List *list = _e_border_sub_borders_new(bd);
2273 /* We need to set raise to one, else the child wont
2274 * follow to the new layer. It should be like this,
2275 * even if the user usually doesn't want to raise
2278 e_config->transient.raise = 1;
2279 EINA_LIST_FOREACH(list, l, child)
2281 e_border_layer_set(child, layer);
2285 e_config->transient.raise = oldraise;
2289 e_border_raise(E_Border *bd)
2291 E_Event_Border_Stack *ev;
2292 E_Border *last = NULL, *child;
2296 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2298 ecore_x_window_shadow_tree_flush();
2300 if (e_config->transient.raise)
2302 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2303 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2306 Eina_List *list = _e_border_sub_borders_new(bd);
2308 EINA_LIST_REVERSE_FOREACH(list, l, child)
2310 /* Don't stack iconic transients. If the user wants these shown,
2311 * thats another option.
2316 e_border_stack_below(child, last);
2321 /* First raise the border to find out which border we will end up above */
2322 above = e_container_border_raise(child);
2326 /* We ended up above a border, now we must stack this border to
2327 * generate the stacking event, and to check if this transient
2328 * has other transients etc.
2330 e_border_stack_above(child, above);
2334 /* If we didn't end up above any border, we are on the bottom! */
2335 e_border_lower(child);
2341 eina_list_free(list);
2342 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2346 EINA_LIST_FOREACH(bd->transients, l, child)
2348 /* Don't stack iconic transients. If the user wants these shown,
2349 * thats another option.
2353 child->layer = bd->layer;
2354 if (!last) last = child;
2355 e_border_raise (child);
2362 ev = E_NEW(E_Event_Border_Stack, 1);
2364 e_object_ref(E_OBJECT(bd));
2368 e_container_border_stack_below(bd, last);
2370 e_object_ref(E_OBJECT(last));
2371 ev->type = E_STACKING_BELOW;
2377 /* If we don't have any children, raise this border */
2378 above = e_container_border_raise(bd);
2379 e_border_raise_latest_set(bd);
2382 /* We ended up above a border */
2384 e_object_ref(E_OBJECT(above));
2385 ev->type = E_STACKING_ABOVE;
2389 /* No border to raise above, same as a lower! */
2391 ev->type = E_STACKING_ABOVE;
2395 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2396 e_remember_update(bd);
2400 e_border_lower(E_Border *bd)
2402 E_Event_Border_Stack *ev;
2403 E_Border *last = NULL, *child;
2407 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2409 ecore_x_window_shadow_tree_flush();
2411 if (e_config->transient.lower)
2413 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2414 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2417 Eina_List *list = _e_border_sub_borders_new(bd);
2419 EINA_LIST_REVERSE_FOREACH(list, l, child)
2421 /* Don't stack iconic transients. If the user wants these shown,
2422 * thats another option.
2427 e_border_stack_below(child, last);
2432 /* First lower the border to find out which border we will end up below */
2433 below = e_container_border_lower(child);
2437 /* We ended up below a border, now we must stack this border to
2438 * generate the stacking event, and to check if this transient
2439 * has other transients etc.
2441 e_border_stack_below(child, below);
2445 /* If we didn't end up below any border, we are on top! */
2446 e_border_raise(child);
2452 eina_list_free(list);
2454 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2458 EINA_LIST_FOREACH(bd->transients, l, child)
2460 /* Don't stack iconic transients. If the user wants these shown,
2461 * thats another option.
2465 child->layer = bd->layer;
2466 e_border_lower (child);
2474 ev = E_NEW(E_Event_Border_Stack, 1);
2476 e_object_ref(E_OBJECT(bd));
2480 e_container_border_stack_below(bd, last);
2482 e_object_ref(E_OBJECT(last));
2483 ev->type = E_STACKING_BELOW;
2489 /* If we don't have any children, lower this border */
2490 below = e_container_border_lower(bd);
2493 /* We ended up below a border */
2495 e_object_ref(E_OBJECT(below));
2496 ev->type = E_STACKING_BELOW;
2500 /* No border to hide under, same as a raise! */
2502 ev->type = E_STACKING_BELOW;
2506 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2507 e_remember_update(bd);
2511 e_border_stack_above(E_Border *bd,
2514 /* TODO: Should stack above allow the border to change level */
2515 E_Event_Border_Stack *ev;
2516 E_Border *last = NULL, *child;
2520 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2522 ecore_x_window_shadow_tree_flush();
2524 if (e_config->transient.raise)
2526 Eina_List *list = _e_border_sub_borders_new(bd);
2528 EINA_LIST_REVERSE_FOREACH(list, l, child)
2530 /* Don't stack iconic transients. If the user wants these shown,
2531 * thats another option.
2536 e_border_stack_below(child, last);
2538 e_border_stack_above(child, above);
2542 eina_list_free(list);
2545 ev = E_NEW(E_Event_Border_Stack, 1);
2547 e_object_ref(E_OBJECT(bd));
2551 e_container_border_stack_below(bd, last);
2553 e_object_ref(E_OBJECT(last));
2554 ev->type = E_STACKING_BELOW;
2558 e_container_border_stack_above(bd, above);
2560 e_object_ref(E_OBJECT(above));
2561 ev->type = E_STACKING_ABOVE;
2564 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2565 e_remember_update(bd);
2569 e_border_stack_below(E_Border *bd,
2572 /* TODO: Should stack below allow the border to change level */
2573 E_Event_Border_Stack *ev;
2574 E_Border *last = NULL, *child;
2578 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2580 ecore_x_window_shadow_tree_flush();
2582 if (e_config->transient.lower)
2584 Eina_List *list = _e_border_sub_borders_new(bd);
2586 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2588 /* Don't stack iconic transients. If the user wants these shown,
2589 * thats another option.
2594 e_border_stack_below(child, last);
2596 e_border_stack_below(child, below);
2600 eina_list_free(list);
2603 ev = E_NEW(E_Event_Border_Stack, 1);
2605 e_object_ref(E_OBJECT(bd));
2609 e_container_border_stack_below(bd, last);
2611 e_object_ref(E_OBJECT(last));
2612 ev->type = E_STACKING_BELOW;
2616 e_container_border_stack_below(bd, below);
2618 e_object_ref(E_OBJECT(below));
2619 ev->type = E_STACKING_BELOW;
2622 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2623 e_remember_update(bd);
2627 e_border_focus_latest_set(E_Border *bd)
2629 focus_stack = eina_list_remove(focus_stack, bd);
2630 focus_stack = eina_list_prepend(focus_stack, bd);
2634 e_border_raise_latest_set(E_Border *bd)
2636 raise_stack = eina_list_remove(raise_stack, bd);
2637 raise_stack = eina_list_prepend(raise_stack, bd);
2641 * Sets the focus to the given border if necessary
2642 * There are 3 cases of different focus_policy-configurations:
2644 * - E_FOCUS_CLICK: just set the focus, the most simple one
2646 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2647 * warp the pointer to the window. If this fails (because
2648 * the pointer is already in the window), just set the focus.
2650 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2651 * last window which was focused, if the mouse is on the
2652 * desktop. So, we need to look if there is another window
2653 * under the pointer and warp to pointer to the right
2654 * one if so (also, we set the focus afterwards). In case
2655 * there is no window under pointer, the pointer is on the
2656 * desktop and so we just set the focus.
2659 * This function is to be called when setting the focus was not
2660 * explicitly triggered by the user (by moving the mouse or
2661 * clicking for example), but implicitly (by closing a window,
2662 * the last focused window should get focus).
2666 e_border_focus_set_with_pointer(E_Border *bd)
2668 #ifdef PRINT_LOTS_OF_DEBUG
2669 E_PRINT_BORDER_INFO(bd);
2671 /* note: this is here as it seems there are enough apps that do not even
2672 * expect us to emulate a look of focus but not actually set x input
2673 * focus as we do - so simply abort any focuse set on such windows */
2674 /* be strict about accepting focus hint */
2675 if ((!bd->client.icccm.accepts_focus) &&
2676 (!bd->client.icccm.take_focus)) return;
2677 if (bd->lock_focus_out) return;
2679 e_border_focus_set(bd, 1, 1);
2681 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2682 if (!bd->visible) return;
2684 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2686 if (!e_border_under_pointer_get(bd->desk, bd))
2688 e_border_pointer_warp_to_center(bd);
2693 e_border_pointer_warp_to_center(bd);
2698 e_border_focus_set(E_Border *bd,
2702 E_Border *bd_unfocus = NULL;
2703 Eina_Bool focus_changed = EINA_FALSE;
2706 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2707 /* note: this is here as it seems there are enough apps that do not even
2708 * expect us to emulate a look of focus but not actually set x input
2709 * focus as we do - so simply abort any focuse set on such windows */
2710 /* be strict about accepting focus hint */
2711 if ((!bd->client.icccm.accepts_focus) &&
2712 (!bd->client.icccm.take_focus))
2714 if ((set) && (focus) && (bd->lock_focus_out)) return;
2716 /* dont focus an iconified window. that's silly! */
2721 e_border_uniconify(bd);
2722 if (!focus_track_frozen)
2723 e_border_focus_latest_set(bd);
2726 else if (!bd->visible)
2730 /* FIXME: hack for deskflip animation:
2731 * dont update focus when sliding previous desk */
2732 else if ((!bd->sticky) &&
2733 (bd->desk != e_desk_current_get(bd->desk->zone)))
2739 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2741 e_border_focus_set(bd->modal, focus, set);
2744 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2746 e_border_focus_set(bd->leader->modal, focus, set);
2754 if (bd->visible && bd->changes.visible)
2759 else if ((!bd->focused) ||
2760 (focus_next && (bd != eina_list_data_get(focus_next))))
2764 if ((l = eina_list_data_find_list(focus_next, bd)))
2765 focus_next = eina_list_promote_list(focus_next, l);
2767 focus_next = eina_list_prepend(focus_next, bd);
2769 if ((bd->client.icccm.take_focus) &&
2770 (bd->client.icccm.accepts_focus))
2772 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2773 /* TODO what if the client didn't take focus ? */
2775 else if (!bd->client.icccm.accepts_focus)
2777 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2779 else if (!bd->client.icccm.take_focus)
2781 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2782 /* e_border_focus_set(bd, 1, 0); */
2792 if (focused) bd_unfocus = focused;
2793 if (focusing == bd) focusing = NULL;
2798 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2800 if ((bd2->fullscreen) &&
2802 (bd2->zone == bd->zone) &&
2803 ((bd2->desk == bd->desk) ||
2804 (bd2->sticky) || (bd->sticky)))
2806 Eina_Bool unfocus_is_parent = EINA_FALSE;
2807 E_Border *bd_parent;
2809 bd_parent = bd->parent;
2812 if (bd_parent == bd2)
2814 unfocus_is_parent = EINA_TRUE;
2817 bd_parent = bd->parent;
2819 if ((!unfocus_is_parent) &&
2820 (!e_config->allow_above_fullscreen))
2822 e_border_iconify(bd2);
2827 focus_changed = EINA_TRUE;
2833 focus_next = eina_list_remove(focus_next, bd);
2834 if (bd == focusing) focusing = NULL;
2836 if ((bd->focused) &&
2837 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2839 Eina_Bool wasfocused = EINA_FALSE;
2842 /* should always be the case. anyway */
2846 wasfocused = EINA_TRUE;
2849 if ((set) && (!focus_next) && (!focusing))
2851 e_grabinput_focus(bd->zone->container->bg_win,
2852 E_FOCUS_METHOD_PASSIVE);
2854 if ((bd->fullscreen) && (wasfocused))
2856 Eina_Bool have_vis_child = EINA_FALSE;
2860 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2863 (bd2->zone == bd->zone) &&
2864 ((bd2->desk == bd->desk) ||
2865 (bd2->sticky) || (bd->sticky)))
2867 if (bd2->parent == bd)
2869 have_vis_child = EINA_TRUE;
2874 if ((!have_vis_child) &&
2875 (!e_config->allow_above_fullscreen))
2876 e_border_iconify(bd);
2882 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2883 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2885 E_Event_Border_Focus_Out *ev;
2887 bd_unfocus->focused = 0;
2888 e_focus_event_focus_out(bd_unfocus);
2890 if (bd_unfocus->raise_timer)
2891 ecore_timer_del(bd_unfocus->raise_timer);
2892 bd_unfocus->raise_timer = NULL;
2894 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2895 if (bd_unfocus->icon_object)
2896 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2898 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2899 ev->border = bd_unfocus;
2900 e_object_ref(E_OBJECT(bd_unfocus));
2902 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2903 _e_border_event_border_focus_out_free, NULL);
2904 if ((bd_unfocus->fullscreen) &&
2905 (bd != bd_unfocus) &&
2906 (bd->zone == bd_unfocus->zone) &&
2907 ((bd->desk == bd_unfocus->desk) ||
2908 (bd->sticky) || (bd_unfocus->sticky)))
2910 Eina_Bool unfocus_is_parent = EINA_FALSE;
2911 E_Border *bd_parent;
2913 bd_parent = bd->parent;
2916 if (bd_parent == bd_unfocus)
2918 unfocus_is_parent = EINA_TRUE;
2921 bd_parent = bd->parent;
2923 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2925 e_border_iconify(bd_unfocus);
2932 E_Event_Border_Focus_In *ev;
2934 e_focus_event_focus_in(bd);
2936 if (!focus_track_frozen)
2937 e_border_focus_latest_set(bd);
2939 e_hints_active_window_set(bd->zone->container->manager, bd);
2941 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2942 if (bd->icon_object)
2943 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2945 ev = E_NEW(E_Event_Border_Focus_In, 1);
2947 e_object_ref(E_OBJECT(bd));
2949 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2950 _e_border_event_border_focus_in_free, NULL);
2955 e_border_shade(E_Border *bd,
2958 E_Event_Border_Resize *ev;
2963 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2964 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2965 ((bd->maximized) && (!e_config->allow_manip))) return;
2966 if ((bd->client.border.name) &&
2967 (!strcmp("borderless", bd->client.border.name))) return;
2969 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2970 ecore_x_window_hide(tmp->win);
2972 ecore_x_window_shadow_tree_flush();
2974 bd->shade.x = bd->x;
2975 bd->shade.y = bd->y;
2976 bd->shade.dir = dir;
2978 e_hints_window_shaded_set(bd, 1);
2979 e_hints_window_shade_direction_set(bd, dir);
2981 if (e_config->border_shade_animate)
2983 bd->shade.start = ecore_loop_time_get();
2985 bd->changes.shading = 1;
2988 if (bd->shade.dir == E_DIRECTION_UP ||
2989 bd->shade.dir == E_DIRECTION_LEFT)
2990 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2992 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2994 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2995 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2999 if (bd->shade.dir == E_DIRECTION_UP)
3001 bd->h = bd->client_inset.t + bd->client_inset.b;
3003 else if (bd->shade.dir == E_DIRECTION_DOWN)
3005 bd->h = bd->client_inset.t + bd->client_inset.b;
3006 bd->y = bd->y + bd->client.h;
3007 bd->changes.pos = 1;
3009 else if (bd->shade.dir == E_DIRECTION_LEFT)
3011 bd->w = bd->client_inset.l + bd->client_inset.r;
3013 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3015 bd->w = bd->client_inset.l + bd->client_inset.r;
3016 bd->x = bd->x + bd->client.w;
3017 bd->changes.pos = 1;
3020 if ((bd->shaped) || (bd->client.shaped))
3022 bd->need_shape_merge = 1;
3023 bd->need_shape_export = 1;
3025 if (bd->shaped_input)
3027 bd->need_shape_merge = 1;
3030 bd->changes.size = 1;
3032 bd->changes.shaded = 1;
3034 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3035 e_border_frame_recalc(bd);
3036 ev = E_NEW(E_Event_Border_Resize, 1);
3038 /* The resize is added in the animator when animation complete */
3039 /* For non-animated, we add it immediately with the new size */
3040 e_object_ref(E_OBJECT(bd));
3041 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3042 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3045 e_remember_update(bd);
3049 e_border_unshade(E_Border *bd,
3052 E_Event_Border_Resize *ev;
3057 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3058 if ((!bd->shaded) || (bd->shading))
3061 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3062 ecore_x_window_show(tmp->win);
3064 ecore_x_window_shadow_tree_flush();
3066 bd->shade.dir = dir;
3068 e_hints_window_shaded_set(bd, 0);
3069 e_hints_window_shade_direction_set(bd, dir);
3071 if (bd->shade.dir == E_DIRECTION_UP ||
3072 bd->shade.dir == E_DIRECTION_LEFT)
3074 bd->shade.x = bd->x;
3075 bd->shade.y = bd->y;
3079 bd->shade.x = bd->x - bd->client.w;
3080 bd->shade.y = bd->y - bd->client.h;
3082 if (e_config->border_shade_animate)
3084 bd->shade.start = ecore_loop_time_get();
3086 bd->changes.shading = 1;
3089 if (bd->shade.dir == E_DIRECTION_UP)
3091 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3092 ecore_x_window_move_resize(bd->client.win, 0,
3093 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3095 bd->client.w, bd->client.h);
3097 else if (bd->shade.dir == E_DIRECTION_LEFT)
3099 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3100 ecore_x_window_move_resize(bd->client.win,
3101 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3103 0, bd->client.w, bd->client.h);
3106 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3108 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3109 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3113 if (bd->shade.dir == E_DIRECTION_UP)
3115 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3117 else if (bd->shade.dir == E_DIRECTION_DOWN)
3119 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3120 bd->y = bd->y - bd->client.h;
3121 bd->changes.pos = 1;
3123 else if (bd->shade.dir == E_DIRECTION_LEFT)
3125 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3127 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3129 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3130 bd->x = bd->x - bd->client.w;
3131 bd->changes.pos = 1;
3133 if ((bd->shaped) || (bd->client.shaped))
3135 bd->need_shape_merge = 1;
3136 bd->need_shape_export = 1;
3138 if (bd->shaped_input)
3140 bd->need_shape_merge = 1;
3143 bd->changes.size = 1;
3145 bd->changes.shaded = 1;
3147 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3148 e_border_frame_recalc(bd);
3149 ev = E_NEW(E_Event_Border_Resize, 1);
3151 /* The resize is added in the animator when animation complete */
3152 /* For non-animated, we add it immediately with the new size */
3153 e_object_ref(E_OBJECT(bd));
3154 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3155 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3158 e_remember_update(bd);
3162 _e_border_client_inset_calc(E_Border *bd)
3165 Evas_Coord cx, cy, cw, ch;
3169 evas_object_resize(bd->bg_object, 1000, 1000);
3170 edje_object_message_signal_process(bd->bg_object);
3171 edje_object_calc_force(bd->bg_object);
3172 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3173 bd->client_inset.l = cx;
3174 bd->client_inset.r = 1000 - (cx + cw);
3175 bd->client_inset.t = cy;
3176 bd->client_inset.b = 1000 - (cy + ch);
3180 bd->client_inset.l = 0;
3181 bd->client_inset.r = 0;
3182 bd->client_inset.t = 0;
3183 bd->client_inset.b = 0;
3186 ecore_x_netwm_frame_size_set(bd->client.win,
3187 bd->client_inset.l, bd->client_inset.r,
3188 bd->client_inset.t, bd->client_inset.b);
3189 ecore_x_e_frame_size_set(bd->client.win,
3190 bd->client_inset.l, bd->client_inset.r,
3191 bd->client_inset.t, bd->client_inset.b);
3195 _e_border_maximize(E_Border *bd, E_Maximize max)
3197 int x1, yy1, x2, y2;
3200 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3204 zx = zy = zw = zh = 0;
3206 switch (max & E_MAXIMIZE_TYPE)
3208 case E_MAXIMIZE_NONE:
3212 case E_MAXIMIZE_FULLSCREEN:
3218 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3219 _e_border_client_inset_calc(bd);
3221 e_border_resize_limit(bd, &w, &h);
3222 /* center x-direction */
3223 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3224 /* center y-direction */
3225 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3227 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3228 cy = bd->zone->y + (bd->zone->h / 2);
3231 switch (max & E_MAXIMIZE_DIRECTION)
3233 case E_MAXIMIZE_BOTH:
3234 e_border_move_resize(bd, x1, yy1, w, h);
3237 case E_MAXIMIZE_VERTICAL:
3238 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3241 case E_MAXIMIZE_HORIZONTAL:
3242 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3245 case E_MAXIMIZE_LEFT:
3246 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3249 case E_MAXIMIZE_RIGHT:
3250 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3252 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3253 case E_MAXIMIZE_TOP:
3254 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3256 case E_MAXIMIZE_BOTTOM:
3257 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3263 case E_MAXIMIZE_SMART:
3264 case E_MAXIMIZE_EXPAND:
3266 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3278 if (bd->x < zx) // window left not useful coordinates
3280 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3281 x1 = zx + zw - bd->w;
3282 else // window normal position
3285 if (bd->y < zy) // window top not useful coordinates
3287 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3288 yy1 = zy + zh - bd->h;
3289 else // window normal position
3292 switch (max & E_MAXIMIZE_DIRECTION)
3294 case E_MAXIMIZE_BOTH:
3295 e_border_move_resize(bd, zx, zy, zw, zh);
3298 case E_MAXIMIZE_VERTICAL:
3299 e_border_move_resize(bd, x1, zy, w, zh);
3302 case E_MAXIMIZE_HORIZONTAL:
3303 e_border_move_resize(bd, zx, yy1, zw, h);
3306 case E_MAXIMIZE_LEFT:
3307 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3310 case E_MAXIMIZE_RIGHT:
3311 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3315 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3318 case E_MAXIMIZE_FILL:
3321 x2 = bd->zone->x + bd->zone->w;
3322 y2 = bd->zone->y + bd->zone->h;
3324 /* walk through all shelves */
3325 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3327 /* walk through all windows */
3328 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3334 e_border_resize_limit(bd, &w, &h);
3335 /* center x-direction */
3336 x1 = x1 + (pw - w) / 2;
3337 /* center y-direction */
3338 yy1 = yy1 + (ph - h) / 2;
3340 switch (max & E_MAXIMIZE_DIRECTION)
3342 case E_MAXIMIZE_BOTH:
3343 e_border_move_resize(bd, x1, yy1, w, h);
3346 case E_MAXIMIZE_VERTICAL:
3347 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3350 case E_MAXIMIZE_HORIZONTAL:
3351 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3354 case E_MAXIMIZE_LEFT:
3355 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3358 case E_MAXIMIZE_RIGHT:
3359 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3367 e_border_maximize(E_Border *bd,
3371 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3373 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3375 if ((bd->shaded) || (bd->shading)) return;
3376 ecore_x_window_shadow_tree_flush();
3378 e_border_unfullscreen(bd);
3379 /* Only allow changes in vertical/ horizontal maximization */
3380 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3381 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3384 bd->need_maximize = 1;
3385 bd->maximized &= ~E_MAXIMIZE_TYPE;
3386 bd->maximized |= max;
3390 bd->pre_res_change.valid = 0;
3391 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3393 /* Horizontal hasn't been set */
3394 bd->saved.x = bd->x - bd->zone->x;
3395 bd->saved.w = bd->w;
3397 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3399 /* Vertical hasn't been set */
3400 bd->saved.y = bd->y - bd->zone->y;
3401 bd->saved.h = bd->h;
3404 bd->saved.zone = bd->zone->num;
3405 e_hints_window_size_set(bd);
3409 _e_border_maximize(bd, max);
3412 /* Remove previous type */
3413 bd->maximized &= ~E_MAXIMIZE_TYPE;
3414 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3415 bd->maximized |= max;
3417 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3418 bd->maximized & E_MAXIMIZE_VERTICAL);
3419 e_remember_update(bd);
3423 e_border_unmaximize(E_Border *bd,
3427 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3428 if (!(max & E_MAXIMIZE_DIRECTION))
3430 CRI("BUG: Unmaximize call without direction!");
3434 if ((bd->shaded) || (bd->shading)) return;
3435 ecore_x_window_shadow_tree_flush();
3436 /* Remove directions not used */
3437 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3438 /* Can only remove existing maximization directions */
3440 if (bd->maximized & E_MAXIMIZE_TYPE)
3442 bd->pre_res_change.valid = 0;
3443 bd->need_maximize = 0;
3445 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3449 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3450 _e_border_client_inset_calc(bd);
3453 bd->maximized = E_MAXIMIZE_NONE;
3454 _e_border_move_resize_internal(bd,
3455 bd->zone->x + bd->saved.x,
3456 bd->zone->y + bd->saved.y,
3457 bd->saved.w, bd->saved.h, 0, 1);
3458 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3459 e_hints_window_size_unset(bd);
3470 if (max & E_MAXIMIZE_VERTICAL)
3472 /* Remove vertical */
3474 y = bd->saved.y + bd->zone->y;
3475 bd->saved.h = bd->saved.y = 0;
3476 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3477 bd->maximized &= ~E_MAXIMIZE_LEFT;
3478 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3480 if (max & E_MAXIMIZE_HORIZONTAL)
3482 /* Remove horizontal */
3484 x = bd->saved.x + bd->zone->x;
3485 bd->saved.w = bd->saved.x = 0;
3486 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3489 e_border_resize_limit(bd, &w, &h);
3491 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3493 bd->maximized = E_MAXIMIZE_NONE;
3494 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3495 e_hints_window_size_unset(bd);
3496 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3500 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3501 e_hints_window_size_set(bd);
3504 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3505 bd->maximized & E_MAXIMIZE_VERTICAL);
3507 e_remember_update(bd);
3511 e_border_fullscreen(E_Border *bd,
3512 E_Fullscreen policy)
3514 E_Event_Border_Fullscreen *ev;
3517 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3519 if ((bd->shaded) || (bd->shading)) return;
3520 ecore_x_window_shadow_tree_flush();
3523 bd->need_fullscreen = 1;
3526 if (!bd->fullscreen)
3528 bd->pre_res_change.valid = 0;
3530 bd->saved.x = bd->x - bd->zone->x;
3531 bd->saved.y = bd->y - bd->zone->y;
3532 bd->saved.w = bd->client.w;
3533 bd->saved.h = bd->client.h;
3534 bd->saved.maximized = bd->maximized;
3535 bd->saved.zone = bd->zone->num;
3538 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3539 e_hints_window_size_set(bd);
3541 bd->client_inset.l = 0;
3542 bd->client_inset.r = 0;
3543 bd->client_inset.t = 0;
3544 bd->client_inset.b = 0;
3546 bd->desk->fullscreen_borders++;
3548 /* e_zone_fullscreen_set(bd->zone, 1); */
3549 bd->saved.layer = bd->layer;
3550 if (!e_config->allow_above_fullscreen)
3551 e_border_layer_set(bd, 250);
3553 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3554 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3556 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3558 else if (policy == E_FULLSCREEN_ZOOM)
3560 Ecore_X_Randr_Screen_Size_MM *sizes;
3561 int num_sizes, i, best_size_index = 0;
3563 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3565 &screen_size.height,
3567 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3571 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3572 int best_dist = INT_MAX, dist;
3574 for (i = 0; i < num_sizes; i++)
3576 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3578 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3579 if (dist < best_dist)
3581 best_size.width = sizes[i].width;
3582 best_size.height = sizes[i].height;
3584 best_size_index = i;
3588 if (((best_size.width != -1) && (best_size.height != -1)) &&
3589 ((best_size.width != screen_size.width) ||
3590 (best_size.height != screen_size.height)))
3592 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3594 screen_size_index = best_size_index;
3595 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3599 screen_size.width = -1;
3600 screen_size.height = -1;
3601 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3606 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3610 e_hints_window_fullscreen_set(bd, 1);
3611 e_hints_window_size_unset(bd);
3612 bd->client.border.changed = 1;
3615 bd->fullscreen_policy = policy;
3617 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3619 e_object_ref(E_OBJECT(bd));
3620 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3621 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3623 e_remember_update(bd);
3627 e_border_unfullscreen(E_Border *bd)
3629 E_Event_Border_Unfullscreen *ev;
3632 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3633 if ((bd->shaded) || (bd->shading)) return;
3634 ecore_x_window_shadow_tree_flush();
3637 bd->pre_res_change.valid = 0;
3639 bd->need_fullscreen = 0;
3640 bd->desk->fullscreen_borders--;
3642 if ((screen_size.width != -1) && (screen_size.height != -1))
3644 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3646 screen_size.width = -1;
3647 screen_size.height = -1;
3649 e_border_move_resize(bd,
3650 bd->saved.x + bd->zone->x,
3651 bd->saved.y + bd->zone->y,
3652 bd->saved.w, bd->saved.h);
3654 if (bd->saved.maximized)
3655 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3656 bd->saved.maximized);
3658 e_border_layer_set(bd, bd->saved.layer);
3660 e_hints_window_fullscreen_set(bd, 0);
3661 bd->client.border.changed = 1;
3664 bd->fullscreen_policy = 0;
3666 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3668 e_object_ref(E_OBJECT(bd));
3669 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3670 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3672 e_remember_update(bd);
3676 e_border_iconify(E_Border *bd)
3678 E_Event_Border_Iconify *ev;
3679 unsigned int iconic;
3682 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3683 if (bd->shading) return;
3684 ecore_x_window_shadow_tree_flush();
3688 e_border_hide(bd, 1);
3689 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3690 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3693 e_hints_window_iconic_set(bd);
3694 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3696 ev = E_NEW(E_Event_Border_Iconify, 1);
3698 e_object_ref(E_OBJECT(bd));
3699 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3700 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3702 if (e_config->transient.iconify)
3706 Eina_List *list = _e_border_sub_borders_new(bd);
3708 EINA_LIST_FOREACH(list, l, child)
3710 e_border_iconify(child);
3712 eina_list_free(list);
3714 e_remember_update(bd);
3717 #ifdef _F_DEICONIFY_APPROVE_
3719 _e_border_uniconify_timeout(void *data)
3726 if (!e_object_is_del(E_OBJECT(bd)))
3728 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3729 bd->client.e.state.deiconify_approve.render_done = 1;
3730 if (bd->client.e.state.deiconify_approve.req_list)
3732 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3734 child_bd->client.e.state.deiconify_approve.render_done = 1;
3735 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3738 bd->client.e.state.deiconify_approve.req_list = NULL;
3739 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3740 e_border_uniconify(bd);
3743 return ECORE_CALLBACK_CANCEL;
3747 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
3749 if (!bd || !bd_ancestor) return;
3751 if (e_config->deiconify_approve)
3753 if (e_config->transient.iconify)
3757 Eina_List *list = _e_border_sub_borders_new(bd);
3758 EINA_LIST_FOREACH(list, l, child)
3760 #ifdef _F_ZONE_WINDOW_ROTATION_
3761 if ((e_config->wm_win_rotation) &&
3762 ((child->client.e.state.rot.support) ||
3763 (child->client.e.state.rot.app_set)))
3765 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3766 int rotation = _e_border_rotation_angle_get(bd);
3767 if (rotation != -1) e_border_rotation_set(bd, rotation);
3770 _e_border_deiconify_approve_send(child, bd_ancestor);
3771 if (child->client.e.state.deiconify_approve.support)
3773 ELBF(ELBT_BD, 0, child->client.win,
3774 "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
3776 ecore_x_client_message32_send(child->client.win,
3777 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3778 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3779 child->client.win, 0, 0, 0, 0);
3780 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3781 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3784 eina_list_free(list);
3790 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3792 E_Border *bd_ancestor;
3795 if (e_config->deiconify_approve)
3797 #ifdef _F_ZONE_WINDOW_ROTATION_
3798 if ((e_config->wm_win_rotation) &&
3799 ((bd->client.e.state.rot.support) ||
3800 (bd->client.e.state.rot.app_set)))
3802 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3803 int rotation = _e_border_rotation_angle_get(bd);
3804 if (rotation != -1) e_border_rotation_set(bd, rotation);
3808 if (e_config->transient.iconify)
3810 _e_border_deiconify_approve_send(bd, bd_ancestor);
3813 if (bd->client.e.state.deiconify_approve.support)
3815 ELBF(ELBT_BD, 0, bd->client.win,
3816 "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
3818 ecore_x_client_message32_send(bd->client.win,
3819 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3820 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3821 bd->client.win, 0, 0, 0, 0);
3822 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3829 e_border_uniconify(E_Border *bd)
3832 E_Event_Border_Uniconify *ev;
3833 unsigned int iconic;
3836 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3838 #ifdef _F_DEICONIFY_APPROVE_
3839 if (e_config->deiconify_approve)
3841 if (bd->client.e.state.deiconify_approve.support)
3843 if (bd->client.e.state.deiconify_approve.wait_timer)
3845 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3848 if (bd->client.e.state.deiconify_approve.render_done == 0)
3850 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3851 _e_border_deiconify_approve_send_all_transient(bd);
3855 bd->client.e.state.deiconify_approve.render_done = 0;
3859 #if _F_ZONE_WINDOW_ROTATION_
3860 if (!bd->client.win)
3862 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3867 if (bd->shading) return;
3868 ecore_x_window_shadow_tree_flush();
3873 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3874 desk = e_desk_current_get(bd->desk->zone);
3875 #ifdef _F_USE_EXTENDED_ICONIFY_
3876 if (e_manager_comp_evas_get(bd->zone->container->manager))
3878 if (bd->await_hide_event > 0)
3879 bd->await_hide_event--;
3882 e_border_desk_set(bd, desk);
3884 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3887 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3889 ev = E_NEW(E_Event_Border_Uniconify, 1);
3891 e_object_ref(E_OBJECT(bd));
3892 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3893 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3895 if (e_config->transient.iconify)
3899 Eina_List *list = _e_border_sub_borders_new(bd);
3901 EINA_LIST_FOREACH(list, l, child)
3903 e_border_uniconify(child);
3905 eina_list_free(list);
3907 e_remember_update(bd);
3911 e_border_stick(E_Border *bd)
3913 E_Event_Border_Stick *ev;
3916 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3917 if (bd->sticky) return;
3919 e_hints_window_sticky_set(bd, 1);
3922 if (e_config->transient.desktop)
3926 Eina_List *list = _e_border_sub_borders_new(bd);
3928 EINA_LIST_FOREACH(list, l, child)
3931 e_hints_window_sticky_set(child, 1);
3932 e_border_show(child);
3934 eina_list_free(list);
3937 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3938 ev = E_NEW(E_Event_Border_Stick, 1);
3940 e_object_ref(E_OBJECT(bd));
3941 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3942 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3943 e_remember_update(bd);
3947 e_border_unstick(E_Border *bd)
3949 E_Event_Border_Unstick *ev;
3952 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3953 /* Set the desk before we unstick the border */
3954 if (!bd->sticky) return;
3956 e_hints_window_sticky_set(bd, 0);
3958 if (e_config->transient.desktop)
3962 Eina_List *list = _e_border_sub_borders_new(bd);
3964 EINA_LIST_FOREACH(list, l, child)
3967 e_hints_window_sticky_set(child, 0);
3969 eina_list_free(list);
3972 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3973 ev = E_NEW(E_Event_Border_Unstick, 1);
3975 e_object_ref(E_OBJECT(bd));
3976 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3977 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3979 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3980 e_remember_update(bd);
3984 e_border_pinned_set(E_Border *bd,
3992 bd->borderless = set;
3993 bd->user_skip_winlist = set;
3997 stacking = E_STACKING_BELOW;
4002 stacking = E_STACKING_NONE;
4005 e_border_layer_set(bd, layer);
4006 e_hints_window_stacking_set(bd, stacking);
4008 bd->client.border.changed = 1;
4014 e_border_find_by_client_window(Ecore_X_Window win)
4018 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4019 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4020 (bd->client.win == win))
4026 e_border_find_all_by_client_window(Ecore_X_Window win)
4030 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4031 if ((bd) && (bd->client.win == win))
4037 e_border_find_by_frame_window(Ecore_X_Window win)
4041 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4042 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4043 (bd->bg_win == win))
4049 e_border_find_by_window(Ecore_X_Window win)
4053 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4054 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4061 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4066 EINA_LIST_FOREACH(borders, l, bd)
4068 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4069 (bd->client.netwm.sync.alarm == al))
4076 e_border_focused_get(void)
4082 _e_border_shape_input_rectangle_set(E_Border* bd)
4086 if ((bd->visible) && (bd->shaped_input))
4088 Ecore_X_Rectangle rects[4];
4089 Ecore_X_Window twin, twin2;
4092 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4093 0, 0, bd->w, bd->h);
4096 rects[0].width = bd->w;
4097 rects[0].height = bd->client_inset.t;
4099 rects[1].y = bd->client_inset.t;
4100 rects[1].width = bd->client_inset.l;
4101 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4102 rects[2].x = bd->w - bd->client_inset.r;
4103 rects[2].y = bd->client_inset.t;
4104 rects[2].width = bd->client_inset.r;
4105 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4107 rects[3].y = bd->h - bd->client_inset.b;
4108 rects[3].width = bd->w;
4109 rects[3].height = bd->client_inset.b;
4110 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4112 twin2 = ecore_x_window_override_new
4113 (bd->zone->container->scratch_win, 0, 0,
4114 bd->w - bd->client_inset.l - bd->client_inset.r,
4115 bd->h - bd->client_inset.t - bd->client_inset.b);
4118 if ((bd->shading) || (bd->shaded))
4120 if (bd->shade.dir == E_DIRECTION_UP)
4121 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4123 else if (bd->shade.dir == E_DIRECTION_LEFT)
4124 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4127 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4129 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4130 bd->w - bd->client_inset.l - bd->client_inset.r,
4131 bd->h - bd->client_inset.t - bd->client_inset.b);
4132 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4134 bd->client_inset.t);
4135 ecore_x_window_shape_input_window_set(bd->win, twin);
4136 ecore_x_window_free(twin2);
4137 ecore_x_window_free(twin);
4141 if (bd->visible) // not shaped input
4143 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4144 ecore_x_composite_window_events_enable(bd->win);
4146 ecore_x_composite_window_events_disable(bd->win);
4150 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4151 ecore_x_composite_window_events_enable(bd->win);
4153 ecore_x_composite_window_events_disable(bd->win);
4159 e_border_idler_before(void)
4168 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4170 EINA_LIST_FOREACH(man->containers, cl, con)
4175 // pass 1 - eval0. fetch properties on new or on change and
4176 // call hooks to decide what to do - maybe move/resize
4177 bl = e_container_border_list_last(con);
4178 while ((bd = e_container_border_list_prev(bl)))
4180 if (bd->changed) _e_border_eval0(bd);
4182 e_container_border_list_free(bl);
4184 // layout hook - this is where a hook gets to figure out what to
4186 _e_border_container_layout_hook(con);
4188 // pass 2 - show windows needing show
4189 bl = e_container_border_list_last(con);
4190 while ((bd = e_container_border_list_prev(bl)))
4192 if ((bd->changes.visible) && (bd->visible) &&
4193 (!bd->new_client) && (!bd->changes.pos) &&
4194 (!bd->changes.size))
4197 bd->changes.visible = 0;
4200 e_container_border_list_free(bl);
4202 // pass 3 - hide windows needing hide and eval (main eval)
4203 bl = e_container_border_list_first(con);
4204 while ((bd = e_container_border_list_next(bl)))
4206 if (e_object_is_del(E_OBJECT(bd))) continue;
4208 if ((bd->changes.visible) && (!bd->visible))
4211 bd->changes.visible = 0;
4214 if (bd->changed) _e_border_eval(bd);
4216 if ((bd->changes.visible) && (bd->visible))
4219 bd->changes.visible = 0;
4222 e_container_border_list_free(bl);
4228 E_Border *bd = NULL, *bd2;
4230 EINA_LIST_FREE(focus_next, bd2)
4231 if ((!bd) && (bd2->visible)) bd = bd2;
4235 /* TODO revert focus when lost here ? */
4241 /* already focused. but anyway dont be so strict, this
4242 fcks up illume setting focus on internal windows */
4247 focus_time = ecore_x_current_time_get();
4251 if ((bd->client.icccm.take_focus) &&
4252 (bd->client.icccm.accepts_focus))
4254 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4255 /* TODO what if the client didn't take focus ? */
4257 else if (!bd->client.icccm.accepts_focus)
4259 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4261 else if (!bd->client.icccm.take_focus)
4263 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4264 /* e_border_focus_set(bd, 1, 0); */
4268 #ifdef _F_ZONE_WINDOW_ROTATION_
4269 if ((e_config->wm_win_rotation) &&
4272 Ecore_X_Event_Client_Message *msg = NULL;
4274 EINA_LIST_FREE(rot.msgs, msg)
4276 t = msg->message_type;
4277 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4279 if ((rot.vkbd_ctrl_win) &&
4280 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4283 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4284 if (rot.vkbd_show_prepare_timer)
4285 _e_border_vkbd_show(rot.vkbd);
4287 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4290 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4292 if ((rot.vkbd_ctrl_win) &&
4293 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4296 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4297 if (rot.vkbd_hide_prepare_timer)
4299 _e_border_vkbd_hide(rot.vkbd);
4300 rot.vkbd_hide_prepare_timer = NULL;
4301 e_object_unref(E_OBJECT(rot.vkbd));
4304 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4307 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4309 rot.vkbd_ctrl_win = msg->data.l[0];
4310 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4312 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4314 if ((rot.vkbd_ctrl_win) &&
4315 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4317 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4318 E_Manager *m = e_manager_current_get();
4319 E_Zone *zone = NULL;
4320 if (m) zone = e_util_zone_current_get(m);
4321 if ((zone) && (rot.wait_prepare_done))
4325 _e_border_rotation_change_request(zone);
4326 if (rot.prepare_timer)
4327 ecore_timer_del(rot.prepare_timer);
4328 rot.prepare_timer = NULL;
4329 rot.wait_prepare_done = EINA_FALSE;
4338 rot.fetch = EINA_FALSE;
4344 e_border_client_list(void)
4346 /* FIXME: This should be a somewhat ordered list */
4350 static Ecore_X_Window action_input_win = 0;
4351 static E_Border *action_border = NULL;
4352 static Ecore_Event_Handler *action_handler_key = NULL;
4353 static Ecore_Event_Handler *action_handler_mouse = NULL;
4354 static Ecore_Timer *action_timer = NULL;
4355 static Ecore_X_Rectangle action_orig;
4358 _e_border_show(E_Border *bd)
4363 ecore_evas_show(bd->bg_ecore_evas);
4371 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4373 _e_border_shape_input_rectangle_set(bd);
4375 // ecore_x_composite_window_events_enable(bd->win);
4376 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4379 ecore_x_window_show(bd->win);
4381 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4382 ecore_x_window_show(tmp->win);
4386 _e_border_hide(E_Border *bd)
4391 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4393 ecore_x_window_hide(bd->win);
4394 ecore_evas_hide(bd->bg_ecore_evas);
4396 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4397 ecore_x_window_hide(tmp->win);
4401 ecore_x_composite_window_events_disable(bd->win);
4402 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4407 _e_border_action_input_win_del(void)
4409 if (!action_input_win)
4412 e_grabinput_release(action_input_win, action_input_win);
4413 ecore_x_window_free(action_input_win);
4414 action_input_win = 0;
4419 _e_border_action_input_win_new(E_Border *bd)
4421 if (!action_input_win)
4423 Ecore_X_Window parent = bd->zone->container->win;
4424 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4425 if (!action_input_win)
4429 ecore_x_window_show(action_input_win);
4430 if (e_grabinput_get(action_input_win, 0, action_input_win))
4433 _e_border_action_input_win_del();
4438 _e_border_action_finish(void)
4440 _e_border_action_input_win_del();
4444 ecore_timer_del(action_timer);
4445 action_timer = NULL;
4448 if (action_handler_key)
4450 ecore_event_handler_del(action_handler_key);
4451 action_handler_key = NULL;
4454 if (action_handler_mouse)
4456 ecore_event_handler_del(action_handler_mouse);
4457 action_handler_mouse = NULL;
4460 action_border = NULL;
4464 _e_border_action_init(E_Border *bd)
4466 action_orig.x = bd->x;
4467 action_orig.y = bd->y;
4468 action_orig.width = bd->w;
4469 action_orig.height = bd->h;
4475 _e_border_action_restore_orig(E_Border *bd)
4477 if (action_border != bd)
4480 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4484 _e_border_key_down_modifier_apply(int modifier,
4487 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4489 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4502 _e_border_action_move_timeout(void *data __UNUSED__)
4504 _e_border_move_end(action_border);
4505 _e_border_action_finish();
4506 return ECORE_CALLBACK_CANCEL;
4510 _e_border_action_move_timeout_add(void)
4513 ecore_timer_del(action_timer);
4514 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4518 _e_border_move_key_down(void *data __UNUSED__,
4519 int type __UNUSED__,
4522 Ecore_Event_Key *ev = event;
4525 if (ev->event_window != action_input_win)
4526 return ECORE_CALLBACK_PASS_ON;
4529 fputs("ERROR: no action_border!\n", stderr);
4533 x = action_border->x;
4534 y = action_border->y;
4536 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4537 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4538 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4539 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4540 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4541 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4542 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4543 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4544 else if (strcmp(ev->key, "Return") == 0)
4546 else if (strcmp(ev->key, "Escape") == 0)
4548 _e_border_action_restore_orig(action_border);
4551 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4552 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4555 e_border_move(action_border, x, y);
4556 _e_border_action_move_timeout_add();
4558 return ECORE_CALLBACK_PASS_ON;
4561 _e_border_move_end(action_border);
4562 _e_border_action_finish();
4563 return ECORE_CALLBACK_DONE;
4567 _e_border_move_mouse_down(void *data __UNUSED__,
4568 int type __UNUSED__,
4571 Ecore_Event_Mouse_Button *ev = event;
4573 if (ev->event_window != action_input_win)
4574 return ECORE_CALLBACK_PASS_ON;
4577 fputs("ERROR: no action_border!\n", stderr);
4579 _e_border_move_end(action_border);
4580 _e_border_action_finish();
4581 return ECORE_CALLBACK_DONE;
4585 e_border_act_move_keyboard(E_Border *bd)
4590 if (!_e_border_move_begin(bd))
4593 if (!_e_border_action_input_win_new(bd))
4595 _e_border_move_end(bd);
4599 _e_border_action_init(bd);
4600 _e_border_action_move_timeout_add();
4601 _e_border_move_update(bd);
4603 if (action_handler_key)
4604 ecore_event_handler_del(action_handler_key);
4605 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4607 if (action_handler_mouse)
4608 ecore_event_handler_del(action_handler_mouse);
4609 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4613 _e_border_action_resize_timeout(void *data __UNUSED__)
4615 _e_border_resize_end(action_border);
4616 _e_border_action_finish();
4617 return ECORE_CALLBACK_CANCEL;
4621 _e_border_action_resize_timeout_add(void)
4624 ecore_timer_del(action_timer);
4625 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4629 _e_border_resize_key_down(void *data __UNUSED__,
4630 int type __UNUSED__,
4633 Ecore_Event_Key *ev = event;
4636 if (ev->event_window != action_input_win)
4637 return ECORE_CALLBACK_PASS_ON;
4640 fputs("ERROR: no action_border!\n", stderr);
4644 w = action_border->w;
4645 h = action_border->h;
4647 dx = e_config->border_keyboard.resize.dx;
4648 if (dx < action_border->client.icccm.step_w)
4649 dx = action_border->client.icccm.step_w;
4650 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4651 if (dx < action_border->client.icccm.step_w)
4652 dx = action_border->client.icccm.step_w;
4654 dy = e_config->border_keyboard.resize.dy;
4655 if (dy < action_border->client.icccm.step_h)
4656 dy = action_border->client.icccm.step_h;
4657 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4658 if (dy < action_border->client.icccm.step_h)
4659 dy = action_border->client.icccm.step_h;
4661 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4663 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4665 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4667 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4669 else if (strcmp(ev->key, "Return") == 0)
4671 else if (strcmp(ev->key, "Escape") == 0)
4673 _e_border_action_restore_orig(action_border);
4676 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4677 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4680 e_border_resize_limit(action_border, &w, &h);
4681 e_border_resize(action_border, w, h);
4682 _e_border_action_resize_timeout_add();
4684 return ECORE_CALLBACK_PASS_ON;
4687 _e_border_resize_end(action_border);
4688 _e_border_action_finish();
4689 return ECORE_CALLBACK_DONE;
4693 _e_border_resize_mouse_down(void *data __UNUSED__,
4694 int type __UNUSED__,
4697 Ecore_Event_Mouse_Button *ev = event;
4699 if (ev->event_window != action_input_win)
4700 return ECORE_CALLBACK_PASS_ON;
4703 fputs("ERROR: no action_border!\n", stderr);
4705 _e_border_resize_end(action_border);
4706 _e_border_action_finish();
4707 return ECORE_CALLBACK_DONE;
4711 e_border_act_resize_keyboard(E_Border *bd)
4716 if (!_e_border_resize_begin(bd))
4719 if (!_e_border_action_input_win_new(bd))
4721 _e_border_resize_end(bd);
4725 _e_border_action_init(bd);
4726 _e_border_action_resize_timeout_add();
4727 _e_border_resize_update(bd);
4729 if (action_handler_key)
4730 ecore_event_handler_del(action_handler_key);
4731 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4733 if (action_handler_mouse)
4734 ecore_event_handler_del(action_handler_mouse);
4735 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4739 e_border_act_move_begin(E_Border *bd,
4740 Ecore_Event_Mouse_Button *ev)
4743 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4744 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4745 if (!_e_border_move_begin(bd))
4748 e_zone_edge_disable();
4750 _e_border_pointer_move_begin(bd);
4755 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4756 _e_border_moveinfo_gather(bd, source);
4761 e_border_act_move_end(E_Border *bd,
4762 Ecore_Event_Mouse_Button *ev __UNUSED__)
4765 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4766 if (!bd->moving) return;
4768 _e_border_pointer_move_end(bd);
4769 e_zone_edge_enable();
4770 _e_border_move_end(bd);
4771 e_zone_flip_coords_handle(bd->zone, -1, -1);
4775 e_border_act_resize_begin(E_Border *bd,
4776 Ecore_Event_Mouse_Button *ev)
4779 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4780 if (bd->lock_user_size) return;
4781 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4782 if (!_e_border_resize_begin(bd))
4784 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4786 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4788 bd->resize_mode = RESIZE_TL;
4789 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4793 bd->resize_mode = RESIZE_BL;
4794 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4799 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4801 bd->resize_mode = RESIZE_TR;
4802 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4806 bd->resize_mode = RESIZE_BR;
4807 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4810 _e_border_pointer_resize_begin(bd);
4815 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4816 _e_border_moveinfo_gather(bd, source);
4821 e_border_act_resize_end(E_Border *bd,
4822 Ecore_Event_Mouse_Button *ev __UNUSED__)
4825 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4826 if (bd->resize_mode != RESIZE_NONE)
4828 _e_border_pointer_resize_end(bd);
4829 bd->resize_mode = RESIZE_NONE;
4830 _e_border_resize_end(bd);
4831 bd->changes.reset_gravity = 1;
4837 e_border_act_menu_begin(E_Border *bd,
4838 Ecore_Event_Mouse_Button *ev,
4842 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4845 e_int_border_menu_show(bd,
4846 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4847 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4854 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4855 e_int_border_menu_show(bd, x, y, key, 0);
4860 e_border_act_close_begin(E_Border *bd)
4863 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4864 if (bd->lock_close) return;
4865 if (bd->client.icccm.delete_request)
4867 bd->delete_requested = 1;
4868 ecore_x_window_delete_request_send(bd->client.win);
4869 if (bd->client.netwm.ping)
4872 else if (e_config->kill_if_close_not_possible)
4874 e_border_act_kill_begin(bd);
4879 e_border_act_kill_begin(E_Border *bd)
4882 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4883 if (bd->internal) return;
4884 if (bd->lock_close) return;
4885 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4887 kill(bd->client.netwm.pid, SIGINT);
4888 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4889 _e_border_cb_kill_timer, bd);
4893 if (!bd->internal) ecore_x_kill(bd->client.win);
4898 e_border_icon_add(E_Border *bd,
4903 E_OBJECT_CHECK_RETURN(bd, NULL);
4904 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4909 if (!bd->internal_icon)
4911 o = e_icon_add(evas);
4912 e_util_icon_theme_set(o, "enlightenment");
4916 if (!bd->internal_icon_key)
4920 ext = strrchr(bd->internal_icon, '.');
4921 if ((ext) && ((!strcmp(ext, ".edj"))))
4923 o = edje_object_add(evas);
4924 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4925 e_util_icon_theme_set(o, "enlightenment");
4929 o = e_icon_add(evas);
4930 e_icon_file_set(o, bd->internal_icon);
4934 o = e_icon_add(evas);
4935 if (!e_util_icon_theme_set(o, bd->internal_icon))
4936 e_util_icon_theme_set(o, "enlightenment");
4941 o = edje_object_add(evas);
4942 edje_object_file_set(o, bd->internal_icon,
4943 bd->internal_icon_key);
4948 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4950 if (bd->client.netwm.icons)
4952 o = e_icon_add(evas);
4953 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4954 bd->client.netwm.icons[0].width,
4955 bd->client.netwm.icons[0].height);
4956 e_icon_alpha_set(o, 1);
4962 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4964 o = e_icon_add(evas);
4967 e_icon_fdo_icon_set(o, bd->desktop->icon);
4971 else if (bd->client.netwm.icons)
4973 o = e_icon_add(evas);
4974 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4975 bd->client.netwm.icons[0].width,
4976 bd->client.netwm.icons[0].height);
4977 e_icon_alpha_set(o, 1);
4982 o = e_icon_add(evas);
4983 e_util_icon_theme_set(o, "unknown");
4988 e_border_button_bindings_ungrab_all(void)
4993 EINA_LIST_FOREACH(borders, l, bd)
4995 e_focus_setdown(bd);
4996 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4997 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5002 e_border_button_bindings_grab_all(void)
5007 EINA_LIST_FOREACH(borders, l, bd)
5009 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5010 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5016 e_border_focus_stack_get(void)
5022 e_border_raise_stack_get(void)
5028 e_border_lost_windows_get(E_Zone *zone)
5030 Eina_List *list = NULL, *l;
5032 int loss_overlap = 5;
5034 E_OBJECT_CHECK_RETURN(zone, NULL);
5035 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5036 EINA_LIST_FOREACH(borders, l, bd)
5041 if ((bd->zone != zone) ||
5042 (bd->zone->container != zone->container))
5045 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5046 bd->zone->y + loss_overlap,
5047 bd->zone->w - (2 * loss_overlap),
5048 bd->zone->h - (2 * loss_overlap),
5049 bd->x, bd->y, bd->w, bd->h))
5051 list = eina_list_append(list, bd);
5053 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5054 bd->zone->w, bd->zone->h,
5055 bd->x, bd->y, bd->w, bd->h)) &&
5058 Ecore_X_Rectangle *rect;
5061 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5067 for (i = 0; i < num; i++)
5069 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5070 bd->zone->y + loss_overlap,
5071 bd->zone->w - (2 * loss_overlap),
5072 bd->zone->h - (2 * loss_overlap),
5073 rect[i].x, rect[i].y,
5074 (int)rect[i].width, (int)rect[i].height))
5082 list = eina_list_append(list, bd);
5090 e_border_ping(E_Border *bd)
5093 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5094 if (!e_config->ping_clients) return;
5096 ecore_x_netwm_ping_send(bd->client.win);
5097 bd->ping = ecore_loop_time_get();
5098 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5099 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5100 e_config->ping_clients_interval,
5101 _e_border_cb_ping_poller, bd);
5105 e_border_move_cancel(void)
5109 if (bdmove->cur_mouse_action)
5114 e_object_ref(E_OBJECT(bd));
5115 if (bd->cur_mouse_action->func.end_mouse)
5116 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5117 else if (bd->cur_mouse_action->func.end)
5118 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5119 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5120 bd->cur_mouse_action = NULL;
5121 e_object_unref(E_OBJECT(bd));
5124 _e_border_move_end(bdmove);
5129 e_border_resize_cancel(void)
5133 if (bdresize->cur_mouse_action)
5138 e_object_ref(E_OBJECT(bd));
5139 if (bd->cur_mouse_action->func.end_mouse)
5140 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5141 else if (bd->cur_mouse_action->func.end)
5142 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5143 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5144 bd->cur_mouse_action = NULL;
5145 e_object_unref(E_OBJECT(bd));
5149 bdresize->resize_mode = RESIZE_NONE;
5150 _e_border_resize_end(bdresize);
5156 e_border_frame_recalc(E_Border *bd)
5158 if (!bd->bg_object) return;
5160 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5161 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5163 _e_border_client_inset_calc(bd);
5165 bd->w += (bd->client_inset.l + bd->client_inset.r);
5166 bd->h += (bd->client_inset.t + bd->client_inset.b);
5169 bd->changes.size = 1;
5170 if ((bd->shaped) || (bd->client.shaped))
5172 bd->need_shape_merge = 1;
5173 bd->need_shape_export = 1;
5175 if (bd->shaped_input)
5177 bd->need_shape_merge = 1;
5179 _e_border_client_move_resize_send(bd);
5183 e_border_immortal_windows_get(void)
5185 Eina_List *list = NULL, *l;
5188 EINA_LIST_FOREACH(borders, l, bd)
5191 list = eina_list_append(list, bd);
5197 e_border_name_get(const E_Border *bd)
5199 E_OBJECT_CHECK_RETURN(bd, "");
5200 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5201 if (bd->client.netwm.name)
5202 return bd->client.netwm.name;
5203 else if (bd->client.icccm.title)
5204 return bd->client.icccm.title;
5209 e_border_signal_move_begin(E_Border *bd,
5211 const char *src __UNUSED__)
5214 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5216 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5217 if (!_e_border_move_begin(bd)) return;
5219 _e_border_pointer_move_begin(bd);
5220 e_zone_edge_disable();
5221 _e_border_moveinfo_gather(bd, sig);
5222 if (bd->cur_mouse_action)
5224 if ((!bd->cur_mouse_action->func.end_mouse) &&
5225 (!bd->cur_mouse_action->func.end))
5226 bd->cur_mouse_action = NULL;
5228 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5230 bd->cur_mouse_action = e_action_find("window_move");
5231 if (bd->cur_mouse_action)
5232 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5236 e_border_signal_move_end(E_Border *bd,
5237 const char *sig __UNUSED__,
5238 const char *src __UNUSED__)
5241 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5242 if (!bd->moving) return;
5244 _e_border_pointer_move_end(bd);
5245 e_zone_edge_enable();
5246 _e_border_move_end(bd);
5247 e_zone_flip_coords_handle(bd->zone, -1, -1);
5251 e_border_resizing_get(E_Border *bd)
5253 E_OBJECT_CHECK_RETURN(bd, 0);
5254 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5255 if (bd->resize_mode == RESIZE_NONE) return 0;
5260 e_border_signal_resize_begin(E_Border *bd,
5263 const char *src __UNUSED__)
5265 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5266 int resize_mode = RESIZE_BR;
5269 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5271 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5272 if (!_e_border_resize_begin(bd))
5274 if (!strcmp(dir, "tl"))
5276 resize_mode = RESIZE_TL;
5277 grav = ECORE_X_GRAVITY_SE;
5279 else if (!strcmp(dir, "t"))
5281 resize_mode = RESIZE_T;
5282 grav = ECORE_X_GRAVITY_S;
5284 else if (!strcmp(dir, "tr"))
5286 resize_mode = RESIZE_TR;
5287 grav = ECORE_X_GRAVITY_SW;
5289 else if (!strcmp(dir, "r"))
5291 resize_mode = RESIZE_R;
5292 grav = ECORE_X_GRAVITY_W;
5294 else if (!strcmp(dir, "br"))
5296 resize_mode = RESIZE_BR;
5297 grav = ECORE_X_GRAVITY_NW;
5299 else if (!strcmp(dir, "b"))
5301 resize_mode = RESIZE_B;
5302 grav = ECORE_X_GRAVITY_N;
5304 else if (!strcmp(dir, "bl"))
5306 resize_mode = RESIZE_BL;
5307 grav = ECORE_X_GRAVITY_NE;
5309 else if (!strcmp(dir, "l"))
5311 resize_mode = RESIZE_L;
5312 grav = ECORE_X_GRAVITY_E;
5314 bd->resize_mode = resize_mode;
5315 _e_border_pointer_resize_begin(bd);
5316 _e_border_moveinfo_gather(bd, sig);
5318 if (bd->cur_mouse_action)
5320 if ((!bd->cur_mouse_action->func.end_mouse) &&
5321 (!bd->cur_mouse_action->func.end))
5322 bd->cur_mouse_action = NULL;
5324 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5326 bd->cur_mouse_action = e_action_find("window_resize");
5327 if (bd->cur_mouse_action)
5328 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5332 e_border_signal_resize_end(E_Border *bd,
5333 const char *dir __UNUSED__,
5334 const char *sig __UNUSED__,
5335 const char *src __UNUSED__)
5338 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5339 if (bd->resize_mode == RESIZE_NONE) return;
5340 _e_border_resize_handle(bd);
5341 _e_border_pointer_resize_end(bd);
5342 bd->resize_mode = RESIZE_NONE;
5343 _e_border_resize_end(bd);
5344 bd->changes.reset_gravity = 1;
5349 e_border_resize_limit(E_Border *bd,
5356 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5357 *w -= bd->client_inset.l + bd->client_inset.r;
5358 *h -= bd->client_inset.t + bd->client_inset.b;
5361 if ((bd->client.icccm.base_w >= 0) &&
5362 (bd->client.icccm.base_h >= 0))
5366 tw = *w - bd->client.icccm.base_w;
5367 th = *h - bd->client.icccm.base_h;
5370 a = (double)(tw) / (double)(th);
5371 if ((bd->client.icccm.min_aspect != 0.0) &&
5372 (a < bd->client.icccm.min_aspect))
5374 th = tw / bd->client.icccm.max_aspect;
5375 *h = th + bd->client.icccm.base_h;
5377 else if ((bd->client.icccm.max_aspect != 0.0) &&
5378 (a > bd->client.icccm.max_aspect))
5380 tw = th * bd->client.icccm.max_aspect;
5381 *w = tw + bd->client.icccm.base_w;
5386 a = (double)*w / (double)*h;
5387 if ((bd->client.icccm.min_aspect != 0.0) &&
5388 (a < bd->client.icccm.min_aspect))
5389 *h = *w / bd->client.icccm.min_aspect;
5390 else if ((bd->client.icccm.max_aspect != 0.0) &&
5391 (a > bd->client.icccm.max_aspect))
5392 *w = *h * bd->client.icccm.max_aspect;
5394 if (bd->client.icccm.step_w > 0)
5396 if (bd->client.icccm.base_w >= 0)
5397 *w = bd->client.icccm.base_w +
5398 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5399 bd->client.icccm.step_w);
5401 *w = bd->client.icccm.min_w +
5402 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5403 bd->client.icccm.step_w);
5405 if (bd->client.icccm.step_h > 0)
5407 if (bd->client.icccm.base_h >= 0)
5408 *h = bd->client.icccm.base_h +
5409 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5410 bd->client.icccm.step_h);
5412 *h = bd->client.icccm.min_h +
5413 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5414 bd->client.icccm.step_h);
5420 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5421 else if (*w < bd->client.icccm.min_w)
5422 *w = bd->client.icccm.min_w;
5423 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5424 else if (*h < bd->client.icccm.min_h)
5425 *h = bd->client.icccm.min_h;
5427 *w += bd->client_inset.l + bd->client_inset.r;
5428 *h += bd->client_inset.t + bd->client_inset.b;
5431 /* local subsystem functions */
5433 _e_border_free(E_Border *bd)
5435 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5438 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5440 bd->client.e.state.video_parent_border->client.e.state.video_child =
5442 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5445 if (bd->client.e.state.video_child)
5449 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5451 tmp->client.e.state.video_parent_border = NULL;
5456 efreet_desktop_free(bd->desktop);
5461 ecore_idle_enterer_del(bd->post_job);
5462 bd->post_job = NULL;
5466 e_object_del(E_OBJECT(bd->pointer));
5470 _e_border_resize_end(bd);
5472 _e_border_move_end(bd);
5473 /* TODO: Other states to end before dying? */
5475 if (bd->cur_mouse_action)
5477 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5478 bd->cur_mouse_action = NULL;
5481 E_FREE(bd->shape_rects);
5482 bd->shape_rects_num = 0;
5484 if (bd->dangling_ref_check)
5486 ecore_timer_del(bd->dangling_ref_check);
5487 bd->dangling_ref_check = NULL;
5492 ecore_timer_del(bd->kill_timer);
5493 bd->kill_timer = NULL;
5495 if (bd->ping_poller)
5497 ecore_poller_del(bd->ping_poller);
5498 bd->ping_poller = NULL;
5500 E_FREE_LIST(bd->pending_move_resize, free);
5502 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5503 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5505 if (bd->border_locks_dialog)
5507 e_object_del(E_OBJECT(bd->border_locks_dialog));
5508 bd->border_locks_dialog = NULL;
5510 if (bd->border_remember_dialog)
5512 e_object_del(E_OBJECT(bd->border_remember_dialog));
5513 bd->border_remember_dialog = NULL;
5515 if (bd->border_border_dialog)
5517 e_object_del(E_OBJECT(bd->border_border_dialog));
5518 bd->border_border_dialog = NULL;
5520 if (bd->border_prop_dialog)
5522 e_object_del(E_OBJECT(bd->border_prop_dialog));
5523 bd->border_prop_dialog = NULL;
5526 e_int_border_menu_del(bd);
5531 focus_next = eina_list_remove(focus_next, bd);
5533 if ((focused == bd) ||
5534 (e_grabinput_last_focus_win_get() == bd->client.win))
5536 if ((!focus_next) && (!focusing))
5538 e_grabinput_focus(bd->zone->container->bg_win,
5539 E_FOCUS_METHOD_PASSIVE);
5540 e_hints_active_window_set(bd->zone->container->manager, NULL);
5545 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5551 bd->remember = NULL;
5552 e_remember_unuse(rem);
5554 if (!bd->already_unparented)
5556 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5557 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5558 ecore_x_window_save_set_del(bd->client.win);
5559 bd->already_unparented = 1;
5561 if (bd->group) eina_list_free(bd->group);
5562 if (bd->transients) eina_list_free(bd->transients);
5563 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5564 if (bd->client.netwm.icons)
5567 for (i = 0; i < bd->client.netwm.num_icons; i++)
5568 free(bd->client.netwm.icons[i].data);
5569 free(bd->client.netwm.icons);
5571 if (bd->client.netwm.extra_types)
5572 free(bd->client.netwm.extra_types);
5573 if (bd->client.border.name)
5574 eina_stringshare_del(bd->client.border.name);
5576 eina_stringshare_del(bd->bordername);
5577 if (bd->client.icccm.name)
5578 eina_stringshare_del(bd->client.icccm.name);
5579 if (bd->client.icccm.class)
5581 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5582 e_bindings_mapping_change_enable(EINA_TRUE);
5583 eina_stringshare_del(bd->client.icccm.class);
5585 if (bd->client.icccm.title)
5586 eina_stringshare_del(bd->client.icccm.title);
5587 if (bd->client.icccm.icon_name)
5588 eina_stringshare_del(bd->client.icccm.icon_name);
5589 if (bd->client.icccm.machine)
5590 eina_stringshare_del(bd->client.icccm.machine);
5591 if (bd->client.icccm.window_role)
5592 eina_stringshare_del(bd->client.icccm.window_role);
5594 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5598 for (i = 0; i < bd->client.icccm.command.argc; i++)
5599 free(bd->client.icccm.command.argv[i]);
5600 free(bd->client.icccm.command.argv);
5602 if (bd->client.netwm.name)
5603 eina_stringshare_del(bd->client.netwm.name);
5604 if (bd->client.netwm.icon_name)
5605 eina_stringshare_del(bd->client.netwm.icon_name);
5606 e_object_del(E_OBJECT(bd->shape));
5607 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5608 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5609 if (bd->icon_object) evas_object_del(bd->icon_object);
5610 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5611 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5613 if (str) eina_stringshare_del(str);
5615 bd->client.e.state.profiles = NULL;
5616 if (bd->client.e.state.profile)
5617 eina_stringshare_del(bd->client.e.state.profile);
5618 bd->client.e.state.profile = NULL;
5620 #ifdef _F_ZONE_WINDOW_ROTATION_
5621 if (e_config->wm_win_rotation)
5623 bd->client.e.fetch.rot.app_set = 0;
5624 bd->client.e.state.rot.preferred_rot = -1;
5626 if (bd->client.e.state.rot.available_rots)
5627 E_FREE(bd->client.e.state.rot.available_rots);
5629 _e_border_rotation_list_remove(bd);
5630 if ((rot.vkbd) && (rot.vkbd == bd))
5632 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5634 if (rot.vkbd_ctrl_win)
5636 ELB(ELBT_BD, "SET KBD_OFF", 0);
5637 ecore_x_e_virtual_keyboard_state_set
5638 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5641 rot.vkbd_hide_prepare_done = EINA_FALSE;
5642 if (rot.vkbd_hide_prepare_timer)
5643 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5644 rot.vkbd_hide_prepare_timer = NULL;
5645 if (rot.vkbd_hide_timer)
5646 ecore_timer_del(rot.vkbd_hide_timer);
5647 rot.vkbd_hide_timer = NULL;
5649 rot.vkbd_show_prepare_done = EINA_FALSE;
5650 if (rot.vkbd_show_prepare_timer)
5651 ecore_timer_del(rot.vkbd_show_prepare_timer);
5652 rot.vkbd_show_prepare_timer = NULL;
5653 if (rot.vkbd_show_timer)
5654 ecore_timer_del(rot.vkbd_show_timer);
5655 rot.vkbd_show_timer = NULL;
5657 else if ((rot.vkbd_prediction) &&
5658 (rot.vkbd_prediction == bd))
5659 rot.vkbd_prediction = NULL;
5662 evas_object_del(bd->bg_object);
5663 e_canvas_del(bd->bg_ecore_evas);
5664 ecore_evas_free(bd->bg_ecore_evas);
5665 ecore_x_window_free(bd->client.shell_win);
5666 e_focus_setdown(bd);
5667 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5668 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5669 ecore_x_window_free(bd->win);
5671 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5672 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5673 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5674 borders = eina_list_remove(borders, bd);
5675 focus_stack = eina_list_remove(focus_stack, bd);
5676 raise_stack = eina_list_remove(raise_stack, bd);
5678 e_container_border_remove(bd);
5684 _e_border_del_dangling_ref_check(void *data)
5690 printf("EEK EEK border still around 1 second after being deleted!\n");
5691 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5692 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5693 bd->client.icccm.name, bd->client.icccm.class);
5694 // e_object_breadcrumb_debug(E_OBJECT(bd));
5701 _e_border_del(E_Border *bd)
5703 E_Event_Border_Remove *ev;
5706 #ifdef _F_BORDER_HOOK_PATCH_
5707 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5718 focus_next = eina_list_remove(focus_next, bd);
5720 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5722 if ((drag_border) && (drag_border->data == bd))
5724 e_object_del(E_OBJECT(drag_border));
5727 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5729 if (bd->border_locks_dialog)
5731 e_object_del(E_OBJECT(bd->border_locks_dialog));
5732 bd->border_locks_dialog = NULL;
5734 if (bd->border_remember_dialog)
5736 e_object_del(E_OBJECT(bd->border_remember_dialog));
5737 bd->border_remember_dialog = NULL;
5739 if (bd->border_border_dialog)
5741 e_object_del(E_OBJECT(bd->border_border_dialog));
5742 bd->border_border_dialog = NULL;
5744 if (bd->border_prop_dialog)
5746 e_object_del(E_OBJECT(bd->border_prop_dialog));
5747 bd->border_prop_dialog = NULL;
5750 e_int_border_menu_del(bd);
5752 if (bd->raise_timer)
5754 ecore_timer_del(bd->raise_timer);
5755 bd->raise_timer = NULL;
5757 if (!bd->already_unparented)
5759 ecore_x_window_reparent(bd->client.win,
5760 bd->zone->container->manager->root,
5761 bd->x + bd->client_inset.l,
5762 bd->y + bd->client_inset.t);
5763 ecore_x_window_save_set_del(bd->client.win);
5764 bd->already_unparented = 1;
5765 // bd->client.win = 0;
5767 bd->already_unparented = 1;
5769 if ((!bd->new_client) && (!stopping))
5771 ev = E_NEW(E_Event_Border_Remove, 1);
5773 e_object_ref(E_OBJECT(bd));
5774 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5775 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5780 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5781 if (bd->parent->modal == bd)
5783 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5784 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5785 bd->parent->lock_close = 0;
5786 bd->parent->saved.event_mask = 0;
5787 bd->parent->modal = NULL;
5791 EINA_LIST_FREE(bd->transients, child)
5793 child->parent = NULL;
5796 #ifdef _F_DEICONIFY_APPROVE_
5797 bd->client.e.state.deiconify_approve.render_done = 0;
5799 E_Border *ancestor_bd;
5800 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5801 if ((ancestor_bd) &&
5802 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5804 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5805 bd->client.e.state.deiconify_approve.ancestor = NULL;
5807 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5808 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5810 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5812 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5813 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5814 e_border_uniconify(ancestor_bd);
5819 if (bd->client.e.state.deiconify_approve.wait_timer)
5821 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5822 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5825 if (bd->client.e.state.deiconify_approve.req_list)
5827 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5829 child->client.e.state.deiconify_approve.render_done = 0;
5830 child->client.e.state.deiconify_approve.ancestor = NULL;
5835 #ifdef _F_ZONE_WINDOW_ROTATION_
5836 if (rot.list) _e_border_rotation_list_remove(bd);
5840 E_Border_Rotation_Info *info = NULL;
5842 EINA_LIST_FOREACH(rot.async_list, l, info)
5845 rot.async_list = eina_list_remove(rot.async_list, info);
5853 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5854 if (bd->leader->modal == bd)
5855 bd->leader->modal = NULL;
5858 EINA_LIST_FREE(bd->group, child)
5860 child->leader = NULL;
5864 #ifdef PRINT_LOTS_OF_DEBUG
5866 _e_border_print(E_Border *bd,
5875 "\tBorderless: %s\n",
5876 bd, bd->client.icccm.name, bd->client.icccm.title,
5877 bd->borderless ? "TRUE" : "FALSE");
5883 _e_border_cb_window_show_request(void *data __UNUSED__,
5884 int ev_type __UNUSED__,
5889 Ecore_X_Event_Window_Show_Request *e;
5892 bd = e_border_find_by_client_window(e->win);
5893 if (!bd) return ECORE_CALLBACK_PASS_ON;
5895 if ((e_config->wm_win_rotation) &&
5896 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5898 (rot.vkbd_hide_prepare_timer))
5900 con = bd->zone->container;
5901 bd = e_border_new(con, e->win, 0, 0);
5906 if (!bd->lock_client_iconify)
5907 e_border_uniconify(bd);
5911 /* FIXME: make border "urgent" for a bit - it wants attention */
5912 /* e_border_show(bd); */
5913 if (!bd->lock_client_stacking)
5916 return ECORE_CALLBACK_PASS_ON;
5920 _e_border_cb_window_destroy(void *data __UNUSED__,
5921 int ev_type __UNUSED__,
5925 Ecore_X_Event_Window_Destroy *e;
5928 bd = e_border_find_by_client_window(e->win);
5929 if (!bd) return ECORE_CALLBACK_PASS_ON;
5930 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
5931 #ifdef _F_ZONE_WINDOW_ROTATION_
5932 if (e_config->wm_win_rotation)
5934 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5936 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
5937 if (!rot.vkbd_hide_prepare_timer)
5939 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
5940 e_border_hide(bd, 0);
5941 if (!rot.vkbd_hide_prepare_timer)
5943 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
5944 e_object_del(E_OBJECT(bd));
5947 return ECORE_CALLBACK_PASS_ON;
5951 e_border_hide(bd, 0);
5952 e_object_del(E_OBJECT(bd));
5953 return ECORE_CALLBACK_PASS_ON;
5957 _e_border_cb_window_hide(void *data __UNUSED__,
5958 int ev_type __UNUSED__,
5961 E_Border *bd = NULL;
5962 Ecore_X_Event_Window_Hide *e;
5965 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5966 // not interested in hide events from windows other than the window in question
5967 if (e->win != e->event_win)
5969 bd = e_border_find_by_client_window(e->win);
5970 if (!bd) return ECORE_CALLBACK_PASS_ON;
5971 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5975 (bd->zone->container->manager->root == e->event_win)))
5976 return ECORE_CALLBACK_PASS_ON;
5979 if (!bd) bd = e_border_find_by_client_window(e->win);
5980 // printf(" bd = %p\n", bd);
5983 if (ecore_x_window_visible_get(e->win))
5985 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5986 ecore_x_window_hide(e->win);
5988 return ECORE_CALLBACK_PASS_ON;
5991 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5992 if (bd->ignore_first_unmap > 0)
5994 bd->ignore_first_unmap--;
5995 return ECORE_CALLBACK_PASS_ON;
5997 /* Don't delete hidden or iconified windows */
5998 #ifdef _F_USE_EXTENDED_ICONIFY_
5999 if (bd->await_hide_event > 0)
6001 if ((bd->iconic) || (bd->await_hide_event > 0))
6004 // printf(" Don't delete hidden or iconified windows\n");
6005 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6006 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6007 if (bd->await_hide_event > 0)
6009 bd->await_hide_event--;
6013 // printf(" hide really\n");
6014 /* Only hide the border if it is visible */
6015 if (bd->visible) e_border_hide(bd, 1);
6020 // printf(" hide2\n");
6021 #ifdef _F_USE_EXTENDED_ICONIFY_
6029 #ifdef _F_ZONE_WINDOW_ROTATION_
6030 if (e_config->wm_win_rotation)
6032 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6034 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6035 if (!rot.vkbd_hide_prepare_timer)
6037 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6038 e_border_hide(bd, 0);
6039 if (!rot.vkbd_hide_prepare_timer)
6041 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6042 e_object_del(E_OBJECT(bd));
6045 return ECORE_CALLBACK_PASS_ON;
6049 e_border_hide(bd, 0);
6050 e_object_del(E_OBJECT(bd));
6052 return ECORE_CALLBACK_PASS_ON;
6056 _e_border_cb_window_reparent(void *data __UNUSED__,
6057 int ev_type __UNUSED__,
6058 void *ev __UNUSED__)
6062 Ecore_X_Event_Window_Reparent *e;
6065 bd = e_border_find_by_client_window(e->win);
6067 if (e->parent == bd->client.shell_win) return 1;
6068 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6072 e_border_hide(bd, 0);
6073 e_object_del(E_OBJECT(bd));
6075 return ECORE_CALLBACK_PASS_ON;
6079 _e_border_cb_window_configure_request(void *data __UNUSED__,
6080 int ev_type __UNUSED__,
6084 Ecore_X_Event_Window_Configure_Request *e;
6087 bd = e_border_find_by_client_window(e->win);
6090 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6091 if (!e_util_container_window_find(e->win))
6092 ecore_x_window_configure(e->win, e->value_mask,
6093 e->x, e->y, e->w, e->h, e->border,
6094 e->abovewin, e->detail);
6095 return ECORE_CALLBACK_PASS_ON;
6098 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6099 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6105 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6107 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6109 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6110 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6116 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6117 w = e->w + bd->client_inset.l + bd->client_inset.r;
6118 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6119 h = e->h + bd->client_inset.t + bd->client_inset.b;
6120 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6122 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6124 bd->saved.x = x - bd->zone->x;
6125 bd->saved.y = y - bd->zone->y;
6130 e_border_move_resize(bd, x, y, w, h);
6132 else if (!bd->lock_client_location)
6134 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6136 bd->saved.x = x - bd->zone->x;
6137 bd->saved.y = y - bd->zone->y;
6140 e_border_move(bd, x, y);
6142 else if (!bd->lock_client_size)
6144 if ((bd->shaded) || (bd->shading))
6150 if ((bd->shade.dir == E_DIRECTION_UP) ||
6151 (bd->shade.dir == E_DIRECTION_DOWN))
6153 e_border_resize(bd, w, bd->h);
6158 e_border_resize(bd, bd->w, h);
6164 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6170 e_border_resize(bd, w, h);
6176 if (!bd->lock_client_location)
6178 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6180 bd->saved.x = x - bd->zone->x;
6181 bd->saved.y = y - bd->zone->y;
6184 e_border_move(bd, x, y);
6188 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6189 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6195 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6196 w = e->w + bd->client_inset.l + bd->client_inset.r;
6197 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6198 h = e->h + bd->client_inset.t + bd->client_inset.b;
6199 #ifdef _F_ZONE_WINDOW_ROTATION_
6200 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6202 if (!bd->lock_client_size)
6204 if ((bd->shaded) || (bd->shading))
6210 if ((bd->shade.dir == E_DIRECTION_UP) ||
6211 (bd->shade.dir == E_DIRECTION_DOWN))
6213 e_border_resize(bd, w, bd->h);
6218 e_border_resize(bd, bd->w, h);
6224 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6229 zx = zy = zw = zh = 0;
6232 * This code does resize and move a window on a
6233 * X configure request into an useful geometry.
6234 * This is really useful for size jumping file dialogs.
6239 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6241 if (e_config->geometry_auto_resize_limit == 1)
6250 e_border_resize(bd, w, h);
6252 if (e_config->geometry_auto_move == 1)
6254 /* z{x,y,w,h} are only set here; FIXME! */
6257 // move window horizontal if resize to not useful geometry
6258 if (bd->x + bd->w > zx + zw)
6259 rx = zx + zw - bd->w;
6260 else if (bd->x < zx)
6263 // move window vertical if resize to not useful geometry
6264 if (bd->y + bd->h > zy + zh)
6265 ry = zy + zh - bd->h;
6266 else if (bd->y < zy)
6269 e_border_move(bd, rx, ry);
6275 if (!bd->lock_client_stacking)
6277 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6278 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6282 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6284 obd = e_border_find_by_client_window(e->abovewin);
6287 e_border_stack_above(bd, obd);
6291 ecore_x_window_configure(bd->win,
6292 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6293 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6295 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6296 /* FIXME: need to rebuiuld border list from current stacking */
6299 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6301 obd = e_border_find_by_client_window(e->abovewin);
6304 e_border_stack_below(bd, obd);
6308 ecore_x_window_configure(bd->win,
6309 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6310 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6312 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6313 /* FIXME: need to rebuiuld border list from current stacking */
6316 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6320 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6324 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6329 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6331 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6335 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6339 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6343 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6347 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6354 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6355 _e_border_client_move_resize_send(bd);
6356 return ECORE_CALLBACK_PASS_ON;
6360 _e_border_cb_window_resize_request(void *data __UNUSED__,
6361 int ev_type __UNUSED__,
6365 Ecore_X_Event_Window_Resize_Request *e;
6368 bd = e_border_find_by_client_window(e->win);
6371 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6372 ecore_x_window_resize(e->win, e->w, e->h);
6373 return ECORE_CALLBACK_PASS_ON;
6378 w = e->w + bd->client_inset.l + bd->client_inset.r;
6379 h = e->h + bd->client_inset.t + bd->client_inset.b;
6380 if ((bd->shaded) || (bd->shading))
6386 if ((bd->shade.dir == E_DIRECTION_UP) ||
6387 (bd->shade.dir == E_DIRECTION_DOWN))
6389 e_border_resize(bd, w, bd->h);
6394 e_border_resize(bd, bd->w, h);
6399 e_border_resize(bd, w, h);
6402 _e_border_client_move_resize_send(bd);
6403 return ECORE_CALLBACK_PASS_ON;
6407 _e_border_cb_window_gravity(void *data __UNUSED__,
6408 int ev_type __UNUSED__,
6409 void *ev __UNUSED__)
6412 // Ecore_X_Event_Window_Gravity *e;
6415 // bd = e_border_find_by_client_window(e->win);
6416 // if (!bd) return 1;
6421 _e_border_cb_window_stack_request(void *data __UNUSED__,
6422 int ev_type __UNUSED__,
6426 Ecore_X_Event_Window_Stack_Request *e;
6429 bd = e_border_find_by_client_window(e->win);
6432 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6433 if (!e_util_container_window_find(e->win))
6435 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6436 ecore_x_window_raise(e->win);
6437 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6438 ecore_x_window_lower(e->win);
6440 return ECORE_CALLBACK_PASS_ON;
6442 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6444 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6446 return ECORE_CALLBACK_PASS_ON;
6450 _e_border_cb_window_property(void *data __UNUSED__,
6451 int ev_type __UNUSED__,
6455 Ecore_X_Event_Window_Property *e;
6458 bd = e_border_find_by_client_window(e->win);
6459 if (!bd) return ECORE_CALLBACK_PASS_ON;
6460 if (e->atom == ECORE_X_ATOM_WM_NAME)
6462 if ((!bd->client.netwm.name) &&
6463 (!bd->client.netwm.fetch.name))
6465 bd->client.icccm.fetch.title = 1;
6469 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6471 bd->client.netwm.fetch.name = 1;
6474 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6476 bd->client.icccm.fetch.name_class = 1;
6479 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6481 if ((!bd->client.netwm.icon_name) &&
6482 (!bd->client.netwm.fetch.icon_name))
6484 bd->client.icccm.fetch.icon_name = 1;
6488 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6490 bd->client.netwm.fetch.icon_name = 1;
6493 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6495 bd->client.icccm.fetch.machine = 1;
6498 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6500 bd->client.icccm.fetch.protocol = 1;
6503 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6505 bd->client.icccm.fetch.hints = 1;
6508 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6510 bd->client.icccm.fetch.size_pos_hints = 1;
6513 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6516 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6517 (!bd->client.netwm.fetch.type))
6520 bd->client.mwm.fetch.hints = 1;
6526 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6528 bd->client.icccm.fetch.transient_for = 1;
6531 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6533 bd->client.icccm.fetch.client_leader = 1;
6536 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6538 bd->client.icccm.fetch.window_role = 1;
6541 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6543 bd->client.netwm.fetch.icon = 1;
6546 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6548 bd->client.qtopia.fetch.soft_menu = 1;
6551 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6553 bd->client.qtopia.fetch.soft_menus = 1;
6556 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6558 bd->client.vkbd.fetch.state = 1;
6561 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6563 bd->client.vkbd.fetch.vkbd = 1;
6566 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6568 bd->client.illume.conformant.fetch.conformant = 1;
6571 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6573 bd->client.illume.quickpanel.fetch.state = 1;
6576 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6578 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6581 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6583 bd->client.illume.quickpanel.fetch.priority.major = 1;
6586 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6588 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6591 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6593 bd->client.illume.quickpanel.fetch.zone = 1;
6596 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6598 bd->client.illume.drag.fetch.locked = 1;
6601 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6603 bd->client.illume.drag.fetch.drag = 1;
6606 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6608 bd->client.illume.win_state.fetch.state = 1;
6612 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6614 bd->client.netwm.fetch.user_time = 1;
6617 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6619 bd->client.netwm.fetch.strut = 1;
6622 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6624 bd->client.netwm.fetch.strut = 1;
6628 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6630 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6632 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6634 bd->client.e.fetch.video_position = 1;
6637 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6639 bd->client.e.fetch.video_parent = 1;
6642 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6644 bd->client.netwm.fetch.state = 1;
6647 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6648 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6650 bd->client.e.fetch.profile_list = 1;
6654 #ifdef _F_ZONE_WINDOW_ROTATION_
6655 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6657 if (e_config->wm_win_rotation)
6659 bd->client.e.fetch.rot.support = 1;
6663 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6664 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6665 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6666 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6668 if (e_config->wm_win_rotation)
6670 bd->client.e.fetch.rot.geom_hint = 1;
6674 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6676 if (e_config->wm_win_rotation)
6678 bd->client.e.fetch.rot.app_set = 1;
6682 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6684 if (e_config->wm_win_rotation)
6686 bd->client.e.fetch.rot.preferred_rot = 1;
6690 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6692 if (e_config->wm_win_rotation)
6694 bd->client.e.fetch.rot.available_rots = 1;
6700 return ECORE_CALLBACK_PASS_ON;
6704 _e_border_cb_window_colormap(void *data __UNUSED__,
6705 int ev_type __UNUSED__,
6709 Ecore_X_Event_Window_Colormap *e;
6712 bd = e_border_find_by_client_window(e->win);
6713 if (!bd) return ECORE_CALLBACK_PASS_ON;
6714 return ECORE_CALLBACK_PASS_ON;
6718 _e_border_cb_window_shape(void *data __UNUSED__,
6719 int ev_type __UNUSED__,
6723 Ecore_X_Event_Window_Shape *e;
6726 bd = e_border_find_by_client_window(e->win);
6728 if (e->type == ECORE_X_SHAPE_INPUT)
6732 bd->need_shape_merge = 1;
6733 // YYY bd->shaped_input = 1;
6734 bd->changes.shape_input = 1;
6738 return ECORE_CALLBACK_PASS_ON;
6743 bd->changes.shape = 1;
6745 return ECORE_CALLBACK_PASS_ON;
6747 bd = e_border_find_by_window(e->win);
6750 bd->need_shape_export = 1;
6752 return ECORE_CALLBACK_PASS_ON;
6754 bd = e_border_find_by_frame_window(e->win);
6757 bd->need_shape_merge = 1;
6759 return ECORE_CALLBACK_PASS_ON;
6761 return ECORE_CALLBACK_PASS_ON;
6765 _e_border_cb_window_focus_in(void *data __UNUSED__,
6766 int ev_type __UNUSED__,
6770 Ecore_X_Event_Window_Focus_In *e;
6773 bd = e_border_find_by_client_window(e->win);
6774 if (!bd) return ECORE_CALLBACK_PASS_ON;
6775 #ifdef INOUTDEBUG_FOCUS
6780 const char *modes[] = {
6782 "MODE_WHILE_GRABBED",
6786 const char *details[] = {
6790 "DETAIL_NON_LINEAR",
6791 "DETAIL_NON_LINEAR_VIRTUAL",
6793 "DETAIL_POINTER_ROOT",
6794 "DETAIL_DETAIL_NONE"
6798 ct[strlen(ct) - 1] = 0;
6799 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6804 details[e->detail]);
6806 DBG("%s cb focus in %d %d\n",
6807 e_border_name_get(bd),
6808 bd->client.icccm.accepts_focus,
6809 bd->client.icccm.take_focus);
6812 _e_border_pri_raise(bd);
6813 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6815 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6817 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6819 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6822 /* ignore focus in from !take_focus windows, we just gave it em */
6823 /* if (!bd->client.icccm.take_focus)
6824 * return ECORE_CALLBACK_PASS_ON; */
6826 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6827 if (e->time >= focus_time)
6828 e_border_focus_set(bd, 1, 0);
6829 return ECORE_CALLBACK_PASS_ON;
6833 _e_border_cb_window_focus_out(void *data __UNUSED__,
6834 int ev_type __UNUSED__,
6838 Ecore_X_Event_Window_Focus_Out *e;
6841 bd = e_border_find_by_client_window(e->win);
6842 if (!bd) return ECORE_CALLBACK_PASS_ON;
6843 #ifdef INOUTDEBUG_FOCUS
6848 const char *modes[] = {
6850 "MODE_WHILE_GRABBED",
6854 const char *details[] = {
6858 "DETAIL_NON_LINEAR",
6859 "DETAIL_NON_LINEAR_VIRTUAL",
6861 "DETAIL_POINTER_ROOT",
6862 "DETAIL_DETAIL_NONE"
6866 ct[strlen(ct) - 1] = 0;
6867 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6872 details[e->detail]);
6874 DBG("%s cb focus out %d %d",
6875 e_border_name_get(bd),
6876 bd->client.icccm.accepts_focus,
6877 bd->client.icccm.take_focus);
6880 _e_border_pri_norm(bd);
6881 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6883 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6884 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6885 return ECORE_CALLBACK_PASS_ON;
6886 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6887 return ECORE_CALLBACK_PASS_ON;
6889 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6891 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6892 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6893 return ECORE_CALLBACK_PASS_ON;
6894 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6895 return ECORE_CALLBACK_PASS_ON;
6896 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6897 return ECORE_CALLBACK_PASS_ON;
6898 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6899 return ECORE_CALLBACK_PASS_ON;
6901 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6903 /* for firefox/thunderbird (xul) menu walking */
6904 /* NB: why did i disable this before? */
6905 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6906 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6907 return ECORE_CALLBACK_PASS_ON;
6909 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6911 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6912 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6913 return ECORE_CALLBACK_PASS_ON;
6915 e_border_focus_set(bd, 0, 0);
6916 return ECORE_CALLBACK_PASS_ON;
6919 #if _F_BORDER_CLIP_TO_ZONE_
6921 _e_border_shape_input_clip_to_zone(E_Border *bd)
6923 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6927 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6928 bd->zone->w, bd->zone->h,
6929 bd->x, bd->y, bd->w, bd->h)))
6932 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6933 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6934 bd->zone->x, bd->zone->y,
6935 bd->zone->w, bd->zone->h);
6938 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6939 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6943 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6944 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6947 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6950 _e_border_cb_client_message(void *data __UNUSED__,
6951 int ev_type __UNUSED__,
6954 Ecore_X_Event_Client_Message *e;
6958 #ifdef _F_DEICONIFY_APPROVE_
6959 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6961 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6963 bd = e_border_find_by_client_window(e->win);
6966 if (bd->client.e.state.deiconify_approve.support)
6968 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6969 bd->client.e.state.deiconify_approve.render_done = 1;
6971 E_Border *ancestor_bd;
6972 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
6975 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
6976 bd->client.e.state.deiconify_approve.ancestor = NULL;
6983 ELBF(ELBT_BD, 0, bd->client.win,
6984 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
6986 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
6987 (ancestor_bd->client.e.state.deiconify_approve.render_done))
6989 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
6991 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
6992 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
6993 e_border_uniconify(ancestor_bd);
6997 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
6998 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7003 return ECORE_CALLBACK_PASS_ON;
7007 #ifdef _F_ZONE_WINDOW_ROTATION_
7008 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7010 bd = e_border_find_by_client_window(e->win);
7013 if (e_config->wm_win_rotation)
7015 Ecore_X_Event_Client_Message *msg = NULL;
7016 Ecore_X_Atom t = e->message_type;
7017 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7018 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7019 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7020 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7022 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7023 if (!msg) return ECORE_CALLBACK_PASS_ON;
7026 msg->message_type = e->message_type;
7027 msg->data.l[0] = e->data.l[0];
7028 msg->data.l[1] = e->data.l[1];
7029 msg->data.l[2] = e->data.l[2];
7030 msg->data.l[3] = e->data.l[3];
7031 msg->data.l[4] = e->data.l[4];
7032 rot.msgs = eina_list_append(rot.msgs, msg);
7034 rot.fetch = EINA_TRUE;
7037 return ECORE_CALLBACK_PASS_ON;
7040 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7042 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7043 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7045 if (e_config->wm_win_rotation)
7047 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7049 _e_border_rotation_list_remove(bd);
7050 if (bd->client.e.state.rot.pending_show)
7052 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7054 bd->client.e.state.rot.pending_show = 0;
7060 return ECORE_CALLBACK_PASS_ON;
7064 _e_border_cb_window_state_request(void *data __UNUSED__,
7065 int ev_type __UNUSED__,
7069 Ecore_X_Event_Window_State_Request *e;
7073 bd = e_border_find_by_client_window(e->win);
7074 if (!bd) return ECORE_CALLBACK_PASS_ON;
7076 for (i = 0; i < 2; i++)
7077 e_hints_window_state_update(bd, e->state[i], e->action);
7079 return ECORE_CALLBACK_PASS_ON;
7083 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7084 int ev_type __UNUSED__,
7088 Ecore_X_Event_Window_Move_Resize_Request *e;
7091 bd = e_border_find_by_client_window(e->win);
7092 if (!bd) return ECORE_CALLBACK_PASS_ON;
7094 if ((bd->shaded) || (bd->shading) ||
7095 (bd->fullscreen) || (bd->moving) ||
7096 (bd->resize_mode != RESIZE_NONE))
7097 return ECORE_CALLBACK_PASS_ON;
7099 if ((e->button >= 1) && (e->button <= 3))
7101 bd->mouse.last_down[e->button - 1].mx = e->x;
7102 bd->mouse.last_down[e->button - 1].my = e->y;
7103 bd->mouse.last_down[e->button - 1].x = bd->x;
7104 bd->mouse.last_down[e->button - 1].y = bd->y;
7105 bd->mouse.last_down[e->button - 1].w = bd->w;
7106 bd->mouse.last_down[e->button - 1].h = bd->h;
7110 bd->moveinfo.down.x = bd->x;
7111 bd->moveinfo.down.y = bd->y;
7112 bd->moveinfo.down.w = bd->w;
7113 bd->moveinfo.down.h = bd->h;
7115 bd->mouse.current.mx = e->x;
7116 bd->mouse.current.my = e->y;
7117 bd->moveinfo.down.button = e->button;
7118 bd->moveinfo.down.mx = e->x;
7119 bd->moveinfo.down.my = e->y;
7122 if (!bd->lock_user_stacking)
7125 if (e->direction == MOVE)
7127 bd->cur_mouse_action = e_action_find("window_move");
7128 if (bd->cur_mouse_action)
7130 if ((!bd->cur_mouse_action->func.end_mouse) &&
7131 (!bd->cur_mouse_action->func.end))
7132 bd->cur_mouse_action = NULL;
7133 if (bd->cur_mouse_action)
7135 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7136 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7139 return ECORE_CALLBACK_PASS_ON;
7142 if (!_e_border_resize_begin(bd))
7143 return ECORE_CALLBACK_PASS_ON;
7145 switch (e->direction)
7148 bd->resize_mode = RESIZE_TL;
7149 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7153 bd->resize_mode = RESIZE_T;
7154 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7158 bd->resize_mode = RESIZE_TR;
7159 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7163 bd->resize_mode = RESIZE_R;
7164 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7168 bd->resize_mode = RESIZE_BR;
7169 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7173 bd->resize_mode = RESIZE_B;
7174 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7178 bd->resize_mode = RESIZE_BL;
7179 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7183 bd->resize_mode = RESIZE_L;
7184 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7188 return ECORE_CALLBACK_PASS_ON;
7191 bd->cur_mouse_action = e_action_find("window_resize");
7192 if (bd->cur_mouse_action)
7194 if ((!bd->cur_mouse_action->func.end_mouse) &&
7195 (!bd->cur_mouse_action->func.end))
7196 bd->cur_mouse_action = NULL;
7198 if (bd->cur_mouse_action)
7199 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7201 return ECORE_CALLBACK_PASS_ON;
7205 _e_border_cb_desktop_change(void *data __UNUSED__,
7206 int ev_type __UNUSED__,
7210 Ecore_X_Event_Desktop_Change *e;
7213 bd = e_border_find_by_client_window(e->win);
7216 if (e->desk == 0xffffffff)
7218 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7222 desk = e_desk_at_pos_get(bd->zone, e->desk);
7224 e_border_desk_set(bd, desk);
7229 ecore_x_netwm_desktop_set(e->win, e->desk);
7231 return ECORE_CALLBACK_PASS_ON;
7235 _e_border_cb_sync_alarm(void *data __UNUSED__,
7236 int ev_type __UNUSED__,
7240 Ecore_X_Event_Sync_Alarm *e;
7241 unsigned int serial;
7244 bd = e_border_find_by_alarm(e->alarm);
7245 if (!bd) return ECORE_CALLBACK_PASS_ON;
7247 if (bd->client.netwm.sync.wait)
7248 bd->client.netwm.sync.wait--;
7250 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7252 E_Border_Pending_Move_Resize *pnd = NULL;
7254 /* skip pending for which we didn't get a reply */
7255 while (bd->pending_move_resize)
7257 pnd = bd->pending_move_resize->data;
7258 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7260 if (serial == pnd->serial)
7272 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7273 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7278 bd->changes.size = 1;
7279 bd->changes.pos = 1;
7282 evas_render(bd->bg_evas);
7284 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7285 &bd->mouse.current.mx,
7286 &bd->mouse.current.my);
7288 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7289 _e_border_resize_handle(bd);
7291 return ECORE_CALLBACK_PASS_ON;
7295 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7296 int ev_type __UNUSED__,
7297 void *ev __UNUSED__)
7302 /* mark all borders for desktop/icon updates */
7303 EINA_LIST_FOREACH(borders, l, bd)
7307 efreet_desktop_free(bd->desktop);
7310 bd->changes.icon = 1;
7314 e_init_status_set(_("Desktop files scan done"));
7317 return ECORE_CALLBACK_PASS_ON;
7321 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7322 int ev_type __UNUSED__,
7323 void *ev __UNUSED__)
7328 /* mark all borders for desktop/icon updates */
7329 EINA_LIST_FOREACH(borders, l, bd)
7331 bd->changes.icon = 1;
7334 return ECORE_CALLBACK_PASS_ON;
7338 _e_border_cb_pointer_warp(void *data __UNUSED__,
7339 int ev_type __UNUSED__,
7342 E_Event_Pointer_Warp *e;
7345 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7346 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7347 return ECORE_CALLBACK_PASS_ON;
7351 _e_border_cb_signal_bind(void *data,
7352 Evas_Object *obj __UNUSED__,
7353 const char *emission,
7359 if (e_dnd_active()) return;
7360 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7365 _e_border_cb_mouse_in(void *data,
7366 int type __UNUSED__,
7369 Ecore_X_Event_Mouse_In *ev;
7374 #ifdef INOUTDEBUG_MOUSE
7379 const char *modes[] = {
7381 "MODE_WHILE_GRABBED",
7385 const char *details[] = {
7389 "DETAIL_NON_LINEAR",
7390 "DETAIL_NON_LINEAR_VIRTUAL",
7392 "DETAIL_POINTER_ROOT",
7393 "DETAIL_DETAIL_NONE"
7397 ct[strlen(ct) - 1] = 0;
7398 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7399 ev->win, ev->event_win,
7402 details[ev->detail]);
7405 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7406 if (ev->event_win == bd->win)
7408 e_focus_event_mouse_in(bd);
7411 if ((ev->win != bd->win) &&
7412 (ev->win != bd->event_win) &&
7413 (ev->event_win != bd->win) &&
7414 (ev->event_win != bd->event_win))
7415 return ECORE_CALLBACK_PASS_ON;
7417 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7419 bd->mouse.current.mx = ev->root.x;
7420 bd->mouse.current.my = ev->root.y;
7421 if (!bd->bg_evas_in)
7423 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7424 bd->bg_evas_in = EINA_TRUE;
7426 return ECORE_CALLBACK_PASS_ON;
7430 _e_border_cb_mouse_out(void *data,
7431 int type __UNUSED__,
7434 Ecore_X_Event_Mouse_Out *ev;
7439 #ifdef INOUTDEBUG_MOUSE
7444 const char *modes[] = {
7446 "MODE_WHILE_GRABBED",
7450 const char *details[] = {
7454 "DETAIL_NON_LINEAR",
7455 "DETAIL_NON_LINEAR_VIRTUAL",
7457 "DETAIL_POINTER_ROOT",
7458 "DETAIL_DETAIL_NONE"
7462 ct[strlen(ct) - 1] = 0;
7463 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7464 ev->win, ev->event_win,
7467 details[ev->detail]);
7470 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7471 if (ev->event_win == bd->win)
7474 return ECORE_CALLBACK_PASS_ON;
7475 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7476 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7477 return ECORE_CALLBACK_PASS_ON;
7478 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7479 return ECORE_CALLBACK_PASS_ON;
7480 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7481 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7482 return ECORE_CALLBACK_PASS_ON;
7483 e_focus_event_mouse_out(bd);
7486 if ((ev->win != bd->win) &&
7487 (ev->win != bd->event_win) &&
7488 (ev->event_win != bd->win) &&
7489 (ev->event_win != bd->event_win))
7490 return ECORE_CALLBACK_PASS_ON;
7492 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7494 bd->mouse.current.mx = ev->root.x;
7495 bd->mouse.current.my = ev->root.y;
7498 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7499 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7500 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7502 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7503 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7504 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7505 bd->bg_evas_in = EINA_FALSE;
7508 return ECORE_CALLBACK_PASS_ON;
7512 _e_border_cb_mouse_wheel(void *data,
7513 int type __UNUSED__,
7516 Ecore_Event_Mouse_Wheel *ev;
7521 if ((ev->event_window == bd->win) ||
7522 (ev->event_window == bd->event_win))
7524 bd->mouse.current.mx = ev->root.x;
7525 bd->mouse.current.my = ev->root.y;
7526 if (!bd->cur_mouse_action)
7527 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7530 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7531 return ECORE_CALLBACK_PASS_ON;
7535 _e_border_cb_mouse_down(void *data,
7536 int type __UNUSED__,
7539 Ecore_Event_Mouse_Button *ev;
7544 if ((ev->event_window == bd->win) ||
7545 (ev->event_window == bd->event_win))
7547 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7549 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7550 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7551 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7552 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7553 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7554 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7558 bd->moveinfo.down.x = bd->x + bd->fx.x;
7559 bd->moveinfo.down.y = bd->y + bd->fx.y;
7560 bd->moveinfo.down.w = bd->w;
7561 bd->moveinfo.down.h = bd->h;
7563 bd->mouse.current.mx = ev->root.x;
7564 bd->mouse.current.my = ev->root.y;
7565 if (!bd->cur_mouse_action)
7567 bd->cur_mouse_action =
7568 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7570 if (bd->cur_mouse_action)
7572 if ((!bd->cur_mouse_action->func.end_mouse) &&
7573 (!bd->cur_mouse_action->func.end))
7574 bd->cur_mouse_action = NULL;
7575 if (bd->cur_mouse_action)
7576 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7579 e_focus_event_mouse_down(bd);
7581 if (ev->window != ev->event_window)
7585 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7589 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7591 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7592 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7593 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7594 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7595 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7596 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7600 bd->moveinfo.down.x = bd->x + bd->fx.x;
7601 bd->moveinfo.down.y = bd->y + bd->fx.y;
7602 bd->moveinfo.down.w = bd->w;
7603 bd->moveinfo.down.h = bd->h;
7605 bd->mouse.current.mx = ev->root.x;
7606 bd->mouse.current.my = ev->root.y;
7611 else if (bd->resize_mode != RESIZE_NONE)
7617 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7619 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7620 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7621 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7623 return ECORE_CALLBACK_PASS_ON;
7627 _e_border_cb_mouse_up(void *data,
7628 int type __UNUSED__,
7631 Ecore_Event_Mouse_Button *ev;
7636 if ((ev->event_window == bd->win) ||
7637 (ev->event_window == bd->event_win))
7639 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7641 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7642 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7643 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7644 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7646 bd->mouse.current.mx = ev->root.x;
7647 bd->mouse.current.my = ev->root.y;
7648 /* also we dont pass the same params that went in - then again that */
7649 /* should be ok as we are just ending the action if it has an end */
7650 if (bd->cur_mouse_action)
7652 if (bd->cur_mouse_action->func.end_mouse)
7653 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7654 else if (bd->cur_mouse_action->func.end)
7655 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7656 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7657 bd->cur_mouse_action = NULL;
7661 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7662 e_focus_event_mouse_up(bd);
7665 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7666 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7668 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7669 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7670 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7671 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7673 bd->mouse.current.mx = ev->root.x;
7674 bd->mouse.current.my = ev->root.y;
7678 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7679 return ECORE_CALLBACK_PASS_ON;
7683 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7685 #ifdef _F_BORDER_CLIP_TO_ZONE_
7686 int new_x_max, new_y_max;
7687 int new_x_min, new_y_min;
7688 int margin_x, margin_y;
7690 margin_x = bd->w - 100;
7691 margin_y = bd->h - 100;
7693 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7694 new_x_min = bd->zone->x - margin_x;
7695 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7696 new_y_min = bd->zone->y - margin_y;
7698 if (x >= new_x_max) *new_x = new_x_max;
7699 else if (x <= new_x_min) *new_x = new_x_min;
7701 if (y >= new_y_max) *new_y = new_y_max;
7702 else if (y <= new_y_min) *new_y = new_y_min;
7707 _e_border_cb_mouse_move(void *data,
7708 int type __UNUSED__,
7711 Ecore_Event_Mouse_Move *ev;
7716 if ((ev->window != bd->event_win) &&
7717 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7718 bd->mouse.current.mx = ev->root.x;
7719 bd->mouse.current.my = ev->root.y;
7722 int x, y, new_x, new_y;
7724 Eina_List *skiplist = NULL;
7726 // FIXME: remove? sync what for when only moving?
7727 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7728 bd->client.netwm.sync.wait = 0;
7729 if ((bd->client.netwm.sync.request) &&
7730 (bd->client.netwm.sync.alarm) &&
7731 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7733 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7735 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7736 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7737 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7738 (bd->mouse.current.my - bd->moveinfo.down.my);
7742 x = bd->moveinfo.down.x +
7743 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7744 y = bd->moveinfo.down.y +
7745 (bd->mouse.current.my - bd->moveinfo.down.my);
7750 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7751 skiplist = eina_list_append(skiplist, bd);
7752 e_resist_container_border_position(bd->zone->container, skiplist,
7753 bd->x, bd->y, bd->w, bd->h,
7755 &new_x, &new_y, &new_w, &new_h);
7756 eina_list_free(skiplist);
7758 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7760 /* if (e_config->window_out_of_vscreen_limits_partly) */
7762 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7765 skiplist = eina_list_append(skiplist, bd);
7766 e_resist_container_border_position(bd->zone->container, skiplist,
7767 bd->x, bd->y, bd->w, bd->h,
7769 &new_x, &new_y, &new_w, &new_h);
7770 eina_list_free(skiplist);
7773 bd->shelf_fix.x = 0;
7774 bd->shelf_fix.y = 0;
7775 bd->shelf_fix.modified = 0;
7776 e_border_move(bd, new_x, new_y);
7777 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7779 else if (bd->resize_mode != RESIZE_NONE)
7781 if ((bd->client.netwm.sync.request) &&
7782 (bd->client.netwm.sync.alarm))
7784 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7786 E_Border_Pending_Move_Resize *pnd;
7788 if (bd->pending_move_resize)
7790 bd->changes.pos = 1;
7791 bd->changes.size = 1;
7793 _e_border_client_move_resize_send(bd);
7795 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7798 bd->client.netwm.sync.wait = 0;
7800 /* sync.wait is incremented when resize_handle sends
7801 * sync-request and decremented by sync-alarm cb. so
7802 * we resize here either on initial resize, timeout or
7803 * when no new resize-request was added by sync-alarm cb.
7805 if (!bd->client.netwm.sync.wait)
7806 _e_border_resize_handle(bd);
7809 _e_border_resize_handle(bd);
7815 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7817 bd->drag.x = ev->root.x;
7818 bd->drag.y = ev->root.y;
7824 dx = bd->drag.x - ev->root.x;
7825 dy = bd->drag.y - ev->root.y;
7826 if (((dx * dx) + (dy * dy)) >
7827 (e_config->drag_resist * e_config->drag_resist))
7830 if (bd->icon_object)
7832 Evas_Object *o = NULL;
7833 Evas_Coord x, y, w, h;
7834 const char *drag_types[] = { "enlightenment/border" };
7836 e_object_ref(E_OBJECT(bd));
7837 evas_object_geometry_get(bd->icon_object,
7839 drag_border = e_drag_new(bd->zone->container,
7840 bd->x + bd->fx.x + x,
7841 bd->y + bd->fx.y + y,
7842 drag_types, 1, bd, -1,
7844 _e_border_cb_drag_finished);
7845 o = e_border_icon_add(bd, drag_border->evas);
7848 /* FIXME: fallback icon for drag */
7849 o = evas_object_rectangle_add(drag_border->evas);
7850 evas_object_color_set(o, 255, 255, 255, 255);
7852 e_drag_object_set(drag_border, o);
7854 e_drag_resize(drag_border, w, h);
7855 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7861 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7863 return ECORE_CALLBACK_PASS_ON;
7867 _e_border_cb_grab_replay(void *data __UNUSED__,
7871 Ecore_Event_Mouse_Button *ev;
7873 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7875 if ((e_config->pass_click_on)
7876 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7877 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7882 bd = e_border_find_by_window(ev->event_window);
7885 if (bd->cur_mouse_action)
7886 return ECORE_CALLBACK_DONE;
7887 if (ev->event_window == bd->win)
7889 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7890 E_OBJECT(bd), ev, NULL))
7891 return ECORE_CALLBACK_PASS_ON;
7895 return ECORE_CALLBACK_DONE;
7899 _e_border_cb_drag_finished(E_Drag *drag,
7900 int dropped __UNUSED__)
7905 e_object_unref(E_OBJECT(bd));
7909 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7911 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7912 int ev_type __UNUSED__,
7915 E_Event_Desk_Window_Profile_Change *e;
7920 EINA_LIST_FOREACH(borders, l, bd)
7922 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7924 bd->client.e.fetch.profile_list = 1;
7928 return ECORE_CALLBACK_PASS_ON;
7932 #ifdef _F_ZONE_WINDOW_ROTATION_
7934 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
7935 int ev_type __UNUSED__,
7938 E_Event_Zone_Rotation_Change_Begin *e = ev;
7940 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7941 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7943 if (!_e_border_rotation_zone_set(e->zone))
7945 /* there is no border which supports window manager rotation */
7946 e_zone_rotation_update_cancel(e->zone);
7948 return ECORE_CALLBACK_PASS_ON;
7952 _e_border_cb_rotation_sync_job(void *data)
7954 E_Zone *zone = data;
7956 E_Border_Rotation_Info *info = NULL;
7958 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
7962 EINA_LIST_FOREACH(rot.list, l, info)
7963 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
7964 if (!rot.wait_prepare_done)
7966 _e_border_rotation_change_request(zone);
7973 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
7974 ecore_job_del(rot.sync_job);
7975 rot.sync_job = NULL;
7980 _e_border_cb_rotation_async_job(void *data)
7982 E_Zone *zone = data;
7984 if (rot.list) goto end;
7986 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
7988 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
7989 rot.async_list = NULL;
7995 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
7996 ecore_job_del(rot.async_job);
7997 rot.async_job = NULL;
8002 _e_border_rotation_change_prepare_timeout(void *data)
8004 E_Zone *zone = data;
8005 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8007 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8009 if ((zone) && (rot.wait_prepare_done))
8013 _e_border_rotation_change_request(zone);
8014 if (rot.prepare_timer)
8015 ecore_timer_del(rot.prepare_timer);
8016 rot.prepare_timer = NULL;
8017 rot.wait_prepare_done = EINA_FALSE;
8020 return ECORE_CALLBACK_CANCEL;
8024 _e_border_rotation_change_request(E_Zone *zone)
8026 if (!e_config->wm_win_rotation) return;
8027 if (!rot.list) return;
8028 if (eina_list_count(rot.list) <= 0) return;
8029 if (zone->rot.block_count) return;
8031 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8032 rot.prepare_timer = NULL;
8033 rot.wait_prepare_done = EINA_FALSE;
8035 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8038 ecore_timer_del(rot.done_timer);
8039 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8040 rot.done_timer = ecore_timer_add(4.0f,
8041 _e_border_rotation_change_done_timeout,
8046 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8049 E_Border_Rotation_Info *info =NULL;
8052 EINA_LIST_FOREACH (list, l, info)
8054 if (!info->bd) continue;
8055 if ((info->bd->client.e.state.rot.wait_for_done) &&
8056 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8058 _e_border_event_border_rotation_change_begin_send(info->bd);
8061 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8062 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8064 info->x = x; info->y = y;
8065 info->w = w; info->h = h;
8067 ELBF(ELBT_ROT, 1, info->bd->client.win,
8068 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8069 info->ang, info->win_resize, info->w, info->h);
8071 ecore_x_e_window_rotation_change_prepare_send
8072 (info->bd->client.win, info->ang,
8073 info->win_resize, info->w, info->h);
8075 if (!info->bd->client.e.state.rot.pending_change_request)
8077 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8078 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8080 info->bd->client.e.state.rot.wait_for_done = 1;
8081 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8087 EINA_LIST_FREE(list, info)
8093 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8095 E_Border_Rotation_Info *info = NULL;
8097 if (send_request) _e_border_rotation_change_request(zone);
8100 EINA_LIST_FREE(rot.list, info)
8107 _e_border_rotation_list_remove(E_Border *bd)
8109 Eina_List *l = NULL;
8110 E_Border_Rotation_Info *info = NULL;
8111 E_Event_Border_Rotation_Change_End *ev = NULL;
8112 Eina_Bool found = EINA_FALSE;
8114 if (!e_config->wm_win_rotation) return;
8116 EINA_LIST_FOREACH(rot.list, l, info)
8120 rot.list = eina_list_remove(rot.list, info);
8126 if (bd->client.e.state.rot.wait_for_done)
8128 bd->client.e.state.rot.wait_for_done = 0;
8130 /* if we make the border event in the _e_border_free function,
8131 * then we may meet a crash problem, only work this at least e_border_hide.
8133 if (!e_object_is_del(E_OBJECT(bd)))
8135 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8139 e_object_ref(E_OBJECT(bd));
8140 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8142 _e_border_event_border_rotation_change_end_free,
8148 (eina_list_count(rot.list) == 0))
8150 _e_border_rotation_change_done();
8156 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8158 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8159 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8160 _e_border_rotation_change_done();
8161 return ECORE_CALLBACK_CANCEL;
8165 _e_border_rotation_change_done(void)
8167 E_Manager *m = NULL;
8168 E_Border_Rotation_Info *info = NULL;
8170 if (!e_config->wm_win_rotation) return;
8172 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8173 rot.prepare_timer = NULL;
8175 rot.wait_prepare_done = EINA_FALSE;
8177 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8178 rot.done_timer = NULL;
8180 EINA_LIST_FREE(rot.list, info)
8184 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8185 if (info->bd->client.e.state.rot.pending_show)
8187 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8188 e_border_show(info->bd);
8189 info->bd->client.e.state.rot.pending_show = 0;
8191 info->bd->client.e.state.rot.wait_for_done = 0;
8196 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8199 rot.async_list = NULL;
8201 m = e_manager_current_get();
8202 e_manager_comp_screen_unlock(m);
8203 e_zone_rotation_update_done(e_util_zone_current_get(m));
8207 _prev_angle_get(Ecore_X_Window win)
8209 int ret, count = 0, ang = -1;
8210 unsigned char* data = NULL;
8212 ret = ecore_x_window_prop_property_get
8213 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8214 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8216 if ((ret) && (data) && (count))
8217 ang = ((int *)data)[0];
8218 if (data) free(data);
8222 /* get proper rotation value using preferred rotation and list of available rotations */
8224 _e_border_rotation_get(E_Border *bd,
8228 int current_ang = bd->client.e.state.rot.curr;
8230 Eina_Bool found = EINA_FALSE;
8231 Eina_Bool found_curr_ang = EINA_FALSE;
8233 if (!e_config->wm_win_rotation) return ang;
8234 if (!bd->client.e.state.rot.app_set) return ang;
8236 if (bd->client.e.state.rot.preferred_rot != -1)
8238 ang = bd->client.e.state.rot.preferred_rot;
8239 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8241 else if ((bd->client.e.state.rot.available_rots) &&
8242 (bd->client.e.state.rot.count))
8244 for (i = 0; i < bd->client.e.state.rot.count; i++)
8246 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8252 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8253 found_curr_ang = EINA_TRUE;
8256 /* do nothing. this window wants to maintain current state.
8257 * for example, window's available_rots: 0, 90, 270,
8258 * current zone rotation request: 180. the WM does nothing
8263 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8264 ang = bd->client.e.state.rot.curr;
8266 ang = bd->client.e.state.rot.available_rots[0];
8271 /* In this case, border doesn't have a list of
8272 * available rotations, thus WM should request
8273 * rotation with '0' degree to the application.
8282 _e_border_rotation_angle_get(E_Border *bd)
8284 E_Zone *zone = bd->zone;
8289 if (!e_config->wm_win_rotation) return ret;
8290 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8292 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8294 if (bd->parent) will_ang = bd->parent->client.e.state.rot.curr;
8295 else will_ang = zone->rot.curr;
8297 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8299 ELBF(ELBT_ROT, 1, bd->client.win,
8300 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8301 (rot.vkbd == bd) ? "vkbd" : "prediction",
8302 bd->parent ? bd->parent->client.win : 0,
8303 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8304 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8305 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8309 will_ang = bd->parent->client.e.state.rot.curr;
8310 if ((!bd->parent->client.e.state.rot.support) &&
8311 (!bd->parent->client.e.state.rot.app_set))
8318 if ((!bd->client.e.state.rot.app_set) &&
8319 (!bd->client.e.state.rot.support))
8321 /* hack for magnifier and keyboard popup */
8322 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8323 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8325 ELB(ELBT_BD, "MAG", bd->client.win);
8327 if ((rot.vkbd) && (rot.vkbd->visible))
8328 will_ang = rot.vkbd->client.e.state.rot.curr;
8332 if (bd->client.e.state.rot.app_set)
8334 /* utility type window should be rotated according to
8335 * rotation of the transient_for window.
8338 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8340 will_ang = bd->parent->client.e.state.rot.curr;
8341 if ((!bd->parent->client.e.state.rot.support) &&
8342 (!bd->parent->client.e.state.rot.app_set))
8344 /* if transient_for window doesn't support rotation feature,
8345 * then this window should't be rotated.
8346 * TODO: need to check whether window supports '0' degree or not.
8349 ELBF(ELBT_ROT, 0, bd->client.win,
8350 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8351 will_ang, bd->parent->client.win);
8355 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8356 ELBF(ELBT_ROT, 0, bd->client.win,
8357 "GET ROT ang:%d Transient_For:0x%08x",
8358 will_ang, bd->parent->client.win);
8363 will_ang = _e_border_rotation_get(bd, will_ang);
8364 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8365 will_ang, bd->parent ? bd->parent->client.win : 0,
8366 bd->client.netwm.type);
8372 _ang = _prev_angle_get(bd->client.win);
8374 bd->client.e.state.rot.curr = _ang;
8375 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8378 if (bd->client.e.state.rot.curr != will_ang)
8386 _e_border_rotation_zone_set(E_Zone *zone)
8388 E_Border_List *l = NULL;
8389 E_Border *bd = NULL;
8390 Eina_Bool ret = EINA_FALSE;
8392 if (!e_config->wm_win_rotation) return EINA_FALSE;
8394 l = e_container_border_list_last(zone->container);
8397 /* step 1. make the list needs to be rotated. */
8398 while ((bd = e_container_border_list_prev(l)))
8402 // if this window have parent,
8403 // it will be rotated when parent do rotate itself.
8405 if (bd->parent) continue;
8407 // this type is set by illume.
8408 // if it's not normal type window, will be rotated by illume.
8410 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8412 if ((!bd->visible) ||
8413 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8414 bd->x, bd->y, bd->w, bd->h))) continue;
8416 if (_e_border_rotatable_check(bd, zone->rot.curr))
8418 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8419 bd->client.e.state.rot.curr, zone->rot.curr);
8421 ret = e_border_rotation_set(bd, zone->rot.curr);
8424 if (l) e_container_border_list_free(l);
8430 e_border_rotation_set(E_Border *bd, int rotation)
8432 E_Zone *zone = bd->zone;
8433 E_Border_Rotation_Info *info = NULL;
8434 Eina_List *list, *l;
8437 if (rotation < 0) return EINA_FALSE;
8439 /* step 1. check if rotation */
8440 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8442 /* step 2. add to async/sync list */
8443 if ((!zone->rot.block_count) &&
8445 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8447 // send rotation change request later.
8448 // and no need to wait message of rotation done.
8451 info = E_NEW(E_Border_Rotation_Info, 1);
8452 if (!info) return EINA_FALSE;
8453 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8455 info->ang = rotation;
8456 rot.async_list = eina_list_append(rot.async_list, info);
8458 // add job for sending event.
8461 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8462 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8468 info = E_NEW(E_Border_Rotation_Info, 1);
8469 if (!info) return EINA_FALSE;
8470 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8472 info->ang = rotation;
8473 rot.list = eina_list_append(rot.list, info);
8475 // add job for sending event.
8478 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8479 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8482 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8484 // but, DO NOT lock the screen when rotation block state.
8485 if ((!zone->rot.block_count) &&
8486 ((eina_list_count(rot.list) == 2)))
8487 e_manager_comp_screen_lock(e_manager_current_get());
8490 /* step 3. search rotatable window in this window's child */
8491 list = _e_border_sub_borders_new(bd);
8492 EINA_LIST_FOREACH(list, l, child)
8494 if (_e_border_rotatable_check(child, rotation))
8496 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8497 bd->client.e.state.rot.curr, rotation);
8498 e_border_rotation_set(child, rotation);
8502 /* step 4. if there is vkbd window, send message to prepare rotation */
8503 if (_e_border_is_vkbd(bd))
8505 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8506 if (rot.prepare_timer)
8507 ecore_timer_del(rot.prepare_timer);
8508 rot.prepare_timer = NULL;
8511 ecore_timer_del(rot.done_timer);
8512 rot.done_timer = NULL;
8514 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8515 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8518 rot.prepare_timer = ecore_timer_add(4.0f,
8519 _e_border_rotation_change_prepare_timeout,
8522 rot.wait_prepare_done = EINA_TRUE;
8525 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8526 bd->client.e.state.rot.curr = rotation;
8531 // check if border is rotatable in ang.
8533 _e_border_rotatable_check(E_Border *bd, int ang)
8535 Eina_Bool ret = EINA_FALSE;
8537 if (!bd) return ret;
8538 if (ang < 0) return ret;
8539 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8540 if (e_object_is_del(E_OBJECT(bd))) return ret;
8542 // same with current angle of window, then false return.
8543 if (ang == bd->client.e.state.rot.curr) return ret;
8545 /* basically WM allows only fullscreen window to rotate */
8546 if (bd->client.e.state.rot.preferred_rot == -1)
8550 if (bd->client.e.state.rot.app_set)
8552 if (bd->client.e.state.rot.available_rots &&
8553 bd->client.e.state.rot.count)
8555 Eina_Bool found = EINA_FALSE;
8556 for (i = 0; i < bd->client.e.state.rot.count; i++)
8558 if (bd->client.e.state.rot.available_rots[i] == ang)
8563 if (found) ret = EINA_TRUE;
8568 ELB(ELBT_ROT, "DO ROT", 0);
8572 // if it has preferred rotation angle,
8573 // it will be rotated at border's evaluation time.
8575 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8580 /* check whether virtual keyboard is visible on the zone */
8582 _e_border_is_vkbd(E_Border *bd)
8584 if (!e_config->wm_win_rotation) return EINA_FALSE;
8586 if ((rot.vkbd_ctrl_win) &&
8588 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8589 (rot.vkbd->visible) &&
8590 (rot.vkbd->zone == bd->zone) &&
8591 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8592 bd->zone->w, bd->zone->h,
8593 rot.vkbd->x, rot.vkbd->y,
8594 rot.vkbd->w, rot.vkbd->h)))
8601 #define SIZE_EQUAL_TO_ZONE(a, z) \
8602 ((((a)->w) == ((z)->w)) && \
8603 (((a)->h) == ((z)->h)))
8605 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8607 E_Zone *zone = bd->zone;
8610 Eina_Bool move = EINA_FALSE;
8611 Eina_Bool hint = EINA_FALSE;
8612 Eina_Bool resize = EINA_FALSE;
8619 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8621 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8622 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8623 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8625 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8626 &_x, &_y, &_w, &_h, &move);
8629 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8631 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8632 bd->client.icccm.name, _x, _y, _w, _h);
8636 _x = bd->x; _y = bd->y;
8637 _w = bd->w; _h = bd->h;
8639 rot_dif = bd->client.e.state.rot.prev - rotation;
8640 if (rot_dif < 0) rot_dif = -rot_dif;
8649 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8650 EINA_TRUE, EINA_TRUE);
8651 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8652 bd->client.icccm.name, _x, _y, _w, _h);
8670 _e_border_cb_window_configure(void *data __UNUSED__,
8671 int ev_type __UNUSED__,
8674 Ecore_X_Event_Window_Configure *e = ev;
8675 E_Border_Rotation_Info *info = NULL;
8677 Eina_Bool found = EINA_FALSE;
8679 if (!e) return ECORE_CALLBACK_PASS_ON;
8680 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8682 E_Border *bd = e_border_find_by_client_window(e->win);
8683 if (!bd) return ECORE_CALLBACK_PASS_ON;
8685 if (bd->client.e.state.rot.pending_change_request)
8687 if ((e->w == bd->w) && (e->h == bd->h))
8689 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8690 bd->client.e.state.rot.pending_change_request = 0;
8692 if ((bd->client.e.state.rot.wait_for_done) &&
8693 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8695 // if this window is rotation dependent window and zone is blocked to rotate,
8696 // then skip here, request will be sent after cancel block.
8697 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
8698 (bd->zone->rot.block_count)) goto end;
8700 EINA_LIST_FOREACH(rot.list, l, info)
8701 if (info->bd == bd) found = EINA_TRUE;
8702 // send request message if it's async rotation window,
8703 // even if wait prepare done.
8704 if ((found) && (rot.wait_prepare_done)) goto end;
8706 ELBF(ELBT_ROT, 0, bd->client.win,
8707 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8708 bd->client.e.state.rot.curr,
8710 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8711 bd->client.e.state.rot.curr);
8712 bd->client.e.state.rot.wait_for_done = 1;
8713 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
8718 return ECORE_CALLBACK_PASS_ON;
8722 _e_border_rotation_geom_get(E_Border *bd,
8731 if (!e_config->wm_win_rotation) return EINA_FALSE;
8733 Eina_Bool res = EINA_FALSE;
8734 Eina_Bool _move = EINA_TRUE;
8744 if (move) *move = EINA_TRUE;
8746 if (bd->client.e.state.rot.geom_hint)
8751 _w = bd->client.e.state.rot.geom[0].w;
8752 _h = bd->client.e.state.rot.geom[0].h;
8753 if (_w == 0) _w = bd->w;
8754 if (_h == 0) _h = bd->h;
8755 _x = 0; _y = zone->h - _h;
8758 _w = bd->client.e.state.rot.geom[1].w;
8759 _h = bd->client.e.state.rot.geom[1].h;
8760 if (_w == 0) _w = bd->w;
8761 if (_h == 0) _h = bd->h;
8762 _x = zone->w - _w; _y = 0;
8765 _w = bd->client.e.state.rot.geom[2].w;
8766 _h = bd->client.e.state.rot.geom[2].h;
8767 if (_w == 0) _w = bd->w;
8768 if (_h == 0) _h = bd->h;
8772 _w = bd->client.e.state.rot.geom[3].w;
8773 _h = bd->client.e.state.rot.geom[3].h;
8774 if (_w == 0) _w = bd->w;
8775 if (_h == 0) _h = bd->h;
8785 if (!((rot.vkbd) && (rot.vkbd == bd)))
8789 if (move) *move = EINA_FALSE;
8797 _x = 0; _y = 0; _w = 0; _h = 0;
8802 if (move) _move = *move;
8804 ELBF(ELBT_ROT, 1, bd->client.win,
8805 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8806 ang, _x, _y, _w, _h, _move);
8814 _e_border_post_move_resize_job(void *data)
8818 bd = (E_Border *)data;
8824 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8825 ecore_x_window_move(tmp->win,
8827 bd->client_inset.l +
8829 tmp->client.e.state.video_position.x,
8831 bd->client_inset.t +
8833 tmp->client.e.state.video_position.y);
8835 if (bd->client.e.state.video)
8839 parent = bd->client.e.state.video_parent_border;
8840 ecore_x_window_move(bd->win,
8842 parent->client_inset.l +
8844 bd->client.e.state.video_position.x,
8846 parent->client_inset.t +
8848 bd->client.e.state.video_position.y);
8850 else if ((bd->post_move) && (bd->post_resize))
8852 ecore_x_window_move_resize(bd->win,
8857 else if (bd->post_move)
8859 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
8861 else if (bd->post_resize)
8863 ecore_x_window_resize(bd->win, bd->w, bd->h);
8866 if (bd->client.e.state.video)
8868 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
8870 bd->client.e.state.video_parent_border->x +
8871 bd->client.e.state.video_parent_border->client_inset.l +
8872 bd->client.e.state.video_parent_border->fx.x +
8873 bd->client.e.state.video_position.x,
8874 bd->client.e.state.video_parent_border->y +
8875 bd->client.e.state.video_parent_border->client_inset.t +
8876 bd->client.e.state.video_parent_border->fx.y +
8877 bd->client.e.state.video_position.y,
8885 bd->post_job = NULL;
8891 bd->post_resize = 0;
8892 bd->post_job = NULL;
8893 return ECORE_CALLBACK_CANCEL;
8897 _e_border_container_layout_hook(E_Container *con)
8899 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
8903 _e_border_eval0(E_Border *bd)
8905 int change_urgent = 0;
8907 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8908 Eina_Bool need_desk_set = EINA_FALSE;
8910 #ifdef _F_ZONE_WINDOW_ROTATION_
8911 Eina_Bool need_rotation_set = EINA_FALSE;
8913 if ((e_config->wm_win_rotation) &&
8914 (bd->client.icccm.fetch.transient_for))
8916 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8917 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
8919 need_rotation_set = EINA_TRUE;
8920 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
8925 if (e_object_is_del(E_OBJECT(bd)))
8927 CRI("_e_border_eval(%p) with deleted border!\n", bd);
8932 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
8934 bd->changes.border = 0;
8936 /* fetch any info queued to be fetched */
8937 if (bd->client.netwm.fetch.state)
8939 e_hints_window_state_get(bd);
8940 bd->client.netwm.fetch.state = 0;
8943 if (bd->client.icccm.fetch.client_leader)
8945 /* TODO: What do to if the client leader isn't mapped yet? */
8946 E_Border *bd_leader = NULL;
8948 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
8949 if (bd->client.icccm.client_leader)
8950 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
8953 if (bd->leader != bd_leader)
8955 bd->leader->group = eina_list_remove(bd->leader->group, bd);
8956 if (bd->leader->modal == bd) bd->leader->modal = NULL;
8962 /* If this border is the leader of the group, don't register itself */
8963 if ((bd_leader) && (bd_leader != bd))
8965 bd_leader->group = eina_list_append(bd_leader->group, bd);
8966 bd->leader = bd_leader;
8967 /* Only set the window modal to the leader it there is no parent */
8968 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
8969 ((!bd->parent) || (bd->parent->modal != bd)))
8971 bd->leader->modal = bd;
8972 if (bd->leader->focused)
8973 e_border_focus_set(bd, 1, 1);
8979 EINA_LIST_FOREACH(bd->leader->group, l, child)
8981 if ((child != bd) && (child->focused))
8982 e_border_focus_set(bd, 1, 1);
8987 bd->client.icccm.fetch.client_leader = 0;
8990 if (bd->client.icccm.fetch.title)
8992 char *title = ecore_x_icccm_title_get(bd->client.win);
8993 eina_stringshare_replace(&bd->client.icccm.title, title);
8994 if (title) free(title);
8997 edje_object_part_text_set(bd->bg_object, "e.text.title",
8998 bd->client.icccm.title);
8999 bd->client.icccm.fetch.title = 0;
9002 if (bd->client.netwm.fetch.name)
9005 ecore_x_netwm_name_get(bd->client.win, &name);
9006 eina_stringshare_replace(&bd->client.netwm.name, name);
9007 if (name) free(name);
9010 edje_object_part_text_set(bd->bg_object, "e.text.title",
9011 bd->client.netwm.name);
9012 bd->client.netwm.fetch.name = 0;
9015 if (bd->client.icccm.fetch.name_class)
9017 const char *pname, *pclass;
9018 char *nname, *nclass;
9020 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9021 pname = bd->client.icccm.name;
9022 pclass = bd->client.icccm.class;
9023 bd->client.icccm.name = eina_stringshare_add(nname);
9024 bd->client.icccm.class = eina_stringshare_add(nclass);
9025 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9026 e_bindings_mapping_change_enable(EINA_FALSE);
9027 #ifdef _F_ZONE_WINDOW_ROTATION_
9028 if (e_config->wm_win_rotation)
9030 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9032 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9033 (!strcmp(bd->client.icccm.class, "ISF")))
9035 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9036 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9039 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9040 (!strcmp(bd->client.icccm.class, "ISF")))
9042 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9043 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9044 rot.vkbd_prediction = bd;
9046 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9047 (!strcmp(bd->client.icccm.class, "ISF")))
9049 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9050 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9052 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9053 (!strcmp(bd->client.icccm.class, "ISF")))
9055 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9056 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9061 if (nname) free(nname);
9062 if (nclass) free(nclass);
9064 if (!((bd->client.icccm.name == pname) &&
9065 (bd->client.icccm.class == pclass)))
9066 bd->changes.icon = 1;
9068 if (pname) eina_stringshare_del(pname);
9069 if (pclass) eina_stringshare_del(pclass);
9070 bd->client.icccm.fetch.name_class = 0;
9071 bd->changes.icon = 1;
9074 if (bd->client.icccm.fetch.state)
9076 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9077 bd->client.icccm.fetch.state = 0;
9080 if (bd->client.e.fetch.state)
9082 e_hints_window_e_state_get(bd);
9083 bd->client.e.fetch.state = 0;
9086 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9087 if (bd->client.e.fetch.profile_list)
9089 const char **profiles = NULL;
9093 if (bd->client.e.state.profile)
9094 eina_stringshare_del(bd->client.e.state.profile);
9095 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9097 if (str) eina_stringshare_del(str);
9099 bd->client.e.state.profile = NULL;
9100 bd->client.e.state.profiles = NULL;
9101 bd->client.e.state.profile_list = 0;
9103 if (ecore_x_e_window_profile_list_get(bd->client.win,
9106 bd->client.e.state.profile_list = 1;
9107 for (i = 0; i < num; i++)
9109 str = eina_stringshare_add(profiles[i]);
9110 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9113 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9114 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9116 need_desk_set = EINA_TRUE;
9120 if (strcmp(bd->desk->window_profile,
9121 e_config->desktop_default_window_profile) != 0)
9123 ecore_x_e_window_profile_set(bd->client.win,
9124 bd->desk->window_profile);
9130 for (i = 0; i < num; i++)
9131 if (profiles[i]) free(profiles[i]);
9135 bd->client.e.fetch.profile_list = 0;
9138 #ifdef _F_ZONE_WINDOW_ROTATION_
9139 if ((e_config->wm_win_rotation) &&
9140 (bd->client.e.fetch.rot.support))
9143 unsigned int support = 0;
9145 ret = ecore_x_window_prop_card32_get
9147 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9150 bd->client.e.state.rot.support = 0;
9151 if ((ret == 1) && (support == 1))
9152 bd->client.e.state.rot.support = 1;
9154 if (bd->client.e.state.rot.support)
9155 need_rotation_set = EINA_TRUE;
9157 bd->client.e.fetch.rot.support = 0;
9159 if ((e_config->wm_win_rotation) &&
9160 (bd->client.e.fetch.rot.geom_hint))
9162 Eina_Rectangle r[4];
9164 bd->client.e.state.rot.geom_hint = 0;
9165 for (i = 0; i < 4; i++)
9167 r[i].x = bd->client.e.state.rot.geom[i].x;
9168 r[i].y = bd->client.e.state.rot.geom[i].y;
9169 r[i].w = bd->client.e.state.rot.geom[i].w;
9170 r[i].h = bd->client.e.state.rot.geom[i].h;
9172 bd->client.e.state.rot.geom[i].x = 0;
9173 bd->client.e.state.rot.geom[i].y = 0;
9174 bd->client.e.state.rot.geom[i].w = 0;
9175 bd->client.e.state.rot.geom[i].h = 0;
9178 for (i = 0; i < 4; i++)
9180 x = 0; y = 0; w = 0; h = 0;
9181 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9183 bd->client.e.state.rot.geom_hint = 1;
9184 bd->client.e.state.rot.geom[i].x = x;
9185 bd->client.e.state.rot.geom[i].y = y;
9186 bd->client.e.state.rot.geom[i].w = w;
9187 bd->client.e.state.rot.geom[i].h = h;
9189 if (!((r[i].x == x) && (r[i].y == y) &&
9190 (r[i].w == w) && (r[i].h == h)))
9192 need_rotation_set = EINA_TRUE;
9196 bd->client.e.fetch.rot.geom_hint = 0;
9198 if ((e_config->wm_win_rotation) &&
9199 (bd->client.e.fetch.rot.app_set))
9201 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9202 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9203 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9205 if (_prev_app_set != bd->client.e.state.rot.app_set)
9206 need_rotation_set = EINA_TRUE;
9208 bd->client.e.fetch.rot.app_set = 0;
9210 if ((e_config->wm_win_rotation) &&
9211 (bd->client.e.fetch.rot.preferred_rot))
9213 int r = 0, _prev_preferred_rot;
9214 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9215 bd->client.e.state.rot.preferred_rot = -1;
9216 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9218 bd->client.e.state.rot.preferred_rot = r;
9219 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9223 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9226 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9227 need_rotation_set = EINA_TRUE;
9229 bd->client.e.fetch.rot.preferred_rot = 0;
9231 if ((e_config->wm_win_rotation) &&
9232 (bd->client.e.fetch.rot.available_rots))
9234 Eina_Bool res, diff = EINA_FALSE;
9236 unsigned int count = 0, i = 0;
9237 int _prev_rots[4] = { -1, };
9239 if (bd->client.e.state.rot.available_rots)
9242 bd->client.e.state.rot.available_rots,
9243 (sizeof(int) * bd->client.e.state.rot.count));
9245 E_FREE(bd->client.e.state.rot.available_rots);
9248 bd->client.e.state.rot.count = 0;
9250 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9252 if ((res) && (count > 0) && (rots))
9254 bd->client.e.state.rot.available_rots = rots;
9255 bd->client.e.state.rot.count = count;
9257 for (i = 0; i < count; i++)
9259 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9260 if ((!diff) && (_prev_rots[i] != rots[i]))
9262 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9263 count, i, _prev_rots[i], rots[i]);
9270 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9274 if (diff) need_rotation_set = EINA_TRUE;
9275 bd->client.e.fetch.rot.available_rots = 0;
9278 if (bd->client.netwm.fetch.type)
9280 e_hints_window_type_get(bd);
9281 if ((!bd->lock_border) || (!bd->client.border.name))
9282 bd->client.border.changed = 1;
9284 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9286 if (!bd->client.netwm.state.skip_pager)
9288 bd->client.netwm.state.skip_pager = 1;
9289 bd->client.netwm.update.state = 1;
9291 if (!bd->client.netwm.state.skip_taskbar)
9293 bd->client.netwm.state.skip_taskbar = 1;
9294 bd->client.netwm.update.state = 1;
9297 bd->client.netwm.fetch.type = 0;
9299 if (bd->client.icccm.fetch.machine)
9301 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9303 if ((!machine) && (bd->client.icccm.client_leader))
9304 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9306 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9307 if (machine) free(machine);
9309 bd->client.icccm.fetch.machine = 0;
9312 if (bd->client.icccm.fetch.command)
9314 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9318 for (i = 0; i < bd->client.icccm.command.argc; i++)
9319 free(bd->client.icccm.command.argv[i]);
9320 free(bd->client.icccm.command.argv);
9322 bd->client.icccm.command.argc = 0;
9323 bd->client.icccm.command.argv = NULL;
9324 ecore_x_icccm_command_get(bd->client.win,
9325 &(bd->client.icccm.command.argc),
9326 &(bd->client.icccm.command.argv));
9327 if ((bd->client.icccm.client_leader) &&
9328 (!bd->client.icccm.command.argv))
9329 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9330 &(bd->client.icccm.command.argc),
9331 &(bd->client.icccm.command.argv));
9332 bd->client.icccm.fetch.command = 0;
9335 if (bd->client.icccm.fetch.hints)
9337 Eina_Bool accepts_focus, is_urgent;
9339 accepts_focus = EINA_TRUE;
9340 is_urgent = EINA_FALSE;
9341 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9342 if (ecore_x_icccm_hints_get(bd->client.win,
9344 &bd->client.icccm.initial_state,
9345 &bd->client.icccm.icon_pixmap,
9346 &bd->client.icccm.icon_mask,
9347 &bd->client.icccm.icon_window,
9348 &bd->client.icccm.window_group,
9351 bd->client.icccm.accepts_focus = accepts_focus;
9352 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9354 bd->client.icccm.urgent = is_urgent;
9356 /* If this is a new window, set the state as requested. */
9357 if ((bd->new_client) &&
9358 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9360 e_border_iconify(bd);
9361 e_border_hide(bd, 1);
9364 bd->client.icccm.fetch.hints = 0;
9367 if (bd->client.icccm.fetch.size_pos_hints)
9369 Eina_Bool request_pos;
9371 request_pos = EINA_FALSE;
9372 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9374 &bd->client.icccm.gravity,
9375 &bd->client.icccm.min_w,
9376 &bd->client.icccm.min_h,
9377 &bd->client.icccm.max_w,
9378 &bd->client.icccm.max_h,
9379 &bd->client.icccm.base_w,
9380 &bd->client.icccm.base_h,
9381 &bd->client.icccm.step_w,
9382 &bd->client.icccm.step_h,
9383 &bd->client.icccm.min_aspect,
9384 &bd->client.icccm.max_aspect))
9386 bd->client.icccm.request_pos = request_pos;
9391 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9392 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9393 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9394 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9395 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9396 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9397 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9398 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9399 // if doing a resize, fix it up
9400 if (bd->resize_mode != RESIZE_NONE)
9402 int x, y, w, h, new_w, new_h;
9410 e_border_resize_limit(bd, &new_w, &new_h);
9411 if ((bd->resize_mode == RESIZE_TL) ||
9412 (bd->resize_mode == RESIZE_L) ||
9413 (bd->resize_mode == RESIZE_BL))
9415 if ((bd->resize_mode == RESIZE_TL) ||
9416 (bd->resize_mode == RESIZE_T) ||
9417 (bd->resize_mode == RESIZE_TR))
9419 e_border_move_resize(bd, x, y, new_w, new_h);
9421 bd->client.icccm.fetch.size_pos_hints = 0;
9424 if (bd->client.icccm.fetch.protocol)
9427 Ecore_X_WM_Protocol *proto;
9429 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9432 for (i = 0; i < num; i++)
9434 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9435 bd->client.icccm.delete_request = 1;
9436 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9437 bd->client.icccm.take_focus = 1;
9438 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9439 bd->client.netwm.ping = 1;
9440 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9442 bd->client.netwm.sync.request = 1;
9443 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9444 &bd->client.netwm.sync.counter))
9445 bd->client.netwm.sync.request = 0;
9450 if (bd->client.netwm.ping)
9454 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9455 bd->ping_poller = NULL;
9457 bd->client.icccm.fetch.protocol = 0;
9459 if (bd->client.icccm.fetch.transient_for)
9461 /* TODO: What do to if the transient for isn't mapped yet? */
9462 E_Border *bd_parent = NULL;
9463 #ifdef _F_DEICONIFY_APPROVE_
9464 Eina_Bool change_parent = EINA_FALSE;
9467 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9468 if (bd->client.icccm.transient_for)
9469 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9470 /* If we already have a parent, remove it */
9473 if (bd_parent != bd->parent)
9475 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9476 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9482 if ((bd_parent) && (bd_parent != bd) &&
9483 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9485 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9486 bd->parent = bd_parent;
9487 #ifdef _F_DEICONIFY_APPROVE_
9488 change_parent = EINA_TRUE;
9493 e_border_layer_set(bd, bd->parent->layer);
9494 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9496 Ecore_X_Window_Attributes attr;
9497 bd->parent->modal = bd;
9498 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9499 bd->parent->saved.event_mask = attr.event_mask.mine;
9500 bd->parent->lock_close = 1;
9501 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9502 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9505 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9506 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9510 #ifdef _F_DEICONIFY_APPROVE_
9513 bd->client.e.state.deiconify_approve.render_done = 0;
9515 E_Border *ancestor_bd;
9516 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9517 if ((ancestor_bd) &&
9518 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9520 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9521 bd->client.e.state.deiconify_approve.ancestor = NULL;
9523 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9524 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9526 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9528 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9529 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9530 e_border_uniconify(ancestor_bd);
9536 bd->client.icccm.fetch.transient_for = 0;
9539 if (bd->client.icccm.fetch.window_role)
9541 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9542 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9543 if (role) free(role);
9545 bd->client.icccm.fetch.window_role = 0;
9548 if (bd->client.icccm.fetch.icon_name)
9550 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9551 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9552 if (icon_name) free(icon_name);
9554 bd->client.icccm.fetch.icon_name = 0;
9557 if (bd->client.netwm.fetch.icon_name)
9560 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9561 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9562 if (icon_name) free(icon_name);
9564 bd->client.netwm.fetch.icon_name = 0;
9567 if (bd->client.netwm.fetch.icon)
9570 if (bd->client.netwm.icons)
9572 for (i = 0; i < bd->client.netwm.num_icons; i++)
9574 free(bd->client.netwm.icons[i].data);
9575 bd->client.netwm.icons[i].data = NULL;
9577 free(bd->client.netwm.icons);
9579 bd->client.netwm.icons = NULL;
9580 bd->client.netwm.num_icons = 0;
9581 if (ecore_x_netwm_icons_get(bd->client.win,
9582 &bd->client.netwm.icons,
9583 &bd->client.netwm.num_icons))
9585 // unless the rest of e17 uses border icons OTHER than icon #0
9586 // then free the rest that we don't need anymore.
9587 for (i = 1; i < bd->client.netwm.num_icons; i++)
9589 free(bd->client.netwm.icons[i].data);
9590 bd->client.netwm.icons[i].data = NULL;
9592 bd->client.netwm.num_icons = 1;
9593 bd->changes.icon = 1;
9595 bd->client.netwm.fetch.icon = 0;
9597 if (bd->client.netwm.fetch.user_time)
9599 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9600 bd->client.netwm.fetch.user_time = 0;
9602 if (bd->client.netwm.fetch.strut)
9604 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9605 &bd->client.netwm.strut.left,
9606 &bd->client.netwm.strut.right,
9607 &bd->client.netwm.strut.top,
9608 &bd->client.netwm.strut.bottom,
9609 &bd->client.netwm.strut.left_start_y,
9610 &bd->client.netwm.strut.left_end_y,
9611 &bd->client.netwm.strut.right_start_y,
9612 &bd->client.netwm.strut.right_end_y,
9613 &bd->client.netwm.strut.top_start_x,
9614 &bd->client.netwm.strut.top_end_x,
9615 &bd->client.netwm.strut.bottom_start_x,
9616 &bd->client.netwm.strut.bottom_end_x))
9618 ecore_x_netwm_strut_get(bd->client.win,
9619 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9620 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9622 bd->client.netwm.strut.left_start_y = 0;
9623 bd->client.netwm.strut.left_end_y = 0;
9624 bd->client.netwm.strut.right_start_y = 0;
9625 bd->client.netwm.strut.right_end_y = 0;
9626 bd->client.netwm.strut.top_start_x = 0;
9627 bd->client.netwm.strut.top_end_x = 0;
9628 bd->client.netwm.strut.bottom_start_x = 0;
9629 bd->client.netwm.strut.bottom_end_x = 0;
9631 bd->client.netwm.fetch.strut = 0;
9633 if (bd->client.qtopia.fetch.soft_menu)
9635 e_hints_window_qtopia_soft_menu_get(bd);
9636 bd->client.qtopia.fetch.soft_menu = 0;
9639 if (bd->client.qtopia.fetch.soft_menus)
9641 e_hints_window_qtopia_soft_menus_get(bd);
9642 bd->client.qtopia.fetch.soft_menus = 0;
9645 if (bd->client.vkbd.fetch.state)
9647 e_hints_window_virtual_keyboard_state_get(bd);
9648 bd->client.vkbd.fetch.state = 0;
9651 if (bd->client.vkbd.fetch.vkbd)
9653 e_hints_window_virtual_keyboard_get(bd);
9654 bd->client.vkbd.fetch.vkbd = 0;
9657 if (bd->client.illume.conformant.fetch.conformant)
9659 bd->client.illume.conformant.conformant =
9660 ecore_x_e_illume_conformant_get(bd->client.win);
9661 bd->client.illume.conformant.fetch.conformant = 0;
9663 if (bd->client.illume.quickpanel.fetch.state)
9665 bd->client.illume.quickpanel.state =
9666 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9667 bd->client.illume.quickpanel.fetch.state = 0;
9669 if (bd->client.illume.quickpanel.fetch.quickpanel)
9671 bd->client.illume.quickpanel.quickpanel =
9672 ecore_x_e_illume_quickpanel_get(bd->client.win);
9673 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9675 if (bd->client.illume.quickpanel.fetch.priority.major)
9677 bd->client.illume.quickpanel.priority.major =
9678 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9679 bd->client.illume.quickpanel.fetch.priority.major = 0;
9681 if (bd->client.illume.quickpanel.fetch.priority.minor)
9683 bd->client.illume.quickpanel.priority.minor =
9684 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9685 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9687 if (bd->client.illume.quickpanel.fetch.zone)
9689 bd->client.illume.quickpanel.zone =
9690 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9691 bd->client.illume.quickpanel.fetch.zone = 0;
9693 if (bd->client.illume.drag.fetch.drag)
9695 bd->client.illume.drag.drag =
9696 ecore_x_e_illume_drag_get(bd->client.win);
9697 bd->client.illume.drag.fetch.drag = 0;
9699 if (bd->client.illume.drag.fetch.locked)
9701 bd->client.illume.drag.locked =
9702 ecore_x_e_illume_drag_locked_get(bd->client.win);
9703 bd->client.illume.drag.fetch.locked = 0;
9705 if (bd->client.illume.win_state.fetch.state)
9707 bd->client.illume.win_state.state =
9708 ecore_x_e_illume_window_state_get(bd->client.win);
9709 bd->client.illume.win_state.fetch.state = 0;
9711 if (bd->changes.shape)
9713 Ecore_X_Rectangle *rects;
9716 bd->changes.shape = 0;
9717 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9722 /* This doesn't fix the race, but makes it smaller. we detect
9723 * this and if cw and ch != client w/h then mark this as needing
9724 * a shape change again to fixup next event loop.
9726 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9727 if ((cw != bd->client.w) || (ch != bd->client.h))
9728 bd->changes.shape = 1;
9730 (rects[0].x == 0) &&
9731 (rects[0].y == 0) &&
9732 ((int)rects[0].width == cw) &&
9733 ((int)rects[0].height == ch))
9735 if (bd->client.shaped)
9737 bd->client.shaped = 0;
9738 if (!bd->bordername)
9739 bd->client.border.changed = 1;
9744 if (!bd->client.shaped)
9746 bd->client.shaped = 1;
9747 if (!bd->bordername)
9748 bd->client.border.changed = 1;
9755 // FIXME: no rects i think can mean... totally empty window
9756 bd->client.shaped = 0;
9757 if (!bd->bordername)
9758 bd->client.border.changed = 1;
9760 bd->need_shape_merge = 1;
9762 if (bd->changes.shape_input)
9764 Ecore_X_Rectangle *rects;
9767 bd->changes.shape_input = 0;
9768 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9773 /* This doesn't fix the race, but makes it smaller. we detect
9774 * this and if cw and ch != client w/h then mark this as needing
9775 * a shape change again to fixup next event loop.
9777 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9778 if ((cw != bd->client.w) || (ch != bd->client.h))
9779 bd->changes.shape_input = 1;
9781 (rects[0].x == 0) &&
9782 (rects[0].y == 0) &&
9783 ((int)rects[0].width == cw) &&
9784 ((int)rects[0].height == ch))
9786 if (bd->shaped_input)
9788 bd->shaped_input = 0;
9789 if (!bd->bordername)
9790 bd->client.border.changed = 1;
9795 if (!bd->shaped_input)
9797 bd->shaped_input = 1;
9798 if (!bd->bordername)
9799 bd->client.border.changed = 1;
9806 bd->shaped_input = 1;
9807 if (!bd->bordername)
9808 bd->client.border.changed = 1;
9810 bd->need_shape_merge = 1;
9812 if (bd->client.mwm.fetch.hints)
9816 bd->client.mwm.exists =
9817 ecore_x_mwm_hints_get(bd->client.win,
9818 &bd->client.mwm.func,
9819 &bd->client.mwm.decor,
9820 &bd->client.mwm.input);
9821 pb = bd->client.mwm.borderless;
9822 bd->client.mwm.borderless = 0;
9823 if (bd->client.mwm.exists)
9825 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9826 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9827 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9828 bd->client.mwm.borderless = 1;
9830 if (bd->client.mwm.borderless != pb)
9832 if ((!bd->lock_border) || (!bd->client.border.name))
9833 bd->client.border.changed = 1;
9835 bd->client.mwm.fetch.hints = 0;
9838 if (bd->client.e.fetch.video_parent)
9840 /* unlinking child/parent */
9841 if (bd->client.e.state.video_parent_border != NULL)
9843 bd->client.e.state.video_parent_border->client.e.state.video_child =
9845 (bd->client.e.state.video_parent_border->client.e.state.video_child,
9849 ecore_x_window_prop_card32_get(bd->client.win,
9850 ECORE_X_ATOM_E_VIDEO_PARENT,
9851 &bd->client.e.state.video_parent,
9854 /* linking child/parent */
9855 if (bd->client.e.state.video_parent != 0)
9860 EINA_LIST_FOREACH(borders, l, tmp)
9861 if (tmp->client.win == bd->client.e.state.video_parent)
9863 /* fprintf(stderr, "child added to parent \\o/\n"); */
9864 bd->client.e.state.video_parent_border = tmp;
9865 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
9867 if (bd->desk != tmp->desk)
9868 e_border_desk_set(bd, tmp->desk);
9873 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
9875 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
9878 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
9882 ecore_x_window_prop_card32_get(bd->client.win,
9883 ECORE_X_ATOM_E_VIDEO_POSITION,
9886 bd->client.e.state.video_position.x = xy[0];
9887 bd->client.e.state.video_position.y = xy[1];
9888 bd->client.e.state.video_position.updated = 1;
9889 bd->client.e.fetch.video_position = 0;
9890 bd->x = bd->client.e.state.video_position.x;
9891 bd->y = bd->client.e.state.video_position.y;
9893 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
9895 if (bd->client.netwm.update.state)
9897 e_hints_window_state_set(bd);
9898 /* Some stats might change the border, like modal */
9899 if (((!bd->lock_border) || (!bd->client.border.name)) &&
9900 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9902 bd->client.border.changed = 1;
9906 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9908 bd->parent->modal = bd;
9909 if (bd->parent->focused)
9910 e_border_focus_set(bd, 1, 1);
9913 else if (bd->leader)
9915 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9917 bd->leader->modal = bd;
9918 if (bd->leader->focused)
9919 e_border_focus_set(bd, 1, 1);
9925 EINA_LIST_FOREACH(bd->leader->group, l, child)
9927 if ((child != bd) && (child->focused))
9928 e_border_focus_set(bd, 1, 1);
9933 bd->client.netwm.update.state = 0;
9938 E_Event_Border_Add *ev;
9939 E_Exec_Instance *inst;
9941 ev = E_NEW(E_Event_Border_Add, 1);
9943 e_object_ref(E_OBJECT(bd));
9944 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
9945 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
9947 if ((!bd->lock_border) || (!bd->client.border.name))
9948 bd->client.border.changed = 1;
9953 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
9954 ((bd->client.icccm.client_leader > 0) &&
9955 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
9958 if (!strncmp(str, "E_START|", 8))
9963 if (id > 0) bd->client.netwm.startup_id = id;
9968 /* It's ok not to have fetch flag, should only be set on startup
9969 * * and not changed. */
9970 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
9972 if (bd->client.icccm.client_leader)
9974 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
9975 bd->client.netwm.pid = -1;
9978 bd->client.netwm.pid = -1;
9983 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
9984 bd->client.netwm.pid);
9985 if ((inst) && (inst->used == 0))
9991 zone = e_container_zone_number_get(bd->zone->container,
9993 if (zone) e_border_zone_set(bd, zone);
9994 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
9996 if (desk) e_border_desk_set(bd, desk);
9997 e_exec_instance_found(inst);
10000 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10002 E_Border *bdl = NULL;
10007 if (bd->leader) bdl = bd->leader;
10014 bl = e_container_border_list_first(bd->zone->container);
10015 while ((child = e_container_border_list_next(bl)))
10017 if (child == bd) continue;
10018 if (e_object_is_del(E_OBJECT(child))) continue;
10019 if ((bd->client.icccm.client_leader) &&
10020 (child->client.icccm.client_leader ==
10021 bd->client.icccm.client_leader))
10027 e_container_border_list_free(bl);
10032 e_border_zone_set(bd, bdl->zone);
10034 e_border_desk_set(bd, bdl->desk);
10036 e_border_stick(bd);
10042 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10045 E_Container *con = bd->zone->container;
10046 E_Desk *desk = NULL;
10049 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10051 desk = e_container_desk_window_profile_get(con, str);
10054 if (bd->desk != desk)
10056 bd->client.e.state.profile = eina_stringshare_add(str);
10057 if (bd->zone != desk->zone)
10058 e_border_zone_set(bd, desk->zone);
10059 e_border_desk_set(bd, desk);
10067 /* PRE_POST_FETCH calls e_remember apply for new client */
10068 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10069 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10070 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10072 #ifdef _F_ZONE_WINDOW_ROTATION_
10073 if (e_config->wm_win_rotation)
10075 if (need_rotation_set)
10077 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10078 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10079 if (bd->client.e.state.rot.changes != -1) bd->changed = 1;
10082 if (bd->new_client)
10084 Eina_Bool hint = EINA_FALSE;
10086 int x, y, w, h, move;
10088 if (bd->client.e.state.rot.changes != -1)
10089 ang = bd->client.e.state.rot.changes;
10090 else ang = bd->client.e.state.rot.curr;
10092 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10095 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10096 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10097 bd->client.icccm.name, x, y, w, h);
10104 if (bd->need_reparent)
10107 ecore_x_window_save_set_add(bd->client.win);
10108 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10111 if ((bd->new_client) && (bd->internal) &&
10112 (bd->internal_ecore_evas))
10113 ecore_evas_show(bd->internal_ecore_evas);
10114 ecore_x_window_show(bd->client.win);
10116 bd->need_reparent = 0;
10119 if ((bd->client.border.changed) && (!bd->shaded) &&
10120 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10122 const char *bordername;
10124 if (bd->fullscreen)
10125 bordername = "borderless";
10126 else if (bd->bordername)
10127 bordername = bd->bordername;
10128 else if ((bd->client.mwm.borderless) || (bd->borderless))
10129 bordername = "borderless";
10130 else if (((bd->client.icccm.transient_for != 0) ||
10131 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10132 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10133 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10134 bordername = "noresize_dialog";
10135 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10136 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10137 bordername = "noresize";
10138 else if (bd->client.shaped)
10139 bordername = "shaped";
10140 else if ((!bd->client.icccm.accepts_focus) &&
10141 (!bd->client.icccm.take_focus))
10142 bordername = "nofocus";
10143 else if (bd->client.icccm.urgent)
10144 bordername = "urgent";
10145 else if ((bd->client.icccm.transient_for != 0) ||
10146 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10147 bordername = "dialog";
10148 else if (bd->client.netwm.state.modal)
10149 bordername = "modal";
10150 else if ((bd->client.netwm.state.skip_taskbar) ||
10151 (bd->client.netwm.state.skip_pager))
10152 bordername = "skipped";
10153 else if ((bd->internal) && (bd->client.icccm.class) &&
10154 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10155 bordername = "internal_fileman";
10157 bordername = e_config->theme_default_border_style;
10158 if (!bordername) bordername = "default";
10160 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10166 bd->changes.border = 1;
10167 eina_stringshare_replace(&bd->client.border.name, bordername);
10171 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10172 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10173 bd->changes.size = 1;
10174 evas_object_del(bd->bg_object);
10176 o = edje_object_add(bd->bg_evas);
10177 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10178 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10179 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10181 if (bd->client.border.name != e_config->theme_default_border_style)
10183 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10184 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10188 ok = e_theme_edje_object_set(o, "base/theme/borders",
10189 "e/widgets/border/default/border");
10192 /* Reset default border style to default */
10193 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10194 e_config_save_queue();
10202 const char *shape_option, *argb_option;
10207 if ((e_config->use_composite) && (!bd->client.argb))
10209 argb_option = edje_object_data_get(o, "argb");
10210 if ((argb_option) && (!strcmp(argb_option, "1")))
10213 if (use_argb != bd->argb)
10214 _e_border_frame_replace(bd, use_argb);
10221 shape_option = edje_object_data_get(o, "shaped");
10222 if ((shape_option) && (!strcmp(shape_option, "1")))
10226 if (bd->client.netwm.name)
10227 edje_object_part_text_set(o, "e.text.title",
10228 bd->client.netwm.name);
10229 else if (bd->client.icccm.title)
10230 edje_object_part_text_set(o, "e.text.title",
10231 bd->client.icccm.title);
10235 evas_object_del(o);
10236 bd->bg_object = NULL;
10239 _e_border_client_inset_calc(bd);
10241 bd->w += (bd->client_inset.l + bd->client_inset.r);
10242 bd->h += (bd->client_inset.t + bd->client_inset.b);
10243 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10244 bd->changes.size = 1;
10245 /* really needed ? */
10246 ecore_x_window_move(bd->client.shell_win,
10247 bd->client_inset.l,
10248 bd->client_inset.t);
10250 if (bd->maximized != E_MAXIMIZE_NONE)
10252 E_Maximize maximized = bd->maximized;
10254 /* to force possible resizes */
10255 bd->maximized = E_MAXIMIZE_NONE;
10257 _e_border_maximize(bd, maximized);
10259 /* restore maximized state */
10260 bd->maximized = maximized;
10262 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10263 bd->maximized & E_MAXIMIZE_VERTICAL);
10267 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10268 _e_border_cb_signal_bind, bd);
10271 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10272 if (bd->icon_object)
10273 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10276 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10278 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10280 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10281 // FIXME: in eval -do differently
10282 // edje_object_message_signal_process(bd->bg_object);
10283 // e_border_frame_recalc(bd);
10285 evas_object_move(bd->bg_object, 0, 0);
10286 evas_object_resize(bd->bg_object, bd->w, bd->h);
10287 evas_object_show(bd->bg_object);
10290 bd->client.border.changed = 0;
10292 if (bd->icon_object)
10296 evas_object_show(bd->icon_object);
10297 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10300 evas_object_hide(bd->icon_object);
10304 if (rem_change) e_remember_update(bd);
10308 E_Event_Border_Urgent_Change *ev;
10310 if (bd->client.icccm.urgent)
10311 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10313 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10315 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10317 e_object_ref(E_OBJECT(bd));
10318 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10319 _e_border_event_border_urgent_change_free, NULL);
10322 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10325 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10327 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10329 E_Border* temp_bd = NULL;
10330 E_Border* top_focusable_bd = NULL;
10331 Eina_Bool is_fully_obscured = EINA_FALSE;
10332 Ecore_X_XRegion *visible_region = NULL;
10333 Ecore_X_XRegion *win_region = NULL;
10334 Ecore_X_Rectangle visible_rect, win_rect;
10337 // set the entire visible region as a root geometry
10338 visible_rect.x = bd->zone->x;
10339 visible_rect.y = bd->zone->y;
10340 visible_rect.width = bd->zone->w;
10341 visible_rect.height = bd->zone->h;
10343 visible_region = ecore_x_xregion_new();
10344 if (!visible_region) return;
10346 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10348 bl = e_container_border_list_last(bd->zone->container);
10349 while ((temp_bd = e_container_border_list_prev(bl)))
10351 if (temp_bd == bd) break;
10353 if (temp_bd == focused) continue;
10354 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10355 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10356 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10357 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10358 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10359 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10360 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10361 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10362 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10364 if (!top_focusable_bd)
10366 top_focusable_bd = temp_bd;
10369 win_rect.x = temp_bd->x;
10370 win_rect.y = temp_bd->y;
10371 win_rect.width = temp_bd->w;
10372 win_rect.height = temp_bd->h;
10374 // if it stick out or is bigger than the entire visible region,
10375 // clip it by the entire visible's geometry.
10376 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10377 win_rect.width, win_rect.height,
10378 visible_rect.x, visible_rect.y,
10379 (int)(visible_rect.width), (int)(visible_rect.height));
10381 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10383 win_region = ecore_x_xregion_new();
10386 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10387 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10388 ecore_x_xregion_free(win_region);
10391 if (ecore_x_xregion_is_empty(visible_region))
10393 is_fully_obscured = EINA_TRUE;
10401 if (is_fully_obscured == EINA_TRUE)
10403 e_border_focus_set(top_focusable_bd, 1, 1);
10407 e_border_focus_set(bd, 1, 1);
10410 if (visible_region) ecore_x_xregion_free(visible_region);
10411 e_container_border_list_free(bl);
10415 _e_border_latest_stacked_focus(E_Border *bd)
10418 int root_w, root_h;
10420 root_w = bd->zone->w;
10421 root_h = bd->zone->h;
10424 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10426 if (bd == temp_bd) continue;
10427 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10428 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10430 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10431 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10432 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10433 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10434 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10435 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10436 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10438 _e_border_latest_stacked_focus_check_set(temp_bd);
10445 _e_border_check_stack (E_Border *bd)
10447 E_Border* temp_bd = NULL;
10448 E_Border* top_bd = NULL;
10449 int passed_focus = 0;
10451 int root_w = bd->zone->w;
10452 int root_h = bd->zone->h;
10455 bl = e_container_border_list_last(bd->zone->container);
10456 while ((temp_bd = e_container_border_list_prev(bl)))
10458 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10459 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10460 if ((temp_bd != bd) &&
10461 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10463 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10464 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10465 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10466 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10467 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10468 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10469 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10475 e_border_focus_set_with_pointer(bd);
10482 e_border_focus_set_with_pointer(top_bd);
10491 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10493 if (!bd->lock_focus_out)
10495 e_border_focus_latest_set(bd);
10507 if (temp_bd == focused)
10513 e_container_border_list_free(bl);
10517 _e_border_focus_top_stack_set(E_Border* bd)
10520 int root_w, root_h;
10522 root_w = bd->zone->w;
10523 root_h = bd->zone->h;
10526 bl = e_container_border_list_last(bd->zone->container);
10527 while ((temp_bd = e_container_border_list_prev(bl)))
10529 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10530 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10531 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10533 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10534 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10535 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10536 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10537 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10538 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10539 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10541 if (!temp_bd->focused)
10543 /* this border is the top of the latest stack */
10544 e_border_focus_set (temp_bd, 1, 1);
10549 e_container_border_list_free(bl);
10554 _e_border_eval(E_Border *bd)
10556 E_Event_Border_Property *event;
10557 E_Border_Pending_Move_Resize *pnd;
10558 int rem_change = 0;
10559 int send_event = 1;
10561 if (e_object_is_del(E_OBJECT(bd)))
10563 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10568 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10570 if (bd->new_client)
10572 int zx = 0, zy = 0, zw = 0, zh = 0;
10575 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10578 * Limit maximum size of windows to useful geometry
10580 // TODO: temoporary limited maximize algorithm
10592 if ((rw != bd->w) || (rh != bd->h))
10596 e_border_resize (bd, bd->w, bd->h);
10602 bd->x -= bd->client_inset.l;
10603 bd->y -= bd->client_inset.t;
10604 bd->changes.pos = 1;
10607 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10610 Ecore_X_Window_Attributes *att;
10613 att = &bd->client.initial_attributes;
10614 bw = att->border * 2;
10615 switch (bd->client.icccm.gravity)
10617 case ECORE_X_GRAVITY_N:
10618 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10622 case ECORE_X_GRAVITY_NE:
10623 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10627 case ECORE_X_GRAVITY_E:
10628 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10629 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10632 case ECORE_X_GRAVITY_SE:
10633 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10634 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10637 case ECORE_X_GRAVITY_S:
10638 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10639 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10642 case ECORE_X_GRAVITY_SW:
10644 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10647 case ECORE_X_GRAVITY_W:
10649 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10652 case ECORE_X_GRAVITY_CENTER:
10653 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10654 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10657 case ECORE_X_GRAVITY_NW:
10664 * This ensures that windows that like to open with a x/y
10665 * position smaller than returned by e_zone_useful_geometry_get()
10666 * are moved to useful positions.
10669 if (e_config->geometry_auto_move)
10677 if (bd->x + bd->w > zx + zw)
10678 bd->x = zx + zw - bd->w;
10680 if (bd->y + bd->h > zy + zh)
10681 bd->y = zy + zh - bd->h;
10684 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10686 bd->changes.pos = 1;
10692 bd->changes.pos = 1;
10698 /* FIXME: special placement for dialogs etc. etc. etc goes
10700 /* FIXME: what if parent is not on this desktop - or zone? */
10701 if ((bd->parent) && (bd->parent->visible))
10703 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10704 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10705 bd->changes.pos = 1;
10709 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10711 /* TODO: Place in center of group */
10714 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10716 bd->x = zx + ((zw - bd->w) / 2);
10717 bd->y = zy + ((zh - bd->h) / 2);
10718 bd->changes.pos = 1;
10724 Eina_List *skiplist = NULL;
10728 new_x = zx + (rand() % (zw - bd->w));
10732 new_y = zy + (rand() % (zh - bd->h));
10736 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10738 skiplist = eina_list_append(skiplist, bd);
10740 e_place_desk_region_smart(bd->desk, skiplist,
10741 bd->x, bd->y, bd->w, bd->h,
10744 e_place_zone_region_smart(bd->zone, skiplist,
10745 bd->x, bd->y, bd->w, bd->h,
10747 eina_list_free(skiplist);
10749 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10751 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10756 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10757 bd->client_inset.t, &new_x, &new_y);
10761 bd->changes.pos = 1;
10764 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10766 if ((!bd->lock_client_location) && (pnd->move))
10770 bd->changes.pos = 1;
10772 if (pnd->without_border)
10774 bd->x -= bd->client_inset.l;
10775 bd->y -= bd->client_inset.t;
10778 if ((!bd->lock_client_size) && (pnd->resize))
10780 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10781 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10782 bd->client.w = pnd->w;
10783 bd->client.h = pnd->h;
10784 bd->changes.size = 1;
10790 /* Recreate state */
10791 e_hints_window_init(bd);
10792 if ((bd->client.e.state.centered) &&
10793 ((!bd->remember) ||
10794 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10796 bd->x = zx + (zw - bd->w) / 2;
10797 bd->y = zy + (zh - bd->h) / 2;
10798 bd->changes.pos = 1;
10802 _e_border_client_move_resize_send(bd);
10804 /* if the explicit geometry request asks for the app to be
10805 * in another zone - well move it there */
10809 zone = e_container_zone_at_point_get(bd->zone->container,
10810 bd->x + (bd->w / 2),
10811 bd->y + (bd->h / 2));
10813 zone = e_container_zone_at_point_get(bd->zone->container,
10817 zone = e_container_zone_at_point_get(bd->zone->container,
10821 zone = e_container_zone_at_point_get(bd->zone->container,
10823 bd->y + bd->h - 1);
10825 zone = e_container_zone_at_point_get(bd->zone->container,
10827 bd->y + bd->h - 1);
10828 if ((zone) && (zone != bd->zone))
10829 e_border_zone_set(bd, zone);
10833 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10835 /* effect changes to the window border itself */
10836 if ((bd->changes.shading))
10838 /* show at start of unshade (but don't hide until end of shade) */
10840 ecore_x_window_raise(bd->client.shell_win);
10841 bd->changes.shading = 0;
10844 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
10847 ecore_x_window_lower(bd->client.shell_win);
10849 ecore_x_window_raise(bd->client.shell_win);
10850 bd->changes.shaded = 0;
10853 else if ((bd->changes.shaded) && (bd->changes.pos))
10856 ecore_x_window_lower(bd->client.shell_win);
10858 ecore_x_window_raise(bd->client.shell_win);
10859 bd->changes.size = 1;
10860 bd->changes.shaded = 0;
10863 else if ((bd->changes.shaded) && (bd->changes.size))
10866 ecore_x_window_lower(bd->client.shell_win);
10868 ecore_x_window_raise(bd->client.shell_win);
10869 bd->changes.shaded = 0;
10872 else if (bd->changes.shaded)
10875 ecore_x_window_lower(bd->client.shell_win);
10877 ecore_x_window_raise(bd->client.shell_win);
10878 bd->changes.size = 1;
10879 bd->changes.shaded = 0;
10883 if (bd->changes.size)
10885 int x = 0, y = 0, xx = 0, yy = 0;
10887 if ((bd->shaded) && (!bd->shading))
10889 evas_obscured_clear(bd->bg_evas);
10893 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
10894 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
10896 evas_obscured_clear(bd->bg_evas);
10897 evas_obscured_rectangle_add(bd->bg_evas,
10898 bd->client_inset.l, bd->client_inset.t, xx, yy);
10902 if (bd->shade.dir == E_DIRECTION_UP)
10904 y = yy - bd->client.h;
10906 else if (bd->shade.dir == E_DIRECTION_LEFT)
10908 x = xx - bd->client.w;
10913 if (bd->client.e.state.video)
10915 if (bd->client.e.state.video_position.updated)
10917 ecore_x_window_move(bd->win,
10918 bd->client.e.state.video_parent_border->x +
10919 bd->client.e.state.video_parent_border->client_inset.l +
10920 bd->client.e.state.video_parent_border->fx.x +
10921 bd->client.e.state.video_position.x,
10922 bd->client.e.state.video_parent_border->y +
10923 bd->client.e.state.video_parent_border->client_inset.t +
10924 bd->client.e.state.video_parent_border->fx.y +
10925 bd->client.e.state.video_position.y);
10926 bd->client.e.state.video_position.updated = 0;
10929 else if (!bd->changes.pos)
10931 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10932 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10933 bd->post_resize = 1;
10940 ecore_x_window_move_resize(bd->win,
10945 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
10946 ecore_x_window_move(tmp->win,
10947 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
10948 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
10951 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
10953 if ((!bd->shaded) || (bd->shading))
10954 ecore_x_window_move_resize(bd->client.shell_win,
10955 bd->client_inset.l, bd->client_inset.t, xx, yy);
10957 if (bd->internal_ecore_evas)
10958 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
10959 else if (!bd->client.e.state.video)
10960 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
10962 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
10963 evas_object_resize(bd->bg_object, bd->w, bd->h);
10964 e_container_shape_resize(bd->shape, bd->w, bd->h);
10965 if (bd->changes.pos)
10966 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10968 _e_border_client_move_resize_send(bd);
10970 bd->changes.pos = 0;
10971 bd->changes.size = 0;
10974 else if (bd->changes.pos)
10976 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10977 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10980 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10982 _e_border_client_move_resize_send(bd);
10984 bd->changes.pos = 0;
10988 if (bd->changes.reset_gravity)
10990 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
10991 bd->changes.reset_gravity = 0;
10995 if (bd->need_shape_merge)
10997 _e_border_shape_input_rectangle_set(bd);
10998 if ((bd->shaped) || (bd->client.shaped))
11000 Ecore_X_Window twin, twin2;
11003 twin = ecore_x_window_override_new
11004 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11006 ecore_x_window_shape_window_set(twin, bd->bg_win);
11009 Ecore_X_Rectangle rects[4];
11013 rects[0].width = bd->w;
11014 rects[0].height = bd->client_inset.t;
11016 rects[1].y = bd->client_inset.t;
11017 rects[1].width = bd->client_inset.l;
11018 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11019 rects[2].x = bd->w - bd->client_inset.r;
11020 rects[2].y = bd->client_inset.t;
11021 rects[2].width = bd->client_inset.r;
11022 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11024 rects[3].y = bd->h - bd->client_inset.b;
11025 rects[3].width = bd->w;
11026 rects[3].height = bd->client_inset.b;
11027 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11029 twin2 = ecore_x_window_override_new
11030 (bd->zone->container->scratch_win, 0, 0,
11031 bd->w - bd->client_inset.l - bd->client_inset.r,
11032 bd->h - bd->client_inset.t - bd->client_inset.b);
11035 if ((bd->shading) || (bd->shaded))
11037 if (bd->shade.dir == E_DIRECTION_UP)
11038 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11039 else if (bd->shade.dir == E_DIRECTION_LEFT)
11040 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11042 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11044 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11045 bd->w - bd->client_inset.l - bd->client_inset.r,
11046 bd->h - bd->client_inset.t - bd->client_inset.b);
11047 ecore_x_window_shape_window_add_xy(twin, twin2,
11048 bd->client_inset.l,
11049 bd->client_inset.t);
11050 ecore_x_window_free(twin2);
11051 ecore_x_window_shape_window_set(bd->win, twin);
11052 ecore_x_window_free(twin);
11055 ecore_x_window_shape_mask_set(bd->win, 0);
11056 // bd->need_shape_export = 1;
11057 bd->need_shape_merge = 0;
11060 if (bd->need_shape_export)
11062 Ecore_X_Rectangle *rects, *orects;
11065 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11071 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11075 orects = bd->shape_rects;
11077 for (i = 0; i < num; i++)
11079 if (rects[i].x < 0)
11081 rects[i].width -= rects[i].x;
11084 if ((rects[i].x + (int)rects[i].width) > bd->w)
11085 rects[i].width = rects[i].width - rects[i].x;
11086 if (rects[i].y < 0)
11088 rects[i].height -= rects[i].y;
11091 if ((rects[i].y + (int)rects[i].height) > bd->h)
11092 rects[i].height = rects[i].height - rects[i].y;
11094 if ((orects[i].x != rects[i].x) ||
11095 (orects[i].y != rects[i].y) ||
11096 (orects[i].width != rects[i].width) ||
11097 (orects[i].height != rects[i].height))
11106 if (bd->client.shaped)
11107 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11109 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11110 E_FREE(bd->shape_rects);
11111 bd->shape_rects = rects;
11112 bd->shape_rects_num = num;
11113 e_container_shape_rects_set(bd->shape, rects, num);
11120 E_FREE(bd->shape_rects);
11121 bd->shape_rects = NULL;
11122 bd->shape_rects_num = 0;
11123 e_container_shape_rects_set(bd->shape, NULL, 0);
11125 bd->need_shape_export = 0;
11128 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11132 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11133 if ((!bd->placed) && (!bd->re_manage) &&
11134 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11135 (!((bd->client.icccm.transient_for != 0) ||
11136 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11137 (!bdmove) && (!bdresize))
11139 /* Set this window into moving state */
11141 bd->cur_mouse_action = e_action_find("window_move");
11142 if (bd->cur_mouse_action)
11144 if ((!bd->cur_mouse_action->func.end_mouse) &&
11145 (!bd->cur_mouse_action->func.end))
11146 bd->cur_mouse_action = NULL;
11147 if (bd->cur_mouse_action)
11149 bd->x = x - (bd->w >> 1);
11150 bd->y = y - (bd->client_inset.t >> 1);
11152 bd->changes.pos = 1;
11154 _e_border_client_move_resize_send(bd);
11159 _e_border_show(bd);
11161 if (bd->cur_mouse_action)
11163 bd->moveinfo.down.x = bd->x + bd->fx.x;
11164 bd->moveinfo.down.y = bd->y + bd->fx.y;
11165 bd->moveinfo.down.w = bd->w;
11166 bd->moveinfo.down.h = bd->h;
11167 bd->mouse.current.mx = x;
11168 bd->mouse.current.my = y;
11169 bd->moveinfo.down.button = 0;
11170 bd->moveinfo.down.mx = x;
11171 bd->moveinfo.down.my = y;
11174 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11175 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11176 if (e_config->border_raise_on_mouse_action)
11177 e_border_raise(bd);
11178 e_border_focus_set(bd, 1, 1);
11180 bd->changes.visible = 0;
11184 if (bd->changes.icon)
11188 efreet_desktop_free(bd->desktop);
11189 bd->desktop = NULL;
11191 if (bd->icon_object)
11193 evas_object_del(bd->icon_object);
11194 bd->icon_object = NULL;
11196 if (bd->remember && bd->remember->prop.desktop_file)
11198 const char *desktop = bd->remember->prop.desktop_file;
11200 bd->desktop = efreet_desktop_get(desktop);
11202 bd->desktop = efreet_util_desktop_name_find(desktop);
11206 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11207 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11208 bd->client.icccm.class);
11212 /* libreoffice and maybe others match window class
11213 with .desktop file name */
11214 if (bd->client.icccm.class)
11217 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11218 bd->desktop = efreet_util_desktop_file_id_find(buf);
11223 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11224 bd->client.netwm.pid);
11225 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11227 if (!bd->desktop && bd->client.icccm.name)
11229 /* this works for most cases as fallback. useful when app is
11230 run from a shell */
11231 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11233 if (!bd->desktop && bd->client.icccm.transient_for)
11235 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11236 if (bd2 && bd2->desktop)
11238 efreet_desktop_ref(bd2->desktop);
11239 bd->desktop = bd2->desktop;
11244 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11245 bd->desktop->orig_path);
11248 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11249 if ((bd->focused) && (bd->icon_object))
11250 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11253 evas_object_show(bd->icon_object);
11254 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11257 evas_object_hide(bd->icon_object);
11260 E_Event_Border_Icon_Change *ev;
11262 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11264 e_object_ref(E_OBJECT(bd));
11265 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11266 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11267 _e_border_event_border_icon_change_free, NULL);
11269 bd->changes.icon = 0;
11272 bd->new_client = 0;
11274 bd->changes.stack = 0;
11275 bd->changes.prop = 0;
11277 if (bd->client.e.state.rot.changes != -1)
11279 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11280 bd->client.e.state.rot.changes = -1;
11283 if ((bd->take_focus) || (bd->want_focus))
11285 bd->take_focus = 0;
11286 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11287 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11288 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11291 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11294 bd->want_focus = 0;
11295 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11296 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11297 _e_border_check_stack(bd);
11300 e_border_focus_set_with_pointer(bd);
11302 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11304 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11305 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11306 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11307 e_border_focused_get())))
11309 e_border_focus_set_with_pointer(bd);
11314 /* focus window by default when it is the only one on desk */
11315 E_Border *bd2 = NULL;
11317 EINA_LIST_FOREACH(focus_stack, l, bd2)
11319 if (bd == bd2) continue;
11320 if ((!bd2->iconic) && (bd2->visible) &&
11321 ((bd->desk == bd2->desk) || bd2->sticky))
11327 e_border_focus_set_with_pointer(bd);
11332 if (bd->need_maximize)
11335 max = bd->maximized;
11336 bd->maximized = E_MAXIMIZE_NONE;
11337 e_border_maximize(bd, max);
11338 bd->need_maximize = 0;
11341 if (bd->need_fullscreen)
11343 e_border_fullscreen(bd, e_config->fullscreen_policy);
11344 bd->need_fullscreen = 0;
11348 e_remember_update(bd);
11350 if (send_event) // FIXME: send only if a property changed - above need to
11351 { // check on that. for now - always send.
11352 event = E_NEW(E_Event_Border_Property, 1);
11353 event->border = bd;
11354 e_object_ref(E_OBJECT(bd));
11355 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11357 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11361 _e_border_moveinfo_gather(E_Border *bd,
11362 const char *source)
11364 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11365 else if (e_util_glob_match(source, "mouse,*,2"))
11366 bd->moveinfo.down.button = 2;
11367 else if (e_util_glob_match(source, "mouse,*,3"))
11368 bd->moveinfo.down.button = 3;
11369 else bd->moveinfo.down.button = 0;
11370 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11372 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11373 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11377 bd->moveinfo.down.mx = bd->mouse.current.mx;
11378 bd->moveinfo.down.my = bd->mouse.current.my;
11383 _e_border_resize_handle(E_Border *bd)
11386 int new_x, new_y, new_w, new_h;
11388 Eina_List *skiplist = NULL;
11395 if ((bd->resize_mode == RESIZE_TR) ||
11396 (bd->resize_mode == RESIZE_R) ||
11397 (bd->resize_mode == RESIZE_BR))
11399 if ((bd->moveinfo.down.button >= 1) &&
11400 (bd->moveinfo.down.button <= 3))
11401 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11402 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11404 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11406 else if ((bd->resize_mode == RESIZE_TL) ||
11407 (bd->resize_mode == RESIZE_L) ||
11408 (bd->resize_mode == RESIZE_BL))
11410 if ((bd->moveinfo.down.button >= 1) &&
11411 (bd->moveinfo.down.button <= 3))
11412 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11413 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11415 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11418 if ((bd->resize_mode == RESIZE_TL) ||
11419 (bd->resize_mode == RESIZE_T) ||
11420 (bd->resize_mode == RESIZE_TR))
11422 if ((bd->moveinfo.down.button >= 1) &&
11423 (bd->moveinfo.down.button <= 3))
11424 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11425 (bd->mouse.current.my - bd->moveinfo.down.my);
11427 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11429 else if ((bd->resize_mode == RESIZE_BL) ||
11430 (bd->resize_mode == RESIZE_B) ||
11431 (bd->resize_mode == RESIZE_BR))
11433 if ((bd->moveinfo.down.button >= 1) &&
11434 (bd->moveinfo.down.button <= 3))
11435 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11436 (bd->mouse.current.my - bd->moveinfo.down.my);
11438 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11444 if ((bd->resize_mode == RESIZE_TL) ||
11445 (bd->resize_mode == RESIZE_L) ||
11446 (bd->resize_mode == RESIZE_BL))
11448 if ((bd->resize_mode == RESIZE_TL) ||
11449 (bd->resize_mode == RESIZE_T) ||
11450 (bd->resize_mode == RESIZE_TR))
11453 skiplist = eina_list_append(skiplist, bd);
11454 e_resist_container_border_position(bd->zone->container, skiplist,
11455 bd->x, bd->y, bd->w, bd->h,
11457 &new_x, &new_y, &new_w, &new_h);
11458 eina_list_free(skiplist);
11462 e_border_resize_limit(bd, &new_w, &new_h);
11463 if ((bd->resize_mode == RESIZE_TL) ||
11464 (bd->resize_mode == RESIZE_L) ||
11465 (bd->resize_mode == RESIZE_BL))
11466 new_x += (w - new_w);
11467 if ((bd->resize_mode == RESIZE_TL) ||
11468 (bd->resize_mode == RESIZE_T) ||
11469 (bd->resize_mode == RESIZE_TR))
11470 new_y += (h - new_h);
11472 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11476 _e_border_shade_animator(void *data)
11478 E_Border *bd = data;
11480 double dur = bd->client.h / e_config->border_shade_speed;
11482 dt = ecore_loop_time_get() - bd->shade.start;
11485 if (val < 0.0) val = 0.0;
11486 else if (val > 1.0) val = 1.0;
11488 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11491 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11492 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11494 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11497 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11498 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11500 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11503 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11504 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11506 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11509 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11510 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11512 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11515 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11516 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11518 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11521 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11522 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11524 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11527 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11528 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11530 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11533 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11534 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11536 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11539 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11540 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11545 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11546 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11549 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11550 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11551 else if (bd->shade.val > .999)
11552 bd->shade.val = 1.0;
11554 if (bd->shade.dir == E_DIRECTION_UP)
11555 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11556 else if (bd->shade.dir == E_DIRECTION_DOWN)
11558 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11559 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11560 bd->changes.pos = 1;
11562 else if (bd->shade.dir == E_DIRECTION_LEFT)
11563 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11564 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11566 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11567 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11568 bd->changes.pos = 1;
11571 if ((bd->shaped) || (bd->client.shaped))
11573 bd->need_shape_merge = 1;
11574 bd->need_shape_export = 1;
11576 if (bd->shaped_input)
11578 bd->need_shape_merge = 1;
11580 bd->changes.size = 1;
11586 E_Event_Border_Resize *ev;
11589 bd->shaded = !(bd->shaded);
11590 bd->changes.size = 1;
11591 bd->changes.shaded = 1;
11592 bd->changes.shading = 1;
11594 bd->shade.anim = NULL;
11597 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11599 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11600 edje_object_message_signal_process(bd->bg_object);
11601 e_border_frame_recalc(bd);
11603 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11604 ev = E_NEW(E_Event_Border_Resize, 1);
11606 e_object_ref(E_OBJECT(bd));
11607 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11608 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11609 return ECORE_CALLBACK_CANCEL;
11611 return ECORE_CALLBACK_RENEW;
11615 _e_border_event_border_resize_free(void *data __UNUSED__,
11618 E_Event_Border_Resize *e;
11621 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11622 e_object_unref(E_OBJECT(e->border));
11627 _e_border_event_border_move_free(void *data __UNUSED__,
11630 E_Event_Border_Move *e;
11633 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11634 e_object_unref(E_OBJECT(e->border));
11639 _e_border_event_border_add_free(void *data __UNUSED__,
11642 E_Event_Border_Add *e;
11645 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11646 e_object_unref(E_OBJECT(e->border));
11651 _e_border_event_border_remove_free(void *data __UNUSED__,
11654 E_Event_Border_Remove *e;
11657 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11658 e_object_unref(E_OBJECT(e->border));
11663 _e_border_event_border_show_free(void *data __UNUSED__,
11666 E_Event_Border_Show *e;
11669 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11670 e_object_unref(E_OBJECT(e->border));
11675 _e_border_event_border_hide_free(void *data __UNUSED__,
11678 E_Event_Border_Hide *e;
11681 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11682 e_object_unref(E_OBJECT(e->border));
11687 _e_border_event_border_iconify_free(void *data __UNUSED__,
11690 E_Event_Border_Iconify *e;
11693 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11694 e_object_unref(E_OBJECT(e->border));
11699 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11702 E_Event_Border_Uniconify *e;
11705 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11706 e_object_unref(E_OBJECT(e->border));
11711 _e_border_event_border_stick_free(void *data __UNUSED__,
11714 E_Event_Border_Stick *e;
11717 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11718 e_object_unref(E_OBJECT(e->border));
11723 _e_border_event_border_unstick_free(void *data __UNUSED__,
11726 E_Event_Border_Unstick *e;
11729 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11730 e_object_unref(E_OBJECT(e->border));
11735 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11738 E_Event_Border_Zone_Set *e;
11741 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11742 e_object_unref(E_OBJECT(e->border));
11743 e_object_unref(E_OBJECT(e->zone));
11748 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11751 E_Event_Border_Desk_Set *e;
11754 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11755 e_object_unref(E_OBJECT(e->border));
11756 e_object_unref(E_OBJECT(e->desk));
11761 _e_border_event_border_stack_free(void *data __UNUSED__,
11764 E_Event_Border_Stack *e;
11767 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11768 e_object_unref(E_OBJECT(e->border));
11771 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11772 e_object_unref(E_OBJECT(e->stack));
11778 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11781 E_Event_Border_Icon_Change *e;
11784 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11785 e_object_unref(E_OBJECT(e->border));
11790 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11793 E_Event_Border_Urgent_Change *e;
11796 e_object_unref(E_OBJECT(e->border));
11801 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11804 E_Event_Border_Focus_In *e;
11807 e_object_unref(E_OBJECT(e->border));
11812 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11815 E_Event_Border_Focus_Out *e;
11818 e_object_unref(E_OBJECT(e->border));
11823 _e_border_event_border_property_free(void *data __UNUSED__,
11826 E_Event_Border_Property *e;
11829 e_object_unref(E_OBJECT(e->border));
11834 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11837 E_Event_Border_Fullscreen *e;
11840 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11841 e_object_unref(E_OBJECT(e->border));
11846 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
11849 E_Event_Border_Unfullscreen *e;
11852 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
11853 e_object_unref(E_OBJECT(e->border));
11857 #ifdef _F_ZONE_WINDOW_ROTATION_
11859 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
11862 E_Event_Border_Rotation_Change_Begin *e;
11864 e_object_unref(E_OBJECT(e->border));
11869 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
11872 E_Event_Border_Rotation_Change_Cancel *e;
11874 e_object_unref(E_OBJECT(e->border));
11879 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
11882 E_Event_Border_Rotation_Change_End *e;
11884 e_object_unref(E_OBJECT(e->border));
11889 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
11891 E_Event_Border_Rotation_Change_Begin *ev = NULL;
11892 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
11896 e_object_ref(E_OBJECT(bd));
11897 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
11899 _e_border_event_border_rotation_change_begin_free,
11906 _e_border_zone_update(E_Border *bd)
11912 /* still within old zone - leave it there */
11913 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11914 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
11915 #if _F_BORDER_CLIP_TO_ZONE_
11917 _e_border_shape_input_clip_to_zone(bd);
11922 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11923 /* find a new zone */
11924 con = bd->zone->container;
11925 EINA_LIST_FOREACH(con->zones, l, zone)
11927 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11928 zone->x, zone->y, zone->w, zone->h))
11930 e_border_zone_set(bd, zone);
11931 #if _F_BORDER_CLIP_TO_ZONE_
11932 _e_border_shape_input_clip_to_zone(bd);
11933 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11940 _e_border_resize_begin(E_Border *bd)
11942 if (!bd->lock_user_stacking)
11944 if (e_config->border_raise_on_mouse_action)
11945 e_border_raise(bd);
11947 if ((bd->shaded) || (bd->shading) ||
11948 (bd->fullscreen) || (bd->lock_user_size))
11951 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11957 if (bd->client.netwm.sync.request)
11959 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11960 bd->client.netwm.sync.serial = 1;
11961 bd->client.netwm.sync.wait = 0;
11962 bd->client.netwm.sync.send_time = ecore_loop_time_get();
11965 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
11972 _e_border_resize_end(E_Border *bd)
11976 e_grabinput_release(bd->win, bd->win);
11979 if (bd->client.netwm.sync.alarm)
11981 E_Border_Pending_Move_Resize *pnd;
11983 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11984 bd->client.netwm.sync.alarm = 0;
11985 /* resize to last geometry if sync alarm for it was not yet handled */
11986 if (bd->pending_move_resize)
11989 bd->changes.pos = 1;
11990 bd->changes.size = 1;
11991 _e_border_client_move_resize_send(bd);
11994 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11998 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12002 /* If this border was maximized, we need to unset Maximized state or
12003 * on restart, E still thinks it's maximized */
12004 if (bd->maximized != E_MAXIMIZE_NONE)
12005 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12006 bd->maximized & E_MAXIMIZE_NONE);
12011 _e_border_resize_update(E_Border *bd)
12013 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12017 _e_border_move_begin(E_Border *bd)
12019 if (!bd->lock_user_stacking)
12021 if (e_config->border_raise_on_mouse_action)
12022 e_border_raise(bd);
12024 if ((bd->fullscreen) || (bd->lock_user_location))
12027 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
12033 if (bd->client.netwm.sync.request)
12035 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12036 bd->client.netwm.sync.serial = 0;
12037 bd->client.netwm.sync.wait = 0;
12038 bd->client.netwm.sync.time = ecore_loop_time_get();
12041 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12048 _e_border_move_end(E_Border *bd)
12052 e_grabinput_release(bd->win, bd->win);
12056 if (bd->client.netwm.sync.alarm)
12058 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12059 bd->client.netwm.sync.alarm = 0;
12062 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12069 _e_border_move_update(E_Border *bd)
12071 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12075 _e_border_cb_ping_poller(void *data)
12085 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12086 if (bd->kill_timer)
12088 ecore_timer_del(bd->kill_timer);
12089 bd->kill_timer = NULL;
12095 /* if time between last ping and now is greater
12096 * than half the ping interval... */
12097 if ((ecore_loop_time_get() - bd->ping) >
12098 ((e_config->ping_clients_interval *
12099 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12104 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12105 /* FIXME: if below dialog is up - hide it now */
12107 if (bd->delete_requested)
12109 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12110 e_border_act_kill_begin(bd);
12114 bd->ping_poller = NULL;
12116 return ECORE_CALLBACK_CANCEL;
12120 _e_border_cb_kill_timer(void *data)
12125 // dont wait until it's hung -
12128 if (bd->client.netwm.pid > 1)
12129 kill(bd->client.netwm.pid, SIGKILL);
12131 bd->kill_timer = NULL;
12132 return ECORE_CALLBACK_CANCEL;
12136 _e_border_pointer_resize_begin(E_Border *bd)
12138 switch (bd->resize_mode)
12141 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12145 e_pointer_type_push(bd->pointer, bd, "resize_t");
12149 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12153 e_pointer_type_push(bd->pointer, bd, "resize_r");
12157 e_pointer_type_push(bd->pointer, bd, "resize_br");
12161 e_pointer_type_push(bd->pointer, bd, "resize_b");
12165 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12169 e_pointer_type_push(bd->pointer, bd, "resize_l");
12175 _e_border_pointer_resize_end(E_Border *bd)
12177 switch (bd->resize_mode)
12180 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12184 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12188 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12192 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12196 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12200 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12204 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12208 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12214 _e_border_pointer_move_begin(E_Border *bd)
12216 e_pointer_type_push(bd->pointer, bd, "move");
12220 _e_border_pointer_move_end(E_Border *bd)
12222 e_pointer_type_pop(bd->pointer, bd, "move");
12225 static Eina_List *_e_border_hooks = NULL;
12226 static int _e_border_hooks_delete = 0;
12227 static int _e_border_hooks_walking = 0;
12230 _e_border_hooks_clean(void)
12235 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12239 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12246 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12252 _e_border_hooks_walking++;
12253 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12255 if (bh->delete_me) continue;
12256 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12258 _e_border_hooks_walking--;
12259 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12260 _e_border_hooks_clean();
12263 EAPI E_Border_Hook *
12264 e_border_hook_add(E_Border_Hook_Point hookpoint,
12265 void (*func)(void *data,
12271 bh = E_NEW(E_Border_Hook, 1);
12272 if (!bh) return NULL;
12273 bh->hookpoint = hookpoint;
12276 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12281 e_border_hook_del(E_Border_Hook *bh)
12284 if (_e_border_hooks_walking == 0)
12286 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12290 _e_border_hooks_delete++;
12294 e_border_focus_track_freeze(void)
12296 focus_track_frozen++;
12300 e_border_focus_track_thaw(void)
12302 focus_track_frozen--;
12306 e_border_under_pointer_get(E_Desk *desk,
12309 E_Border *bd = NULL, *cbd;
12313 /* We need to ensure that we can get the container window for the
12314 * zone of either the given desk or the desk of the excluded
12315 * window, so return if neither is given */
12317 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12319 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12323 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12325 if (!cbd) continue;
12326 /* If a border was specified which should be excluded from the list
12327 * (because it will be closed shortly for example), skip */
12328 if ((exclude) && (cbd == exclude)) continue;
12329 if ((desk) && (cbd->desk != desk)) continue;
12330 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12332 /* If the layer is higher, the position of the window is higher
12333 * (always on top vs always below) */
12334 if (!bd || (cbd->layer > bd->layer))
12344 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12351 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12352 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12353 (y - warp_y) > 5 || (y - warp_y) < -5)
12355 /* User moved the mouse, so stop warping */
12360 /* We just use the same warp speed as configured
12361 * for the windowlist */
12362 spd = e_config->winlist_warp_speed;
12365 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12366 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12367 if (warp_x == x && warp_y == y)
12369 warp_x = warp_to_x;
12370 warp_y = warp_to_y;
12374 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12375 return ECORE_CALLBACK_RENEW;
12378 ecore_timer_del(warp_timer);
12380 return ECORE_CALLBACK_CANCEL;
12384 e_border_pointer_warp_to_center(E_Border *bd)
12388 /* Do not slide pointer when disabled (probably breaks focus
12389 * on sloppy/mouse focus but requested by users). */
12390 if (!e_config->pointer_slide) return 0;
12391 /* Only warp the pointer if it is not already in the area of
12392 * the given border */
12393 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12394 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12395 (y >= bd->y) && (y <= (bd->y + bd->h)))
12398 warp_to_x = bd->x + (bd->w / 2);
12399 if (warp_to_x < (bd->zone->x + 1))
12400 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12401 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12402 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12404 warp_to_y = bd->y + (bd->h / 2);
12405 if (warp_to_y < (bd->zone->y + 1))
12406 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12407 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12408 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12411 warp_to_win = bd->zone->container->win;
12412 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12414 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12419 e_border_comp_hidden_set(E_Border *bd,
12425 E_OBJECT_CHECK(bd);
12426 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12428 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12431 ecore_x_window_hide(tmp->win);
12433 ecore_x_window_show(tmp->win);
12436 if (bd->comp_hidden == hidden) return;
12438 bd->comp_hidden = hidden;
12440 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12442 ecore_x_composite_window_events_disable(bd->win);
12443 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12447 _e_border_shape_input_rectangle_set(bd);
12448 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12453 e_border_tmp_input_hidden_push(E_Border *bd)
12458 E_OBJECT_CHECK(bd);
12459 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12461 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12462 e_border_tmp_input_hidden_push(tmp);
12464 bd->tmp_input_hidden++;
12465 if (bd->tmp_input_hidden != 1) return;
12467 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12469 ecore_x_composite_window_events_disable(bd->win);
12470 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12474 _e_border_shape_input_rectangle_set(bd);
12475 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12480 e_border_tmp_input_hidden_pop(E_Border *bd)
12485 E_OBJECT_CHECK(bd);
12486 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12488 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12489 e_border_tmp_input_hidden_pop(tmp);
12491 bd->tmp_input_hidden--;
12492 if (bd->tmp_input_hidden != 0) return;
12494 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12496 ecore_x_composite_window_events_disable(bd->win);
12497 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12501 _e_border_shape_input_rectangle_set(bd);
12502 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12507 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12509 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12511 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12512 ((bd->parent->focused) &&
12513 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12518 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12519 e_desk_show(bd->desk);
12521 if (!bd->lock_user_iconify)
12522 e_border_uniconify(bd);
12524 if ((!bd->iconic) && (!bd->sticky))
12525 e_desk_show(bd->desk);
12526 if (!bd->lock_user_stacking) e_border_raise(bd);
12527 if (!bd->lock_focus_out)
12529 /* XXX ooffice does send this request for
12530 config dialogs when the main window gets focus.
12531 causing the pointer to jump back and forth. */
12532 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12533 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12534 ecore_x_pointer_warp(bd->zone->container->win,
12535 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12536 e_border_focus_set(bd, 1, 1);
12540 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/