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);
183 static Eina_Bool _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending);
185 static void _e_border_move_resize_internal(E_Border *bd,
190 Eina_Bool without_border,
193 static void _e_border_eval(E_Border *bd);
194 static void _e_border_eval0(E_Border *bd);
195 static void _e_border_container_layout_hook(E_Container *con);
197 static void _e_border_moveinfo_gather(E_Border *bd,
199 static void _e_border_resize_handle(E_Border *bd);
201 static Eina_Bool _e_border_shade_animator(void *data);
203 static void _e_border_event_border_add_free(void *data,
205 static void _e_border_event_border_remove_free(void *data,
207 static void _e_border_event_border_zone_set_free(void *data,
209 static void _e_border_event_border_desk_set_free(void *data,
211 static void _e_border_event_border_stack_free(void *data,
213 static void _e_border_event_border_icon_change_free(void *data,
215 static void _e_border_event_border_urgent_change_free(void *data,
217 static void _e_border_event_border_focus_in_free(void *data,
219 static void _e_border_event_border_focus_out_free(void *data,
221 static void _e_border_event_border_resize_free(void *data,
223 static void _e_border_event_border_move_free(void *data,
225 static void _e_border_event_border_show_free(void *data,
227 static void _e_border_event_border_hide_free(void *data,
229 static void _e_border_event_border_iconify_free(void *data,
231 static void _e_border_event_border_uniconify_free(void *data,
233 static void _e_border_event_border_stick_free(void *data,
235 static void _e_border_event_border_unstick_free(void *data,
237 static void _e_border_event_border_property_free(void *data,
239 static void _e_border_event_border_fullscreen_free(void *data,
241 static void _e_border_event_border_unfullscreen_free(void *data,
243 #ifdef _F_ZONE_WINDOW_ROTATION_
244 static void _e_border_event_border_rotation_change_begin_free(void *data,
246 static void _e_border_event_border_rotation_change_cancel_free(void *data,
248 static void _e_border_event_border_rotation_change_end_free(void *data,
250 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
253 static void _e_border_zone_update(E_Border *bd);
255 static int _e_border_resize_begin(E_Border *bd);
256 static int _e_border_resize_end(E_Border *bd);
257 static void _e_border_resize_update(E_Border *bd);
259 static int _e_border_move_begin(E_Border *bd);
260 static int _e_border_move_end(E_Border *bd);
261 static void _e_border_move_update(E_Border *bd);
263 static Eina_Bool _e_border_cb_ping_poller(void *data);
264 static Eina_Bool _e_border_cb_kill_timer(void *data);
266 static void _e_border_pointer_resize_begin(E_Border *bd);
267 static void _e_border_pointer_resize_end(E_Border *bd);
268 static void _e_border_pointer_move_begin(E_Border *bd);
269 static void _e_border_pointer_move_end(E_Border *bd);
271 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
274 static void _e_border_client_move_resize_send(E_Border *bd);
276 static void _e_border_frame_replace(E_Border *bd,
279 static void _e_border_shape_input_rectangle_set(E_Border* bd);
280 static void _e_border_show(E_Border *bd);
281 static void _e_border_hide(E_Border *bd);
284 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
285 static void _e_border_latest_stacked_focus (E_Border* bd);
286 static void _e_border_check_stack (E_Border *bd);
287 static void _e_border_focus_top_stack_set (E_Border* bd);
289 #if _F_BORDER_CLIP_TO_ZONE_
290 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
291 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
292 /* local subsystem globals */
293 static Eina_List *handlers = NULL;
294 static Eina_List *borders = NULL;
295 static Eina_Hash *borders_hash = NULL;
296 static E_Border *focused = NULL;
297 static E_Border *focusing = NULL;
298 static Eina_List *focus_next = NULL;
299 static Ecore_X_Time focus_time = 0;
301 static E_Border *bdresize = NULL;
302 static E_Border *bdmove = NULL;
303 static E_Drag *drag_border = NULL;
305 static int grabbed = 0;
307 static Eina_List *focus_stack = NULL;
308 static Eina_List *raise_stack = NULL;
310 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
311 static int screen_size_index = -1;
313 static int focus_track_frozen = 0;
315 static int warp_to = 0;
316 static int warp_to_x = 0;
317 static int warp_to_y = 0;
318 static int warp_x = 0;
319 static int warp_y = 0;
320 static Ecore_X_Window warp_to_win;
321 static Ecore_Timer *warp_timer = NULL;
323 #ifdef _F_ZONE_WINDOW_ROTATION_
324 typedef struct _E_Border_Rotation E_Border_Rotation;
325 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
327 struct _E_Border_Rotation
330 Eina_List *async_list;
332 Eina_Bool wait_prepare_done;
333 Ecore_Timer *prepare_timer;
334 Ecore_Timer *done_timer;
336 Ecore_Job *async_job;
338 Ecore_X_Window vkbd_ctrl_win;
340 E_Border *vkbd_prediction;
342 /* vkbd show/hide preprare */
343 Eina_Bool vkbd_show_prepare_done;
344 Ecore_Timer *vkbd_show_prepare_timer;
345 Ecore_Timer *vkbd_show_timer;
347 Eina_Bool vkbd_hide_prepare_done;
348 Ecore_Timer *vkbd_hide_prepare_timer;
349 Ecore_Timer *vkbd_hide_timer;
355 struct _E_Border_Rotation_Info
360 Eina_Bool win_resize;
363 static E_Border_Rotation rot =
386 EAPI int E_EVENT_BORDER_ADD = 0;
387 EAPI int E_EVENT_BORDER_REMOVE = 0;
388 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
389 EAPI int E_EVENT_BORDER_DESK_SET = 0;
390 EAPI int E_EVENT_BORDER_RESIZE = 0;
391 EAPI int E_EVENT_BORDER_MOVE = 0;
392 EAPI int E_EVENT_BORDER_SHOW = 0;
393 EAPI int E_EVENT_BORDER_HIDE = 0;
394 EAPI int E_EVENT_BORDER_ICONIFY = 0;
395 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
396 EAPI int E_EVENT_BORDER_STICK = 0;
397 EAPI int E_EVENT_BORDER_UNSTICK = 0;
398 EAPI int E_EVENT_BORDER_STACK = 0;
399 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
400 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
401 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
402 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
403 EAPI int E_EVENT_BORDER_PROPERTY = 0;
404 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
405 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
406 #ifdef _F_ZONE_WINDOW_ROTATION_
407 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
408 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
409 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
410 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
413 #define GRAV_SET(bd, grav) \
414 ecore_x_window_gravity_set(bd->bg_win, grav); \
415 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
416 ecore_x_window_gravity_set(bd->client.win, grav);
419 _e_border_sub_borders_new(E_Border *bd)
421 Eina_List *list = NULL, *l;
425 EINA_LIST_FOREACH(bd->transients, l, child)
427 if (!eina_list_data_find(list, child))
428 list = eina_list_append(list, child);
430 bl = e_container_border_list_first(bd->zone->container);
431 while ((child = e_container_border_list_next(bl)))
433 if (e_object_is_del(E_OBJECT(child))) continue;
434 if (child == bd) continue;
436 if ((bd->client.icccm.client_leader) &&
437 (child->client.icccm.client_leader ==
438 bd->client.icccm.client_leader))
440 printf("bd %s in group with %s\n",
441 e_border_name_get(child),
442 e_border_name_get(bd));
443 if (!eina_list_data_find(list, child))
444 list = eina_list_append(list, child);
448 e_container_border_list_free(bl);
452 /* externally accessible functions */
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
473 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
474 #ifdef _F_ZONE_WINDOW_ROTATION_
475 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
478 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
480 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
483 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
484 #ifdef _F_USE_DESK_WINDOW_PROFILE_
485 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
487 #ifdef _F_ZONE_WINDOW_ROTATION_
488 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
491 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
493 E_EVENT_BORDER_ADD = ecore_event_type_new();
494 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
495 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
496 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
497 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
498 E_EVENT_BORDER_MOVE = ecore_event_type_new();
499 E_EVENT_BORDER_SHOW = ecore_event_type_new();
500 E_EVENT_BORDER_HIDE = ecore_event_type_new();
501 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
502 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
503 E_EVENT_BORDER_STICK = ecore_event_type_new();
504 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
505 E_EVENT_BORDER_STACK = ecore_event_type_new();
506 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
507 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
508 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
509 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
510 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
511 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
512 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
513 #ifdef _F_ZONE_WINDOW_ROTATION_
514 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
515 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
516 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
517 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
526 e_border_shutdown(void)
528 E_FREE_LIST(handlers, ecore_event_handler_del);
530 if (borders_hash) eina_hash_free(borders_hash);
532 e_int_border_menu_hooks_clear();
538 e_border_new(E_Container *con,
544 Ecore_X_Window_Attributes *att;
545 unsigned int managed, desk[2];
548 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
549 if (!bd) return NULL;
550 ecore_x_window_shadow_tree_flush();
551 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
555 /* FIXME: ewww - round trip */
556 bd->client.argb = ecore_x_window_argb_get(win);
558 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
561 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
562 ecore_x_window_shape_events_select(bd->win, 1);
564 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
565 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
567 bd->bg_ecore_evas = e_canvas_new(bd->win,
568 0, 0, bd->w, bd->h, 1, 0,
570 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
571 e_canvas_add(bd->bg_ecore_evas);
572 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
573 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
574 ecore_x_window_shape_events_select(bd->bg_win, 1);
575 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
576 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
578 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
580 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
581 ecore_x_window_container_manage(bd->client.shell_win);
582 if (!internal) ecore_x_window_client_manage(win);
583 /* FIXME: Round trip. XCB */
584 /* fetch needed to avoid grabbing the server as window may vanish */
585 att = &bd->client.initial_attributes;
586 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
588 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
589 e_canvas_del(bd->bg_ecore_evas);
590 ecore_evas_free(bd->bg_ecore_evas);
591 ecore_x_window_free(bd->client.shell_win);
592 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
593 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
594 ecore_x_window_free(bd->win);
599 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
600 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
602 /* FIXME: if first_map is 1 then we should ignore the first hide event
603 * or ensure the window is already hidden and events flushed before we
604 * create a border for it */
607 // printf("##- FIRST MAP\n");
612 // needed to be 1 for internal windw and on restart.
613 // bd->ignore_first_unmap = 2;
616 bd->client.win = win;
617 bd->zone = e_zone_current_get(con);
619 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
621 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
622 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
623 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
624 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
625 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
626 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
628 bd->client.icccm.title = NULL;
629 bd->client.icccm.name = NULL;
630 bd->client.icccm.class = NULL;
631 bd->client.icccm.icon_name = NULL;
632 bd->client.icccm.machine = NULL;
633 bd->client.icccm.min_w = 1;
634 bd->client.icccm.min_h = 1;
635 bd->client.icccm.max_w = 32767;
636 bd->client.icccm.max_h = 32767;
637 bd->client.icccm.base_w = 0;
638 bd->client.icccm.base_h = 0;
639 bd->client.icccm.step_w = -1;
640 bd->client.icccm.step_h = -1;
641 bd->client.icccm.min_aspect = 0.0;
642 bd->client.icccm.max_aspect = 0.0;
643 bd->client.icccm.accepts_focus = 1;
645 bd->client.netwm.pid = 0;
646 bd->client.netwm.name = NULL;
647 bd->client.netwm.icon_name = NULL;
648 bd->client.netwm.desktop = 0;
649 bd->client.netwm.state.modal = 0;
650 bd->client.netwm.state.sticky = 0;
651 bd->client.netwm.state.shaded = 0;
652 bd->client.netwm.state.hidden = 0;
653 bd->client.netwm.state.maximized_v = 0;
654 bd->client.netwm.state.maximized_h = 0;
655 bd->client.netwm.state.skip_taskbar = 0;
656 bd->client.netwm.state.skip_pager = 0;
657 bd->client.netwm.state.fullscreen = 0;
658 bd->client.netwm.state.stacking = E_STACKING_NONE;
659 bd->client.netwm.action.move = 0;
660 bd->client.netwm.action.resize = 0;
661 bd->client.netwm.action.minimize = 0;
662 bd->client.netwm.action.shade = 0;
663 bd->client.netwm.action.stick = 0;
664 bd->client.netwm.action.maximized_h = 0;
665 bd->client.netwm.action.maximized_v = 0;
666 bd->client.netwm.action.fullscreen = 0;
667 bd->client.netwm.action.change_desktop = 0;
668 bd->client.netwm.action.close = 0;
669 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
675 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
676 bd->client.icccm.fetch.command = 1;
679 Eina_Bool video_parent = EINA_FALSE;
680 Eina_Bool video_position = EINA_FALSE;
683 for (i = 0; i < at_num; i++)
685 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
686 bd->client.icccm.fetch.title = 1;
687 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
688 bd->client.icccm.fetch.name_class = 1;
689 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
690 bd->client.icccm.fetch.icon_name = 1;
691 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
692 bd->client.icccm.fetch.machine = 1;
693 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
694 bd->client.icccm.fetch.hints = 1;
695 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
696 bd->client.icccm.fetch.size_pos_hints = 1;
697 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
698 bd->client.icccm.fetch.protocol = 1;
699 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
700 bd->client.mwm.fetch.hints = 1;
701 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
703 bd->client.icccm.fetch.transient_for = 1;
704 bd->client.netwm.fetch.type = 1;
706 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
707 bd->client.icccm.fetch.client_leader = 1;
708 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
709 bd->client.icccm.fetch.window_role = 1;
710 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
711 bd->client.icccm.fetch.state = 1;
713 /* netwm, loop again, netwm will ignore some icccm, so we
714 * have to be sure that netwm is checked after */
715 for (i = 0; i < at_num; i++)
717 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
720 bd->client.icccm.fetch.title = 0;
721 bd->client.netwm.fetch.name = 1;
723 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
726 bd->client.icccm.fetch.icon_name = 0;
727 bd->client.netwm.fetch.icon_name = 1;
729 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
731 bd->client.netwm.fetch.icon = 1;
733 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
735 bd->client.netwm.fetch.user_time = 1;
737 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
739 DBG("ECORE_X_ATOM_NET_WM_STRUT");
740 bd->client.netwm.fetch.strut = 1;
742 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
744 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
745 bd->client.netwm.fetch.strut = 1;
747 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
750 bd->client.mwm.fetch.hints = 0;
752 bd->client.netwm.fetch.type = 1;
754 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
756 bd->client.netwm.fetch.state = 1;
759 /* other misc atoms */
760 for (i = 0; i < at_num; i++)
762 /* loop to check for own atoms */
763 if (atoms[i] == E_ATOM_WINDOW_STATE)
765 bd->client.e.fetch.state = 1;
767 /* loop to check for qtopia atoms */
768 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
769 bd->client.qtopia.fetch.soft_menu = 1;
770 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
771 bd->client.qtopia.fetch.soft_menus = 1;
772 /* loop to check for vkbd atoms */
773 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
774 bd->client.vkbd.fetch.state = 1;
775 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
776 bd->client.vkbd.fetch.vkbd = 1;
777 /* loop to check for illume atoms */
778 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
779 bd->client.illume.conformant.fetch.conformant = 1;
780 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
781 bd->client.illume.quickpanel.fetch.state = 1;
782 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
783 bd->client.illume.quickpanel.fetch.quickpanel = 1;
784 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
785 bd->client.illume.quickpanel.fetch.priority.major = 1;
786 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
787 bd->client.illume.quickpanel.fetch.priority.minor = 1;
788 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
789 bd->client.illume.quickpanel.fetch.zone = 1;
790 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
791 bd->client.illume.drag.fetch.locked = 1;
792 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
793 bd->client.illume.drag.fetch.drag = 1;
794 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
795 bd->client.illume.win_state.fetch.state = 1;
796 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
797 video_parent = EINA_TRUE;
798 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
799 video_position = EINA_TRUE;
800 #ifdef _F_USE_DESK_WINDOW_PROFILE_
801 /* loop to check for window profile list atom */
802 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
803 bd->client.e.fetch.profile_list = 1;
805 #ifdef _F_ZONE_WINDOW_ROTATION_
806 /* loop to check for wm rotation */
807 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
809 if (e_config->wm_win_rotation)
810 bd->client.e.fetch.rot.support = 1;
812 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
813 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
814 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
815 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
817 if (e_config->wm_win_rotation)
818 bd->client.e.fetch.rot.geom_hint = 1;
820 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
822 if (e_config->wm_win_rotation)
823 bd->client.e.fetch.rot.app_set = 1;
825 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
827 if (e_config->wm_win_rotation)
828 bd->client.e.fetch.rot.preferred_rot = 1;
830 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
832 if (e_config->wm_win_rotation)
833 bd->client.e.fetch.rot.available_rots = 1;
836 #ifdef _F_DEICONIFY_APPROVE_
837 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
839 bd->client.e.state.deiconify_approve.support = 1;
843 if (video_position && video_parent)
845 bd->client.e.state.video = 1;
846 bd->client.e.fetch.video_parent = 1;
847 bd->client.e.fetch.video_position = 1;
848 ecore_x_window_lower(bd->win);
849 ecore_x_composite_window_events_disable(bd->win);
850 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
851 fprintf(stderr, "We found a video window \\o/ %x\n", win);
856 bd->client.border.changed = 1;
858 bd->client.w = att->w;
859 bd->client.h = att->h;
861 bd->w = bd->client.w;
862 bd->h = bd->client.h;
864 bd->resize_mode = RESIZE_NONE;
866 bd->saved.layer = bd->layer;
867 bd->changes.icon = 1;
868 bd->changes.size = 1;
869 bd->changes.shape = 1;
870 bd->changes.shape_input = 1;
872 bd->offer_resistance = 1;
874 /* just to friggin make java happy - we're DELAYING the reparent until
877 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
878 bd->need_reparent = 1;
880 ecore_x_window_border_width_set(win, 0);
881 ecore_x_window_show(bd->event_win);
882 ecore_x_window_show(bd->client.shell_win);
883 bd->shape = e_container_shape_add(con);
888 #ifdef _F_ZONE_WINDOW_ROTATION_
889 bd->client.e.state.rot.preferred_rot = -1;
890 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
891 bd->client.e.state.rot.changes = -1;
892 bd->client.e.state.rot.pending_show = 0;
893 bd->client.e.state.rot.curr = 0;
894 bd->client.e.state.rot.prev = 0;
897 // bd->zone = e_zone_current_get(con);
898 bd->desk = e_desk_current_get(bd->zone);
899 e_container_border_add(bd);
900 borders = eina_list_append(borders, bd);
901 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
905 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
906 "optimisations failing due to bizarre client behavior. will\n"
908 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
909 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
912 ELBF(ELBT_BD, 0, bd->client.win,
913 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
914 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
916 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
917 printf("optimisations failing due to bizarre client behavior. will\n");
918 printf("work around.\n");
919 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
920 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
923 ELBF(ELBT_BD, 0, bd->client.win,
924 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
925 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
928 #ifdef _F_ZONE_WINDOW_ROTATION_
929 if ((rot.vkbd) && (rot.vkbd == bd2))
931 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
932 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
933 rot.vkbd_hide_prepare_done);
935 if (rot.vkbd_hide_prepare_timer)
937 ecore_timer_del(rot.vkbd_hide_prepare_timer);
938 rot.vkbd_hide_prepare_timer = NULL;
940 e_object_unref(E_OBJECT(bd2));
943 _e_border_vkbd_hide(rot.vkbd);
945 if (rot.vkbd_ctrl_win)
947 ELB(ELBT_BD, "SET KBD_OFF", 0);
948 ecore_x_e_virtual_keyboard_state_set
949 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
951 rot.vkbd_hide_prepare_done = EINA_FALSE;
953 if (rot.vkbd_hide_timer)
954 ecore_timer_del(rot.vkbd_hide_timer);
955 rot.vkbd_hide_timer = NULL;
957 rot.vkbd_show_prepare_done = EINA_FALSE;
958 if (rot.vkbd_show_prepare_timer)
959 ecore_timer_del(rot.vkbd_show_prepare_timer);
960 rot.vkbd_show_prepare_timer = NULL;
961 if (rot.vkbd_show_timer)
962 ecore_timer_del(rot.vkbd_show_timer);
963 rot.vkbd_show_timer = NULL;
968 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
969 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
970 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
972 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
973 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
974 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
976 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
977 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
978 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
980 unsigned int zgeom[4];
982 zgeom[0] = bd->zone->x;
983 zgeom[1] = bd->zone->y;
984 zgeom[2] = bd->zone->w;
985 zgeom[3] = bd->zone->h;
986 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
988 e_desk_xy_get(bd->desk, &deskx, &desky);
991 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
992 #ifdef _F_USE_DESK_WINDOW_PROFILE_
993 if (strcmp(bd->desk->window_profile,
994 e_config->desktop_default_window_profile) != 0)
996 ecore_x_e_window_profile_set(bd->client.win,
997 bd->desk->window_profile);
1001 focus_stack = eina_list_append(focus_stack, bd);
1003 bd->pointer = e_pointer_window_new(bd->win, 0);
1008 e_border_res_change_geometry_save(E_Border *bd)
1011 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1013 if (bd->pre_res_change.valid) return;
1014 bd->pre_res_change.valid = 1;
1015 bd->pre_res_change.x = bd->x;
1016 bd->pre_res_change.y = bd->y;
1017 bd->pre_res_change.w = bd->w;
1018 bd->pre_res_change.h = bd->h;
1019 bd->pre_res_change.saved.x = bd->saved.x;
1020 bd->pre_res_change.saved.y = bd->saved.y;
1021 bd->pre_res_change.saved.w = bd->saved.w;
1022 bd->pre_res_change.saved.h = bd->saved.h;
1026 e_border_res_change_geometry_restore(E_Border *bd)
1030 unsigned char valid : 1;
1039 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1040 if (!bd->pre_res_change.valid) return;
1041 if (bd->new_client) return;
1043 ecore_x_window_shadow_tree_flush();
1044 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1048 e_border_unfullscreen(bd);
1049 e_border_fullscreen(bd, e_config->fullscreen_policy);
1051 else if (bd->maximized != E_MAXIMIZE_NONE)
1055 max = bd->maximized;
1056 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1057 e_border_maximize(bd, max);
1061 int x, y, w, h, zx, zy, zw, zh;
1063 bd->saved.x = bd->pre_res_change.saved.x;
1064 bd->saved.y = bd->pre_res_change.saved.y;
1065 bd->saved.w = bd->pre_res_change.saved.w;
1066 bd->saved.h = bd->pre_res_change.saved.h;
1068 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1070 if (bd->saved.w > zw)
1072 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1073 bd->saved.x = zx + zw - bd->saved.w;
1075 if (bd->saved.h > zh)
1077 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1078 bd->saved.y = zy + zh - bd->saved.h;
1080 x = bd->pre_res_change.x;
1081 y = bd->pre_res_change.y;
1082 w = bd->pre_res_change.w;
1083 h = bd->pre_res_change.h;
1088 if ((x + w) > (zx + zw))
1090 if ((y + h) > (zy + zh))
1092 e_border_move_resize(bd, x, y, w, h);
1094 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1098 e_border_zone_set(E_Border *bd,
1101 E_Event_Border_Zone_Set *ev;
1104 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1105 E_OBJECT_CHECK(zone);
1106 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1108 if (bd->zone == zone) return;
1110 /* if the window does not lie in the new zone, move it so that it does */
1111 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1114 /* first guess -- get offset from old zone, and apply to new zone */
1115 x = zone->x + (bd->x - bd->zone->x);
1116 y = zone->y + (bd->y - bd->zone->y);
1118 /* keep window from hanging off bottom and left */
1119 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1120 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1122 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1123 if (x < zone->x) x = zone->x;
1124 if (y < zone->y) y = zone->y;
1126 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1128 /* still not in zone at all, so just move it to closest edge */
1129 if (x < zone->x) x = zone->x;
1130 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1131 if (y < zone->y) y = zone->y;
1132 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1134 e_border_move(bd, x, y);
1139 if (bd->desk->zone != bd->zone)
1140 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1142 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1144 e_object_ref(E_OBJECT(bd));
1145 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1147 e_object_ref(E_OBJECT(zone));
1149 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1151 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1152 // XXXXXXXXXXXXXXXXXXXXXXXXX
1153 // XXX ZZZZZZZZZZZZZZZZZZZzz
1154 // need to adjust this if zone pos/size changes
1156 unsigned int zgeom[4];
1158 zgeom[0] = bd->zone->x;
1159 zgeom[1] = bd->zone->y;
1160 zgeom[2] = bd->zone->w;
1161 zgeom[3] = bd->zone->h;
1162 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1164 e_remember_update(bd);
1168 e_border_desk_set(E_Border *bd,
1171 E_Event_Border_Desk_Set *ev;
1175 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1176 E_OBJECT_CHECK(desk);
1177 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1178 if (bd->desk == desk) return;
1179 ecore_x_window_shadow_tree_flush();
1182 bd->desk->fullscreen_borders--;
1183 desk->fullscreen_borders++;
1185 old_desk = bd->desk;
1187 e_border_zone_set(bd, desk->zone);
1189 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1190 e_hints_window_desktop_set(bd);
1192 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1194 e_object_ref(E_OBJECT(bd));
1195 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1196 ev->desk = old_desk;
1197 e_object_ref(E_OBJECT(old_desk));
1198 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1200 if (bd->ignore_first_unmap != 1)
1202 if ((bd->desk->visible) || (bd->sticky))
1205 e_border_hide(bd, 1);
1208 if (e_config->transient.desktop)
1212 Eina_List *list = _e_border_sub_borders_new(bd);
1214 EINA_LIST_FOREACH(list, l, child)
1216 e_border_desk_set(child, bd->desk);
1218 eina_list_free(list);
1220 e_remember_update(bd);
1223 #ifdef _F_ZONE_WINDOW_ROTATION_
1225 _e_border_vkbd_state_check(E_Border *bd,
1228 Eina_Bool res = EINA_TRUE;
1229 if (!e_config->wm_win_rotation) return EINA_FALSE;
1230 if ((rot.vkbd) && (rot.vkbd == bd))
1234 if ((rot.vkbd_hide_prepare_done) ||
1235 (rot.vkbd_hide_prepare_timer))
1240 if ((rot.vkbd_show_prepare_done) ||
1241 (rot.vkbd_show_prepare_timer))
1249 _e_border_vkbd_show_timeout(void *data)
1251 E_Border *bd = data;
1252 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1253 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1255 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1257 if (rot.vkbd_ctrl_win)
1259 ELB(ELBT_BD, "SET KBD_ON", 0);
1260 ecore_x_e_virtual_keyboard_state_set
1261 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1266 rot.vkbd_show_prepare_done = EINA_FALSE;
1268 if (rot.vkbd_show_prepare_timer)
1269 ecore_timer_del(rot.vkbd_show_prepare_timer);
1270 rot.vkbd_show_prepare_timer = NULL;
1272 if (rot.vkbd_show_timer)
1273 ecore_timer_del(rot.vkbd_show_timer);
1274 rot.vkbd_show_timer = NULL;
1276 return ECORE_CALLBACK_CANCEL;
1280 _e_border_vkbd_hide_timeout(void *data)
1282 E_Border *bd = data;
1283 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1284 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1286 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1288 if (rot.vkbd_ctrl_win)
1290 ELB(ELBT_BD, "SET KBD_OFF", 0);
1291 ecore_x_e_virtual_keyboard_state_set
1292 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1295 e_object_unref(E_OBJECT(bd));
1298 rot.vkbd_hide_prepare_done = EINA_FALSE;
1300 if (rot.vkbd_hide_prepare_timer)
1301 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1302 rot.vkbd_hide_prepare_timer = NULL;
1304 if (rot.vkbd_hide_timer)
1305 ecore_timer_del(rot.vkbd_hide_timer);
1306 rot.vkbd_hide_timer = NULL;
1308 return ECORE_CALLBACK_CANCEL;
1312 _e_border_vkbd_show(E_Border *bd)
1314 if (!e_config->wm_win_rotation) return;
1315 rot.vkbd_show_prepare_done = EINA_TRUE;
1316 if (rot.vkbd_show_prepare_timer)
1317 ecore_timer_del(rot.vkbd_show_prepare_timer);
1318 rot.vkbd_show_prepare_timer = NULL;
1319 if (rot.vkbd_show_timer)
1320 ecore_timer_del(rot.vkbd_show_timer);
1321 rot.vkbd_show_timer = NULL;
1322 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1325 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1330 _e_border_vkbd_hide(E_Border *bd)
1332 if (!e_config->wm_win_rotation) return;
1333 rot.vkbd_hide_prepare_done = EINA_TRUE;
1334 if (rot.vkbd_hide_prepare_timer)
1335 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1336 rot.vkbd_hide_prepare_timer = NULL;
1337 if (rot.vkbd_hide_timer)
1338 ecore_timer_del(rot.vkbd_hide_timer);
1339 rot.vkbd_hide_timer = NULL;
1340 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1342 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1343 e_border_hide(bd, 0);
1344 if (!e_object_is_del(E_OBJECT(bd)))
1346 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1347 e_object_del(E_OBJECT(bd));
1349 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1354 _e_border_vkbd_show_prepare_timeout(void *data)
1356 E_Border *bd = data;
1357 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1358 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1360 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1361 _e_border_vkbd_show(bd);
1363 return ECORE_CALLBACK_CANCEL;
1367 _e_border_vkbd_hide_prepare_timeout(void *data)
1369 E_Border *bd = data;
1370 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1371 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1373 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1374 _e_border_vkbd_hide(bd);
1376 return ECORE_CALLBACK_CANCEL;
1381 e_border_show(E_Border *bd)
1383 E_Event_Border_Show *ev;
1384 unsigned int visible;
1387 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1388 if (bd->visible) return;
1389 #ifdef _F_ZONE_WINDOW_ROTATION_
1390 // newly created window that has to be rotated will be show after rotation done.
1391 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1392 if ((bd->new_client) &&
1393 (bd->client.e.state.rot.changes != -1))
1395 ELB(ELBT_BD, "PENDING SHOW UNTIL GETTING ROT_DONE", bd->client.win);
1396 // if this window is in withdrawn state, set the normal state
1397 // that's because the window in withdrawn state can't render its canvas.
1398 // eventually, this window will not send the message of rotation done,
1399 // even if e17 request to rotation this window.
1400 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1401 e_hints_window_visible_set(bd);
1403 bd->client.e.state.rot.pending_show = 1;
1406 if ((e_config->wm_win_rotation) &&
1407 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1409 (!rot.vkbd_show_prepare_done))
1411 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1412 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1413 if (rot.vkbd_show_prepare_timer)
1414 ecore_timer_del(rot.vkbd_show_prepare_timer);
1415 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1416 _e_border_vkbd_show_prepare_timeout,
1420 ELB(ELBT_BD, "SHOW", bd->client.win);
1422 ecore_x_window_shadow_tree_flush();
1423 e_container_shape_show(bd->shape);
1424 if (!bd->need_reparent)
1425 ecore_x_window_show(bd->client.win);
1426 e_hints_window_visible_set(bd);
1429 bd->changes.visible = 1;
1432 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1433 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1435 ev = E_NEW(E_Event_Border_Show, 1);
1437 e_object_ref(E_OBJECT(bd));
1438 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1439 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1441 #ifdef _F_ZONE_WINDOW_ROTATION_
1442 if ((e_config->wm_win_rotation) &&
1443 ((bd->client.e.state.rot.support) ||
1444 (bd->client.e.state.rot.app_set)))
1446 ELB(ELBT_ROT, "CHECK", bd->client.win);
1447 int rotation = _e_border_rotation_angle_get(bd);
1448 if (rotation != -1) e_border_rotation_set(bd, rotation);
1454 e_border_hide(E_Border *bd,
1457 unsigned int visible;
1460 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1462 #ifdef _F_ZONE_WINDOW_ROTATION_
1463 if ((e_config->wm_win_rotation) &&
1464 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1466 (!rot.vkbd_hide_prepare_done) &&
1469 Eina_Bool need_prepare = EINA_TRUE;
1470 E_Border *child = NULL;
1473 if (e_object_is_del(E_OBJECT(bd->parent)))
1474 need_prepare = EINA_FALSE;
1477 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1478 if (bd->parent->modal == bd)
1480 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1481 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1482 bd->parent->lock_close = 0;
1483 bd->parent->saved.event_mask = 0;
1484 bd->parent->modal = NULL;
1490 need_prepare = EINA_FALSE;
1492 EINA_LIST_FREE(bd->transients, child)
1494 child->parent = NULL;
1497 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1501 e_object_ref(E_OBJECT(bd));
1502 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1503 if (rot.vkbd_hide_prepare_timer)
1504 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1505 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1506 _e_border_vkbd_hide_prepare_timeout,
1512 e_object_ref(E_OBJECT(bd));
1514 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1515 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1517 /* cleanup code from _e_border_vkbd_hide() */
1518 rot.vkbd_hide_prepare_done = EINA_TRUE;
1519 if (rot.vkbd_hide_prepare_timer)
1520 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1521 rot.vkbd_hide_prepare_timer = NULL;
1522 if (rot.vkbd_hide_timer)
1523 ecore_timer_del(rot.vkbd_hide_timer);
1524 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1527 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1529 if (!bd->visible) goto send_event;
1530 ecore_x_window_shadow_tree_flush();
1532 _e_border_move_end(bd);
1533 if (bd->resize_mode != RESIZE_NONE)
1535 _e_border_pointer_resize_end(bd);
1536 bd->resize_mode = RESIZE_NONE;
1537 _e_border_resize_end(bd);
1540 e_container_shape_hide(bd->shape);
1541 if (!bd->iconic) e_hints_window_hidden_set(bd);
1544 bd->changes.visible = 1;
1546 if (!bd->need_reparent)
1548 if ((bd->focused) ||
1549 (e_grabinput_last_focus_win_get() == bd->client.win))
1551 e_border_focus_set(bd, 0, 1);
1559 con = e_container_current_get(e_manager_current_get());
1560 zone = e_zone_current_get(con);
1561 desk = e_desk_current_get(zone);
1564 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1565 e_border_focus_set(bd->parent, 1, 1);
1566 else if (e_config->focus_revert_on_hide_or_close)
1568 /* When using pointer focus, the border under the
1569 * pointer (if any) gets focused, in sloppy/click
1570 * focus the last focused window on the current
1571 * desk gets focus */
1572 if (e_config->focus_policy == E_FOCUS_MOUSE)
1574 pbd = e_border_under_pointer_get(desk, bd);
1576 e_border_focus_set(pbd, 1, 1);
1578 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1579 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1580 (e_config->focus_policy == E_FOCUS_CLICK))
1581 _e_border_latest_stacked_focus(bd);
1585 e_desk_last_focused_focus(desk);
1595 /* Make sure that this border isn't deleted */
1596 bd->await_hide_event++;
1598 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1599 ecore_x_window_hide(bd->client.win);
1604 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1606 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1613 #ifdef _F_ZONE_WINDOW_ROTATION_
1614 _e_border_rotation_list_remove(bd);
1617 E_Event_Border_Hide *ev;
1619 ev = E_NEW(E_Event_Border_Hide, 1);
1621 e_object_ref(E_OBJECT(bd));
1622 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1623 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1628 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1632 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1633 setpriority(PRIO_PROCESS, pid, newpri);
1634 // shouldnt need to do this as default ionice class is "none" (0), and
1635 // this inherits io priority FROM nice level
1636 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1637 // IOPRIO_PRIO_VALUE(2, 5));
1641 char *file, buf[PATH_MAX];
1645 // yes - this is /proc specific... so this may not work on some
1646 // os's - works on linux. too bad for others.
1647 files = ecore_file_ls("/proc");
1648 EINA_LIST_FREE(files, file)
1650 if (isdigit(file[0]))
1652 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1653 f = fopen(buf, "r");
1658 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1664 _pri_adj(pid2, set, adj, EINA_TRUE,
1665 adj_children, do_children);
1667 _pri_adj(pid2, set, adj, use_adj,
1668 adj_children, do_children);
1680 _e_border_pri_raise(E_Border *bd)
1682 if (bd->client.netwm.pid <= 0) return;
1683 if (bd->client.netwm.pid == getpid()) return;
1684 _pri_adj(bd->client.netwm.pid,
1685 e_config->priority - 1, -1, EINA_FALSE,
1686 // EINA_TRUE, EINA_TRUE);
1687 EINA_TRUE, EINA_FALSE);
1688 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1689 // bd->client.netwm.pid, e_border_name_get(bd));
1693 _e_border_pri_norm(E_Border *bd)
1695 if (bd->client.netwm.pid <= 0) return;
1696 if (bd->client.netwm.pid == getpid()) return;
1697 _pri_adj(bd->client.netwm.pid,
1698 e_config->priority, 1, EINA_FALSE,
1699 // EINA_TRUE, EINA_TRUE);
1700 EINA_TRUE, EINA_FALSE);
1701 // printf("WIN: pid %i, title %s (NORMAL)\n",
1702 // bd->client.netwm.pid, e_border_name_get(bd));
1706 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1709 Ecore_Evas *bg_ecore_evas;
1715 bg_ecore_evas = bd->bg_ecore_evas;
1717 /* unregister old frame window */
1718 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1719 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1721 e_focus_setdown(bd);
1722 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1723 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1725 if (bd->icon_object)
1726 evas_object_del(bd->icon_object);
1728 evas_object_del(bd->bg_object);
1729 e_canvas_del(bg_ecore_evas);
1730 ecore_evas_free(bg_ecore_evas);
1733 e_object_del(E_OBJECT(bd->pointer));
1735 /* create new frame */
1737 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1738 bd->x, bd->y, bd->w, bd->h);
1741 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1742 bd->x, bd->y, bd->w, bd->h);
1743 ecore_x_window_shape_events_select(bd->win, 1);
1746 ecore_x_window_configure(bd->win,
1747 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1748 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1750 win, ECORE_X_WINDOW_STACK_BELOW);
1752 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1753 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1756 bd->bg_ecore_evas = e_canvas_new(bd->win,
1757 0, 0, bd->w, bd->h, 1, 0,
1760 e_canvas_add(bd->bg_ecore_evas);
1761 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1763 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1764 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1765 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1767 ecore_x_window_shape_events_select(bd->bg_win, 1);
1769 /* move client with shell win over to new frame */
1770 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1771 bd->client_inset.l, bd->client_inset.t);
1773 bd->pointer = e_pointer_window_new(bd->win, 0);
1775 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1776 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1783 ecore_evas_show(bd->bg_ecore_evas);
1784 ecore_x_window_show(bd->win);
1786 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1787 ecore_x_window_show(tmp->win);
1790 bd->bg_object = edje_object_add(bd->bg_evas);
1791 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1792 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1794 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1796 /* cleanup old frame */
1797 ecore_x_window_free(win);
1801 _e_border_client_move_resize_send(E_Border *bd)
1803 if (bd->internal_ecore_evas)
1804 ecore_evas_managed_move(bd->internal_ecore_evas,
1805 bd->x + bd->fx.x + bd->client_inset.l,
1806 bd->y + bd->fx.y + bd->client_inset.t);
1808 ecore_x_icccm_move_resize_send(bd->client.win,
1809 bd->x + bd->fx.x + bd->client_inset.l,
1810 bd->y + bd->fx.y + bd->client_inset.t,
1816 _e_border_pending_move_resize_add(E_Border *bd,
1823 Eina_Bool without_border,
1824 unsigned int serial)
1826 E_Border_Pending_Move_Resize *pnd;
1828 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1830 pnd->resize = resize;
1832 pnd->without_border = without_border;
1837 pnd->serial = serial;
1838 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1842 _e_border_move_internal(E_Border *bd,
1845 Eina_Bool without_border)
1847 E_Event_Border_Move *ev;
1850 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1852 ecore_x_window_shadow_tree_flush();
1855 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1861 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1863 if (e_config->allow_manip)
1866 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1871 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1876 else if (e_config->allow_manip)
1884 x -= bd->client_inset.l;
1885 y -= bd->client_inset.t;
1887 if (bd->move_intercept_cb)
1890 px = bd->x, py = bd->y;
1891 bd->move_intercept_cb(bd, x, y);
1892 if ((bd->x == px) && (bd->y == py)) return;
1894 else if ((x == bd->x) && (y == bd->y)) return;
1895 bd->pre_res_change.valid = 0;
1899 bd->changes.pos = 1;
1901 if (bd->client.netwm.sync.request)
1903 bd->client.netwm.sync.wait++;
1904 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1907 _e_border_client_move_resize_send(bd);
1908 _e_border_move_update(bd);
1909 ev = E_NEW(E_Event_Border_Move, 1);
1911 e_object_ref(E_OBJECT(bd));
1912 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1913 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1914 _e_border_zone_update(bd);
1918 * Move window to coordinates that already account border decorations.
1920 * This call will consider given position already accounts border
1921 * decorations, so it will not be considered later. This will just
1922 * work properly with borders that have being evaluated and border
1923 * decorations are known (border->client_inset).
1925 * @parm x horizontal position to place window.
1926 * @parm y vertical position to place window.
1928 * @see e_border_move_without_border()
1931 e_border_move(E_Border *bd,
1938 _e_border_move_internal(bd, x, y, 0);
1943 * Set a callback which will be called just prior to updating the
1944 * move coordinates for a border
1947 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1949 bd->move_intercept_cb = cb;
1953 * Move window to coordinates that do not account border decorations yet.
1955 * This call will consider given position does not account border
1956 * decoration, so these values (border->client_inset) will be
1957 * accounted automatically. This is specially useful when it is a new
1958 * client and has not be evaluated yet, in this case
1959 * border->client_inset will be zeroed and no information is known. It
1960 * will mark pending requests so border will be accounted on
1961 * evalutation phase.
1963 * @parm x horizontal position to place window.
1964 * @parm y vertical position to place window.
1966 * @see e_border_move()
1969 e_border_move_without_border(E_Border *bd,
1976 _e_border_move_internal(bd, x, y, 1);
1980 e_border_center(E_Border *bd)
1984 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1986 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1987 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1991 e_border_center_pos_get(E_Border *bd,
1997 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1999 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2000 if (x) *x = zx + (zw - bd->w) / 2;
2001 if (y) *y = zy + (zh - bd->h) / 2;
2005 e_border_fx_offset(E_Border *bd,
2010 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2012 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2016 bd->changes.pos = 1;
2019 if (bd->moving) _e_border_move_update(bd);
2023 _e_border_move_resize_internal(E_Border *bd,
2028 Eina_Bool without_border,
2031 E_Event_Border_Move *mev;
2032 E_Event_Border_Resize *rev;
2035 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2037 ecore_x_window_shadow_tree_flush();
2041 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2047 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2049 if (e_config->allow_manip)
2052 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2058 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2065 if (e_config->allow_manip)
2073 x -= bd->client_inset.l;
2074 y -= bd->client_inset.t;
2075 w += (bd->client_inset.l + bd->client_inset.r);
2076 h += (bd->client_inset.t + bd->client_inset.b);
2079 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2080 (w == bd->w) && (h == bd->h))
2083 bd->pre_res_change.valid = 0;
2086 bd->changes.pos = 1;
2092 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2093 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2095 if ((bd->shaped) || (bd->client.shaped))
2097 bd->need_shape_merge = 1;
2098 bd->need_shape_export = 1;
2100 if (bd->shaped_input)
2102 bd->need_shape_merge = 1;
2105 if (bd->internal_ecore_evas)
2108 bd->changes.size = 1;
2112 if (bdresize && bd->client.netwm.sync.request)
2114 bd->client.netwm.sync.wait++;
2115 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2116 * when no move is intended. The border geometry is set above anyways.
2118 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2119 bd->client.netwm.sync.serial);
2120 ecore_x_netwm_sync_request_send(bd->client.win,
2121 bd->client.netwm.sync.serial++);
2126 bd->changes.size = 1;
2130 _e_border_client_move_resize_send(bd);
2132 _e_border_resize_update(bd);
2135 mev = E_NEW(E_Event_Border_Move, 1);
2137 e_object_ref(E_OBJECT(bd));
2138 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2139 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2142 rev = E_NEW(E_Event_Border_Resize, 1);
2144 e_object_ref(E_OBJECT(bd));
2145 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2146 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2147 _e_border_zone_update(bd);
2151 * Move and resize window to values that already account border decorations.
2153 * This call will consider given values already accounts border
2154 * decorations, so it will not be considered later. This will just
2155 * work properly with borders that have being evaluated and border
2156 * decorations are known (border->client_inset).
2158 * @parm x horizontal position to place window.
2159 * @parm y vertical position to place window.
2160 * @parm w horizontal window size.
2161 * @parm h vertical window size.
2163 * @see e_border_move_resize_without_border()
2166 e_border_move_resize(E_Border *bd,
2175 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2179 * Move and resize window to values that do not account border decorations yet.
2181 * This call will consider given values already accounts border
2182 * decorations, so it will not be considered later. This will just
2183 * work properly with borders that have being evaluated and border
2184 * decorations are known (border->client_inset).
2186 * @parm x horizontal position to place window.
2187 * @parm y vertical position to place window.
2188 * @parm w horizontal window size.
2189 * @parm h vertical window size.
2191 * @see e_border_move_resize()
2194 e_border_move_resize_without_border(E_Border *bd,
2203 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2207 * Resize window to values that already account border decorations.
2209 * This call will consider given size already accounts border
2210 * decorations, so it will not be considered later. This will just
2211 * work properly with borders that have being evaluated and border
2212 * decorations are known (border->client_inset).
2214 * @parm w horizontal window size.
2215 * @parm h vertical window size.
2217 * @see e_border_resize_without_border()
2220 e_border_resize(E_Border *bd,
2227 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2230 #ifdef _F_ZONE_WINDOW_ROTATION_
2232 e_border_rotation_set(E_Border *bd, int rotation)
2234 return _e_border_rotation_set_internal(bd, rotation, NULL);
2239 * Resize window to values that do not account border decorations yet.
2241 * This call will consider given size does not account border
2242 * decoration, so these values (border->client_inset) will be
2243 * accounted automatically. This is specially useful when it is a new
2244 * client and has not be evaluated yet, in this case
2245 * border->client_inset will be zeroed and no information is known. It
2246 * will mark pending requests so border will be accounted on
2247 * evalutation phase.
2249 * @parm w horizontal window size.
2250 * @parm h vertical window size.
2252 * @see e_border_resize()
2255 e_border_resize_without_border(E_Border *bd,
2262 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2266 e_border_layer_set(E_Border *bd,
2272 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2274 ecore_x_window_shadow_tree_flush();
2276 oldraise = e_config->transient.raise;
2280 bd->saved.layer = layer;
2284 if (e_config->transient.layer)
2288 Eina_List *list = _e_border_sub_borders_new(bd);
2290 /* We need to set raise to one, else the child wont
2291 * follow to the new layer. It should be like this,
2292 * even if the user usually doesn't want to raise
2295 e_config->transient.raise = 1;
2296 EINA_LIST_FOREACH(list, l, child)
2298 e_border_layer_set(child, layer);
2302 e_config->transient.raise = oldraise;
2306 e_border_raise(E_Border *bd)
2308 E_Event_Border_Stack *ev;
2309 E_Border *last = NULL, *child;
2313 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2315 ecore_x_window_shadow_tree_flush();
2317 if (e_config->transient.raise)
2319 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2320 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2323 Eina_List *list = _e_border_sub_borders_new(bd);
2325 EINA_LIST_REVERSE_FOREACH(list, l, child)
2327 /* Don't stack iconic transients. If the user wants these shown,
2328 * thats another option.
2333 e_border_stack_below(child, last);
2338 /* First raise the border to find out which border we will end up above */
2339 above = e_container_border_raise(child);
2343 /* We ended up above a border, now we must stack this border to
2344 * generate the stacking event, and to check if this transient
2345 * has other transients etc.
2347 e_border_stack_above(child, above);
2351 /* If we didn't end up above any border, we are on the bottom! */
2352 e_border_lower(child);
2358 eina_list_free(list);
2359 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2363 EINA_LIST_FOREACH(bd->transients, l, child)
2365 /* Don't stack iconic transients. If the user wants these shown,
2366 * thats another option.
2370 child->layer = bd->layer;
2371 if (!last) last = child;
2372 e_border_raise (child);
2379 ev = E_NEW(E_Event_Border_Stack, 1);
2381 e_object_ref(E_OBJECT(bd));
2385 e_container_border_stack_below(bd, last);
2387 e_object_ref(E_OBJECT(last));
2388 ev->type = E_STACKING_BELOW;
2394 /* If we don't have any children, raise this border */
2395 above = e_container_border_raise(bd);
2396 e_border_raise_latest_set(bd);
2399 /* We ended up above a border */
2401 e_object_ref(E_OBJECT(above));
2402 ev->type = E_STACKING_ABOVE;
2406 /* No border to raise above, same as a lower! */
2408 ev->type = E_STACKING_ABOVE;
2412 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2413 e_remember_update(bd);
2417 e_border_lower(E_Border *bd)
2419 E_Event_Border_Stack *ev;
2420 E_Border *last = NULL, *child;
2424 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2426 ecore_x_window_shadow_tree_flush();
2428 if (e_config->transient.lower)
2430 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2431 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2434 Eina_List *list = _e_border_sub_borders_new(bd);
2436 EINA_LIST_REVERSE_FOREACH(list, l, child)
2438 /* Don't stack iconic transients. If the user wants these shown,
2439 * thats another option.
2444 e_border_stack_below(child, last);
2449 /* First lower the border to find out which border we will end up below */
2450 below = e_container_border_lower(child);
2454 /* We ended up below a border, now we must stack this border to
2455 * generate the stacking event, and to check if this transient
2456 * has other transients etc.
2458 e_border_stack_below(child, below);
2462 /* If we didn't end up below any border, we are on top! */
2463 e_border_raise(child);
2469 eina_list_free(list);
2471 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2475 EINA_LIST_FOREACH(bd->transients, l, child)
2477 /* Don't stack iconic transients. If the user wants these shown,
2478 * thats another option.
2482 child->layer = bd->layer;
2483 e_border_lower (child);
2491 ev = E_NEW(E_Event_Border_Stack, 1);
2493 e_object_ref(E_OBJECT(bd));
2497 e_container_border_stack_below(bd, last);
2499 e_object_ref(E_OBJECT(last));
2500 ev->type = E_STACKING_BELOW;
2506 /* If we don't have any children, lower this border */
2507 below = e_container_border_lower(bd);
2510 /* We ended up below a border */
2512 e_object_ref(E_OBJECT(below));
2513 ev->type = E_STACKING_BELOW;
2517 /* No border to hide under, same as a raise! */
2519 ev->type = E_STACKING_BELOW;
2523 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2524 e_remember_update(bd);
2528 e_border_stack_above(E_Border *bd,
2531 /* TODO: Should stack above allow the border to change level */
2532 E_Event_Border_Stack *ev;
2533 E_Border *last = NULL, *child;
2537 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2539 ecore_x_window_shadow_tree_flush();
2541 if (e_config->transient.raise)
2543 Eina_List *list = _e_border_sub_borders_new(bd);
2545 EINA_LIST_REVERSE_FOREACH(list, l, child)
2547 /* Don't stack iconic transients. If the user wants these shown,
2548 * thats another option.
2553 e_border_stack_below(child, last);
2555 e_border_stack_above(child, above);
2559 eina_list_free(list);
2562 ev = E_NEW(E_Event_Border_Stack, 1);
2564 e_object_ref(E_OBJECT(bd));
2568 e_container_border_stack_below(bd, last);
2570 e_object_ref(E_OBJECT(last));
2571 ev->type = E_STACKING_BELOW;
2575 e_container_border_stack_above(bd, above);
2577 e_object_ref(E_OBJECT(above));
2578 ev->type = E_STACKING_ABOVE;
2581 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2582 e_remember_update(bd);
2586 e_border_stack_below(E_Border *bd,
2589 /* TODO: Should stack below allow the border to change level */
2590 E_Event_Border_Stack *ev;
2591 E_Border *last = NULL, *child;
2595 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2597 ecore_x_window_shadow_tree_flush();
2599 if (e_config->transient.lower)
2601 Eina_List *list = _e_border_sub_borders_new(bd);
2603 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2605 /* Don't stack iconic transients. If the user wants these shown,
2606 * thats another option.
2611 e_border_stack_below(child, last);
2613 e_border_stack_below(child, below);
2617 eina_list_free(list);
2620 ev = E_NEW(E_Event_Border_Stack, 1);
2622 e_object_ref(E_OBJECT(bd));
2626 e_container_border_stack_below(bd, last);
2628 e_object_ref(E_OBJECT(last));
2629 ev->type = E_STACKING_BELOW;
2633 e_container_border_stack_below(bd, below);
2635 e_object_ref(E_OBJECT(below));
2636 ev->type = E_STACKING_BELOW;
2639 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2640 e_remember_update(bd);
2644 e_border_focus_latest_set(E_Border *bd)
2646 focus_stack = eina_list_remove(focus_stack, bd);
2647 focus_stack = eina_list_prepend(focus_stack, bd);
2651 e_border_raise_latest_set(E_Border *bd)
2653 raise_stack = eina_list_remove(raise_stack, bd);
2654 raise_stack = eina_list_prepend(raise_stack, bd);
2658 * Sets the focus to the given border if necessary
2659 * There are 3 cases of different focus_policy-configurations:
2661 * - E_FOCUS_CLICK: just set the focus, the most simple one
2663 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2664 * warp the pointer to the window. If this fails (because
2665 * the pointer is already in the window), just set the focus.
2667 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2668 * last window which was focused, if the mouse is on the
2669 * desktop. So, we need to look if there is another window
2670 * under the pointer and warp to pointer to the right
2671 * one if so (also, we set the focus afterwards). In case
2672 * there is no window under pointer, the pointer is on the
2673 * desktop and so we just set the focus.
2676 * This function is to be called when setting the focus was not
2677 * explicitly triggered by the user (by moving the mouse or
2678 * clicking for example), but implicitly (by closing a window,
2679 * the last focused window should get focus).
2683 e_border_focus_set_with_pointer(E_Border *bd)
2685 #ifdef PRINT_LOTS_OF_DEBUG
2686 E_PRINT_BORDER_INFO(bd);
2688 /* note: this is here as it seems there are enough apps that do not even
2689 * expect us to emulate a look of focus but not actually set x input
2690 * focus as we do - so simply abort any focuse set on such windows */
2691 /* be strict about accepting focus hint */
2692 if ((!bd->client.icccm.accepts_focus) &&
2693 (!bd->client.icccm.take_focus)) return;
2694 if (bd->lock_focus_out) return;
2696 e_border_focus_set(bd, 1, 1);
2698 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2699 if (!bd->visible) return;
2701 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2703 if (!e_border_under_pointer_get(bd->desk, bd))
2705 e_border_pointer_warp_to_center(bd);
2710 e_border_pointer_warp_to_center(bd);
2715 e_border_focus_set(E_Border *bd,
2719 E_Border *bd_unfocus = NULL;
2720 Eina_Bool focus_changed = EINA_FALSE;
2723 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2724 /* note: this is here as it seems there are enough apps that do not even
2725 * expect us to emulate a look of focus but not actually set x input
2726 * focus as we do - so simply abort any focuse set on such windows */
2727 /* be strict about accepting focus hint */
2728 if ((!bd->client.icccm.accepts_focus) &&
2729 (!bd->client.icccm.take_focus))
2731 if ((set) && (focus) && (bd->lock_focus_out)) return;
2733 /* dont focus an iconified window. that's silly! */
2738 e_border_uniconify(bd);
2739 if (!focus_track_frozen)
2740 e_border_focus_latest_set(bd);
2743 else if (!bd->visible)
2747 /* FIXME: hack for deskflip animation:
2748 * dont update focus when sliding previous desk */
2749 else if ((!bd->sticky) &&
2750 (bd->desk != e_desk_current_get(bd->desk->zone)))
2756 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2758 e_border_focus_set(bd->modal, focus, set);
2761 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2763 e_border_focus_set(bd->leader->modal, focus, set);
2771 if (bd->visible && bd->changes.visible)
2776 else if ((!bd->focused) ||
2777 (focus_next && (bd != eina_list_data_get(focus_next))))
2781 if ((l = eina_list_data_find_list(focus_next, bd)))
2782 focus_next = eina_list_promote_list(focus_next, l);
2784 focus_next = eina_list_prepend(focus_next, bd);
2786 if ((bd->client.icccm.take_focus) &&
2787 (bd->client.icccm.accepts_focus))
2789 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2790 /* TODO what if the client didn't take focus ? */
2792 else if (!bd->client.icccm.accepts_focus)
2794 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2796 else if (!bd->client.icccm.take_focus)
2798 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2799 /* e_border_focus_set(bd, 1, 0); */
2809 if (focused) bd_unfocus = focused;
2810 if (focusing == bd) focusing = NULL;
2815 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2817 if ((bd2->fullscreen) &&
2819 (bd2->zone == bd->zone) &&
2820 ((bd2->desk == bd->desk) ||
2821 (bd2->sticky) || (bd->sticky)))
2823 Eina_Bool unfocus_is_parent = EINA_FALSE;
2824 E_Border *bd_parent;
2826 bd_parent = bd->parent;
2829 if (bd_parent == bd2)
2831 unfocus_is_parent = EINA_TRUE;
2834 bd_parent = bd->parent;
2836 if ((!unfocus_is_parent) &&
2837 (!e_config->allow_above_fullscreen))
2839 e_border_iconify(bd2);
2844 focus_changed = EINA_TRUE;
2850 focus_next = eina_list_remove(focus_next, bd);
2851 if (bd == focusing) focusing = NULL;
2853 if ((bd->focused) &&
2854 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2856 Eina_Bool wasfocused = EINA_FALSE;
2859 /* should always be the case. anyway */
2863 wasfocused = EINA_TRUE;
2866 if ((set) && (!focus_next) && (!focusing))
2868 e_grabinput_focus(bd->zone->container->bg_win,
2869 E_FOCUS_METHOD_PASSIVE);
2871 if ((bd->fullscreen) && (wasfocused))
2873 Eina_Bool have_vis_child = EINA_FALSE;
2877 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2880 (bd2->zone == bd->zone) &&
2881 ((bd2->desk == bd->desk) ||
2882 (bd2->sticky) || (bd->sticky)))
2884 if (bd2->parent == bd)
2886 have_vis_child = EINA_TRUE;
2891 if ((!have_vis_child) &&
2892 (!e_config->allow_above_fullscreen))
2893 e_border_iconify(bd);
2899 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2900 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2902 E_Event_Border_Focus_Out *ev;
2904 bd_unfocus->focused = 0;
2905 e_focus_event_focus_out(bd_unfocus);
2907 if (bd_unfocus->raise_timer)
2908 ecore_timer_del(bd_unfocus->raise_timer);
2909 bd_unfocus->raise_timer = NULL;
2911 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2912 if (bd_unfocus->icon_object)
2913 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2915 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2916 ev->border = bd_unfocus;
2917 e_object_ref(E_OBJECT(bd_unfocus));
2919 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2920 _e_border_event_border_focus_out_free, NULL);
2921 if ((bd_unfocus->fullscreen) &&
2922 (bd != bd_unfocus) &&
2923 (bd->zone == bd_unfocus->zone) &&
2924 ((bd->desk == bd_unfocus->desk) ||
2925 (bd->sticky) || (bd_unfocus->sticky)))
2927 Eina_Bool unfocus_is_parent = EINA_FALSE;
2928 E_Border *bd_parent;
2930 bd_parent = bd->parent;
2933 if (bd_parent == bd_unfocus)
2935 unfocus_is_parent = EINA_TRUE;
2938 bd_parent = bd->parent;
2940 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2942 e_border_iconify(bd_unfocus);
2949 E_Event_Border_Focus_In *ev;
2951 e_focus_event_focus_in(bd);
2953 if (!focus_track_frozen)
2954 e_border_focus_latest_set(bd);
2956 e_hints_active_window_set(bd->zone->container->manager, bd);
2958 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2959 if (bd->icon_object)
2960 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2962 ev = E_NEW(E_Event_Border_Focus_In, 1);
2964 e_object_ref(E_OBJECT(bd));
2966 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2967 _e_border_event_border_focus_in_free, NULL);
2972 e_border_shade(E_Border *bd,
2975 E_Event_Border_Resize *ev;
2980 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2981 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2982 ((bd->maximized) && (!e_config->allow_manip))) return;
2983 if ((bd->client.border.name) &&
2984 (!strcmp("borderless", bd->client.border.name))) return;
2986 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2987 ecore_x_window_hide(tmp->win);
2989 ecore_x_window_shadow_tree_flush();
2991 bd->shade.x = bd->x;
2992 bd->shade.y = bd->y;
2993 bd->shade.dir = dir;
2995 e_hints_window_shaded_set(bd, 1);
2996 e_hints_window_shade_direction_set(bd, dir);
2998 if (e_config->border_shade_animate)
3000 bd->shade.start = ecore_loop_time_get();
3002 bd->changes.shading = 1;
3005 if (bd->shade.dir == E_DIRECTION_UP ||
3006 bd->shade.dir == E_DIRECTION_LEFT)
3007 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3009 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3011 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3012 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3016 if (bd->shade.dir == E_DIRECTION_UP)
3018 bd->h = bd->client_inset.t + bd->client_inset.b;
3020 else if (bd->shade.dir == E_DIRECTION_DOWN)
3022 bd->h = bd->client_inset.t + bd->client_inset.b;
3023 bd->y = bd->y + bd->client.h;
3024 bd->changes.pos = 1;
3026 else if (bd->shade.dir == E_DIRECTION_LEFT)
3028 bd->w = bd->client_inset.l + bd->client_inset.r;
3030 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3032 bd->w = bd->client_inset.l + bd->client_inset.r;
3033 bd->x = bd->x + bd->client.w;
3034 bd->changes.pos = 1;
3037 if ((bd->shaped) || (bd->client.shaped))
3039 bd->need_shape_merge = 1;
3040 bd->need_shape_export = 1;
3042 if (bd->shaped_input)
3044 bd->need_shape_merge = 1;
3047 bd->changes.size = 1;
3049 bd->changes.shaded = 1;
3051 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3052 e_border_frame_recalc(bd);
3053 ev = E_NEW(E_Event_Border_Resize, 1);
3055 /* The resize is added in the animator when animation complete */
3056 /* For non-animated, we add it immediately with the new size */
3057 e_object_ref(E_OBJECT(bd));
3058 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3059 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3062 e_remember_update(bd);
3066 e_border_unshade(E_Border *bd,
3069 E_Event_Border_Resize *ev;
3074 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3075 if ((!bd->shaded) || (bd->shading))
3078 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3079 ecore_x_window_show(tmp->win);
3081 ecore_x_window_shadow_tree_flush();
3083 bd->shade.dir = dir;
3085 e_hints_window_shaded_set(bd, 0);
3086 e_hints_window_shade_direction_set(bd, dir);
3088 if (bd->shade.dir == E_DIRECTION_UP ||
3089 bd->shade.dir == E_DIRECTION_LEFT)
3091 bd->shade.x = bd->x;
3092 bd->shade.y = bd->y;
3096 bd->shade.x = bd->x - bd->client.w;
3097 bd->shade.y = bd->y - bd->client.h;
3099 if (e_config->border_shade_animate)
3101 bd->shade.start = ecore_loop_time_get();
3103 bd->changes.shading = 1;
3106 if (bd->shade.dir == E_DIRECTION_UP)
3108 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3109 ecore_x_window_move_resize(bd->client.win, 0,
3110 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3112 bd->client.w, bd->client.h);
3114 else if (bd->shade.dir == E_DIRECTION_LEFT)
3116 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3117 ecore_x_window_move_resize(bd->client.win,
3118 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3120 0, bd->client.w, bd->client.h);
3123 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3125 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3126 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3130 if (bd->shade.dir == E_DIRECTION_UP)
3132 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3134 else if (bd->shade.dir == E_DIRECTION_DOWN)
3136 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3137 bd->y = bd->y - bd->client.h;
3138 bd->changes.pos = 1;
3140 else if (bd->shade.dir == E_DIRECTION_LEFT)
3142 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3144 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3146 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3147 bd->x = bd->x - bd->client.w;
3148 bd->changes.pos = 1;
3150 if ((bd->shaped) || (bd->client.shaped))
3152 bd->need_shape_merge = 1;
3153 bd->need_shape_export = 1;
3155 if (bd->shaped_input)
3157 bd->need_shape_merge = 1;
3160 bd->changes.size = 1;
3162 bd->changes.shaded = 1;
3164 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3165 e_border_frame_recalc(bd);
3166 ev = E_NEW(E_Event_Border_Resize, 1);
3168 /* The resize is added in the animator when animation complete */
3169 /* For non-animated, we add it immediately with the new size */
3170 e_object_ref(E_OBJECT(bd));
3171 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3172 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3175 e_remember_update(bd);
3179 _e_border_client_inset_calc(E_Border *bd)
3182 Evas_Coord cx, cy, cw, ch;
3186 evas_object_resize(bd->bg_object, 1000, 1000);
3187 edje_object_message_signal_process(bd->bg_object);
3188 edje_object_calc_force(bd->bg_object);
3189 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3190 bd->client_inset.l = cx;
3191 bd->client_inset.r = 1000 - (cx + cw);
3192 bd->client_inset.t = cy;
3193 bd->client_inset.b = 1000 - (cy + ch);
3197 bd->client_inset.l = 0;
3198 bd->client_inset.r = 0;
3199 bd->client_inset.t = 0;
3200 bd->client_inset.b = 0;
3203 ecore_x_netwm_frame_size_set(bd->client.win,
3204 bd->client_inset.l, bd->client_inset.r,
3205 bd->client_inset.t, bd->client_inset.b);
3206 ecore_x_e_frame_size_set(bd->client.win,
3207 bd->client_inset.l, bd->client_inset.r,
3208 bd->client_inset.t, bd->client_inset.b);
3212 _e_border_maximize(E_Border *bd, E_Maximize max)
3214 int x1, yy1, x2, y2;
3217 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3221 zx = zy = zw = zh = 0;
3223 switch (max & E_MAXIMIZE_TYPE)
3225 case E_MAXIMIZE_NONE:
3229 case E_MAXIMIZE_FULLSCREEN:
3235 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3236 _e_border_client_inset_calc(bd);
3238 e_border_resize_limit(bd, &w, &h);
3239 /* center x-direction */
3240 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3241 /* center y-direction */
3242 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3244 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3245 cy = bd->zone->y + (bd->zone->h / 2);
3248 switch (max & E_MAXIMIZE_DIRECTION)
3250 case E_MAXIMIZE_BOTH:
3251 e_border_move_resize(bd, x1, yy1, w, h);
3254 case E_MAXIMIZE_VERTICAL:
3255 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3258 case E_MAXIMIZE_HORIZONTAL:
3259 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3262 case E_MAXIMIZE_LEFT:
3263 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3266 case E_MAXIMIZE_RIGHT:
3267 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3269 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3270 case E_MAXIMIZE_TOP:
3271 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3273 case E_MAXIMIZE_BOTTOM:
3274 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3280 case E_MAXIMIZE_SMART:
3281 case E_MAXIMIZE_EXPAND:
3283 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3295 if (bd->x < zx) // window left not useful coordinates
3297 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3298 x1 = zx + zw - bd->w;
3299 else // window normal position
3302 if (bd->y < zy) // window top not useful coordinates
3304 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3305 yy1 = zy + zh - bd->h;
3306 else // window normal position
3309 switch (max & E_MAXIMIZE_DIRECTION)
3311 case E_MAXIMIZE_BOTH:
3312 e_border_move_resize(bd, zx, zy, zw, zh);
3315 case E_MAXIMIZE_VERTICAL:
3316 e_border_move_resize(bd, x1, zy, w, zh);
3319 case E_MAXIMIZE_HORIZONTAL:
3320 e_border_move_resize(bd, zx, yy1, zw, h);
3323 case E_MAXIMIZE_LEFT:
3324 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3327 case E_MAXIMIZE_RIGHT:
3328 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3332 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3335 case E_MAXIMIZE_FILL:
3338 x2 = bd->zone->x + bd->zone->w;
3339 y2 = bd->zone->y + bd->zone->h;
3341 /* walk through all shelves */
3342 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3344 /* walk through all windows */
3345 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3351 e_border_resize_limit(bd, &w, &h);
3352 /* center x-direction */
3353 x1 = x1 + (pw - w) / 2;
3354 /* center y-direction */
3355 yy1 = yy1 + (ph - h) / 2;
3357 switch (max & E_MAXIMIZE_DIRECTION)
3359 case E_MAXIMIZE_BOTH:
3360 e_border_move_resize(bd, x1, yy1, w, h);
3363 case E_MAXIMIZE_VERTICAL:
3364 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3367 case E_MAXIMIZE_HORIZONTAL:
3368 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3371 case E_MAXIMIZE_LEFT:
3372 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3375 case E_MAXIMIZE_RIGHT:
3376 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3384 e_border_maximize(E_Border *bd,
3388 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3390 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3392 if ((bd->shaded) || (bd->shading)) return;
3393 ecore_x_window_shadow_tree_flush();
3395 e_border_unfullscreen(bd);
3396 /* Only allow changes in vertical/ horizontal maximization */
3397 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3398 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3401 bd->need_maximize = 1;
3402 bd->maximized &= ~E_MAXIMIZE_TYPE;
3403 bd->maximized |= max;
3407 bd->pre_res_change.valid = 0;
3408 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3410 /* Horizontal hasn't been set */
3411 bd->saved.x = bd->x - bd->zone->x;
3412 bd->saved.w = bd->w;
3414 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3416 /* Vertical hasn't been set */
3417 bd->saved.y = bd->y - bd->zone->y;
3418 bd->saved.h = bd->h;
3421 bd->saved.zone = bd->zone->num;
3422 e_hints_window_size_set(bd);
3426 _e_border_maximize(bd, max);
3429 /* Remove previous type */
3430 bd->maximized &= ~E_MAXIMIZE_TYPE;
3431 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3432 bd->maximized |= max;
3434 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3435 bd->maximized & E_MAXIMIZE_VERTICAL);
3436 e_remember_update(bd);
3440 e_border_unmaximize(E_Border *bd,
3444 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3445 if (!(max & E_MAXIMIZE_DIRECTION))
3447 CRI("BUG: Unmaximize call without direction!");
3451 if ((bd->shaded) || (bd->shading)) return;
3452 ecore_x_window_shadow_tree_flush();
3453 /* Remove directions not used */
3454 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3455 /* Can only remove existing maximization directions */
3457 if (bd->maximized & E_MAXIMIZE_TYPE)
3459 bd->pre_res_change.valid = 0;
3460 bd->need_maximize = 0;
3462 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3466 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3467 _e_border_client_inset_calc(bd);
3470 bd->maximized = E_MAXIMIZE_NONE;
3471 _e_border_move_resize_internal(bd,
3472 bd->zone->x + bd->saved.x,
3473 bd->zone->y + bd->saved.y,
3474 bd->saved.w, bd->saved.h, 0, 1);
3475 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3476 e_hints_window_size_unset(bd);
3487 if (max & E_MAXIMIZE_VERTICAL)
3489 /* Remove vertical */
3491 y = bd->saved.y + bd->zone->y;
3492 bd->saved.h = bd->saved.y = 0;
3493 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3494 bd->maximized &= ~E_MAXIMIZE_LEFT;
3495 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3497 if (max & E_MAXIMIZE_HORIZONTAL)
3499 /* Remove horizontal */
3501 x = bd->saved.x + bd->zone->x;
3502 bd->saved.w = bd->saved.x = 0;
3503 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3506 e_border_resize_limit(bd, &w, &h);
3508 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3510 bd->maximized = E_MAXIMIZE_NONE;
3511 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3512 e_hints_window_size_unset(bd);
3513 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3517 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3518 e_hints_window_size_set(bd);
3521 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3522 bd->maximized & E_MAXIMIZE_VERTICAL);
3524 e_remember_update(bd);
3528 e_border_fullscreen(E_Border *bd,
3529 E_Fullscreen policy)
3531 E_Event_Border_Fullscreen *ev;
3534 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3536 if ((bd->shaded) || (bd->shading)) return;
3537 ecore_x_window_shadow_tree_flush();
3540 bd->need_fullscreen = 1;
3543 if (!bd->fullscreen)
3545 bd->pre_res_change.valid = 0;
3547 bd->saved.x = bd->x - bd->zone->x;
3548 bd->saved.y = bd->y - bd->zone->y;
3549 bd->saved.w = bd->client.w;
3550 bd->saved.h = bd->client.h;
3551 bd->saved.maximized = bd->maximized;
3552 bd->saved.zone = bd->zone->num;
3555 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3556 e_hints_window_size_set(bd);
3558 bd->client_inset.l = 0;
3559 bd->client_inset.r = 0;
3560 bd->client_inset.t = 0;
3561 bd->client_inset.b = 0;
3563 bd->desk->fullscreen_borders++;
3565 /* e_zone_fullscreen_set(bd->zone, 1); */
3566 bd->saved.layer = bd->layer;
3567 if (!e_config->allow_above_fullscreen)
3568 e_border_layer_set(bd, 250);
3570 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3571 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3573 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3575 else if (policy == E_FULLSCREEN_ZOOM)
3577 Ecore_X_Randr_Screen_Size_MM *sizes;
3578 int num_sizes, i, best_size_index = 0;
3580 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3582 &screen_size.height,
3584 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3588 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3589 int best_dist = INT_MAX, dist;
3591 for (i = 0; i < num_sizes; i++)
3593 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3595 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3596 if (dist < best_dist)
3598 best_size.width = sizes[i].width;
3599 best_size.height = sizes[i].height;
3601 best_size_index = i;
3605 if (((best_size.width != -1) && (best_size.height != -1)) &&
3606 ((best_size.width != screen_size.width) ||
3607 (best_size.height != screen_size.height)))
3609 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3611 screen_size_index = best_size_index;
3612 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3616 screen_size.width = -1;
3617 screen_size.height = -1;
3618 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3623 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3627 e_hints_window_fullscreen_set(bd, 1);
3628 e_hints_window_size_unset(bd);
3629 bd->client.border.changed = 1;
3632 bd->fullscreen_policy = policy;
3634 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3636 e_object_ref(E_OBJECT(bd));
3637 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3638 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3640 e_remember_update(bd);
3644 e_border_unfullscreen(E_Border *bd)
3646 E_Event_Border_Unfullscreen *ev;
3649 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3650 if ((bd->shaded) || (bd->shading)) return;
3651 ecore_x_window_shadow_tree_flush();
3654 bd->pre_res_change.valid = 0;
3656 bd->need_fullscreen = 0;
3657 bd->desk->fullscreen_borders--;
3659 if ((screen_size.width != -1) && (screen_size.height != -1))
3661 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3663 screen_size.width = -1;
3664 screen_size.height = -1;
3666 e_border_move_resize(bd,
3667 bd->saved.x + bd->zone->x,
3668 bd->saved.y + bd->zone->y,
3669 bd->saved.w, bd->saved.h);
3671 if (bd->saved.maximized)
3672 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3673 bd->saved.maximized);
3675 e_border_layer_set(bd, bd->saved.layer);
3677 e_hints_window_fullscreen_set(bd, 0);
3678 bd->client.border.changed = 1;
3681 bd->fullscreen_policy = 0;
3683 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3685 e_object_ref(E_OBJECT(bd));
3686 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3687 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3689 e_remember_update(bd);
3693 e_border_iconify(E_Border *bd)
3695 E_Event_Border_Iconify *ev;
3696 unsigned int iconic;
3699 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3700 if (bd->shading) return;
3701 ecore_x_window_shadow_tree_flush();
3705 e_border_hide(bd, 1);
3706 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3707 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3710 e_hints_window_iconic_set(bd);
3711 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3713 ev = E_NEW(E_Event_Border_Iconify, 1);
3715 e_object_ref(E_OBJECT(bd));
3716 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3717 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3719 if (e_config->transient.iconify)
3723 Eina_List *list = _e_border_sub_borders_new(bd);
3725 EINA_LIST_FOREACH(list, l, child)
3727 e_border_iconify(child);
3729 eina_list_free(list);
3731 e_remember_update(bd);
3734 #ifdef _F_DEICONIFY_APPROVE_
3736 _e_border_uniconify_timeout(void *data)
3743 if (!e_object_is_del(E_OBJECT(bd)))
3745 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3746 bd->client.e.state.deiconify_approve.render_done = 1;
3747 if (bd->client.e.state.deiconify_approve.req_list)
3749 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3751 child_bd->client.e.state.deiconify_approve.render_done = 1;
3752 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3755 bd->client.e.state.deiconify_approve.req_list = NULL;
3756 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3757 e_border_uniconify(bd);
3760 return ECORE_CALLBACK_CANCEL;
3764 _e_border_deiconify_approve_send_pending_end(void *data)
3766 E_Border *bd = (E_Border *)data;
3767 E_Border *bd_ancestor;
3769 if (e_config->deiconify_approve)
3771 if (!e_object_is_del(E_OBJECT(bd)))
3773 bd->client.e.state.deiconify_approve.pending_job = NULL;
3775 ELBF(ELBT_BD, 0, bd->client.win,
3776 "SEND DEICONIFY_APPROVE. (PENDING_END) ancestor:%x",
3779 ecore_x_client_message32_send(bd->client.win,
3780 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3781 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3782 bd->client.win, 0, 0, 0, 0);
3783 bd_ancestor = bd->client.e.state.deiconify_approve.ancestor;
3786 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, bd);
3789 if (!bd->client.e.state.deiconify_approve.wait_timer)
3790 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3796 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor, Eina_Bool pending_ancestor)
3798 if (!bd || !bd_ancestor) return;
3800 if (e_config->deiconify_approve)
3802 if (e_config->transient.iconify)
3806 Eina_List *list = _e_border_sub_borders_new(bd);
3807 EINA_LIST_FOREACH(list, l, child)
3809 Eina_Bool pending = EINA_FALSE;
3810 Eina_Bool p = EINA_FALSE;
3812 #ifdef _F_ZONE_WINDOW_ROTATION_
3813 if ((e_config->wm_win_rotation) &&
3814 ((child->client.e.state.rot.support) ||
3815 (child->client.e.state.rot.app_set)))
3817 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3818 int rotation = _e_border_rotation_angle_get(bd);
3819 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3822 if ((pending_ancestor) || (pending)) p = EINA_TRUE;
3824 _e_border_deiconify_approve_send(child, bd_ancestor, p);
3825 if (child->client.e.state.deiconify_approve.support)
3829 ELBF(ELBT_BD, 0, child->client.win,
3830 "SEND DEICONIFY_APPROVE. ancestor:%x pending(%d,%d)",
3831 bd_ancestor->client.win,
3832 pending_ancestor, pending);
3834 ecore_x_client_message32_send(child->client.win,
3835 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3836 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3837 child->client.win, 0, 0, 0, 0);
3838 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3839 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3843 /* queue a deiconify send job to give the chance to other jobs */
3844 ELBF(ELBT_BD, 0, child->client.win,
3845 "SEND DEICONIFY_APPROVE. (PENDING) ancestor:%x",
3846 bd_ancestor->client.win);
3847 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3848 child->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, child);
3852 eina_list_free(list);
3858 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3860 Eina_Bool pending = EINA_FALSE;
3862 if (e_config->deiconify_approve)
3864 #ifdef _F_ZONE_WINDOW_ROTATION_
3865 if ((e_config->wm_win_rotation) &&
3866 ((bd->client.e.state.rot.support) ||
3867 (bd->client.e.state.rot.app_set)))
3869 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3870 int rotation = _e_border_rotation_angle_get(bd);
3871 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3875 if (e_config->transient.iconify)
3877 _e_border_deiconify_approve_send(bd, bd, pending);
3880 if (bd->client.e.state.deiconify_approve.support)
3884 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE.");
3885 ecore_x_client_message32_send(bd->client.win,
3886 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3887 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3888 bd->client.win, 0, 0, 0, 0);
3889 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3893 /* queue a deiconify send job to give the chance to other jobs */
3894 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE. (PENDING)");
3895 bd->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, bd);
3903 e_border_uniconify(E_Border *bd)
3906 E_Event_Border_Uniconify *ev;
3907 unsigned int iconic;
3910 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3912 #ifdef _F_DEICONIFY_APPROVE_
3913 if (e_config->deiconify_approve)
3915 if (bd->client.e.state.deiconify_approve.support)
3917 if (bd->client.e.state.deiconify_approve.wait_timer)
3919 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3923 if (bd->client.e.state.deiconify_approve.pending_job)
3925 ELB(ELBT_BD, "DEICONIFY_APPROVE PENDING_JOB is already running", bd->client.win);
3929 if (bd->client.e.state.deiconify_approve.render_done == 0)
3931 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3932 _e_border_deiconify_approve_send_all_transient(bd);
3936 bd->client.e.state.deiconify_approve.render_done = 0;
3940 #if _F_ZONE_WINDOW_ROTATION_
3941 if (!bd->client.win)
3943 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3948 if (bd->shading) return;
3949 ecore_x_window_shadow_tree_flush();
3954 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3955 desk = e_desk_current_get(bd->desk->zone);
3956 #ifdef _F_USE_EXTENDED_ICONIFY_
3957 if (e_manager_comp_evas_get(bd->zone->container->manager))
3959 if (bd->await_hide_event > 0)
3960 bd->await_hide_event--;
3963 e_border_desk_set(bd, desk);
3965 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3968 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3970 ev = E_NEW(E_Event_Border_Uniconify, 1);
3972 e_object_ref(E_OBJECT(bd));
3973 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3974 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3976 if (e_config->transient.iconify)
3980 Eina_List *list = _e_border_sub_borders_new(bd);
3982 EINA_LIST_FOREACH(list, l, child)
3984 e_border_uniconify(child);
3986 eina_list_free(list);
3988 e_remember_update(bd);
3992 e_border_stick(E_Border *bd)
3994 E_Event_Border_Stick *ev;
3997 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3998 if (bd->sticky) return;
4000 e_hints_window_sticky_set(bd, 1);
4003 if (e_config->transient.desktop)
4007 Eina_List *list = _e_border_sub_borders_new(bd);
4009 EINA_LIST_FOREACH(list, l, child)
4012 e_hints_window_sticky_set(child, 1);
4013 e_border_show(child);
4015 eina_list_free(list);
4018 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
4019 ev = E_NEW(E_Event_Border_Stick, 1);
4021 e_object_ref(E_OBJECT(bd));
4022 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
4023 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
4024 e_remember_update(bd);
4028 e_border_unstick(E_Border *bd)
4030 E_Event_Border_Unstick *ev;
4033 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4034 /* Set the desk before we unstick the border */
4035 if (!bd->sticky) return;
4037 e_hints_window_sticky_set(bd, 0);
4039 if (e_config->transient.desktop)
4043 Eina_List *list = _e_border_sub_borders_new(bd);
4045 EINA_LIST_FOREACH(list, l, child)
4048 e_hints_window_sticky_set(child, 0);
4050 eina_list_free(list);
4053 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
4054 ev = E_NEW(E_Event_Border_Unstick, 1);
4056 e_object_ref(E_OBJECT(bd));
4057 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
4058 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
4060 e_border_desk_set(bd, e_desk_current_get(bd->zone));
4061 e_remember_update(bd);
4065 e_border_pinned_set(E_Border *bd,
4073 bd->borderless = set;
4074 bd->user_skip_winlist = set;
4078 stacking = E_STACKING_BELOW;
4083 stacking = E_STACKING_NONE;
4086 e_border_layer_set(bd, layer);
4087 e_hints_window_stacking_set(bd, stacking);
4089 bd->client.border.changed = 1;
4095 e_border_find_by_client_window(Ecore_X_Window win)
4099 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4100 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4101 (bd->client.win == win))
4107 e_border_find_all_by_client_window(Ecore_X_Window win)
4111 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4112 if ((bd) && (bd->client.win == win))
4118 e_border_find_by_frame_window(Ecore_X_Window win)
4122 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4123 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4124 (bd->bg_win == win))
4130 e_border_find_by_window(Ecore_X_Window win)
4134 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4135 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4142 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4147 EINA_LIST_FOREACH(borders, l, bd)
4149 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4150 (bd->client.netwm.sync.alarm == al))
4157 e_border_focused_get(void)
4163 _e_border_shape_input_rectangle_set(E_Border* bd)
4167 if ((bd->visible) && (bd->shaped_input))
4169 Ecore_X_Rectangle rects[4];
4170 Ecore_X_Window twin, twin2;
4173 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4174 0, 0, bd->w, bd->h);
4177 rects[0].width = bd->w;
4178 rects[0].height = bd->client_inset.t;
4180 rects[1].y = bd->client_inset.t;
4181 rects[1].width = bd->client_inset.l;
4182 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4183 rects[2].x = bd->w - bd->client_inset.r;
4184 rects[2].y = bd->client_inset.t;
4185 rects[2].width = bd->client_inset.r;
4186 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4188 rects[3].y = bd->h - bd->client_inset.b;
4189 rects[3].width = bd->w;
4190 rects[3].height = bd->client_inset.b;
4191 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4193 twin2 = ecore_x_window_override_new
4194 (bd->zone->container->scratch_win, 0, 0,
4195 bd->w - bd->client_inset.l - bd->client_inset.r,
4196 bd->h - bd->client_inset.t - bd->client_inset.b);
4199 if ((bd->shading) || (bd->shaded))
4201 if (bd->shade.dir == E_DIRECTION_UP)
4202 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4204 else if (bd->shade.dir == E_DIRECTION_LEFT)
4205 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4208 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4210 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4211 bd->w - bd->client_inset.l - bd->client_inset.r,
4212 bd->h - bd->client_inset.t - bd->client_inset.b);
4213 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4215 bd->client_inset.t);
4216 ecore_x_window_shape_input_window_set(bd->win, twin);
4217 ecore_x_window_free(twin2);
4218 ecore_x_window_free(twin);
4222 if (bd->visible) // not shaped input
4224 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4225 ecore_x_composite_window_events_enable(bd->win);
4227 ecore_x_composite_window_events_disable(bd->win);
4231 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4232 ecore_x_composite_window_events_enable(bd->win);
4234 ecore_x_composite_window_events_disable(bd->win);
4240 e_border_idler_before(void)
4249 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4251 EINA_LIST_FOREACH(man->containers, cl, con)
4256 // pass 1 - eval0. fetch properties on new or on change and
4257 // call hooks to decide what to do - maybe move/resize
4258 bl = e_container_border_list_last(con);
4259 while ((bd = e_container_border_list_prev(bl)))
4261 if (bd->changed) _e_border_eval0(bd);
4263 e_container_border_list_free(bl);
4265 // layout hook - this is where a hook gets to figure out what to
4267 _e_border_container_layout_hook(con);
4269 // pass 2 - show windows needing show
4270 bl = e_container_border_list_last(con);
4271 while ((bd = e_container_border_list_prev(bl)))
4273 if ((bd->changes.visible) && (bd->visible) &&
4274 (!bd->new_client) && (!bd->changes.pos) &&
4275 (!bd->changes.size))
4278 bd->changes.visible = 0;
4281 e_container_border_list_free(bl);
4283 // pass 3 - hide windows needing hide and eval (main eval)
4284 bl = e_container_border_list_first(con);
4285 while ((bd = e_container_border_list_next(bl)))
4287 if (e_object_is_del(E_OBJECT(bd))) continue;
4289 if ((bd->changes.visible) && (!bd->visible))
4292 bd->changes.visible = 0;
4295 if (bd->changed) _e_border_eval(bd);
4297 if ((bd->changes.visible) && (bd->visible))
4300 bd->changes.visible = 0;
4303 e_container_border_list_free(bl);
4309 E_Border *bd = NULL, *bd2;
4311 EINA_LIST_FREE(focus_next, bd2)
4312 if ((!bd) && (bd2->visible)) bd = bd2;
4316 /* TODO revert focus when lost here ? */
4322 /* already focused. but anyway dont be so strict, this
4323 fcks up illume setting focus on internal windows */
4328 focus_time = ecore_x_current_time_get();
4332 if ((bd->client.icccm.take_focus) &&
4333 (bd->client.icccm.accepts_focus))
4335 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4336 /* TODO what if the client didn't take focus ? */
4338 else if (!bd->client.icccm.accepts_focus)
4340 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4342 else if (!bd->client.icccm.take_focus)
4344 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4345 /* e_border_focus_set(bd, 1, 0); */
4349 #ifdef _F_ZONE_WINDOW_ROTATION_
4350 if ((e_config->wm_win_rotation) &&
4353 Ecore_X_Event_Client_Message *msg = NULL;
4355 EINA_LIST_FREE(rot.msgs, msg)
4357 t = msg->message_type;
4358 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4360 if ((rot.vkbd_ctrl_win) &&
4361 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4364 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4365 if (rot.vkbd_show_prepare_timer)
4366 _e_border_vkbd_show(rot.vkbd);
4368 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4371 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4373 if ((rot.vkbd_ctrl_win) &&
4374 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4377 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4378 if (rot.vkbd_hide_prepare_timer)
4380 _e_border_vkbd_hide(rot.vkbd);
4381 rot.vkbd_hide_prepare_timer = NULL;
4382 e_object_unref(E_OBJECT(rot.vkbd));
4385 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4388 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4390 rot.vkbd_ctrl_win = msg->data.l[0];
4391 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4393 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4395 if ((rot.vkbd_ctrl_win) &&
4396 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4398 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4399 E_Manager *m = e_manager_current_get();
4400 E_Zone *zone = NULL;
4401 if (m) zone = e_util_zone_current_get(m);
4402 if ((zone) && (rot.wait_prepare_done))
4405 _e_border_rotation_change_request(zone);
4406 else if (rot.async_list)
4408 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
4409 rot.async_list = NULL;
4411 if (rot.prepare_timer)
4412 ecore_timer_del(rot.prepare_timer);
4413 rot.prepare_timer = NULL;
4414 rot.wait_prepare_done = EINA_FALSE;
4421 rot.fetch = EINA_FALSE;
4427 e_border_client_list(void)
4429 /* FIXME: This should be a somewhat ordered list */
4433 static Ecore_X_Window action_input_win = 0;
4434 static E_Border *action_border = NULL;
4435 static Ecore_Event_Handler *action_handler_key = NULL;
4436 static Ecore_Event_Handler *action_handler_mouse = NULL;
4437 static Ecore_Timer *action_timer = NULL;
4438 static Ecore_X_Rectangle action_orig;
4441 _e_border_show(E_Border *bd)
4446 ecore_evas_show(bd->bg_ecore_evas);
4454 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4456 _e_border_shape_input_rectangle_set(bd);
4458 // ecore_x_composite_window_events_enable(bd->win);
4459 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4462 ecore_x_window_show(bd->win);
4464 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4465 ecore_x_window_show(tmp->win);
4469 _e_border_hide(E_Border *bd)
4474 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4476 ecore_x_window_hide(bd->win);
4477 ecore_evas_hide(bd->bg_ecore_evas);
4479 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4480 ecore_x_window_hide(tmp->win);
4484 ecore_x_composite_window_events_disable(bd->win);
4485 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4490 _e_border_action_input_win_del(void)
4492 if (!action_input_win)
4495 e_grabinput_release(action_input_win, action_input_win);
4496 ecore_x_window_free(action_input_win);
4497 action_input_win = 0;
4502 _e_border_action_input_win_new(E_Border *bd)
4504 if (!action_input_win)
4506 Ecore_X_Window parent = bd->zone->container->win;
4507 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4508 if (!action_input_win)
4512 ecore_x_window_show(action_input_win);
4513 if (e_grabinput_get(action_input_win, 0, action_input_win))
4516 _e_border_action_input_win_del();
4521 _e_border_action_finish(void)
4523 _e_border_action_input_win_del();
4527 ecore_timer_del(action_timer);
4528 action_timer = NULL;
4531 if (action_handler_key)
4533 ecore_event_handler_del(action_handler_key);
4534 action_handler_key = NULL;
4537 if (action_handler_mouse)
4539 ecore_event_handler_del(action_handler_mouse);
4540 action_handler_mouse = NULL;
4543 action_border = NULL;
4547 _e_border_action_init(E_Border *bd)
4549 action_orig.x = bd->x;
4550 action_orig.y = bd->y;
4551 action_orig.width = bd->w;
4552 action_orig.height = bd->h;
4558 _e_border_action_restore_orig(E_Border *bd)
4560 if (action_border != bd)
4563 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4567 _e_border_key_down_modifier_apply(int modifier,
4570 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4572 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4585 _e_border_action_move_timeout(void *data __UNUSED__)
4587 _e_border_move_end(action_border);
4588 _e_border_action_finish();
4589 return ECORE_CALLBACK_CANCEL;
4593 _e_border_action_move_timeout_add(void)
4596 ecore_timer_del(action_timer);
4597 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4601 _e_border_move_key_down(void *data __UNUSED__,
4602 int type __UNUSED__,
4605 Ecore_Event_Key *ev = event;
4608 if (ev->event_window != action_input_win)
4609 return ECORE_CALLBACK_PASS_ON;
4612 fputs("ERROR: no action_border!\n", stderr);
4616 x = action_border->x;
4617 y = action_border->y;
4619 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4620 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4621 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4622 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4623 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4624 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4625 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4626 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4627 else if (strcmp(ev->key, "Return") == 0)
4629 else if (strcmp(ev->key, "Escape") == 0)
4631 _e_border_action_restore_orig(action_border);
4634 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4635 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4638 e_border_move(action_border, x, y);
4639 _e_border_action_move_timeout_add();
4641 return ECORE_CALLBACK_PASS_ON;
4644 _e_border_move_end(action_border);
4645 _e_border_action_finish();
4646 return ECORE_CALLBACK_DONE;
4650 _e_border_move_mouse_down(void *data __UNUSED__,
4651 int type __UNUSED__,
4654 Ecore_Event_Mouse_Button *ev = event;
4656 if (ev->event_window != action_input_win)
4657 return ECORE_CALLBACK_PASS_ON;
4660 fputs("ERROR: no action_border!\n", stderr);
4662 _e_border_move_end(action_border);
4663 _e_border_action_finish();
4664 return ECORE_CALLBACK_DONE;
4668 e_border_act_move_keyboard(E_Border *bd)
4673 if (!_e_border_move_begin(bd))
4676 if (!_e_border_action_input_win_new(bd))
4678 _e_border_move_end(bd);
4682 _e_border_action_init(bd);
4683 _e_border_action_move_timeout_add();
4684 _e_border_move_update(bd);
4686 if (action_handler_key)
4687 ecore_event_handler_del(action_handler_key);
4688 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4690 if (action_handler_mouse)
4691 ecore_event_handler_del(action_handler_mouse);
4692 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4696 _e_border_action_resize_timeout(void *data __UNUSED__)
4698 _e_border_resize_end(action_border);
4699 _e_border_action_finish();
4700 return ECORE_CALLBACK_CANCEL;
4704 _e_border_action_resize_timeout_add(void)
4707 ecore_timer_del(action_timer);
4708 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4712 _e_border_resize_key_down(void *data __UNUSED__,
4713 int type __UNUSED__,
4716 Ecore_Event_Key *ev = event;
4719 if (ev->event_window != action_input_win)
4720 return ECORE_CALLBACK_PASS_ON;
4723 fputs("ERROR: no action_border!\n", stderr);
4727 w = action_border->w;
4728 h = action_border->h;
4730 dx = e_config->border_keyboard.resize.dx;
4731 if (dx < action_border->client.icccm.step_w)
4732 dx = action_border->client.icccm.step_w;
4733 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4734 if (dx < action_border->client.icccm.step_w)
4735 dx = action_border->client.icccm.step_w;
4737 dy = e_config->border_keyboard.resize.dy;
4738 if (dy < action_border->client.icccm.step_h)
4739 dy = action_border->client.icccm.step_h;
4740 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4741 if (dy < action_border->client.icccm.step_h)
4742 dy = action_border->client.icccm.step_h;
4744 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4746 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4748 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4750 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4752 else if (strcmp(ev->key, "Return") == 0)
4754 else if (strcmp(ev->key, "Escape") == 0)
4756 _e_border_action_restore_orig(action_border);
4759 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4760 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4763 e_border_resize_limit(action_border, &w, &h);
4764 e_border_resize(action_border, w, h);
4765 _e_border_action_resize_timeout_add();
4767 return ECORE_CALLBACK_PASS_ON;
4770 _e_border_resize_end(action_border);
4771 _e_border_action_finish();
4772 return ECORE_CALLBACK_DONE;
4776 _e_border_resize_mouse_down(void *data __UNUSED__,
4777 int type __UNUSED__,
4780 Ecore_Event_Mouse_Button *ev = event;
4782 if (ev->event_window != action_input_win)
4783 return ECORE_CALLBACK_PASS_ON;
4786 fputs("ERROR: no action_border!\n", stderr);
4788 _e_border_resize_end(action_border);
4789 _e_border_action_finish();
4790 return ECORE_CALLBACK_DONE;
4794 e_border_act_resize_keyboard(E_Border *bd)
4799 if (!_e_border_resize_begin(bd))
4802 if (!_e_border_action_input_win_new(bd))
4804 _e_border_resize_end(bd);
4808 _e_border_action_init(bd);
4809 _e_border_action_resize_timeout_add();
4810 _e_border_resize_update(bd);
4812 if (action_handler_key)
4813 ecore_event_handler_del(action_handler_key);
4814 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4816 if (action_handler_mouse)
4817 ecore_event_handler_del(action_handler_mouse);
4818 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4822 e_border_act_move_begin(E_Border *bd,
4823 Ecore_Event_Mouse_Button *ev)
4826 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4827 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4828 if (!_e_border_move_begin(bd))
4831 e_zone_edge_disable();
4833 _e_border_pointer_move_begin(bd);
4838 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4839 _e_border_moveinfo_gather(bd, source);
4844 e_border_act_move_end(E_Border *bd,
4845 Ecore_Event_Mouse_Button *ev __UNUSED__)
4848 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4849 if (!bd->moving) return;
4851 _e_border_pointer_move_end(bd);
4852 e_zone_edge_enable();
4853 _e_border_move_end(bd);
4854 e_zone_flip_coords_handle(bd->zone, -1, -1);
4858 e_border_act_resize_begin(E_Border *bd,
4859 Ecore_Event_Mouse_Button *ev)
4862 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4863 if (bd->lock_user_size) return;
4864 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4865 if (!_e_border_resize_begin(bd))
4867 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4869 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4871 bd->resize_mode = RESIZE_TL;
4872 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4876 bd->resize_mode = RESIZE_BL;
4877 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4882 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4884 bd->resize_mode = RESIZE_TR;
4885 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4889 bd->resize_mode = RESIZE_BR;
4890 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4893 _e_border_pointer_resize_begin(bd);
4898 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4899 _e_border_moveinfo_gather(bd, source);
4904 e_border_act_resize_end(E_Border *bd,
4905 Ecore_Event_Mouse_Button *ev __UNUSED__)
4908 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4909 if (bd->resize_mode != RESIZE_NONE)
4911 _e_border_pointer_resize_end(bd);
4912 bd->resize_mode = RESIZE_NONE;
4913 _e_border_resize_end(bd);
4914 bd->changes.reset_gravity = 1;
4920 e_border_act_menu_begin(E_Border *bd,
4921 Ecore_Event_Mouse_Button *ev,
4925 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4928 e_int_border_menu_show(bd,
4929 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4930 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4937 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4938 e_int_border_menu_show(bd, x, y, key, 0);
4943 e_border_act_close_begin(E_Border *bd)
4946 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4947 if (bd->lock_close) return;
4948 if (bd->client.icccm.delete_request)
4950 bd->delete_requested = 1;
4951 ecore_x_window_delete_request_send(bd->client.win);
4952 if (bd->client.netwm.ping)
4955 else if (e_config->kill_if_close_not_possible)
4957 e_border_act_kill_begin(bd);
4962 e_border_act_kill_begin(E_Border *bd)
4965 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4966 if (bd->internal) return;
4967 if (bd->lock_close) return;
4968 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4970 kill(bd->client.netwm.pid, SIGINT);
4971 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4972 _e_border_cb_kill_timer, bd);
4976 if (!bd->internal) ecore_x_kill(bd->client.win);
4981 e_border_icon_add(E_Border *bd,
4986 E_OBJECT_CHECK_RETURN(bd, NULL);
4987 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4992 if (!bd->internal_icon)
4994 o = e_icon_add(evas);
4995 e_util_icon_theme_set(o, "enlightenment");
4999 if (!bd->internal_icon_key)
5003 ext = strrchr(bd->internal_icon, '.');
5004 if ((ext) && ((!strcmp(ext, ".edj"))))
5006 o = edje_object_add(evas);
5007 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
5008 e_util_icon_theme_set(o, "enlightenment");
5012 o = e_icon_add(evas);
5013 e_icon_file_set(o, bd->internal_icon);
5017 o = e_icon_add(evas);
5018 if (!e_util_icon_theme_set(o, bd->internal_icon))
5019 e_util_icon_theme_set(o, "enlightenment");
5024 o = edje_object_add(evas);
5025 edje_object_file_set(o, bd->internal_icon,
5026 bd->internal_icon_key);
5031 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
5033 if (bd->client.netwm.icons)
5035 o = e_icon_add(evas);
5036 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5037 bd->client.netwm.icons[0].width,
5038 bd->client.netwm.icons[0].height);
5039 e_icon_alpha_set(o, 1);
5045 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
5047 o = e_icon_add(evas);
5050 e_icon_fdo_icon_set(o, bd->desktop->icon);
5054 else if (bd->client.netwm.icons)
5056 o = e_icon_add(evas);
5057 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5058 bd->client.netwm.icons[0].width,
5059 bd->client.netwm.icons[0].height);
5060 e_icon_alpha_set(o, 1);
5065 o = e_icon_add(evas);
5066 e_util_icon_theme_set(o, "unknown");
5071 e_border_button_bindings_ungrab_all(void)
5076 EINA_LIST_FOREACH(borders, l, bd)
5078 e_focus_setdown(bd);
5079 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5080 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5085 e_border_button_bindings_grab_all(void)
5090 EINA_LIST_FOREACH(borders, l, bd)
5092 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5093 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5099 e_border_focus_stack_get(void)
5105 e_border_raise_stack_get(void)
5111 e_border_lost_windows_get(E_Zone *zone)
5113 Eina_List *list = NULL, *l;
5115 int loss_overlap = 5;
5117 E_OBJECT_CHECK_RETURN(zone, NULL);
5118 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5119 EINA_LIST_FOREACH(borders, l, bd)
5124 if ((bd->zone != zone) ||
5125 (bd->zone->container != zone->container))
5128 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5129 bd->zone->y + loss_overlap,
5130 bd->zone->w - (2 * loss_overlap),
5131 bd->zone->h - (2 * loss_overlap),
5132 bd->x, bd->y, bd->w, bd->h))
5134 list = eina_list_append(list, bd);
5136 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5137 bd->zone->w, bd->zone->h,
5138 bd->x, bd->y, bd->w, bd->h)) &&
5141 Ecore_X_Rectangle *rect;
5144 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5150 for (i = 0; i < num; i++)
5152 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5153 bd->zone->y + loss_overlap,
5154 bd->zone->w - (2 * loss_overlap),
5155 bd->zone->h - (2 * loss_overlap),
5156 rect[i].x, rect[i].y,
5157 (int)rect[i].width, (int)rect[i].height))
5165 list = eina_list_append(list, bd);
5173 e_border_ping(E_Border *bd)
5176 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5177 if (!e_config->ping_clients) return;
5179 ecore_x_netwm_ping_send(bd->client.win);
5180 bd->ping = ecore_loop_time_get();
5181 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5182 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5183 e_config->ping_clients_interval,
5184 _e_border_cb_ping_poller, bd);
5188 e_border_move_cancel(void)
5192 if (bdmove->cur_mouse_action)
5197 e_object_ref(E_OBJECT(bd));
5198 if (bd->cur_mouse_action->func.end_mouse)
5199 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5200 else if (bd->cur_mouse_action->func.end)
5201 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5202 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5203 bd->cur_mouse_action = NULL;
5204 e_object_unref(E_OBJECT(bd));
5207 _e_border_move_end(bdmove);
5212 e_border_resize_cancel(void)
5216 if (bdresize->cur_mouse_action)
5221 e_object_ref(E_OBJECT(bd));
5222 if (bd->cur_mouse_action->func.end_mouse)
5223 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5224 else if (bd->cur_mouse_action->func.end)
5225 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5226 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5227 bd->cur_mouse_action = NULL;
5228 e_object_unref(E_OBJECT(bd));
5232 bdresize->resize_mode = RESIZE_NONE;
5233 _e_border_resize_end(bdresize);
5239 e_border_frame_recalc(E_Border *bd)
5241 if (!bd->bg_object) return;
5243 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5244 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5246 _e_border_client_inset_calc(bd);
5248 bd->w += (bd->client_inset.l + bd->client_inset.r);
5249 bd->h += (bd->client_inset.t + bd->client_inset.b);
5252 bd->changes.size = 1;
5253 if ((bd->shaped) || (bd->client.shaped))
5255 bd->need_shape_merge = 1;
5256 bd->need_shape_export = 1;
5258 if (bd->shaped_input)
5260 bd->need_shape_merge = 1;
5262 _e_border_client_move_resize_send(bd);
5266 e_border_immortal_windows_get(void)
5268 Eina_List *list = NULL, *l;
5271 EINA_LIST_FOREACH(borders, l, bd)
5274 list = eina_list_append(list, bd);
5280 e_border_name_get(const E_Border *bd)
5282 E_OBJECT_CHECK_RETURN(bd, "");
5283 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5284 if (bd->client.netwm.name)
5285 return bd->client.netwm.name;
5286 else if (bd->client.icccm.title)
5287 return bd->client.icccm.title;
5292 e_border_signal_move_begin(E_Border *bd,
5294 const char *src __UNUSED__)
5297 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5299 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5300 if (!_e_border_move_begin(bd)) return;
5302 _e_border_pointer_move_begin(bd);
5303 e_zone_edge_disable();
5304 _e_border_moveinfo_gather(bd, sig);
5305 if (bd->cur_mouse_action)
5307 if ((!bd->cur_mouse_action->func.end_mouse) &&
5308 (!bd->cur_mouse_action->func.end))
5309 bd->cur_mouse_action = NULL;
5311 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5313 bd->cur_mouse_action = e_action_find("window_move");
5314 if (bd->cur_mouse_action)
5315 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5319 e_border_signal_move_end(E_Border *bd,
5320 const char *sig __UNUSED__,
5321 const char *src __UNUSED__)
5324 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5325 if (!bd->moving) return;
5327 _e_border_pointer_move_end(bd);
5328 e_zone_edge_enable();
5329 _e_border_move_end(bd);
5330 e_zone_flip_coords_handle(bd->zone, -1, -1);
5334 e_border_resizing_get(E_Border *bd)
5336 E_OBJECT_CHECK_RETURN(bd, 0);
5337 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5338 if (bd->resize_mode == RESIZE_NONE) return 0;
5343 e_border_signal_resize_begin(E_Border *bd,
5346 const char *src __UNUSED__)
5348 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5349 int resize_mode = RESIZE_BR;
5352 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5354 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5355 if (!_e_border_resize_begin(bd))
5357 if (!strcmp(dir, "tl"))
5359 resize_mode = RESIZE_TL;
5360 grav = ECORE_X_GRAVITY_SE;
5362 else if (!strcmp(dir, "t"))
5364 resize_mode = RESIZE_T;
5365 grav = ECORE_X_GRAVITY_S;
5367 else if (!strcmp(dir, "tr"))
5369 resize_mode = RESIZE_TR;
5370 grav = ECORE_X_GRAVITY_SW;
5372 else if (!strcmp(dir, "r"))
5374 resize_mode = RESIZE_R;
5375 grav = ECORE_X_GRAVITY_W;
5377 else if (!strcmp(dir, "br"))
5379 resize_mode = RESIZE_BR;
5380 grav = ECORE_X_GRAVITY_NW;
5382 else if (!strcmp(dir, "b"))
5384 resize_mode = RESIZE_B;
5385 grav = ECORE_X_GRAVITY_N;
5387 else if (!strcmp(dir, "bl"))
5389 resize_mode = RESIZE_BL;
5390 grav = ECORE_X_GRAVITY_NE;
5392 else if (!strcmp(dir, "l"))
5394 resize_mode = RESIZE_L;
5395 grav = ECORE_X_GRAVITY_E;
5397 bd->resize_mode = resize_mode;
5398 _e_border_pointer_resize_begin(bd);
5399 _e_border_moveinfo_gather(bd, sig);
5401 if (bd->cur_mouse_action)
5403 if ((!bd->cur_mouse_action->func.end_mouse) &&
5404 (!bd->cur_mouse_action->func.end))
5405 bd->cur_mouse_action = NULL;
5407 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5409 bd->cur_mouse_action = e_action_find("window_resize");
5410 if (bd->cur_mouse_action)
5411 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5415 e_border_signal_resize_end(E_Border *bd,
5416 const char *dir __UNUSED__,
5417 const char *sig __UNUSED__,
5418 const char *src __UNUSED__)
5421 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5422 if (bd->resize_mode == RESIZE_NONE) return;
5423 _e_border_resize_handle(bd);
5424 _e_border_pointer_resize_end(bd);
5425 bd->resize_mode = RESIZE_NONE;
5426 _e_border_resize_end(bd);
5427 bd->changes.reset_gravity = 1;
5432 e_border_resize_limit(E_Border *bd,
5439 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5440 *w -= bd->client_inset.l + bd->client_inset.r;
5441 *h -= bd->client_inset.t + bd->client_inset.b;
5444 if ((bd->client.icccm.base_w >= 0) &&
5445 (bd->client.icccm.base_h >= 0))
5449 tw = *w - bd->client.icccm.base_w;
5450 th = *h - bd->client.icccm.base_h;
5453 a = (double)(tw) / (double)(th);
5454 if ((bd->client.icccm.min_aspect != 0.0) &&
5455 (a < bd->client.icccm.min_aspect))
5457 th = tw / bd->client.icccm.max_aspect;
5458 *h = th + bd->client.icccm.base_h;
5460 else if ((bd->client.icccm.max_aspect != 0.0) &&
5461 (a > bd->client.icccm.max_aspect))
5463 tw = th * bd->client.icccm.max_aspect;
5464 *w = tw + bd->client.icccm.base_w;
5469 a = (double)*w / (double)*h;
5470 if ((bd->client.icccm.min_aspect != 0.0) &&
5471 (a < bd->client.icccm.min_aspect))
5472 *h = *w / bd->client.icccm.min_aspect;
5473 else if ((bd->client.icccm.max_aspect != 0.0) &&
5474 (a > bd->client.icccm.max_aspect))
5475 *w = *h * bd->client.icccm.max_aspect;
5477 if (bd->client.icccm.step_w > 0)
5479 if (bd->client.icccm.base_w >= 0)
5480 *w = bd->client.icccm.base_w +
5481 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5482 bd->client.icccm.step_w);
5484 *w = bd->client.icccm.min_w +
5485 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5486 bd->client.icccm.step_w);
5488 if (bd->client.icccm.step_h > 0)
5490 if (bd->client.icccm.base_h >= 0)
5491 *h = bd->client.icccm.base_h +
5492 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5493 bd->client.icccm.step_h);
5495 *h = bd->client.icccm.min_h +
5496 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5497 bd->client.icccm.step_h);
5503 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5504 else if (*w < bd->client.icccm.min_w)
5505 *w = bd->client.icccm.min_w;
5506 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5507 else if (*h < bd->client.icccm.min_h)
5508 *h = bd->client.icccm.min_h;
5510 *w += bd->client_inset.l + bd->client_inset.r;
5511 *h += bd->client_inset.t + bd->client_inset.b;
5514 /* local subsystem functions */
5516 _e_border_free(E_Border *bd)
5518 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5521 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5523 bd->client.e.state.video_parent_border->client.e.state.video_child =
5525 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5528 if (bd->client.e.state.video_child)
5532 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5534 tmp->client.e.state.video_parent_border = NULL;
5539 efreet_desktop_free(bd->desktop);
5544 ecore_idle_enterer_del(bd->post_job);
5545 bd->post_job = NULL;
5549 e_object_del(E_OBJECT(bd->pointer));
5553 _e_border_resize_end(bd);
5555 _e_border_move_end(bd);
5556 /* TODO: Other states to end before dying? */
5558 if (bd->cur_mouse_action)
5560 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5561 bd->cur_mouse_action = NULL;
5564 E_FREE(bd->shape_rects);
5565 bd->shape_rects_num = 0;
5567 if (bd->dangling_ref_check)
5569 ecore_timer_del(bd->dangling_ref_check);
5570 bd->dangling_ref_check = NULL;
5575 ecore_timer_del(bd->kill_timer);
5576 bd->kill_timer = NULL;
5578 if (bd->ping_poller)
5580 ecore_poller_del(bd->ping_poller);
5581 bd->ping_poller = NULL;
5583 E_FREE_LIST(bd->pending_move_resize, free);
5585 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5586 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5588 if (bd->border_locks_dialog)
5590 e_object_del(E_OBJECT(bd->border_locks_dialog));
5591 bd->border_locks_dialog = NULL;
5593 if (bd->border_remember_dialog)
5595 e_object_del(E_OBJECT(bd->border_remember_dialog));
5596 bd->border_remember_dialog = NULL;
5598 if (bd->border_border_dialog)
5600 e_object_del(E_OBJECT(bd->border_border_dialog));
5601 bd->border_border_dialog = NULL;
5603 if (bd->border_prop_dialog)
5605 e_object_del(E_OBJECT(bd->border_prop_dialog));
5606 bd->border_prop_dialog = NULL;
5609 e_int_border_menu_del(bd);
5614 focus_next = eina_list_remove(focus_next, bd);
5616 if ((focused == bd) ||
5617 (e_grabinput_last_focus_win_get() == bd->client.win))
5619 if ((!focus_next) && (!focusing))
5621 e_grabinput_focus(bd->zone->container->bg_win,
5622 E_FOCUS_METHOD_PASSIVE);
5623 e_hints_active_window_set(bd->zone->container->manager, NULL);
5628 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5634 bd->remember = NULL;
5635 e_remember_unuse(rem);
5637 if (!bd->already_unparented)
5639 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5640 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5641 ecore_x_window_save_set_del(bd->client.win);
5642 bd->already_unparented = 1;
5644 if (bd->group) eina_list_free(bd->group);
5645 if (bd->transients) eina_list_free(bd->transients);
5646 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5647 if (bd->client.netwm.icons)
5650 for (i = 0; i < bd->client.netwm.num_icons; i++)
5651 free(bd->client.netwm.icons[i].data);
5652 free(bd->client.netwm.icons);
5654 if (bd->client.netwm.extra_types)
5655 free(bd->client.netwm.extra_types);
5656 if (bd->client.border.name)
5657 eina_stringshare_del(bd->client.border.name);
5659 eina_stringshare_del(bd->bordername);
5660 if (bd->client.icccm.name)
5661 eina_stringshare_del(bd->client.icccm.name);
5662 if (bd->client.icccm.class)
5664 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5665 e_bindings_mapping_change_enable(EINA_TRUE);
5666 eina_stringshare_del(bd->client.icccm.class);
5668 if (bd->client.icccm.title)
5669 eina_stringshare_del(bd->client.icccm.title);
5670 if (bd->client.icccm.icon_name)
5671 eina_stringshare_del(bd->client.icccm.icon_name);
5672 if (bd->client.icccm.machine)
5673 eina_stringshare_del(bd->client.icccm.machine);
5674 if (bd->client.icccm.window_role)
5675 eina_stringshare_del(bd->client.icccm.window_role);
5677 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5681 for (i = 0; i < bd->client.icccm.command.argc; i++)
5682 free(bd->client.icccm.command.argv[i]);
5683 free(bd->client.icccm.command.argv);
5685 if (bd->client.netwm.name)
5686 eina_stringshare_del(bd->client.netwm.name);
5687 if (bd->client.netwm.icon_name)
5688 eina_stringshare_del(bd->client.netwm.icon_name);
5689 e_object_del(E_OBJECT(bd->shape));
5690 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5691 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5692 if (bd->icon_object) evas_object_del(bd->icon_object);
5693 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5694 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5696 if (str) eina_stringshare_del(str);
5698 bd->client.e.state.profiles = NULL;
5699 if (bd->client.e.state.profile)
5700 eina_stringshare_del(bd->client.e.state.profile);
5701 bd->client.e.state.profile = NULL;
5703 #ifdef _F_ZONE_WINDOW_ROTATION_
5704 if (e_config->wm_win_rotation)
5706 bd->client.e.fetch.rot.app_set = 0;
5707 bd->client.e.state.rot.preferred_rot = -1;
5709 if (bd->client.e.state.rot.available_rots)
5710 E_FREE(bd->client.e.state.rot.available_rots);
5712 _e_border_rotation_list_remove(bd);
5713 if ((rot.vkbd) && (rot.vkbd == bd))
5715 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5717 if (rot.vkbd_ctrl_win)
5719 ELB(ELBT_BD, "SET KBD_OFF", 0);
5720 ecore_x_e_virtual_keyboard_state_set
5721 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5724 rot.vkbd_hide_prepare_done = EINA_FALSE;
5725 if (rot.vkbd_hide_prepare_timer)
5726 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5727 rot.vkbd_hide_prepare_timer = NULL;
5728 if (rot.vkbd_hide_timer)
5729 ecore_timer_del(rot.vkbd_hide_timer);
5730 rot.vkbd_hide_timer = NULL;
5732 rot.vkbd_show_prepare_done = EINA_FALSE;
5733 if (rot.vkbd_show_prepare_timer)
5734 ecore_timer_del(rot.vkbd_show_prepare_timer);
5735 rot.vkbd_show_prepare_timer = NULL;
5736 if (rot.vkbd_show_timer)
5737 ecore_timer_del(rot.vkbd_show_timer);
5738 rot.vkbd_show_timer = NULL;
5740 else if ((rot.vkbd_prediction) &&
5741 (rot.vkbd_prediction == bd))
5742 rot.vkbd_prediction = NULL;
5745 #ifdef _F_DEICONIFY_APPROVE_
5746 if (bd->client.e.state.deiconify_approve.pending_job)
5748 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5749 bd->client.e.state.deiconify_approve.pending_job = NULL;
5752 evas_object_del(bd->bg_object);
5753 e_canvas_del(bd->bg_ecore_evas);
5754 ecore_evas_free(bd->bg_ecore_evas);
5755 ecore_x_window_free(bd->client.shell_win);
5756 e_focus_setdown(bd);
5757 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5758 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5759 ecore_x_window_free(bd->win);
5761 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5762 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5763 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5764 borders = eina_list_remove(borders, bd);
5765 focus_stack = eina_list_remove(focus_stack, bd);
5766 raise_stack = eina_list_remove(raise_stack, bd);
5768 e_container_border_remove(bd);
5774 _e_border_del_dangling_ref_check(void *data)
5780 printf("EEK EEK border still around 1 second after being deleted!\n");
5781 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5782 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5783 bd->client.icccm.name, bd->client.icccm.class);
5784 // e_object_breadcrumb_debug(E_OBJECT(bd));
5791 _e_border_del(E_Border *bd)
5793 E_Event_Border_Remove *ev;
5796 #ifdef _F_BORDER_HOOK_PATCH_
5797 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5808 focus_next = eina_list_remove(focus_next, bd);
5810 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5812 if ((drag_border) && (drag_border->data == bd))
5814 e_object_del(E_OBJECT(drag_border));
5817 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5819 if (bd->border_locks_dialog)
5821 e_object_del(E_OBJECT(bd->border_locks_dialog));
5822 bd->border_locks_dialog = NULL;
5824 if (bd->border_remember_dialog)
5826 e_object_del(E_OBJECT(bd->border_remember_dialog));
5827 bd->border_remember_dialog = NULL;
5829 if (bd->border_border_dialog)
5831 e_object_del(E_OBJECT(bd->border_border_dialog));
5832 bd->border_border_dialog = NULL;
5834 if (bd->border_prop_dialog)
5836 e_object_del(E_OBJECT(bd->border_prop_dialog));
5837 bd->border_prop_dialog = NULL;
5840 e_int_border_menu_del(bd);
5842 if (bd->raise_timer)
5844 ecore_timer_del(bd->raise_timer);
5845 bd->raise_timer = NULL;
5847 if (!bd->already_unparented)
5849 ecore_x_window_reparent(bd->client.win,
5850 bd->zone->container->manager->root,
5851 bd->x + bd->client_inset.l,
5852 bd->y + bd->client_inset.t);
5853 ecore_x_window_save_set_del(bd->client.win);
5854 bd->already_unparented = 1;
5855 // bd->client.win = 0;
5857 bd->already_unparented = 1;
5859 if ((!bd->new_client) && (!stopping))
5861 ev = E_NEW(E_Event_Border_Remove, 1);
5863 e_object_ref(E_OBJECT(bd));
5864 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5865 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5870 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5871 if (bd->parent->modal == bd)
5873 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5874 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5875 bd->parent->lock_close = 0;
5876 bd->parent->saved.event_mask = 0;
5877 bd->parent->modal = NULL;
5881 EINA_LIST_FREE(bd->transients, child)
5883 child->parent = NULL;
5886 #ifdef _F_DEICONIFY_APPROVE_
5887 bd->client.e.state.deiconify_approve.render_done = 0;
5889 E_Border *ancestor_bd;
5890 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5891 if ((ancestor_bd) &&
5892 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5894 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5895 bd->client.e.state.deiconify_approve.ancestor = NULL;
5897 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5898 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5900 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5902 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5903 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5904 e_border_uniconify(ancestor_bd);
5909 if (bd->client.e.state.deiconify_approve.wait_timer)
5911 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5912 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5915 if (bd->client.e.state.deiconify_approve.pending_job)
5917 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5918 bd->client.e.state.deiconify_approve.pending_job = NULL;
5921 if (bd->client.e.state.deiconify_approve.req_list)
5923 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5925 child->client.e.state.deiconify_approve.render_done = 0;
5926 child->client.e.state.deiconify_approve.ancestor = NULL;
5931 #ifdef _F_ZONE_WINDOW_ROTATION_
5932 if (rot.list) _e_border_rotation_list_remove(bd);
5936 E_Border_Rotation_Info *info = NULL;
5938 EINA_LIST_FOREACH(rot.async_list, l, info)
5941 rot.async_list = eina_list_remove(rot.async_list, info);
5949 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5950 if (bd->leader->modal == bd)
5951 bd->leader->modal = NULL;
5954 EINA_LIST_FREE(bd->group, child)
5956 child->leader = NULL;
5960 #ifdef PRINT_LOTS_OF_DEBUG
5962 _e_border_print(E_Border *bd,
5971 "\tBorderless: %s\n",
5972 bd, bd->client.icccm.name, bd->client.icccm.title,
5973 bd->borderless ? "TRUE" : "FALSE");
5979 _e_border_cb_window_show_request(void *data __UNUSED__,
5980 int ev_type __UNUSED__,
5985 Ecore_X_Event_Window_Show_Request *e;
5988 bd = e_border_find_by_client_window(e->win);
5989 if (!bd) return ECORE_CALLBACK_PASS_ON;
5991 if ((e_config->wm_win_rotation) &&
5992 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5994 (rot.vkbd_hide_prepare_timer))
5996 con = bd->zone->container;
5997 bd = e_border_new(con, e->win, 0, 0);
6002 if (!bd->lock_client_iconify)
6003 e_border_uniconify(bd);
6007 /* FIXME: make border "urgent" for a bit - it wants attention */
6008 /* e_border_show(bd); */
6009 if (!bd->lock_client_stacking)
6012 return ECORE_CALLBACK_PASS_ON;
6016 _e_border_cb_window_destroy(void *data __UNUSED__,
6017 int ev_type __UNUSED__,
6021 Ecore_X_Event_Window_Destroy *e;
6024 bd = e_border_find_by_client_window(e->win);
6025 if (!bd) return ECORE_CALLBACK_PASS_ON;
6026 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
6027 #ifdef _F_ZONE_WINDOW_ROTATION_
6028 if (e_config->wm_win_rotation)
6030 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6032 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
6033 if (!rot.vkbd_hide_prepare_timer)
6035 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6036 e_border_hide(bd, 0);
6037 if (!rot.vkbd_hide_prepare_timer)
6039 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6040 e_object_del(E_OBJECT(bd));
6043 return ECORE_CALLBACK_PASS_ON;
6047 e_border_hide(bd, 0);
6048 e_object_del(E_OBJECT(bd));
6049 return ECORE_CALLBACK_PASS_ON;
6053 _e_border_cb_window_hide(void *data __UNUSED__,
6054 int ev_type __UNUSED__,
6057 E_Border *bd = NULL;
6058 Ecore_X_Event_Window_Hide *e;
6061 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
6062 // not interested in hide events from windows other than the window in question
6063 if (e->win != e->event_win)
6065 bd = e_border_find_by_client_window(e->win);
6066 if (!bd) return ECORE_CALLBACK_PASS_ON;
6067 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
6071 (bd->zone->container->manager->root == e->event_win)))
6072 return ECORE_CALLBACK_PASS_ON;
6075 if (!bd) bd = e_border_find_by_client_window(e->win);
6076 // printf(" bd = %p\n", bd);
6079 if (ecore_x_window_visible_get(e->win))
6081 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
6082 ecore_x_window_hide(e->win);
6084 return ECORE_CALLBACK_PASS_ON;
6087 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6088 if (bd->ignore_first_unmap > 0)
6090 bd->ignore_first_unmap--;
6091 return ECORE_CALLBACK_PASS_ON;
6093 /* Don't delete hidden or iconified windows */
6094 #ifdef _F_USE_EXTENDED_ICONIFY_
6095 if (bd->await_hide_event > 0)
6097 if ((bd->iconic) || (bd->await_hide_event > 0))
6100 // printf(" Don't delete hidden or iconified windows\n");
6101 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6102 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6103 if (bd->await_hide_event > 0)
6105 bd->await_hide_event--;
6109 // printf(" hide really\n");
6110 /* Only hide the border if it is visible */
6111 if (bd->visible) e_border_hide(bd, 1);
6116 // printf(" hide2\n");
6117 #ifdef _F_USE_EXTENDED_ICONIFY_
6125 #ifdef _F_ZONE_WINDOW_ROTATION_
6126 if (e_config->wm_win_rotation)
6128 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6130 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6131 if (!rot.vkbd_hide_prepare_timer)
6133 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6134 e_border_hide(bd, 0);
6135 if (!rot.vkbd_hide_prepare_timer)
6137 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6138 e_object_del(E_OBJECT(bd));
6141 return ECORE_CALLBACK_PASS_ON;
6145 e_border_hide(bd, 0);
6146 e_object_del(E_OBJECT(bd));
6148 return ECORE_CALLBACK_PASS_ON;
6152 _e_border_cb_window_reparent(void *data __UNUSED__,
6153 int ev_type __UNUSED__,
6154 void *ev __UNUSED__)
6158 Ecore_X_Event_Window_Reparent *e;
6161 bd = e_border_find_by_client_window(e->win);
6163 if (e->parent == bd->client.shell_win) return 1;
6164 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6168 e_border_hide(bd, 0);
6169 e_object_del(E_OBJECT(bd));
6171 return ECORE_CALLBACK_PASS_ON;
6175 _e_border_cb_window_configure_request(void *data __UNUSED__,
6176 int ev_type __UNUSED__,
6180 Ecore_X_Event_Window_Configure_Request *e;
6183 bd = e_border_find_by_client_window(e->win);
6186 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6187 if (!e_util_container_window_find(e->win))
6188 ecore_x_window_configure(e->win, e->value_mask,
6189 e->x, e->y, e->w, e->h, e->border,
6190 e->abovewin, e->detail);
6191 return ECORE_CALLBACK_PASS_ON;
6194 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6195 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6201 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6203 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6205 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6206 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6212 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6213 w = e->w + bd->client_inset.l + bd->client_inset.r;
6214 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6215 h = e->h + bd->client_inset.t + bd->client_inset.b;
6216 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6218 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6220 bd->saved.x = x - bd->zone->x;
6221 bd->saved.y = y - bd->zone->y;
6226 e_border_move_resize(bd, x, y, w, h);
6228 else if (!bd->lock_client_location)
6230 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6232 bd->saved.x = x - bd->zone->x;
6233 bd->saved.y = y - bd->zone->y;
6236 e_border_move(bd, x, y);
6238 else if (!bd->lock_client_size)
6240 if ((bd->shaded) || (bd->shading))
6246 if ((bd->shade.dir == E_DIRECTION_UP) ||
6247 (bd->shade.dir == E_DIRECTION_DOWN))
6249 e_border_resize(bd, w, bd->h);
6254 e_border_resize(bd, bd->w, h);
6260 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6266 e_border_resize(bd, w, h);
6272 if (!bd->lock_client_location)
6274 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6276 bd->saved.x = x - bd->zone->x;
6277 bd->saved.y = y - bd->zone->y;
6280 e_border_move(bd, x, y);
6284 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6285 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6291 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6292 w = e->w + bd->client_inset.l + bd->client_inset.r;
6293 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6294 h = e->h + bd->client_inset.t + bd->client_inset.b;
6295 #ifdef _F_ZONE_WINDOW_ROTATION_
6296 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6298 if (!bd->lock_client_size)
6300 if ((bd->shaded) || (bd->shading))
6306 if ((bd->shade.dir == E_DIRECTION_UP) ||
6307 (bd->shade.dir == E_DIRECTION_DOWN))
6309 e_border_resize(bd, w, bd->h);
6314 e_border_resize(bd, bd->w, h);
6320 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6325 zx = zy = zw = zh = 0;
6328 * This code does resize and move a window on a
6329 * X configure request into an useful geometry.
6330 * This is really useful for size jumping file dialogs.
6335 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6337 if (e_config->geometry_auto_resize_limit == 1)
6346 e_border_resize(bd, w, h);
6348 if (e_config->geometry_auto_move == 1)
6350 /* z{x,y,w,h} are only set here; FIXME! */
6353 // move window horizontal if resize to not useful geometry
6354 if (bd->x + bd->w > zx + zw)
6355 rx = zx + zw - bd->w;
6356 else if (bd->x < zx)
6359 // move window vertical if resize to not useful geometry
6360 if (bd->y + bd->h > zy + zh)
6361 ry = zy + zh - bd->h;
6362 else if (bd->y < zy)
6365 e_border_move(bd, rx, ry);
6371 if (!bd->lock_client_stacking)
6373 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6374 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6378 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6380 obd = e_border_find_by_client_window(e->abovewin);
6383 e_border_stack_above(bd, obd);
6387 ecore_x_window_configure(bd->win,
6388 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6389 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6391 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6392 /* FIXME: need to rebuiuld border list from current stacking */
6395 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6397 obd = e_border_find_by_client_window(e->abovewin);
6400 e_border_stack_below(bd, obd);
6404 ecore_x_window_configure(bd->win,
6405 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6406 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6408 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6409 /* FIXME: need to rebuiuld border list from current stacking */
6412 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6416 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6420 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6425 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6427 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6431 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6435 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6439 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6443 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6450 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6451 _e_border_client_move_resize_send(bd);
6452 return ECORE_CALLBACK_PASS_ON;
6456 _e_border_cb_window_resize_request(void *data __UNUSED__,
6457 int ev_type __UNUSED__,
6461 Ecore_X_Event_Window_Resize_Request *e;
6464 bd = e_border_find_by_client_window(e->win);
6467 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6468 ecore_x_window_resize(e->win, e->w, e->h);
6469 return ECORE_CALLBACK_PASS_ON;
6474 w = e->w + bd->client_inset.l + bd->client_inset.r;
6475 h = e->h + bd->client_inset.t + bd->client_inset.b;
6476 if ((bd->shaded) || (bd->shading))
6482 if ((bd->shade.dir == E_DIRECTION_UP) ||
6483 (bd->shade.dir == E_DIRECTION_DOWN))
6485 e_border_resize(bd, w, bd->h);
6490 e_border_resize(bd, bd->w, h);
6495 e_border_resize(bd, w, h);
6498 _e_border_client_move_resize_send(bd);
6499 return ECORE_CALLBACK_PASS_ON;
6503 _e_border_cb_window_gravity(void *data __UNUSED__,
6504 int ev_type __UNUSED__,
6505 void *ev __UNUSED__)
6508 // Ecore_X_Event_Window_Gravity *e;
6511 // bd = e_border_find_by_client_window(e->win);
6512 // if (!bd) return 1;
6517 _e_border_cb_window_stack_request(void *data __UNUSED__,
6518 int ev_type __UNUSED__,
6522 Ecore_X_Event_Window_Stack_Request *e;
6525 bd = e_border_find_by_client_window(e->win);
6528 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6529 if (!e_util_container_window_find(e->win))
6531 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6532 ecore_x_window_raise(e->win);
6533 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6534 ecore_x_window_lower(e->win);
6536 return ECORE_CALLBACK_PASS_ON;
6538 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6540 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6542 return ECORE_CALLBACK_PASS_ON;
6546 _e_border_cb_window_property(void *data __UNUSED__,
6547 int ev_type __UNUSED__,
6551 Ecore_X_Event_Window_Property *e;
6554 bd = e_border_find_by_client_window(e->win);
6555 if (!bd) return ECORE_CALLBACK_PASS_ON;
6556 if (e->atom == ECORE_X_ATOM_WM_NAME)
6558 if ((!bd->client.netwm.name) &&
6559 (!bd->client.netwm.fetch.name))
6561 bd->client.icccm.fetch.title = 1;
6565 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6567 bd->client.netwm.fetch.name = 1;
6570 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6572 bd->client.icccm.fetch.name_class = 1;
6575 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6577 if ((!bd->client.netwm.icon_name) &&
6578 (!bd->client.netwm.fetch.icon_name))
6580 bd->client.icccm.fetch.icon_name = 1;
6584 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6586 bd->client.netwm.fetch.icon_name = 1;
6589 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6591 bd->client.icccm.fetch.machine = 1;
6594 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6596 bd->client.icccm.fetch.protocol = 1;
6599 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6601 bd->client.icccm.fetch.hints = 1;
6604 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6606 bd->client.icccm.fetch.size_pos_hints = 1;
6609 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6612 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6613 (!bd->client.netwm.fetch.type))
6616 bd->client.mwm.fetch.hints = 1;
6622 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6624 bd->client.icccm.fetch.transient_for = 1;
6627 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6629 bd->client.icccm.fetch.client_leader = 1;
6632 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6634 bd->client.icccm.fetch.window_role = 1;
6637 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6639 bd->client.netwm.fetch.icon = 1;
6642 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6644 bd->client.qtopia.fetch.soft_menu = 1;
6647 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6649 bd->client.qtopia.fetch.soft_menus = 1;
6652 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6654 bd->client.vkbd.fetch.state = 1;
6657 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6659 bd->client.vkbd.fetch.vkbd = 1;
6662 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6664 bd->client.illume.conformant.fetch.conformant = 1;
6667 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6669 bd->client.illume.quickpanel.fetch.state = 1;
6672 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6674 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6677 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6679 bd->client.illume.quickpanel.fetch.priority.major = 1;
6682 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6684 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6687 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6689 bd->client.illume.quickpanel.fetch.zone = 1;
6692 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6694 bd->client.illume.drag.fetch.locked = 1;
6697 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6699 bd->client.illume.drag.fetch.drag = 1;
6702 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6704 bd->client.illume.win_state.fetch.state = 1;
6708 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6710 bd->client.netwm.fetch.user_time = 1;
6713 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6715 bd->client.netwm.fetch.strut = 1;
6718 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6720 bd->client.netwm.fetch.strut = 1;
6724 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6726 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6728 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6730 bd->client.e.fetch.video_position = 1;
6733 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6735 bd->client.e.fetch.video_parent = 1;
6738 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6740 bd->client.netwm.fetch.state = 1;
6743 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6744 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6746 bd->client.e.fetch.profile_list = 1;
6750 #ifdef _F_ZONE_WINDOW_ROTATION_
6751 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6753 if (e_config->wm_win_rotation)
6755 bd->client.e.fetch.rot.support = 1;
6759 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6760 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6761 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6762 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6764 if (e_config->wm_win_rotation)
6766 bd->client.e.fetch.rot.geom_hint = 1;
6770 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6772 if (e_config->wm_win_rotation)
6774 bd->client.e.fetch.rot.app_set = 1;
6778 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6780 if (e_config->wm_win_rotation)
6782 bd->client.e.fetch.rot.preferred_rot = 1;
6786 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6788 if (e_config->wm_win_rotation)
6790 bd->client.e.fetch.rot.available_rots = 1;
6796 return ECORE_CALLBACK_PASS_ON;
6800 _e_border_cb_window_colormap(void *data __UNUSED__,
6801 int ev_type __UNUSED__,
6805 Ecore_X_Event_Window_Colormap *e;
6808 bd = e_border_find_by_client_window(e->win);
6809 if (!bd) return ECORE_CALLBACK_PASS_ON;
6810 return ECORE_CALLBACK_PASS_ON;
6814 _e_border_cb_window_shape(void *data __UNUSED__,
6815 int ev_type __UNUSED__,
6819 Ecore_X_Event_Window_Shape *e;
6822 bd = e_border_find_by_client_window(e->win);
6824 if (e->type == ECORE_X_SHAPE_INPUT)
6828 bd->need_shape_merge = 1;
6829 // YYY bd->shaped_input = 1;
6830 bd->changes.shape_input = 1;
6834 return ECORE_CALLBACK_PASS_ON;
6839 bd->changes.shape = 1;
6841 return ECORE_CALLBACK_PASS_ON;
6843 bd = e_border_find_by_window(e->win);
6846 bd->need_shape_export = 1;
6848 return ECORE_CALLBACK_PASS_ON;
6850 bd = e_border_find_by_frame_window(e->win);
6853 bd->need_shape_merge = 1;
6855 return ECORE_CALLBACK_PASS_ON;
6857 return ECORE_CALLBACK_PASS_ON;
6861 _e_border_cb_window_focus_in(void *data __UNUSED__,
6862 int ev_type __UNUSED__,
6866 Ecore_X_Event_Window_Focus_In *e;
6869 bd = e_border_find_by_client_window(e->win);
6870 if (!bd) return ECORE_CALLBACK_PASS_ON;
6871 #ifdef INOUTDEBUG_FOCUS
6876 const char *modes[] = {
6878 "MODE_WHILE_GRABBED",
6882 const char *details[] = {
6886 "DETAIL_NON_LINEAR",
6887 "DETAIL_NON_LINEAR_VIRTUAL",
6889 "DETAIL_POINTER_ROOT",
6890 "DETAIL_DETAIL_NONE"
6894 ct[strlen(ct) - 1] = 0;
6895 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6900 details[e->detail]);
6902 DBG("%s cb focus in %d %d\n",
6903 e_border_name_get(bd),
6904 bd->client.icccm.accepts_focus,
6905 bd->client.icccm.take_focus);
6908 _e_border_pri_raise(bd);
6909 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6911 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6913 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6915 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6918 /* ignore focus in from !take_focus windows, we just gave it em */
6919 /* if (!bd->client.icccm.take_focus)
6920 * return ECORE_CALLBACK_PASS_ON; */
6922 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6923 if (e->time >= focus_time)
6924 e_border_focus_set(bd, 1, 0);
6925 return ECORE_CALLBACK_PASS_ON;
6929 _e_border_cb_window_focus_out(void *data __UNUSED__,
6930 int ev_type __UNUSED__,
6934 Ecore_X_Event_Window_Focus_Out *e;
6937 bd = e_border_find_by_client_window(e->win);
6938 if (!bd) return ECORE_CALLBACK_PASS_ON;
6939 #ifdef INOUTDEBUG_FOCUS
6944 const char *modes[] = {
6946 "MODE_WHILE_GRABBED",
6950 const char *details[] = {
6954 "DETAIL_NON_LINEAR",
6955 "DETAIL_NON_LINEAR_VIRTUAL",
6957 "DETAIL_POINTER_ROOT",
6958 "DETAIL_DETAIL_NONE"
6962 ct[strlen(ct) - 1] = 0;
6963 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6968 details[e->detail]);
6970 DBG("%s cb focus out %d %d",
6971 e_border_name_get(bd),
6972 bd->client.icccm.accepts_focus,
6973 bd->client.icccm.take_focus);
6976 _e_border_pri_norm(bd);
6977 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6979 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6980 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6981 return ECORE_CALLBACK_PASS_ON;
6982 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6983 return ECORE_CALLBACK_PASS_ON;
6985 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6987 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6988 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6989 return ECORE_CALLBACK_PASS_ON;
6990 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6991 return ECORE_CALLBACK_PASS_ON;
6992 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6993 return ECORE_CALLBACK_PASS_ON;
6994 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6995 return ECORE_CALLBACK_PASS_ON;
6997 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6999 /* for firefox/thunderbird (xul) menu walking */
7000 /* NB: why did i disable this before? */
7001 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7002 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
7003 return ECORE_CALLBACK_PASS_ON;
7005 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
7007 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
7008 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7009 return ECORE_CALLBACK_PASS_ON;
7011 e_border_focus_set(bd, 0, 0);
7012 return ECORE_CALLBACK_PASS_ON;
7015 #if _F_BORDER_CLIP_TO_ZONE_
7017 _e_border_shape_input_clip_to_zone(E_Border *bd)
7019 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
7023 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
7024 bd->zone->w, bd->zone->h,
7025 bd->x, bd->y, bd->w, bd->h)))
7028 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
7029 E_RECTS_CLIP_TO_RECT(x, y, w, h,
7030 bd->zone->x, bd->zone->y,
7031 bd->zone->w, bd->zone->h);
7034 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
7035 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
7039 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
7040 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
7043 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
7046 _e_border_cb_client_message(void *data __UNUSED__,
7047 int ev_type __UNUSED__,
7050 Ecore_X_Event_Client_Message *e;
7054 #ifdef _F_DEICONIFY_APPROVE_
7055 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
7057 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
7059 bd = e_border_find_by_client_window(e->win);
7062 if (bd->client.e.state.deiconify_approve.support)
7064 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
7065 bd->client.e.state.deiconify_approve.render_done = 1;
7067 E_Border *ancestor_bd;
7068 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
7071 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
7072 bd->client.e.state.deiconify_approve.ancestor = NULL;
7079 ELBF(ELBT_BD, 0, bd->client.win,
7080 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
7082 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
7083 (ancestor_bd->client.e.state.deiconify_approve.render_done))
7085 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7087 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7088 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7090 if (bd->client.e.state.deiconify_approve.wait_timer)
7092 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7093 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7096 e_border_uniconify(ancestor_bd);
7100 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7101 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7105 if (bd != ancestor_bd)
7107 if (bd->client.e.state.deiconify_approve.wait_timer)
7109 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7110 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7115 return ECORE_CALLBACK_PASS_ON;
7119 #ifdef _F_ZONE_WINDOW_ROTATION_
7120 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7122 bd = e_border_find_by_client_window(e->win);
7125 if (e_config->wm_win_rotation)
7127 Ecore_X_Event_Client_Message *msg = NULL;
7128 Ecore_X_Atom t = e->message_type;
7129 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7130 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7131 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7132 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7134 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7135 if (!msg) return ECORE_CALLBACK_PASS_ON;
7138 msg->message_type = e->message_type;
7139 msg->data.l[0] = e->data.l[0];
7140 msg->data.l[1] = e->data.l[1];
7141 msg->data.l[2] = e->data.l[2];
7142 msg->data.l[3] = e->data.l[3];
7143 msg->data.l[4] = e->data.l[4];
7144 rot.msgs = eina_list_append(rot.msgs, msg);
7146 rot.fetch = EINA_TRUE;
7149 return ECORE_CALLBACK_PASS_ON;
7152 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7154 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7155 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7157 if (e_config->wm_win_rotation)
7159 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7161 _e_border_rotation_list_remove(bd);
7162 if (bd->client.e.state.rot.pending_show)
7164 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7166 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7167 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
7168 _e_border_check_stack(bd);
7170 bd->client.e.state.rot.pending_show = 0;
7176 return ECORE_CALLBACK_PASS_ON;
7180 _e_border_cb_window_state_request(void *data __UNUSED__,
7181 int ev_type __UNUSED__,
7185 Ecore_X_Event_Window_State_Request *e;
7189 bd = e_border_find_by_client_window(e->win);
7190 if (!bd) return ECORE_CALLBACK_PASS_ON;
7192 for (i = 0; i < 2; i++)
7193 e_hints_window_state_update(bd, e->state[i], e->action);
7195 return ECORE_CALLBACK_PASS_ON;
7199 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7200 int ev_type __UNUSED__,
7204 Ecore_X_Event_Window_Move_Resize_Request *e;
7207 bd = e_border_find_by_client_window(e->win);
7208 if (!bd) return ECORE_CALLBACK_PASS_ON;
7210 if ((bd->shaded) || (bd->shading) ||
7211 (bd->fullscreen) || (bd->moving) ||
7212 (bd->resize_mode != RESIZE_NONE))
7213 return ECORE_CALLBACK_PASS_ON;
7215 if ((e->button >= 1) && (e->button <= 3))
7217 bd->mouse.last_down[e->button - 1].mx = e->x;
7218 bd->mouse.last_down[e->button - 1].my = e->y;
7219 bd->mouse.last_down[e->button - 1].x = bd->x;
7220 bd->mouse.last_down[e->button - 1].y = bd->y;
7221 bd->mouse.last_down[e->button - 1].w = bd->w;
7222 bd->mouse.last_down[e->button - 1].h = bd->h;
7226 bd->moveinfo.down.x = bd->x;
7227 bd->moveinfo.down.y = bd->y;
7228 bd->moveinfo.down.w = bd->w;
7229 bd->moveinfo.down.h = bd->h;
7231 bd->mouse.current.mx = e->x;
7232 bd->mouse.current.my = e->y;
7233 bd->moveinfo.down.button = e->button;
7234 bd->moveinfo.down.mx = e->x;
7235 bd->moveinfo.down.my = e->y;
7238 if (!bd->lock_user_stacking)
7241 if (e->direction == MOVE)
7243 bd->cur_mouse_action = e_action_find("window_move");
7244 if (bd->cur_mouse_action)
7246 if ((!bd->cur_mouse_action->func.end_mouse) &&
7247 (!bd->cur_mouse_action->func.end))
7248 bd->cur_mouse_action = NULL;
7249 if (bd->cur_mouse_action)
7251 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7252 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7255 return ECORE_CALLBACK_PASS_ON;
7258 if (!_e_border_resize_begin(bd))
7259 return ECORE_CALLBACK_PASS_ON;
7261 switch (e->direction)
7264 bd->resize_mode = RESIZE_TL;
7265 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7269 bd->resize_mode = RESIZE_T;
7270 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7274 bd->resize_mode = RESIZE_TR;
7275 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7279 bd->resize_mode = RESIZE_R;
7280 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7284 bd->resize_mode = RESIZE_BR;
7285 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7289 bd->resize_mode = RESIZE_B;
7290 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7294 bd->resize_mode = RESIZE_BL;
7295 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7299 bd->resize_mode = RESIZE_L;
7300 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7304 return ECORE_CALLBACK_PASS_ON;
7307 bd->cur_mouse_action = e_action_find("window_resize");
7308 if (bd->cur_mouse_action)
7310 if ((!bd->cur_mouse_action->func.end_mouse) &&
7311 (!bd->cur_mouse_action->func.end))
7312 bd->cur_mouse_action = NULL;
7314 if (bd->cur_mouse_action)
7315 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7317 return ECORE_CALLBACK_PASS_ON;
7321 _e_border_cb_desktop_change(void *data __UNUSED__,
7322 int ev_type __UNUSED__,
7326 Ecore_X_Event_Desktop_Change *e;
7329 bd = e_border_find_by_client_window(e->win);
7332 if (e->desk == 0xffffffff)
7334 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7338 desk = e_desk_at_pos_get(bd->zone, e->desk);
7340 e_border_desk_set(bd, desk);
7345 ecore_x_netwm_desktop_set(e->win, e->desk);
7347 return ECORE_CALLBACK_PASS_ON;
7351 _e_border_cb_sync_alarm(void *data __UNUSED__,
7352 int ev_type __UNUSED__,
7356 Ecore_X_Event_Sync_Alarm *e;
7357 unsigned int serial;
7360 bd = e_border_find_by_alarm(e->alarm);
7361 if (!bd) return ECORE_CALLBACK_PASS_ON;
7363 if (bd->client.netwm.sync.wait)
7364 bd->client.netwm.sync.wait--;
7366 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7368 E_Border_Pending_Move_Resize *pnd = NULL;
7370 /* skip pending for which we didn't get a reply */
7371 while (bd->pending_move_resize)
7373 pnd = bd->pending_move_resize->data;
7374 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7376 if (serial == pnd->serial)
7388 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7389 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7394 bd->changes.size = 1;
7395 bd->changes.pos = 1;
7398 evas_render(bd->bg_evas);
7400 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7401 &bd->mouse.current.mx,
7402 &bd->mouse.current.my);
7404 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7405 _e_border_resize_handle(bd);
7407 return ECORE_CALLBACK_PASS_ON;
7411 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7412 int ev_type __UNUSED__,
7413 void *ev __UNUSED__)
7418 /* mark all borders for desktop/icon updates */
7419 EINA_LIST_FOREACH(borders, l, bd)
7423 efreet_desktop_free(bd->desktop);
7426 bd->changes.icon = 1;
7430 e_init_status_set(_("Desktop files scan done"));
7433 return ECORE_CALLBACK_PASS_ON;
7437 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7438 int ev_type __UNUSED__,
7439 void *ev __UNUSED__)
7444 /* mark all borders for desktop/icon updates */
7445 EINA_LIST_FOREACH(borders, l, bd)
7447 bd->changes.icon = 1;
7450 return ECORE_CALLBACK_PASS_ON;
7454 _e_border_cb_pointer_warp(void *data __UNUSED__,
7455 int ev_type __UNUSED__,
7458 E_Event_Pointer_Warp *e;
7461 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7462 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7463 return ECORE_CALLBACK_PASS_ON;
7467 _e_border_cb_signal_bind(void *data,
7468 Evas_Object *obj __UNUSED__,
7469 const char *emission,
7475 if (e_dnd_active()) return;
7476 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7481 _e_border_cb_mouse_in(void *data,
7482 int type __UNUSED__,
7485 Ecore_X_Event_Mouse_In *ev;
7490 #ifdef INOUTDEBUG_MOUSE
7495 const char *modes[] = {
7497 "MODE_WHILE_GRABBED",
7501 const char *details[] = {
7505 "DETAIL_NON_LINEAR",
7506 "DETAIL_NON_LINEAR_VIRTUAL",
7508 "DETAIL_POINTER_ROOT",
7509 "DETAIL_DETAIL_NONE"
7513 ct[strlen(ct) - 1] = 0;
7514 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7515 ev->win, ev->event_win,
7518 details[ev->detail]);
7521 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7522 if (ev->event_win == bd->win)
7524 e_focus_event_mouse_in(bd);
7527 if ((ev->win != bd->win) &&
7528 (ev->win != bd->event_win) &&
7529 (ev->event_win != bd->win) &&
7530 (ev->event_win != bd->event_win))
7531 return ECORE_CALLBACK_PASS_ON;
7533 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7535 bd->mouse.current.mx = ev->root.x;
7536 bd->mouse.current.my = ev->root.y;
7537 if (!bd->bg_evas_in)
7539 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7540 bd->bg_evas_in = EINA_TRUE;
7542 return ECORE_CALLBACK_PASS_ON;
7546 _e_border_cb_mouse_out(void *data,
7547 int type __UNUSED__,
7550 Ecore_X_Event_Mouse_Out *ev;
7555 #ifdef INOUTDEBUG_MOUSE
7560 const char *modes[] = {
7562 "MODE_WHILE_GRABBED",
7566 const char *details[] = {
7570 "DETAIL_NON_LINEAR",
7571 "DETAIL_NON_LINEAR_VIRTUAL",
7573 "DETAIL_POINTER_ROOT",
7574 "DETAIL_DETAIL_NONE"
7578 ct[strlen(ct) - 1] = 0;
7579 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7580 ev->win, ev->event_win,
7583 details[ev->detail]);
7586 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7587 if (ev->event_win == bd->win)
7590 return ECORE_CALLBACK_PASS_ON;
7591 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7592 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7593 return ECORE_CALLBACK_PASS_ON;
7594 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7595 return ECORE_CALLBACK_PASS_ON;
7596 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7597 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7598 return ECORE_CALLBACK_PASS_ON;
7599 e_focus_event_mouse_out(bd);
7602 if ((ev->win != bd->win) &&
7603 (ev->win != bd->event_win) &&
7604 (ev->event_win != bd->win) &&
7605 (ev->event_win != bd->event_win))
7606 return ECORE_CALLBACK_PASS_ON;
7608 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7610 bd->mouse.current.mx = ev->root.x;
7611 bd->mouse.current.my = ev->root.y;
7614 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7615 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7616 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7618 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7619 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7620 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7621 bd->bg_evas_in = EINA_FALSE;
7624 return ECORE_CALLBACK_PASS_ON;
7628 _e_border_cb_mouse_wheel(void *data,
7629 int type __UNUSED__,
7632 Ecore_Event_Mouse_Wheel *ev;
7637 if ((ev->event_window == bd->win) ||
7638 (ev->event_window == bd->event_win))
7640 bd->mouse.current.mx = ev->root.x;
7641 bd->mouse.current.my = ev->root.y;
7642 if (!bd->cur_mouse_action)
7643 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7646 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7647 return ECORE_CALLBACK_PASS_ON;
7651 _e_border_cb_mouse_down(void *data,
7652 int type __UNUSED__,
7655 Ecore_Event_Mouse_Button *ev;
7660 if ((ev->event_window == bd->win) ||
7661 (ev->event_window == bd->event_win))
7663 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7665 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7666 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7667 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7668 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7669 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7670 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7674 bd->moveinfo.down.x = bd->x + bd->fx.x;
7675 bd->moveinfo.down.y = bd->y + bd->fx.y;
7676 bd->moveinfo.down.w = bd->w;
7677 bd->moveinfo.down.h = bd->h;
7679 bd->mouse.current.mx = ev->root.x;
7680 bd->mouse.current.my = ev->root.y;
7681 if (!bd->cur_mouse_action)
7683 bd->cur_mouse_action =
7684 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7686 if (bd->cur_mouse_action)
7688 if ((!bd->cur_mouse_action->func.end_mouse) &&
7689 (!bd->cur_mouse_action->func.end))
7690 bd->cur_mouse_action = NULL;
7691 if (bd->cur_mouse_action)
7692 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7695 e_focus_event_mouse_down(bd);
7697 if (ev->window != ev->event_window)
7701 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7705 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7707 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7708 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7709 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7710 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7711 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7712 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7716 bd->moveinfo.down.x = bd->x + bd->fx.x;
7717 bd->moveinfo.down.y = bd->y + bd->fx.y;
7718 bd->moveinfo.down.w = bd->w;
7719 bd->moveinfo.down.h = bd->h;
7721 bd->mouse.current.mx = ev->root.x;
7722 bd->mouse.current.my = ev->root.y;
7727 else if (bd->resize_mode != RESIZE_NONE)
7733 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7735 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7736 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7737 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7739 return ECORE_CALLBACK_PASS_ON;
7743 _e_border_cb_mouse_up(void *data,
7744 int type __UNUSED__,
7747 Ecore_Event_Mouse_Button *ev;
7752 if ((ev->event_window == bd->win) ||
7753 (ev->event_window == bd->event_win))
7755 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7757 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7758 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7759 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7760 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7762 bd->mouse.current.mx = ev->root.x;
7763 bd->mouse.current.my = ev->root.y;
7764 /* also we dont pass the same params that went in - then again that */
7765 /* should be ok as we are just ending the action if it has an end */
7766 if (bd->cur_mouse_action)
7768 if (bd->cur_mouse_action->func.end_mouse)
7769 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7770 else if (bd->cur_mouse_action->func.end)
7771 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7772 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7773 bd->cur_mouse_action = NULL;
7777 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7778 e_focus_event_mouse_up(bd);
7781 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7782 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7784 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7785 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7786 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7787 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7789 bd->mouse.current.mx = ev->root.x;
7790 bd->mouse.current.my = ev->root.y;
7794 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7795 return ECORE_CALLBACK_PASS_ON;
7799 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7801 #ifdef _F_BORDER_CLIP_TO_ZONE_
7802 int new_x_max, new_y_max;
7803 int new_x_min, new_y_min;
7804 int margin_x, margin_y;
7806 margin_x = bd->w - 100;
7807 margin_y = bd->h - 100;
7809 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7810 new_x_min = bd->zone->x - margin_x;
7811 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7812 new_y_min = bd->zone->y - margin_y;
7814 if (x >= new_x_max) *new_x = new_x_max;
7815 else if (x <= new_x_min) *new_x = new_x_min;
7817 if (y >= new_y_max) *new_y = new_y_max;
7818 else if (y <= new_y_min) *new_y = new_y_min;
7823 _e_border_cb_mouse_move(void *data,
7824 int type __UNUSED__,
7827 Ecore_Event_Mouse_Move *ev;
7832 if ((ev->window != bd->event_win) &&
7833 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7834 bd->mouse.current.mx = ev->root.x;
7835 bd->mouse.current.my = ev->root.y;
7838 int x, y, new_x, new_y;
7840 Eina_List *skiplist = NULL;
7842 // FIXME: remove? sync what for when only moving?
7843 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7844 bd->client.netwm.sync.wait = 0;
7845 if ((bd->client.netwm.sync.request) &&
7846 (bd->client.netwm.sync.alarm) &&
7847 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7849 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7851 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7852 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7853 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7854 (bd->mouse.current.my - bd->moveinfo.down.my);
7858 x = bd->moveinfo.down.x +
7859 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7860 y = bd->moveinfo.down.y +
7861 (bd->mouse.current.my - bd->moveinfo.down.my);
7866 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7867 skiplist = eina_list_append(skiplist, bd);
7868 e_resist_container_border_position(bd->zone->container, skiplist,
7869 bd->x, bd->y, bd->w, bd->h,
7871 &new_x, &new_y, &new_w, &new_h);
7872 eina_list_free(skiplist);
7874 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7876 /* if (e_config->window_out_of_vscreen_limits_partly) */
7878 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7881 skiplist = eina_list_append(skiplist, bd);
7882 e_resist_container_border_position(bd->zone->container, skiplist,
7883 bd->x, bd->y, bd->w, bd->h,
7885 &new_x, &new_y, &new_w, &new_h);
7886 eina_list_free(skiplist);
7889 bd->shelf_fix.x = 0;
7890 bd->shelf_fix.y = 0;
7891 bd->shelf_fix.modified = 0;
7892 e_border_move(bd, new_x, new_y);
7893 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7895 else if (bd->resize_mode != RESIZE_NONE)
7897 if ((bd->client.netwm.sync.request) &&
7898 (bd->client.netwm.sync.alarm))
7900 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7902 E_Border_Pending_Move_Resize *pnd;
7904 if (bd->pending_move_resize)
7906 bd->changes.pos = 1;
7907 bd->changes.size = 1;
7909 _e_border_client_move_resize_send(bd);
7911 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7914 bd->client.netwm.sync.wait = 0;
7916 /* sync.wait is incremented when resize_handle sends
7917 * sync-request and decremented by sync-alarm cb. so
7918 * we resize here either on initial resize, timeout or
7919 * when no new resize-request was added by sync-alarm cb.
7921 if (!bd->client.netwm.sync.wait)
7922 _e_border_resize_handle(bd);
7925 _e_border_resize_handle(bd);
7931 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7933 bd->drag.x = ev->root.x;
7934 bd->drag.y = ev->root.y;
7940 dx = bd->drag.x - ev->root.x;
7941 dy = bd->drag.y - ev->root.y;
7942 if (((dx * dx) + (dy * dy)) >
7943 (e_config->drag_resist * e_config->drag_resist))
7946 if (bd->icon_object)
7948 Evas_Object *o = NULL;
7949 Evas_Coord x, y, w, h;
7950 const char *drag_types[] = { "enlightenment/border" };
7952 e_object_ref(E_OBJECT(bd));
7953 evas_object_geometry_get(bd->icon_object,
7955 drag_border = e_drag_new(bd->zone->container,
7956 bd->x + bd->fx.x + x,
7957 bd->y + bd->fx.y + y,
7958 drag_types, 1, bd, -1,
7960 _e_border_cb_drag_finished);
7961 o = e_border_icon_add(bd, drag_border->evas);
7964 /* FIXME: fallback icon for drag */
7965 o = evas_object_rectangle_add(drag_border->evas);
7966 evas_object_color_set(o, 255, 255, 255, 255);
7968 e_drag_object_set(drag_border, o);
7970 e_drag_resize(drag_border, w, h);
7971 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7977 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7979 return ECORE_CALLBACK_PASS_ON;
7983 _e_border_cb_grab_replay(void *data __UNUSED__,
7987 Ecore_Event_Mouse_Button *ev;
7989 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7991 if ((e_config->pass_click_on)
7992 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7993 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7998 bd = e_border_find_by_window(ev->event_window);
8001 if (bd->cur_mouse_action)
8002 return ECORE_CALLBACK_DONE;
8003 if (ev->event_window == bd->win)
8005 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
8006 E_OBJECT(bd), ev, NULL))
8007 return ECORE_CALLBACK_PASS_ON;
8011 return ECORE_CALLBACK_DONE;
8015 _e_border_cb_drag_finished(E_Drag *drag,
8016 int dropped __UNUSED__)
8021 e_object_unref(E_OBJECT(bd));
8025 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8027 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
8028 int ev_type __UNUSED__,
8031 E_Event_Desk_Window_Profile_Change *e;
8036 EINA_LIST_FOREACH(borders, l, bd)
8038 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
8040 bd->client.e.fetch.profile_list = 1;
8044 return ECORE_CALLBACK_PASS_ON;
8048 #ifdef _F_ZONE_WINDOW_ROTATION_
8050 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
8051 int ev_type __UNUSED__,
8054 E_Event_Zone_Rotation_Change_Begin *e = ev;
8056 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8057 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
8059 if (!_e_border_rotation_zone_set(e->zone))
8061 /* there is no border which supports window manager rotation */
8062 e_zone_rotation_update_cancel(e->zone);
8064 return ECORE_CALLBACK_PASS_ON;
8068 _e_border_cb_rotation_sync_job(void *data)
8070 E_Zone *zone = data;
8072 E_Border_Rotation_Info *info = NULL;
8074 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
8078 EINA_LIST_FOREACH(rot.list, l, info)
8079 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
8080 if (!rot.wait_prepare_done)
8082 _e_border_rotation_change_request(zone);
8089 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
8090 ecore_job_del(rot.sync_job);
8091 rot.sync_job = NULL;
8096 _e_border_cb_rotation_async_job(void *data)
8098 E_Zone *zone = data;
8100 if (rot.list) goto end;
8102 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
8104 if (!rot.wait_prepare_done)
8106 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8107 rot.async_list = NULL;
8114 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8115 ecore_job_del(rot.async_job);
8116 rot.async_job = NULL;
8121 _e_border_rotation_change_prepare_timeout(void *data)
8123 E_Zone *zone = data;
8124 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8126 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8128 if ((zone) && (rot.wait_prepare_done))
8132 _e_border_rotation_change_request(zone);
8133 if (rot.prepare_timer)
8134 ecore_timer_del(rot.prepare_timer);
8135 rot.prepare_timer = NULL;
8136 rot.wait_prepare_done = EINA_FALSE;
8139 return ECORE_CALLBACK_CANCEL;
8143 _e_border_rotation_change_request(E_Zone *zone)
8145 if (!e_config->wm_win_rotation) return;
8146 if (!rot.list) return;
8147 if (eina_list_count(rot.list) <= 0) return;
8148 if (zone->rot.block_count) return;
8150 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8151 rot.prepare_timer = NULL;
8152 rot.wait_prepare_done = EINA_FALSE;
8154 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8157 ecore_timer_del(rot.done_timer);
8158 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8159 rot.done_timer = ecore_timer_add(5.0f,
8160 _e_border_rotation_change_done_timeout,
8165 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8168 E_Border_Rotation_Info *info =NULL;
8171 EINA_LIST_FOREACH (list, l, info)
8173 if (!info->bd) continue;
8174 if ((info->bd->client.e.state.rot.wait_for_done) &&
8175 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8177 _e_border_event_border_rotation_change_begin_send(info->bd);
8180 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8181 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8183 info->x = x; info->y = y;
8184 info->w = w; info->h = h;
8186 ELBF(ELBT_ROT, 1, info->bd->client.win,
8187 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8188 info->ang, info->win_resize, info->w, info->h);
8190 ecore_x_e_window_rotation_change_prepare_send
8191 (info->bd->client.win, info->ang,
8192 info->win_resize, info->w, info->h);
8194 if (!info->bd->client.e.state.rot.pending_change_request)
8196 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8197 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8199 info->bd->client.e.state.rot.wait_for_done = 1;
8200 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8206 EINA_LIST_FREE(list, info)
8212 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8214 E_Border_Rotation_Info *info = NULL;
8216 if (send_request) _e_border_rotation_change_request(zone);
8219 EINA_LIST_FREE(rot.list, info)
8226 _e_border_rotation_list_remove(E_Border *bd)
8228 Eina_List *l = NULL;
8229 E_Border_Rotation_Info *info = NULL;
8230 E_Event_Border_Rotation_Change_End *ev = NULL;
8231 Eina_Bool found = EINA_FALSE;
8233 if (!e_config->wm_win_rotation) return;
8235 EINA_LIST_FOREACH(rot.list, l, info)
8239 rot.list = eina_list_remove(rot.list, info);
8245 if (bd->client.e.state.rot.wait_for_done)
8247 bd->client.e.state.rot.wait_for_done = 0;
8249 /* if we make the border event in the _e_border_free function,
8250 * then we may meet a crash problem, only work this at least e_border_hide.
8252 if (!e_object_is_del(E_OBJECT(bd)))
8254 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8258 e_object_ref(E_OBJECT(bd));
8259 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8261 _e_border_event_border_rotation_change_end_free,
8267 (eina_list_count(rot.list) == 0))
8269 _e_border_rotation_change_done();
8275 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8277 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8278 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8279 _e_border_rotation_change_done();
8280 return ECORE_CALLBACK_CANCEL;
8284 _e_border_rotation_change_done(void)
8286 E_Manager *m = NULL;
8287 E_Border_Rotation_Info *info = NULL;
8289 if (!e_config->wm_win_rotation) return;
8291 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8292 rot.prepare_timer = NULL;
8294 rot.wait_prepare_done = EINA_FALSE;
8296 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8297 rot.done_timer = NULL;
8299 EINA_LIST_FREE(rot.list, info)
8303 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8304 if (info->bd->client.e.state.rot.pending_show)
8306 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8307 e_border_show(info->bd);
8308 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8309 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8310 _e_border_check_stack(info->bd);
8312 info->bd->client.e.state.rot.pending_show = 0;
8314 info->bd->client.e.state.rot.wait_for_done = 0;
8319 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8322 rot.async_list = NULL;
8324 m = e_manager_current_get();
8325 e_manager_comp_screen_unlock(m);
8326 e_zone_rotation_update_done(e_util_zone_current_get(m));
8330 _prev_angle_get(Ecore_X_Window win)
8332 int ret, count = 0, ang = -1;
8333 unsigned char* data = NULL;
8335 ret = ecore_x_window_prop_property_get
8336 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8337 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8339 if ((ret) && (data) && (count))
8340 ang = ((int *)data)[0];
8341 if (data) free(data);
8345 /* get proper rotation value using preferred rotation and list of available rotations */
8347 _e_border_rotation_get(E_Border *bd,
8351 int current_ang = bd->client.e.state.rot.curr;
8353 Eina_Bool found = EINA_FALSE;
8354 Eina_Bool found_curr_ang = EINA_FALSE;
8356 if (!e_config->wm_win_rotation) return ang;
8357 if (!bd->client.e.state.rot.app_set) return ang;
8359 if (bd->client.e.state.rot.preferred_rot != -1)
8361 ang = bd->client.e.state.rot.preferred_rot;
8362 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8364 else if ((bd->client.e.state.rot.available_rots) &&
8365 (bd->client.e.state.rot.count))
8367 for (i = 0; i < bd->client.e.state.rot.count; i++)
8369 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8375 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8376 found_curr_ang = EINA_TRUE;
8379 /* do nothing. this window wants to maintain current state.
8380 * for example, window's available_rots: 0, 90, 270,
8381 * current zone rotation request: 180. the WM does nothing
8386 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8387 ang = bd->client.e.state.rot.curr;
8389 ang = bd->client.e.state.rot.available_rots[0];
8394 /* In this case, border doesn't have a list of
8395 * available rotations, thus WM should request
8396 * rotation with '0' degree to the application.
8405 _e_border_rotation_angle_get(E_Border *bd)
8407 E_Zone *zone = bd->zone;
8412 if (!e_config->wm_win_rotation) return ret;
8413 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8415 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8417 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8418 // should follow the state of rotation of zone.
8420 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8421 will_ang = bd->parent->client.e.state.rot.curr;
8422 else will_ang = zone->rot.curr;
8424 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8426 ELBF(ELBT_ROT, 1, bd->client.win,
8427 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8428 (rot.vkbd == bd) ? "vkbd" : "prediction",
8429 bd->parent ? bd->parent->client.win : 0,
8430 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8431 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8432 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8436 will_ang = bd->parent->client.e.state.rot.curr;
8437 if ((!bd->parent->client.e.state.rot.support) &&
8438 (!bd->parent->client.e.state.rot.app_set))
8445 if ((!bd->client.e.state.rot.app_set) &&
8446 (!bd->client.e.state.rot.support))
8448 /* hack for magnifier and keyboard popup */
8449 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8450 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8452 ELB(ELBT_BD, "MAG", bd->client.win);
8454 if ((rot.vkbd) && (rot.vkbd->visible))
8455 will_ang = rot.vkbd->client.e.state.rot.curr;
8459 if (bd->client.e.state.rot.app_set)
8461 /* utility type window should be rotated according to
8462 * rotation of the transient_for window.
8465 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8467 will_ang = bd->parent->client.e.state.rot.curr;
8468 if ((!bd->parent->client.e.state.rot.support) &&
8469 (!bd->parent->client.e.state.rot.app_set))
8471 /* if transient_for window doesn't support rotation feature,
8472 * then this window should't be rotated.
8473 * TODO: need to check whether window supports '0' degree or not.
8476 ELBF(ELBT_ROT, 0, bd->client.win,
8477 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8478 will_ang, bd->parent->client.win);
8482 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8483 ELBF(ELBT_ROT, 0, bd->client.win,
8484 "GET ROT ang:%d Transient_For:0x%08x",
8485 will_ang, bd->parent->client.win);
8490 will_ang = _e_border_rotation_get(bd, will_ang);
8491 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8492 will_ang, bd->parent ? bd->parent->client.win : 0,
8493 bd->client.netwm.type);
8499 _ang = _prev_angle_get(bd->client.win);
8501 bd->client.e.state.rot.curr = _ang;
8502 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8505 if (bd->client.e.state.rot.curr != will_ang)
8513 _e_border_rotation_zone_set(E_Zone *zone)
8515 E_Border_List *l = NULL;
8516 E_Border *bd = NULL;
8517 Eina_Bool ret = EINA_FALSE;
8519 if (!e_config->wm_win_rotation) return EINA_FALSE;
8521 l = e_container_border_list_last(zone->container);
8524 /* step 1. make the list needs to be rotated. */
8525 while ((bd = e_container_border_list_prev(l)))
8529 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8530 // it will be rotated when parent do rotate itself.
8533 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8535 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8536 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8537 // if it's not normal type window, will be rotated by illume.
8539 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8541 if ((!bd->visible) ||
8542 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8543 bd->x, bd->y, bd->w, bd->h))) continue;
8545 if (_e_border_rotatable_check(bd, zone->rot.curr))
8547 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8548 bd->client.e.state.rot.curr, zone->rot.curr);
8550 ret = e_border_rotation_set(bd, zone->rot.curr);
8553 if (l) e_container_border_list_free(l);
8559 _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
8561 E_Zone *zone = bd->zone;
8562 E_Border_Rotation_Info *info = NULL;
8563 Eina_List *list, *l;
8566 if (rotation < 0) return EINA_FALSE;
8567 if (pending) *pending = EINA_FALSE;
8569 /* step 1. check if rotation */
8570 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8572 /* step 2. add to async/sync list */
8573 if ((!zone->rot.block_count) &&
8575 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8577 // send rotation change request later.
8578 // and no need to wait message of rotation done.
8581 info = E_NEW(E_Border_Rotation_Info, 1);
8582 if (!info) return EINA_FALSE;
8583 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8585 info->ang = rotation;
8586 rot.async_list = eina_list_append(rot.async_list, info);
8588 // add job for sending event.
8591 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8592 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8598 info = E_NEW(E_Border_Rotation_Info, 1);
8599 if (!info) return EINA_FALSE;
8600 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8602 info->ang = rotation;
8603 rot.list = eina_list_append(rot.list, info);
8605 // add job for sending event.
8608 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8609 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8612 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8614 // but, DO NOT lock the screen when rotation block state.
8615 if ((!zone->rot.block_count) &&
8616 ((eina_list_count(rot.list) == 2)))
8617 e_manager_comp_screen_lock(e_manager_current_get());
8620 if (pending) *pending = EINA_TRUE;
8622 /* step 3. search rotatable window in this window's child */
8623 list = _e_border_sub_borders_new(bd);
8624 EINA_LIST_FOREACH(list, l, child)
8626 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8627 // it shouldn't be rotated by rotation state of parent window.
8628 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8629 if (_e_border_rotatable_check(child, rotation))
8631 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8632 bd->client.e.state.rot.curr, rotation);
8633 e_border_rotation_set(child, rotation);
8637 /* step 4. if there is vkbd window, send message to prepare rotation */
8638 if (_e_border_is_vkbd(bd))
8640 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8641 if (rot.prepare_timer)
8642 ecore_timer_del(rot.prepare_timer);
8643 rot.prepare_timer = NULL;
8646 ecore_timer_del(rot.done_timer);
8647 rot.done_timer = NULL;
8649 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8650 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8653 rot.prepare_timer = ecore_timer_add(4.0f,
8654 _e_border_rotation_change_prepare_timeout,
8657 rot.wait_prepare_done = EINA_TRUE;
8660 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8661 bd->client.e.state.rot.curr = rotation;
8666 // check if border is rotatable in ang.
8668 _e_border_rotatable_check(E_Border *bd, int ang)
8670 Eina_Bool ret = EINA_FALSE;
8672 if (!bd) return ret;
8673 if (ang < 0) return ret;
8674 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8675 if (e_object_is_del(E_OBJECT(bd))) return ret;
8677 // same with current angle of window, then false return.
8678 if (ang == bd->client.e.state.rot.curr) return ret;
8680 /* basically WM allows only fullscreen window to rotate */
8681 if (bd->client.e.state.rot.preferred_rot == -1)
8685 if (bd->client.e.state.rot.app_set)
8687 if (bd->client.e.state.rot.available_rots &&
8688 bd->client.e.state.rot.count)
8690 Eina_Bool found = EINA_FALSE;
8691 for (i = 0; i < bd->client.e.state.rot.count; i++)
8693 if (bd->client.e.state.rot.available_rots[i] == ang)
8698 if (found) ret = EINA_TRUE;
8703 ELB(ELBT_ROT, "DO ROT", 0);
8707 // if it has preferred rotation angle,
8708 // it will be rotated at border's evaluation time.
8710 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8715 /* check whether virtual keyboard is visible on the zone */
8717 _e_border_is_vkbd(E_Border *bd)
8719 if (!e_config->wm_win_rotation) return EINA_FALSE;
8721 if ((rot.vkbd_ctrl_win) &&
8723 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8724 (rot.vkbd->zone == bd->zone) &&
8725 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8726 bd->zone->w, bd->zone->h,
8727 rot.vkbd->x, rot.vkbd->y,
8728 rot.vkbd->w, rot.vkbd->h)))
8736 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8739 int min_title_width=96;
8741 if (!bd) return EINA_FALSE;
8742 if (!x || !y) return EINA_FALSE;
8747 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8748 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8749 // guaranteeing the minimum size of titlebar shown, min_title_width
8750 // so user can initiate drag&drop action after rotation changed.
8751 if (bd->client.e.state.rot.curr == 0)
8753 if (bd->client.e.state.rot.prev == 90)
8755 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8758 else if (bd->client.e.state.rot.prev == 270)
8761 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8763 else if (bd->client.e.state.rot.prev == 180)
8765 new_x = bd->zone->w - bd->x - bd->w;
8766 new_y = bd->zone->h - bd->y - bd->h;
8769 if(new_x + bd->w < min_title_width)
8771 new_x = min_title_width - bd->w;
8773 else if(new_x > bd->zone->w - min_title_width)
8775 new_x = bd->zone->w - min_title_width;
8778 else if (bd->client.e.state.rot.curr == 90)
8780 if (bd->client.e.state.rot.prev == 0)
8783 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8785 else if (bd->client.e.state.rot.prev == 270)
8787 new_x = bd->zone->w - bd->x - bd->w;
8788 new_y = bd->zone->h - bd->y - bd->h;
8790 else if (bd->client.e.state.rot.prev == 180)
8792 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8793 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8796 if(new_y > bd->zone->h - min_title_width)
8798 new_y = bd->zone->h - min_title_width;
8800 else if(new_y < min_title_width - bd->w)
8802 new_y = min_title_width - bd->w;
8805 else if (bd->client.e.state.rot.curr == 270)
8807 if (bd->client.e.state.rot.prev == 0)
8809 new_x = bd->zone->w - bd->h - (bd->y / 2);
8812 else if (bd->client.e.state.rot.prev == 90)
8814 new_x = bd->zone->w - bd->x - bd->w;
8815 new_y = bd->zone->h - bd->y - bd->h;
8817 else if (bd->client.e.state.rot.prev == 180)
8819 new_x = bd->zone->w - bd->x - bd->w;
8820 new_y = bd->zone->h - bd->y - bd->h;
8822 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8823 new_y = (bd->zone->w - bd->x - bd->w) * 2;
8826 if(new_y > bd->zone->h - min_title_width)
8828 new_y = bd->zone->h - min_title_width;
8830 else if( new_y + bd->w < min_title_width)
8832 new_y = min_title_width - bd->w ;
8835 else if (bd->client.e.state.rot.curr == 180)
8837 if (bd->client.e.state.rot.prev == 0)
8839 new_x = bd->zone->w - bd->x - bd->w;
8840 new_y = bd->zone->h - bd->y - bd->h;
8842 else if (bd->client.e.state.rot.prev == 90)
8844 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
8845 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8847 else if (bd->client.e.state.rot.prev == 270)
8849 new_x = bd->zone->w - (bd->y / 2) - bd->h;
8850 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
8853 if(new_x + bd->w < min_title_width)
8855 new_x = min_title_width - bd->w;
8857 else if(new_x > bd->zone->w - min_title_width)
8859 new_x = bd->zone->w - min_title_width;
8863 ELBF(ELBT_ROT, 0, bd->client.win,
8864 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
8865 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
8866 bd->x, bd->y, new_x, new_y);
8868 if ((new_x == *x) &&
8880 #define SIZE_EQUAL_TO_ZONE(a, z) \
8881 ((((a)->w) == ((z)->w)) && \
8882 (((a)->h) == ((z)->h)))
8884 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8886 E_Zone *zone = bd->zone;
8889 Eina_Bool move = EINA_FALSE;
8890 Eina_Bool hint = EINA_FALSE;
8891 Eina_Bool resize = EINA_FALSE;
8898 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8900 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8901 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8902 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8904 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8905 &_x, &_y, &_w, &_h, &move);
8908 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8910 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8911 bd->client.icccm.name, _x, _y, _w, _h);
8915 _x = bd->x; _y = bd->y;
8916 _w = bd->w; _h = bd->h;
8918 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
8919 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
8923 rot_dif = bd->client.e.state.rot.prev - rotation;
8924 if (rot_dif < 0) rot_dif = -rot_dif;
8933 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8934 EINA_TRUE, EINA_TRUE);
8935 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8936 bd->client.icccm.name, _x, _y, _w, _h);
8941 if (!resize && move)
8942 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
8957 _e_border_cb_window_configure(void *data __UNUSED__,
8958 int ev_type __UNUSED__,
8961 Ecore_X_Event_Window_Configure *e = ev;
8962 E_Border_Rotation_Info *info = NULL;
8964 Eina_Bool found = EINA_FALSE;
8966 if (!e) return ECORE_CALLBACK_PASS_ON;
8967 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8969 E_Border *bd = e_border_find_by_client_window(e->win);
8970 if (!bd) return ECORE_CALLBACK_PASS_ON;
8972 if (bd->client.e.state.rot.pending_change_request)
8974 if ((e->w == bd->w) && (e->h == bd->h))
8976 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8977 bd->client.e.state.rot.pending_change_request = 0;
8979 if ((bd->client.e.state.rot.wait_for_done) &&
8980 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8982 // if this window is rotation dependent window and zone is blocked to rotate,
8983 // then skip here, request will be sent after cancel block.
8984 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
8985 (bd->zone->rot.block_count)) goto end;
8987 EINA_LIST_FOREACH(rot.list, l, info)
8988 if (info->bd == bd) found = EINA_TRUE;
8989 // send request message if it's async rotation window,
8990 // even if wait prepare done.
8991 if ((found) && (rot.wait_prepare_done)) goto end;
8993 ELBF(ELBT_ROT, 0, bd->client.win,
8994 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8995 bd->client.e.state.rot.curr,
8997 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8998 bd->client.e.state.rot.curr);
8999 bd->client.e.state.rot.wait_for_done = 1;
9000 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
9005 return ECORE_CALLBACK_PASS_ON;
9009 _e_border_rotation_geom_get(E_Border *bd,
9018 if (!e_config->wm_win_rotation) return EINA_FALSE;
9020 Eina_Bool res = EINA_FALSE;
9021 Eina_Bool _move = EINA_TRUE;
9031 if (move) *move = EINA_TRUE;
9033 if (bd->client.e.state.rot.geom_hint)
9038 _w = bd->client.e.state.rot.geom[0].w;
9039 _h = bd->client.e.state.rot.geom[0].h;
9040 if (_w == 0) _w = bd->w;
9041 if (_h == 0) _h = bd->h;
9042 _x = 0; _y = zone->h - _h;
9045 _w = bd->client.e.state.rot.geom[1].w;
9046 _h = bd->client.e.state.rot.geom[1].h;
9047 if (_w == 0) _w = bd->w;
9048 if (_h == 0) _h = bd->h;
9049 _x = zone->w - _w; _y = 0;
9052 _w = bd->client.e.state.rot.geom[2].w;
9053 _h = bd->client.e.state.rot.geom[2].h;
9054 if (_w == 0) _w = bd->w;
9055 if (_h == 0) _h = bd->h;
9059 _w = bd->client.e.state.rot.geom[3].w;
9060 _h = bd->client.e.state.rot.geom[3].h;
9061 if (_w == 0) _w = bd->w;
9062 if (_h == 0) _h = bd->h;
9072 if (!((rot.vkbd) && (rot.vkbd == bd)))
9076 if (move) *move = EINA_FALSE;
9084 _x = 0; _y = 0; _w = 0; _h = 0;
9089 if (move) _move = *move;
9091 ELBF(ELBT_ROT, 1, bd->client.win,
9092 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
9093 ang, _x, _y, _w, _h, _move);
9101 _e_border_post_move_resize_job(void *data)
9105 bd = (E_Border *)data;
9111 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9112 ecore_x_window_move(tmp->win,
9114 bd->client_inset.l +
9116 tmp->client.e.state.video_position.x,
9118 bd->client_inset.t +
9120 tmp->client.e.state.video_position.y);
9122 if (bd->client.e.state.video)
9126 parent = bd->client.e.state.video_parent_border;
9127 ecore_x_window_move(bd->win,
9129 parent->client_inset.l +
9131 bd->client.e.state.video_position.x,
9133 parent->client_inset.t +
9135 bd->client.e.state.video_position.y);
9137 else if ((bd->post_move) && (bd->post_resize))
9139 ecore_x_window_move_resize(bd->win,
9144 else if (bd->post_move)
9146 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9148 else if (bd->post_resize)
9150 ecore_x_window_resize(bd->win, bd->w, bd->h);
9153 if (bd->client.e.state.video)
9155 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9157 bd->client.e.state.video_parent_border->x +
9158 bd->client.e.state.video_parent_border->client_inset.l +
9159 bd->client.e.state.video_parent_border->fx.x +
9160 bd->client.e.state.video_position.x,
9161 bd->client.e.state.video_parent_border->y +
9162 bd->client.e.state.video_parent_border->client_inset.t +
9163 bd->client.e.state.video_parent_border->fx.y +
9164 bd->client.e.state.video_position.y,
9172 bd->post_job = NULL;
9178 bd->post_resize = 0;
9179 bd->post_job = NULL;
9180 return ECORE_CALLBACK_CANCEL;
9184 _e_border_container_layout_hook(E_Container *con)
9186 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9190 _e_border_eval0(E_Border *bd)
9192 int change_urgent = 0;
9194 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9195 Eina_Bool need_desk_set = EINA_FALSE;
9197 #ifdef _F_ZONE_WINDOW_ROTATION_
9198 Eina_Bool need_rotation_set = EINA_FALSE;
9200 if ((e_config->wm_win_rotation) &&
9201 (bd->client.icccm.fetch.transient_for))
9203 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9204 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9206 need_rotation_set = EINA_TRUE;
9207 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9212 if (e_object_is_del(E_OBJECT(bd)))
9214 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9219 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9221 bd->changes.border = 0;
9223 /* fetch any info queued to be fetched */
9224 if (bd->client.netwm.fetch.state)
9226 e_hints_window_state_get(bd);
9227 bd->client.netwm.fetch.state = 0;
9230 if (bd->client.icccm.fetch.client_leader)
9232 /* TODO: What do to if the client leader isn't mapped yet? */
9233 E_Border *bd_leader = NULL;
9235 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9236 if (bd->client.icccm.client_leader)
9237 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9240 if (bd->leader != bd_leader)
9242 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9243 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9249 /* If this border is the leader of the group, don't register itself */
9250 if ((bd_leader) && (bd_leader != bd))
9252 bd_leader->group = eina_list_append(bd_leader->group, bd);
9253 bd->leader = bd_leader;
9254 /* Only set the window modal to the leader it there is no parent */
9255 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9256 ((!bd->parent) || (bd->parent->modal != bd)))
9258 bd->leader->modal = bd;
9259 if (bd->leader->focused)
9260 e_border_focus_set(bd, 1, 1);
9266 EINA_LIST_FOREACH(bd->leader->group, l, child)
9268 if ((child != bd) && (child->focused))
9269 e_border_focus_set(bd, 1, 1);
9274 bd->client.icccm.fetch.client_leader = 0;
9277 if (bd->client.icccm.fetch.title)
9279 char *title = ecore_x_icccm_title_get(bd->client.win);
9280 eina_stringshare_replace(&bd->client.icccm.title, title);
9281 if (title) free(title);
9284 edje_object_part_text_set(bd->bg_object, "e.text.title",
9285 bd->client.icccm.title);
9286 bd->client.icccm.fetch.title = 0;
9289 if (bd->client.netwm.fetch.name)
9292 ecore_x_netwm_name_get(bd->client.win, &name);
9293 eina_stringshare_replace(&bd->client.netwm.name, name);
9294 if (name) free(name);
9297 edje_object_part_text_set(bd->bg_object, "e.text.title",
9298 bd->client.netwm.name);
9299 bd->client.netwm.fetch.name = 0;
9302 if (bd->client.icccm.fetch.name_class)
9304 const char *pname, *pclass;
9305 char *nname, *nclass;
9307 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9308 pname = bd->client.icccm.name;
9309 pclass = bd->client.icccm.class;
9310 bd->client.icccm.name = eina_stringshare_add(nname);
9311 bd->client.icccm.class = eina_stringshare_add(nclass);
9312 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9313 e_bindings_mapping_change_enable(EINA_FALSE);
9314 #ifdef _F_ZONE_WINDOW_ROTATION_
9315 if (e_config->wm_win_rotation)
9317 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9319 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9320 (!strcmp(bd->client.icccm.class, "ISF")))
9322 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9323 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9326 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9327 (!strcmp(bd->client.icccm.class, "ISF")))
9329 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9330 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9331 rot.vkbd_prediction = bd;
9333 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9334 (!strcmp(bd->client.icccm.class, "ISF")))
9336 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9337 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9339 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9340 (!strcmp(bd->client.icccm.class, "ISF")))
9342 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9343 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9348 if (nname) free(nname);
9349 if (nclass) free(nclass);
9351 if (!((bd->client.icccm.name == pname) &&
9352 (bd->client.icccm.class == pclass)))
9353 bd->changes.icon = 1;
9355 if (pname) eina_stringshare_del(pname);
9356 if (pclass) eina_stringshare_del(pclass);
9357 bd->client.icccm.fetch.name_class = 0;
9358 bd->changes.icon = 1;
9361 if (bd->client.icccm.fetch.state)
9363 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9364 bd->client.icccm.fetch.state = 0;
9367 if (bd->client.e.fetch.state)
9369 e_hints_window_e_state_get(bd);
9370 bd->client.e.fetch.state = 0;
9373 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9374 if (bd->client.e.fetch.profile_list)
9376 const char **profiles = NULL;
9380 if (bd->client.e.state.profile)
9381 eina_stringshare_del(bd->client.e.state.profile);
9382 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9384 if (str) eina_stringshare_del(str);
9386 bd->client.e.state.profile = NULL;
9387 bd->client.e.state.profiles = NULL;
9388 bd->client.e.state.profile_list = 0;
9390 if (ecore_x_e_window_profile_list_get(bd->client.win,
9393 bd->client.e.state.profile_list = 1;
9394 for (i = 0; i < num; i++)
9396 str = eina_stringshare_add(profiles[i]);
9397 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9400 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9401 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9403 need_desk_set = EINA_TRUE;
9407 if (strcmp(bd->desk->window_profile,
9408 e_config->desktop_default_window_profile) != 0)
9410 ecore_x_e_window_profile_set(bd->client.win,
9411 bd->desk->window_profile);
9417 for (i = 0; i < num; i++)
9418 if (profiles[i]) free(profiles[i]);
9422 bd->client.e.fetch.profile_list = 0;
9425 #ifdef _F_ZONE_WINDOW_ROTATION_
9426 if ((e_config->wm_win_rotation) &&
9427 (bd->client.e.fetch.rot.support))
9430 unsigned int support = 0;
9432 ret = ecore_x_window_prop_card32_get
9434 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9437 bd->client.e.state.rot.support = 0;
9438 if ((ret == 1) && (support == 1))
9439 bd->client.e.state.rot.support = 1;
9441 if (bd->client.e.state.rot.support)
9442 need_rotation_set = EINA_TRUE;
9444 bd->client.e.fetch.rot.support = 0;
9446 if ((e_config->wm_win_rotation) &&
9447 (bd->client.e.fetch.rot.geom_hint))
9449 Eina_Rectangle r[4];
9451 bd->client.e.state.rot.geom_hint = 0;
9452 for (i = 0; i < 4; i++)
9454 r[i].x = bd->client.e.state.rot.geom[i].x;
9455 r[i].y = bd->client.e.state.rot.geom[i].y;
9456 r[i].w = bd->client.e.state.rot.geom[i].w;
9457 r[i].h = bd->client.e.state.rot.geom[i].h;
9459 bd->client.e.state.rot.geom[i].x = 0;
9460 bd->client.e.state.rot.geom[i].y = 0;
9461 bd->client.e.state.rot.geom[i].w = 0;
9462 bd->client.e.state.rot.geom[i].h = 0;
9465 for (i = 0; i < 4; i++)
9467 x = 0; y = 0; w = 0; h = 0;
9468 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9470 bd->client.e.state.rot.geom_hint = 1;
9471 bd->client.e.state.rot.geom[i].x = x;
9472 bd->client.e.state.rot.geom[i].y = y;
9473 bd->client.e.state.rot.geom[i].w = w;
9474 bd->client.e.state.rot.geom[i].h = h;
9476 if (!((r[i].x == x) && (r[i].y == y) &&
9477 (r[i].w == w) && (r[i].h == h)))
9479 need_rotation_set = EINA_TRUE;
9483 bd->client.e.fetch.rot.geom_hint = 0;
9485 if ((e_config->wm_win_rotation) &&
9486 (bd->client.e.fetch.rot.app_set))
9488 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9489 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9490 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9492 if (_prev_app_set != bd->client.e.state.rot.app_set)
9493 need_rotation_set = EINA_TRUE;
9495 bd->client.e.fetch.rot.app_set = 0;
9497 if ((e_config->wm_win_rotation) &&
9498 (bd->client.e.fetch.rot.preferred_rot))
9500 int r = 0, _prev_preferred_rot;
9501 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9502 bd->client.e.state.rot.preferred_rot = -1;
9503 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9505 bd->client.e.state.rot.preferred_rot = r;
9506 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9510 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9513 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9514 need_rotation_set = EINA_TRUE;
9516 bd->client.e.fetch.rot.preferred_rot = 0;
9518 if ((e_config->wm_win_rotation) &&
9519 (bd->client.e.fetch.rot.available_rots))
9521 Eina_Bool res, diff = EINA_FALSE;
9523 unsigned int count = 0, i = 0;
9524 int _prev_rots[4] = { -1, };
9526 if (bd->client.e.state.rot.available_rots)
9529 bd->client.e.state.rot.available_rots,
9530 (sizeof(int) * bd->client.e.state.rot.count));
9532 E_FREE(bd->client.e.state.rot.available_rots);
9535 bd->client.e.state.rot.count = 0;
9537 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9539 if ((res) && (count > 0) && (rots))
9541 bd->client.e.state.rot.available_rots = rots;
9542 bd->client.e.state.rot.count = count;
9544 for (i = 0; i < count; i++)
9546 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9547 if ((!diff) && (_prev_rots[i] != rots[i]))
9549 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9550 count, i, _prev_rots[i], rots[i]);
9557 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9561 if (diff) need_rotation_set = EINA_TRUE;
9562 bd->client.e.fetch.rot.available_rots = 0;
9565 if (bd->client.netwm.fetch.type)
9567 e_hints_window_type_get(bd);
9568 if ((!bd->lock_border) || (!bd->client.border.name))
9569 bd->client.border.changed = 1;
9571 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9573 if (!bd->client.netwm.state.skip_pager)
9575 bd->client.netwm.state.skip_pager = 1;
9576 bd->client.netwm.update.state = 1;
9578 if (!bd->client.netwm.state.skip_taskbar)
9580 bd->client.netwm.state.skip_taskbar = 1;
9581 bd->client.netwm.update.state = 1;
9584 bd->client.netwm.fetch.type = 0;
9586 if (bd->client.icccm.fetch.machine)
9588 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9590 if ((!machine) && (bd->client.icccm.client_leader))
9591 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9593 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9594 if (machine) free(machine);
9596 bd->client.icccm.fetch.machine = 0;
9599 if (bd->client.icccm.fetch.command)
9601 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9605 for (i = 0; i < bd->client.icccm.command.argc; i++)
9606 free(bd->client.icccm.command.argv[i]);
9607 free(bd->client.icccm.command.argv);
9609 bd->client.icccm.command.argc = 0;
9610 bd->client.icccm.command.argv = NULL;
9611 ecore_x_icccm_command_get(bd->client.win,
9612 &(bd->client.icccm.command.argc),
9613 &(bd->client.icccm.command.argv));
9614 if ((bd->client.icccm.client_leader) &&
9615 (!bd->client.icccm.command.argv))
9616 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9617 &(bd->client.icccm.command.argc),
9618 &(bd->client.icccm.command.argv));
9619 bd->client.icccm.fetch.command = 0;
9622 if (bd->client.icccm.fetch.hints)
9624 Eina_Bool accepts_focus, is_urgent;
9626 accepts_focus = EINA_TRUE;
9627 is_urgent = EINA_FALSE;
9628 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9629 if (ecore_x_icccm_hints_get(bd->client.win,
9631 &bd->client.icccm.initial_state,
9632 &bd->client.icccm.icon_pixmap,
9633 &bd->client.icccm.icon_mask,
9634 &bd->client.icccm.icon_window,
9635 &bd->client.icccm.window_group,
9638 bd->client.icccm.accepts_focus = accepts_focus;
9639 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9641 bd->client.icccm.urgent = is_urgent;
9643 /* If this is a new window, set the state as requested. */
9644 if ((bd->new_client) &&
9645 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9647 e_border_iconify(bd);
9648 e_border_hide(bd, 1);
9651 bd->client.icccm.fetch.hints = 0;
9654 if (bd->client.icccm.fetch.size_pos_hints)
9656 Eina_Bool request_pos;
9658 request_pos = EINA_FALSE;
9659 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9661 &bd->client.icccm.gravity,
9662 &bd->client.icccm.min_w,
9663 &bd->client.icccm.min_h,
9664 &bd->client.icccm.max_w,
9665 &bd->client.icccm.max_h,
9666 &bd->client.icccm.base_w,
9667 &bd->client.icccm.base_h,
9668 &bd->client.icccm.step_w,
9669 &bd->client.icccm.step_h,
9670 &bd->client.icccm.min_aspect,
9671 &bd->client.icccm.max_aspect))
9673 bd->client.icccm.request_pos = request_pos;
9678 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9679 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9680 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9681 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9682 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9683 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9684 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9685 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9686 // if doing a resize, fix it up
9687 if (bd->resize_mode != RESIZE_NONE)
9689 int x, y, w, h, new_w, new_h;
9697 e_border_resize_limit(bd, &new_w, &new_h);
9698 if ((bd->resize_mode == RESIZE_TL) ||
9699 (bd->resize_mode == RESIZE_L) ||
9700 (bd->resize_mode == RESIZE_BL))
9702 if ((bd->resize_mode == RESIZE_TL) ||
9703 (bd->resize_mode == RESIZE_T) ||
9704 (bd->resize_mode == RESIZE_TR))
9706 e_border_move_resize(bd, x, y, new_w, new_h);
9708 bd->client.icccm.fetch.size_pos_hints = 0;
9711 if (bd->client.icccm.fetch.protocol)
9714 Ecore_X_WM_Protocol *proto;
9716 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9719 for (i = 0; i < num; i++)
9721 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9722 bd->client.icccm.delete_request = 1;
9723 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9724 bd->client.icccm.take_focus = 1;
9725 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9726 bd->client.netwm.ping = 1;
9727 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9729 bd->client.netwm.sync.request = 1;
9730 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9731 &bd->client.netwm.sync.counter))
9732 bd->client.netwm.sync.request = 0;
9737 if (bd->client.netwm.ping)
9741 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9742 bd->ping_poller = NULL;
9744 bd->client.icccm.fetch.protocol = 0;
9746 if (bd->client.icccm.fetch.transient_for)
9748 /* TODO: What do to if the transient for isn't mapped yet? */
9749 E_Border *bd_parent = NULL;
9750 #ifdef _F_DEICONIFY_APPROVE_
9751 Eina_Bool change_parent = EINA_FALSE;
9754 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9755 if (bd->client.icccm.transient_for)
9756 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9757 /* If we already have a parent, remove it */
9760 if (bd_parent != bd->parent)
9762 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9763 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9769 if ((bd_parent) && (bd_parent != bd) &&
9770 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9772 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9773 bd->parent = bd_parent;
9774 #ifdef _F_DEICONIFY_APPROVE_
9775 change_parent = EINA_TRUE;
9780 e_border_layer_set(bd, bd->parent->layer);
9781 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9783 Ecore_X_Window_Attributes attr;
9784 bd->parent->modal = bd;
9785 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9786 bd->parent->saved.event_mask = attr.event_mask.mine;
9787 bd->parent->lock_close = 1;
9788 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9789 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9792 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9793 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9797 #ifdef _F_DEICONIFY_APPROVE_
9800 bd->client.e.state.deiconify_approve.render_done = 0;
9802 E_Border *ancestor_bd;
9803 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9804 if ((ancestor_bd) &&
9805 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9807 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9808 bd->client.e.state.deiconify_approve.ancestor = NULL;
9810 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9811 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9813 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9815 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9816 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9817 e_border_uniconify(ancestor_bd);
9823 bd->client.icccm.fetch.transient_for = 0;
9826 if (bd->client.icccm.fetch.window_role)
9828 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9829 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9830 if (role) free(role);
9832 bd->client.icccm.fetch.window_role = 0;
9835 if (bd->client.icccm.fetch.icon_name)
9837 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9838 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9839 if (icon_name) free(icon_name);
9841 bd->client.icccm.fetch.icon_name = 0;
9844 if (bd->client.netwm.fetch.icon_name)
9847 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9848 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9849 if (icon_name) free(icon_name);
9851 bd->client.netwm.fetch.icon_name = 0;
9854 if (bd->client.netwm.fetch.icon)
9857 if (bd->client.netwm.icons)
9859 for (i = 0; i < bd->client.netwm.num_icons; i++)
9861 free(bd->client.netwm.icons[i].data);
9862 bd->client.netwm.icons[i].data = NULL;
9864 free(bd->client.netwm.icons);
9866 bd->client.netwm.icons = NULL;
9867 bd->client.netwm.num_icons = 0;
9868 if (ecore_x_netwm_icons_get(bd->client.win,
9869 &bd->client.netwm.icons,
9870 &bd->client.netwm.num_icons))
9872 // unless the rest of e17 uses border icons OTHER than icon #0
9873 // then free the rest that we don't need anymore.
9874 for (i = 1; i < bd->client.netwm.num_icons; i++)
9876 free(bd->client.netwm.icons[i].data);
9877 bd->client.netwm.icons[i].data = NULL;
9879 bd->client.netwm.num_icons = 1;
9880 bd->changes.icon = 1;
9882 bd->client.netwm.fetch.icon = 0;
9884 if (bd->client.netwm.fetch.user_time)
9886 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9887 bd->client.netwm.fetch.user_time = 0;
9889 if (bd->client.netwm.fetch.strut)
9891 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9892 &bd->client.netwm.strut.left,
9893 &bd->client.netwm.strut.right,
9894 &bd->client.netwm.strut.top,
9895 &bd->client.netwm.strut.bottom,
9896 &bd->client.netwm.strut.left_start_y,
9897 &bd->client.netwm.strut.left_end_y,
9898 &bd->client.netwm.strut.right_start_y,
9899 &bd->client.netwm.strut.right_end_y,
9900 &bd->client.netwm.strut.top_start_x,
9901 &bd->client.netwm.strut.top_end_x,
9902 &bd->client.netwm.strut.bottom_start_x,
9903 &bd->client.netwm.strut.bottom_end_x))
9905 ecore_x_netwm_strut_get(bd->client.win,
9906 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9907 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9909 bd->client.netwm.strut.left_start_y = 0;
9910 bd->client.netwm.strut.left_end_y = 0;
9911 bd->client.netwm.strut.right_start_y = 0;
9912 bd->client.netwm.strut.right_end_y = 0;
9913 bd->client.netwm.strut.top_start_x = 0;
9914 bd->client.netwm.strut.top_end_x = 0;
9915 bd->client.netwm.strut.bottom_start_x = 0;
9916 bd->client.netwm.strut.bottom_end_x = 0;
9918 bd->client.netwm.fetch.strut = 0;
9920 if (bd->client.qtopia.fetch.soft_menu)
9922 e_hints_window_qtopia_soft_menu_get(bd);
9923 bd->client.qtopia.fetch.soft_menu = 0;
9926 if (bd->client.qtopia.fetch.soft_menus)
9928 e_hints_window_qtopia_soft_menus_get(bd);
9929 bd->client.qtopia.fetch.soft_menus = 0;
9932 if (bd->client.vkbd.fetch.state)
9934 e_hints_window_virtual_keyboard_state_get(bd);
9935 bd->client.vkbd.fetch.state = 0;
9938 if (bd->client.vkbd.fetch.vkbd)
9940 e_hints_window_virtual_keyboard_get(bd);
9941 bd->client.vkbd.fetch.vkbd = 0;
9944 if (bd->client.illume.conformant.fetch.conformant)
9946 bd->client.illume.conformant.conformant =
9947 ecore_x_e_illume_conformant_get(bd->client.win);
9948 bd->client.illume.conformant.fetch.conformant = 0;
9950 if (bd->client.illume.quickpanel.fetch.state)
9952 bd->client.illume.quickpanel.state =
9953 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9954 bd->client.illume.quickpanel.fetch.state = 0;
9956 if (bd->client.illume.quickpanel.fetch.quickpanel)
9958 bd->client.illume.quickpanel.quickpanel =
9959 ecore_x_e_illume_quickpanel_get(bd->client.win);
9960 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9962 if (bd->client.illume.quickpanel.fetch.priority.major)
9964 bd->client.illume.quickpanel.priority.major =
9965 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9966 bd->client.illume.quickpanel.fetch.priority.major = 0;
9968 if (bd->client.illume.quickpanel.fetch.priority.minor)
9970 bd->client.illume.quickpanel.priority.minor =
9971 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9972 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9974 if (bd->client.illume.quickpanel.fetch.zone)
9976 bd->client.illume.quickpanel.zone =
9977 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9978 bd->client.illume.quickpanel.fetch.zone = 0;
9980 if (bd->client.illume.drag.fetch.drag)
9982 bd->client.illume.drag.drag =
9983 ecore_x_e_illume_drag_get(bd->client.win);
9984 bd->client.illume.drag.fetch.drag = 0;
9986 if (bd->client.illume.drag.fetch.locked)
9988 bd->client.illume.drag.locked =
9989 ecore_x_e_illume_drag_locked_get(bd->client.win);
9990 bd->client.illume.drag.fetch.locked = 0;
9992 if (bd->client.illume.win_state.fetch.state)
9994 bd->client.illume.win_state.state =
9995 ecore_x_e_illume_window_state_get(bd->client.win);
9996 bd->client.illume.win_state.fetch.state = 0;
9998 if (bd->changes.shape)
10000 Ecore_X_Rectangle *rects;
10003 bd->changes.shape = 0;
10004 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
10007 int cw = 0, ch = 0;
10009 /* This doesn't fix the race, but makes it smaller. we detect
10010 * this and if cw and ch != client w/h then mark this as needing
10011 * a shape change again to fixup next event loop.
10013 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10014 if ((cw != bd->client.w) || (ch != bd->client.h))
10015 bd->changes.shape = 1;
10017 (rects[0].x == 0) &&
10018 (rects[0].y == 0) &&
10019 ((int)rects[0].width == cw) &&
10020 ((int)rects[0].height == ch))
10022 if (bd->client.shaped)
10024 bd->client.shaped = 0;
10025 if (!bd->bordername)
10026 bd->client.border.changed = 1;
10031 if (!bd->client.shaped)
10033 bd->client.shaped = 1;
10034 if (!bd->bordername)
10035 bd->client.border.changed = 1;
10042 // FIXME: no rects i think can mean... totally empty window
10043 bd->client.shaped = 0;
10044 if (!bd->bordername)
10045 bd->client.border.changed = 1;
10047 bd->need_shape_merge = 1;
10049 if (bd->changes.shape_input)
10051 Ecore_X_Rectangle *rects;
10054 bd->changes.shape_input = 0;
10055 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
10058 int cw = 0, ch = 0;
10060 /* This doesn't fix the race, but makes it smaller. we detect
10061 * this and if cw and ch != client w/h then mark this as needing
10062 * a shape change again to fixup next event loop.
10064 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10065 if ((cw != bd->client.w) || (ch != bd->client.h))
10066 bd->changes.shape_input = 1;
10068 (rects[0].x == 0) &&
10069 (rects[0].y == 0) &&
10070 ((int)rects[0].width == cw) &&
10071 ((int)rects[0].height == ch))
10073 if (bd->shaped_input)
10075 bd->shaped_input = 0;
10076 if (!bd->bordername)
10077 bd->client.border.changed = 1;
10082 if (!bd->shaped_input)
10084 bd->shaped_input = 1;
10085 if (!bd->bordername)
10086 bd->client.border.changed = 1;
10093 bd->shaped_input = 1;
10094 if (!bd->bordername)
10095 bd->client.border.changed = 1;
10097 bd->need_shape_merge = 1;
10099 if (bd->client.mwm.fetch.hints)
10103 bd->client.mwm.exists =
10104 ecore_x_mwm_hints_get(bd->client.win,
10105 &bd->client.mwm.func,
10106 &bd->client.mwm.decor,
10107 &bd->client.mwm.input);
10108 pb = bd->client.mwm.borderless;
10109 bd->client.mwm.borderless = 0;
10110 if (bd->client.mwm.exists)
10112 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
10113 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10114 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10115 bd->client.mwm.borderless = 1;
10117 if (bd->client.mwm.borderless != pb)
10119 if ((!bd->lock_border) || (!bd->client.border.name))
10120 bd->client.border.changed = 1;
10122 bd->client.mwm.fetch.hints = 0;
10125 if (bd->client.e.fetch.video_parent)
10127 /* unlinking child/parent */
10128 if (bd->client.e.state.video_parent_border != NULL)
10130 bd->client.e.state.video_parent_border->client.e.state.video_child =
10132 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10136 ecore_x_window_prop_card32_get(bd->client.win,
10137 ECORE_X_ATOM_E_VIDEO_PARENT,
10138 &bd->client.e.state.video_parent,
10141 /* linking child/parent */
10142 if (bd->client.e.state.video_parent != 0)
10147 EINA_LIST_FOREACH(borders, l, tmp)
10148 if (tmp->client.win == bd->client.e.state.video_parent)
10150 /* fprintf(stderr, "child added to parent \\o/\n"); */
10151 bd->client.e.state.video_parent_border = tmp;
10152 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10154 if (bd->desk != tmp->desk)
10155 e_border_desk_set(bd, tmp->desk);
10160 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10162 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10165 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10167 unsigned int xy[2];
10169 ecore_x_window_prop_card32_get(bd->client.win,
10170 ECORE_X_ATOM_E_VIDEO_POSITION,
10173 bd->client.e.state.video_position.x = xy[0];
10174 bd->client.e.state.video_position.y = xy[1];
10175 bd->client.e.state.video_position.updated = 1;
10176 bd->client.e.fetch.video_position = 0;
10177 bd->x = bd->client.e.state.video_position.x;
10178 bd->y = bd->client.e.state.video_position.y;
10180 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10182 if (bd->client.netwm.update.state)
10184 e_hints_window_state_set(bd);
10185 /* Some stats might change the border, like modal */
10186 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10187 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10189 bd->client.border.changed = 1;
10193 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10195 bd->parent->modal = bd;
10196 if (bd->parent->focused)
10197 e_border_focus_set(bd, 1, 1);
10200 else if (bd->leader)
10202 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10204 bd->leader->modal = bd;
10205 if (bd->leader->focused)
10206 e_border_focus_set(bd, 1, 1);
10212 EINA_LIST_FOREACH(bd->leader->group, l, child)
10214 if ((child != bd) && (child->focused))
10215 e_border_focus_set(bd, 1, 1);
10220 bd->client.netwm.update.state = 0;
10223 if (bd->new_client)
10225 E_Event_Border_Add *ev;
10226 E_Exec_Instance *inst;
10228 ev = E_NEW(E_Event_Border_Add, 1);
10230 e_object_ref(E_OBJECT(bd));
10231 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10232 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10234 if ((!bd->lock_border) || (!bd->client.border.name))
10235 bd->client.border.changed = 1;
10240 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10241 ((bd->client.icccm.client_leader > 0) &&
10242 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10245 if (!strncmp(str, "E_START|", 8))
10249 id = atoi(str + 8);
10250 if (id > 0) bd->client.netwm.startup_id = id;
10255 /* It's ok not to have fetch flag, should only be set on startup
10256 * * and not changed. */
10257 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10259 if (bd->client.icccm.client_leader)
10261 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10262 bd->client.netwm.pid = -1;
10265 bd->client.netwm.pid = -1;
10268 if (!bd->re_manage)
10270 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10271 bd->client.netwm.pid);
10272 if ((inst) && (inst->used == 0))
10278 zone = e_container_zone_number_get(bd->zone->container,
10280 if (zone) e_border_zone_set(bd, zone);
10281 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10283 if (desk) e_border_desk_set(bd, desk);
10284 e_exec_instance_found(inst);
10287 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10289 E_Border *bdl = NULL;
10294 if (bd->leader) bdl = bd->leader;
10301 bl = e_container_border_list_first(bd->zone->container);
10302 while ((child = e_container_border_list_next(bl)))
10304 if (child == bd) continue;
10305 if (e_object_is_del(E_OBJECT(child))) continue;
10306 if ((bd->client.icccm.client_leader) &&
10307 (child->client.icccm.client_leader ==
10308 bd->client.icccm.client_leader))
10314 e_container_border_list_free(bl);
10319 e_border_zone_set(bd, bdl->zone);
10321 e_border_desk_set(bd, bdl->desk);
10323 e_border_stick(bd);
10329 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10332 E_Container *con = bd->zone->container;
10333 E_Desk *desk = NULL;
10336 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10338 desk = e_container_desk_window_profile_get(con, str);
10341 if (bd->desk != desk)
10343 bd->client.e.state.profile = eina_stringshare_add(str);
10344 if (bd->zone != desk->zone)
10345 e_border_zone_set(bd, desk->zone);
10346 e_border_desk_set(bd, desk);
10354 /* PRE_POST_FETCH calls e_remember apply for new client */
10355 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10356 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10357 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10359 #ifdef _F_ZONE_WINDOW_ROTATION_
10360 if (e_config->wm_win_rotation)
10362 if ((need_rotation_set) &&
10363 (bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_NORMAL))
10365 Eina_Bool hint = EINA_FALSE;
10367 int x, y, w, h, move;
10369 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10370 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10372 if (bd->client.e.state.rot.changes == -1)
10374 ang = bd->client.e.state.rot.curr;
10376 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10379 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10380 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10381 bd->client.icccm.name, x, y, w, h);
10384 else bd->changed = 1;
10389 if (bd->need_reparent)
10392 ecore_x_window_save_set_add(bd->client.win);
10393 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10396 if ((bd->new_client) && (bd->internal) &&
10397 (bd->internal_ecore_evas))
10398 ecore_evas_show(bd->internal_ecore_evas);
10399 ecore_x_window_show(bd->client.win);
10401 bd->need_reparent = 0;
10404 if ((bd->client.border.changed) && (!bd->shaded) &&
10405 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10407 const char *bordername;
10409 if (bd->fullscreen)
10410 bordername = "borderless";
10411 else if (bd->bordername)
10412 bordername = bd->bordername;
10413 else if ((bd->client.mwm.borderless) || (bd->borderless))
10414 bordername = "borderless";
10415 else if (((bd->client.icccm.transient_for != 0) ||
10416 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10417 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10418 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10419 bordername = "noresize_dialog";
10420 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10421 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10422 bordername = "noresize";
10423 else if (bd->client.shaped)
10424 bordername = "shaped";
10425 else if ((!bd->client.icccm.accepts_focus) &&
10426 (!bd->client.icccm.take_focus))
10427 bordername = "nofocus";
10428 else if (bd->client.icccm.urgent)
10429 bordername = "urgent";
10430 else if ((bd->client.icccm.transient_for != 0) ||
10431 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10432 bordername = "dialog";
10433 else if (bd->client.netwm.state.modal)
10434 bordername = "modal";
10435 else if ((bd->client.netwm.state.skip_taskbar) ||
10436 (bd->client.netwm.state.skip_pager))
10437 bordername = "skipped";
10438 else if ((bd->internal) && (bd->client.icccm.class) &&
10439 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10440 bordername = "internal_fileman";
10442 bordername = e_config->theme_default_border_style;
10443 if (!bordername) bordername = "default";
10445 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10451 bd->changes.border = 1;
10452 eina_stringshare_replace(&bd->client.border.name, bordername);
10456 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10457 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10458 bd->changes.size = 1;
10459 evas_object_del(bd->bg_object);
10461 o = edje_object_add(bd->bg_evas);
10462 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10463 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10464 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10466 if (bd->client.border.name != e_config->theme_default_border_style)
10468 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10469 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10473 ok = e_theme_edje_object_set(o, "base/theme/borders",
10474 "e/widgets/border/default/border");
10477 /* Reset default border style to default */
10478 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10479 e_config_save_queue();
10487 const char *shape_option, *argb_option;
10492 if ((e_config->use_composite) && (!bd->client.argb))
10494 argb_option = edje_object_data_get(o, "argb");
10495 if ((argb_option) && (!strcmp(argb_option, "1")))
10498 if (use_argb != bd->argb)
10499 _e_border_frame_replace(bd, use_argb);
10506 shape_option = edje_object_data_get(o, "shaped");
10507 if ((shape_option) && (!strcmp(shape_option, "1")))
10511 if (bd->client.netwm.name)
10512 edje_object_part_text_set(o, "e.text.title",
10513 bd->client.netwm.name);
10514 else if (bd->client.icccm.title)
10515 edje_object_part_text_set(o, "e.text.title",
10516 bd->client.icccm.title);
10520 evas_object_del(o);
10521 bd->bg_object = NULL;
10524 _e_border_client_inset_calc(bd);
10526 bd->w += (bd->client_inset.l + bd->client_inset.r);
10527 bd->h += (bd->client_inset.t + bd->client_inset.b);
10528 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10529 bd->changes.size = 1;
10530 /* really needed ? */
10531 ecore_x_window_move(bd->client.shell_win,
10532 bd->client_inset.l,
10533 bd->client_inset.t);
10535 if (bd->maximized != E_MAXIMIZE_NONE)
10537 E_Maximize maximized = bd->maximized;
10539 /* to force possible resizes */
10540 bd->maximized = E_MAXIMIZE_NONE;
10542 _e_border_maximize(bd, maximized);
10544 /* restore maximized state */
10545 bd->maximized = maximized;
10547 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10548 bd->maximized & E_MAXIMIZE_VERTICAL);
10552 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10553 _e_border_cb_signal_bind, bd);
10556 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10557 if (bd->icon_object)
10558 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10561 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10563 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10565 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10566 // FIXME: in eval -do differently
10567 // edje_object_message_signal_process(bd->bg_object);
10568 // e_border_frame_recalc(bd);
10570 evas_object_move(bd->bg_object, 0, 0);
10571 evas_object_resize(bd->bg_object, bd->w, bd->h);
10572 evas_object_show(bd->bg_object);
10575 bd->client.border.changed = 0;
10577 if (bd->icon_object)
10581 evas_object_show(bd->icon_object);
10582 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10585 evas_object_hide(bd->icon_object);
10589 if (rem_change) e_remember_update(bd);
10593 E_Event_Border_Urgent_Change *ev;
10595 if (bd->client.icccm.urgent)
10596 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10598 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10600 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10602 e_object_ref(E_OBJECT(bd));
10603 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10604 _e_border_event_border_urgent_change_free, NULL);
10607 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10610 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10612 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10614 E_Border* temp_bd = NULL;
10615 E_Border* top_focusable_bd = NULL;
10616 Eina_Bool is_fully_obscured = EINA_FALSE;
10617 Ecore_X_XRegion *visible_region = NULL;
10618 Ecore_X_XRegion *win_region = NULL;
10619 Ecore_X_Rectangle visible_rect, win_rect;
10622 // set the entire visible region as a root geometry
10623 visible_rect.x = bd->zone->x;
10624 visible_rect.y = bd->zone->y;
10625 visible_rect.width = bd->zone->w;
10626 visible_rect.height = bd->zone->h;
10628 visible_region = ecore_x_xregion_new();
10629 if (!visible_region) return;
10631 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10633 bl = e_container_border_list_last(bd->zone->container);
10634 while ((temp_bd = e_container_border_list_prev(bl)))
10636 if (temp_bd == bd) break;
10638 if (temp_bd == focused) continue;
10639 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10640 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10641 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10642 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10643 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10644 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10645 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10646 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10647 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10649 if (!top_focusable_bd)
10651 top_focusable_bd = temp_bd;
10654 win_rect.x = temp_bd->x;
10655 win_rect.y = temp_bd->y;
10656 win_rect.width = temp_bd->w;
10657 win_rect.height = temp_bd->h;
10659 // if it stick out or is bigger than the entire visible region,
10660 // clip it by the entire visible's geometry.
10661 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10662 win_rect.width, win_rect.height,
10663 visible_rect.x, visible_rect.y,
10664 (int)(visible_rect.width), (int)(visible_rect.height));
10666 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10668 win_region = ecore_x_xregion_new();
10671 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10672 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10673 ecore_x_xregion_free(win_region);
10676 if (ecore_x_xregion_is_empty(visible_region))
10678 is_fully_obscured = EINA_TRUE;
10686 if (is_fully_obscured == EINA_TRUE)
10688 e_border_focus_set(top_focusable_bd, 1, 1);
10692 e_border_focus_set(bd, 1, 1);
10695 if (visible_region) ecore_x_xregion_free(visible_region);
10696 e_container_border_list_free(bl);
10700 _e_border_latest_stacked_focus(E_Border *bd)
10703 int root_w, root_h;
10705 root_w = bd->zone->w;
10706 root_h = bd->zone->h;
10709 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10711 if (bd == temp_bd) continue;
10712 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10713 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10715 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10716 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10717 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10718 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10719 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10720 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10721 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10723 _e_border_latest_stacked_focus_check_set(temp_bd);
10730 _e_border_check_stack (E_Border *bd)
10732 E_Border* temp_bd = NULL;
10733 E_Border* top_bd = NULL;
10734 int passed_focus = 0;
10736 int root_w = bd->zone->w;
10737 int root_h = bd->zone->h;
10740 bl = e_container_border_list_last(bd->zone->container);
10741 while ((temp_bd = e_container_border_list_prev(bl)))
10743 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10744 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10745 if ((temp_bd != bd) &&
10746 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10748 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10749 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10750 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10751 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10752 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10753 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10754 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10760 e_border_focus_set_with_pointer(bd);
10767 e_border_focus_set_with_pointer(top_bd);
10776 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10778 if (!bd->lock_focus_out)
10780 e_border_focus_latest_set(bd);
10792 if (temp_bd == focused)
10798 e_container_border_list_free(bl);
10802 _e_border_focus_top_stack_set(E_Border* bd)
10805 int root_w, root_h;
10807 root_w = bd->zone->w;
10808 root_h = bd->zone->h;
10811 bl = e_container_border_list_last(bd->zone->container);
10812 while ((temp_bd = e_container_border_list_prev(bl)))
10814 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10815 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10816 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10818 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10819 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10820 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10821 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10822 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10823 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10824 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10826 if (!temp_bd->focused)
10828 /* this border is the top of the latest stack */
10829 e_border_focus_set (temp_bd, 1, 1);
10834 e_container_border_list_free(bl);
10839 _e_border_eval(E_Border *bd)
10841 E_Event_Border_Property *event;
10842 E_Border_Pending_Move_Resize *pnd;
10843 int rem_change = 0;
10844 int send_event = 1;
10846 if (e_object_is_del(E_OBJECT(bd)))
10848 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10853 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10855 if (bd->new_client)
10857 int zx = 0, zy = 0, zw = 0, zh = 0;
10860 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10863 * Limit maximum size of windows to useful geometry
10865 // TODO: temoporary limited maximize algorithm
10877 if ((rw != bd->w) || (rh != bd->h))
10881 e_border_resize (bd, bd->w, bd->h);
10887 bd->x -= bd->client_inset.l;
10888 bd->y -= bd->client_inset.t;
10889 bd->changes.pos = 1;
10892 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10895 Ecore_X_Window_Attributes *att;
10898 att = &bd->client.initial_attributes;
10899 bw = att->border * 2;
10900 switch (bd->client.icccm.gravity)
10902 case ECORE_X_GRAVITY_N:
10903 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10907 case ECORE_X_GRAVITY_NE:
10908 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10912 case ECORE_X_GRAVITY_E:
10913 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10914 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10917 case ECORE_X_GRAVITY_SE:
10918 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10919 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10922 case ECORE_X_GRAVITY_S:
10923 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10924 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10927 case ECORE_X_GRAVITY_SW:
10929 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10932 case ECORE_X_GRAVITY_W:
10934 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10937 case ECORE_X_GRAVITY_CENTER:
10938 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10939 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10942 case ECORE_X_GRAVITY_NW:
10949 * This ensures that windows that like to open with a x/y
10950 * position smaller than returned by e_zone_useful_geometry_get()
10951 * are moved to useful positions.
10954 if (e_config->geometry_auto_move)
10962 if (bd->x + bd->w > zx + zw)
10963 bd->x = zx + zw - bd->w;
10965 if (bd->y + bd->h > zy + zh)
10966 bd->y = zy + zh - bd->h;
10969 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10971 bd->changes.pos = 1;
10977 bd->changes.pos = 1;
10983 /* FIXME: special placement for dialogs etc. etc. etc goes
10985 /* FIXME: what if parent is not on this desktop - or zone? */
10986 if ((bd->parent) && (bd->parent->visible))
10988 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10989 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10990 bd->changes.pos = 1;
10994 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10996 /* TODO: Place in center of group */
10999 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11001 bd->x = zx + ((zw - bd->w) / 2);
11002 bd->y = zy + ((zh - bd->h) / 2);
11003 bd->changes.pos = 1;
11009 Eina_List *skiplist = NULL;
11013 new_x = zx + (rand() % (zw - bd->w));
11017 new_y = zy + (rand() % (zh - bd->h));
11021 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
11023 skiplist = eina_list_append(skiplist, bd);
11025 e_place_desk_region_smart(bd->desk, skiplist,
11026 bd->x, bd->y, bd->w, bd->h,
11029 e_place_zone_region_smart(bd->zone, skiplist,
11030 bd->x, bd->y, bd->w, bd->h,
11032 eina_list_free(skiplist);
11034 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
11036 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
11041 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
11042 bd->client_inset.t, &new_x, &new_y);
11046 bd->changes.pos = 1;
11049 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11051 if ((!bd->lock_client_location) && (pnd->move))
11055 bd->changes.pos = 1;
11057 if (pnd->without_border)
11059 bd->x -= bd->client_inset.l;
11060 bd->y -= bd->client_inset.t;
11063 if ((!bd->lock_client_size) && (pnd->resize))
11065 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
11066 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
11067 bd->client.w = pnd->w;
11068 bd->client.h = pnd->h;
11069 bd->changes.size = 1;
11075 /* Recreate state */
11076 e_hints_window_init(bd);
11077 if ((bd->client.e.state.centered) &&
11078 ((!bd->remember) ||
11079 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
11081 bd->x = zx + (zw - bd->w) / 2;
11082 bd->y = zy + (zh - bd->h) / 2;
11083 bd->changes.pos = 1;
11087 _e_border_client_move_resize_send(bd);
11089 /* if the explicit geometry request asks for the app to be
11090 * in another zone - well move it there */
11094 zone = e_container_zone_at_point_get(bd->zone->container,
11095 bd->x + (bd->w / 2),
11096 bd->y + (bd->h / 2));
11098 zone = e_container_zone_at_point_get(bd->zone->container,
11102 zone = e_container_zone_at_point_get(bd->zone->container,
11106 zone = e_container_zone_at_point_get(bd->zone->container,
11108 bd->y + bd->h - 1);
11110 zone = e_container_zone_at_point_get(bd->zone->container,
11112 bd->y + bd->h - 1);
11113 if ((zone) && (zone != bd->zone))
11114 e_border_zone_set(bd, zone);
11118 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11120 /* effect changes to the window border itself */
11121 if ((bd->changes.shading))
11123 /* show at start of unshade (but don't hide until end of shade) */
11125 ecore_x_window_raise(bd->client.shell_win);
11126 bd->changes.shading = 0;
11129 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11132 ecore_x_window_lower(bd->client.shell_win);
11134 ecore_x_window_raise(bd->client.shell_win);
11135 bd->changes.shaded = 0;
11138 else if ((bd->changes.shaded) && (bd->changes.pos))
11141 ecore_x_window_lower(bd->client.shell_win);
11143 ecore_x_window_raise(bd->client.shell_win);
11144 bd->changes.size = 1;
11145 bd->changes.shaded = 0;
11148 else if ((bd->changes.shaded) && (bd->changes.size))
11151 ecore_x_window_lower(bd->client.shell_win);
11153 ecore_x_window_raise(bd->client.shell_win);
11154 bd->changes.shaded = 0;
11157 else if (bd->changes.shaded)
11160 ecore_x_window_lower(bd->client.shell_win);
11162 ecore_x_window_raise(bd->client.shell_win);
11163 bd->changes.size = 1;
11164 bd->changes.shaded = 0;
11168 if (bd->changes.size)
11170 int x = 0, y = 0, xx = 0, yy = 0;
11172 if ((bd->shaded) && (!bd->shading))
11174 evas_obscured_clear(bd->bg_evas);
11178 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11179 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11181 evas_obscured_clear(bd->bg_evas);
11182 evas_obscured_rectangle_add(bd->bg_evas,
11183 bd->client_inset.l, bd->client_inset.t, xx, yy);
11187 if (bd->shade.dir == E_DIRECTION_UP)
11189 y = yy - bd->client.h;
11191 else if (bd->shade.dir == E_DIRECTION_LEFT)
11193 x = xx - bd->client.w;
11198 if (bd->client.e.state.video)
11200 if (bd->client.e.state.video_position.updated)
11202 ecore_x_window_move(bd->win,
11203 bd->client.e.state.video_parent_border->x +
11204 bd->client.e.state.video_parent_border->client_inset.l +
11205 bd->client.e.state.video_parent_border->fx.x +
11206 bd->client.e.state.video_position.x,
11207 bd->client.e.state.video_parent_border->y +
11208 bd->client.e.state.video_parent_border->client_inset.t +
11209 bd->client.e.state.video_parent_border->fx.y +
11210 bd->client.e.state.video_position.y);
11211 bd->client.e.state.video_position.updated = 0;
11214 else if (!bd->changes.pos)
11216 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11217 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11218 bd->post_resize = 1;
11225 ecore_x_window_move_resize(bd->win,
11230 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11231 ecore_x_window_move(tmp->win,
11232 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11233 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11236 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11238 if ((!bd->shaded) || (bd->shading))
11239 ecore_x_window_move_resize(bd->client.shell_win,
11240 bd->client_inset.l, bd->client_inset.t, xx, yy);
11242 if (bd->internal_ecore_evas)
11243 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11244 else if (!bd->client.e.state.video)
11245 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11247 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11248 evas_object_resize(bd->bg_object, bd->w, bd->h);
11249 e_container_shape_resize(bd->shape, bd->w, bd->h);
11250 if (bd->changes.pos)
11251 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11253 _e_border_client_move_resize_send(bd);
11255 bd->changes.pos = 0;
11256 bd->changes.size = 0;
11259 else if (bd->changes.pos)
11261 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11262 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11265 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11267 _e_border_client_move_resize_send(bd);
11269 bd->changes.pos = 0;
11273 if (bd->changes.reset_gravity)
11275 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11276 bd->changes.reset_gravity = 0;
11280 if (bd->need_shape_merge)
11282 _e_border_shape_input_rectangle_set(bd);
11283 if ((bd->shaped) || (bd->client.shaped))
11285 Ecore_X_Window twin, twin2;
11288 twin = ecore_x_window_override_new
11289 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11291 ecore_x_window_shape_window_set(twin, bd->bg_win);
11294 Ecore_X_Rectangle rects[4];
11298 rects[0].width = bd->w;
11299 rects[0].height = bd->client_inset.t;
11301 rects[1].y = bd->client_inset.t;
11302 rects[1].width = bd->client_inset.l;
11303 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11304 rects[2].x = bd->w - bd->client_inset.r;
11305 rects[2].y = bd->client_inset.t;
11306 rects[2].width = bd->client_inset.r;
11307 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11309 rects[3].y = bd->h - bd->client_inset.b;
11310 rects[3].width = bd->w;
11311 rects[3].height = bd->client_inset.b;
11312 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11314 twin2 = ecore_x_window_override_new
11315 (bd->zone->container->scratch_win, 0, 0,
11316 bd->w - bd->client_inset.l - bd->client_inset.r,
11317 bd->h - bd->client_inset.t - bd->client_inset.b);
11320 if ((bd->shading) || (bd->shaded))
11322 if (bd->shade.dir == E_DIRECTION_UP)
11323 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11324 else if (bd->shade.dir == E_DIRECTION_LEFT)
11325 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11327 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11329 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11330 bd->w - bd->client_inset.l - bd->client_inset.r,
11331 bd->h - bd->client_inset.t - bd->client_inset.b);
11332 ecore_x_window_shape_window_add_xy(twin, twin2,
11333 bd->client_inset.l,
11334 bd->client_inset.t);
11335 ecore_x_window_free(twin2);
11336 ecore_x_window_shape_window_set(bd->win, twin);
11337 ecore_x_window_free(twin);
11340 ecore_x_window_shape_mask_set(bd->win, 0);
11341 // bd->need_shape_export = 1;
11342 bd->need_shape_merge = 0;
11345 if (bd->need_shape_export)
11347 Ecore_X_Rectangle *rects, *orects;
11350 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11356 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11360 orects = bd->shape_rects;
11362 for (i = 0; i < num; i++)
11364 if (rects[i].x < 0)
11366 rects[i].width -= rects[i].x;
11369 if ((rects[i].x + (int)rects[i].width) > bd->w)
11370 rects[i].width = rects[i].width - rects[i].x;
11371 if (rects[i].y < 0)
11373 rects[i].height -= rects[i].y;
11376 if ((rects[i].y + (int)rects[i].height) > bd->h)
11377 rects[i].height = rects[i].height - rects[i].y;
11379 if ((orects[i].x != rects[i].x) ||
11380 (orects[i].y != rects[i].y) ||
11381 (orects[i].width != rects[i].width) ||
11382 (orects[i].height != rects[i].height))
11391 if (bd->client.shaped)
11392 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11394 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11395 E_FREE(bd->shape_rects);
11396 bd->shape_rects = rects;
11397 bd->shape_rects_num = num;
11398 e_container_shape_rects_set(bd->shape, rects, num);
11405 E_FREE(bd->shape_rects);
11406 bd->shape_rects = NULL;
11407 bd->shape_rects_num = 0;
11408 e_container_shape_rects_set(bd->shape, NULL, 0);
11410 bd->need_shape_export = 0;
11413 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11417 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11418 if ((!bd->placed) && (!bd->re_manage) &&
11419 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11420 (!((bd->client.icccm.transient_for != 0) ||
11421 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11422 (!bdmove) && (!bdresize))
11424 /* Set this window into moving state */
11426 bd->cur_mouse_action = e_action_find("window_move");
11427 if (bd->cur_mouse_action)
11429 if ((!bd->cur_mouse_action->func.end_mouse) &&
11430 (!bd->cur_mouse_action->func.end))
11431 bd->cur_mouse_action = NULL;
11432 if (bd->cur_mouse_action)
11434 bd->x = x - (bd->w >> 1);
11435 bd->y = y - (bd->client_inset.t >> 1);
11437 bd->changes.pos = 1;
11439 _e_border_client_move_resize_send(bd);
11444 _e_border_show(bd);
11446 if (bd->cur_mouse_action)
11448 bd->moveinfo.down.x = bd->x + bd->fx.x;
11449 bd->moveinfo.down.y = bd->y + bd->fx.y;
11450 bd->moveinfo.down.w = bd->w;
11451 bd->moveinfo.down.h = bd->h;
11452 bd->mouse.current.mx = x;
11453 bd->mouse.current.my = y;
11454 bd->moveinfo.down.button = 0;
11455 bd->moveinfo.down.mx = x;
11456 bd->moveinfo.down.my = y;
11459 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11460 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11461 if (e_config->border_raise_on_mouse_action)
11462 e_border_raise(bd);
11463 e_border_focus_set(bd, 1, 1);
11465 bd->changes.visible = 0;
11469 if (bd->changes.icon)
11473 efreet_desktop_free(bd->desktop);
11474 bd->desktop = NULL;
11476 if (bd->icon_object)
11478 evas_object_del(bd->icon_object);
11479 bd->icon_object = NULL;
11481 if (bd->remember && bd->remember->prop.desktop_file)
11483 const char *desktop = bd->remember->prop.desktop_file;
11485 bd->desktop = efreet_desktop_get(desktop);
11487 bd->desktop = efreet_util_desktop_name_find(desktop);
11491 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11492 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11493 bd->client.icccm.class);
11497 /* libreoffice and maybe others match window class
11498 with .desktop file name */
11499 if (bd->client.icccm.class)
11502 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11503 bd->desktop = efreet_util_desktop_file_id_find(buf);
11508 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11509 bd->client.netwm.pid);
11510 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11512 if (!bd->desktop && bd->client.icccm.name)
11514 /* this works for most cases as fallback. useful when app is
11515 run from a shell */
11516 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11518 if (!bd->desktop && bd->client.icccm.transient_for)
11520 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11521 if (bd2 && bd2->desktop)
11523 efreet_desktop_ref(bd2->desktop);
11524 bd->desktop = bd2->desktop;
11529 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11530 bd->desktop->orig_path);
11533 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11534 if ((bd->focused) && (bd->icon_object))
11535 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11538 evas_object_show(bd->icon_object);
11539 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11542 evas_object_hide(bd->icon_object);
11545 E_Event_Border_Icon_Change *ev;
11547 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11549 e_object_ref(E_OBJECT(bd));
11550 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11551 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11552 _e_border_event_border_icon_change_free, NULL);
11554 bd->changes.icon = 0;
11557 bd->new_client = 0;
11559 bd->changes.stack = 0;
11560 bd->changes.prop = 0;
11562 if (bd->client.e.state.rot.changes != -1)
11564 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11565 bd->client.e.state.rot.changes = -1;
11568 if ((bd->take_focus) || (bd->want_focus))
11570 bd->take_focus = 0;
11571 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11572 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11573 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11576 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11579 bd->want_focus = 0;
11580 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11581 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11582 _e_border_check_stack(bd);
11585 e_border_focus_set_with_pointer(bd);
11587 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11589 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11590 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11591 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11592 e_border_focused_get())))
11594 e_border_focus_set_with_pointer(bd);
11599 /* focus window by default when it is the only one on desk */
11600 E_Border *bd2 = NULL;
11602 EINA_LIST_FOREACH(focus_stack, l, bd2)
11604 if (bd == bd2) continue;
11605 if ((!bd2->iconic) && (bd2->visible) &&
11606 ((bd->desk == bd2->desk) || bd2->sticky))
11612 e_border_focus_set_with_pointer(bd);
11617 if (bd->need_maximize)
11620 max = bd->maximized;
11621 bd->maximized = E_MAXIMIZE_NONE;
11622 e_border_maximize(bd, max);
11623 bd->need_maximize = 0;
11626 if (bd->need_fullscreen)
11628 e_border_fullscreen(bd, e_config->fullscreen_policy);
11629 bd->need_fullscreen = 0;
11633 e_remember_update(bd);
11635 if (send_event) // FIXME: send only if a property changed - above need to
11636 { // check on that. for now - always send.
11637 event = E_NEW(E_Event_Border_Property, 1);
11638 event->border = bd;
11639 e_object_ref(E_OBJECT(bd));
11640 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11642 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11646 _e_border_moveinfo_gather(E_Border *bd,
11647 const char *source)
11649 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11650 else if (e_util_glob_match(source, "mouse,*,2"))
11651 bd->moveinfo.down.button = 2;
11652 else if (e_util_glob_match(source, "mouse,*,3"))
11653 bd->moveinfo.down.button = 3;
11654 else bd->moveinfo.down.button = 0;
11655 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11657 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11658 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11662 bd->moveinfo.down.mx = bd->mouse.current.mx;
11663 bd->moveinfo.down.my = bd->mouse.current.my;
11668 _e_border_resize_handle(E_Border *bd)
11671 int new_x, new_y, new_w, new_h;
11673 Eina_List *skiplist = NULL;
11680 if ((bd->resize_mode == RESIZE_TR) ||
11681 (bd->resize_mode == RESIZE_R) ||
11682 (bd->resize_mode == RESIZE_BR))
11684 if ((bd->moveinfo.down.button >= 1) &&
11685 (bd->moveinfo.down.button <= 3))
11686 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11687 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11689 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11691 else if ((bd->resize_mode == RESIZE_TL) ||
11692 (bd->resize_mode == RESIZE_L) ||
11693 (bd->resize_mode == RESIZE_BL))
11695 if ((bd->moveinfo.down.button >= 1) &&
11696 (bd->moveinfo.down.button <= 3))
11697 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11698 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11700 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11703 if ((bd->resize_mode == RESIZE_TL) ||
11704 (bd->resize_mode == RESIZE_T) ||
11705 (bd->resize_mode == RESIZE_TR))
11707 if ((bd->moveinfo.down.button >= 1) &&
11708 (bd->moveinfo.down.button <= 3))
11709 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11710 (bd->mouse.current.my - bd->moveinfo.down.my);
11712 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11714 else if ((bd->resize_mode == RESIZE_BL) ||
11715 (bd->resize_mode == RESIZE_B) ||
11716 (bd->resize_mode == RESIZE_BR))
11718 if ((bd->moveinfo.down.button >= 1) &&
11719 (bd->moveinfo.down.button <= 3))
11720 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11721 (bd->mouse.current.my - bd->moveinfo.down.my);
11723 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11729 if ((bd->resize_mode == RESIZE_TL) ||
11730 (bd->resize_mode == RESIZE_L) ||
11731 (bd->resize_mode == RESIZE_BL))
11733 if ((bd->resize_mode == RESIZE_TL) ||
11734 (bd->resize_mode == RESIZE_T) ||
11735 (bd->resize_mode == RESIZE_TR))
11738 skiplist = eina_list_append(skiplist, bd);
11739 e_resist_container_border_position(bd->zone->container, skiplist,
11740 bd->x, bd->y, bd->w, bd->h,
11742 &new_x, &new_y, &new_w, &new_h);
11743 eina_list_free(skiplist);
11747 e_border_resize_limit(bd, &new_w, &new_h);
11748 if ((bd->resize_mode == RESIZE_TL) ||
11749 (bd->resize_mode == RESIZE_L) ||
11750 (bd->resize_mode == RESIZE_BL))
11751 new_x += (w - new_w);
11752 if ((bd->resize_mode == RESIZE_TL) ||
11753 (bd->resize_mode == RESIZE_T) ||
11754 (bd->resize_mode == RESIZE_TR))
11755 new_y += (h - new_h);
11757 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11761 _e_border_shade_animator(void *data)
11763 E_Border *bd = data;
11765 double dur = bd->client.h / e_config->border_shade_speed;
11767 dt = ecore_loop_time_get() - bd->shade.start;
11770 if (val < 0.0) val = 0.0;
11771 else if (val > 1.0) val = 1.0;
11773 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11776 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11777 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11779 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11782 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11783 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11785 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11788 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11789 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11791 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11794 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11795 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11797 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11800 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11801 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11803 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11806 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11807 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11809 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11812 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11813 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11815 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11818 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11819 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11821 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11824 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11825 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11830 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11831 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11834 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11835 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11836 else if (bd->shade.val > .999)
11837 bd->shade.val = 1.0;
11839 if (bd->shade.dir == E_DIRECTION_UP)
11840 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11841 else if (bd->shade.dir == E_DIRECTION_DOWN)
11843 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11844 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11845 bd->changes.pos = 1;
11847 else if (bd->shade.dir == E_DIRECTION_LEFT)
11848 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11849 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11851 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11852 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11853 bd->changes.pos = 1;
11856 if ((bd->shaped) || (bd->client.shaped))
11858 bd->need_shape_merge = 1;
11859 bd->need_shape_export = 1;
11861 if (bd->shaped_input)
11863 bd->need_shape_merge = 1;
11865 bd->changes.size = 1;
11871 E_Event_Border_Resize *ev;
11874 bd->shaded = !(bd->shaded);
11875 bd->changes.size = 1;
11876 bd->changes.shaded = 1;
11877 bd->changes.shading = 1;
11879 bd->shade.anim = NULL;
11882 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11884 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11885 edje_object_message_signal_process(bd->bg_object);
11886 e_border_frame_recalc(bd);
11888 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11889 ev = E_NEW(E_Event_Border_Resize, 1);
11891 e_object_ref(E_OBJECT(bd));
11892 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11893 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11894 return ECORE_CALLBACK_CANCEL;
11896 return ECORE_CALLBACK_RENEW;
11900 _e_border_event_border_resize_free(void *data __UNUSED__,
11903 E_Event_Border_Resize *e;
11906 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11907 e_object_unref(E_OBJECT(e->border));
11912 _e_border_event_border_move_free(void *data __UNUSED__,
11915 E_Event_Border_Move *e;
11918 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11919 e_object_unref(E_OBJECT(e->border));
11924 _e_border_event_border_add_free(void *data __UNUSED__,
11927 E_Event_Border_Add *e;
11930 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11931 e_object_unref(E_OBJECT(e->border));
11936 _e_border_event_border_remove_free(void *data __UNUSED__,
11939 E_Event_Border_Remove *e;
11942 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11943 e_object_unref(E_OBJECT(e->border));
11948 _e_border_event_border_show_free(void *data __UNUSED__,
11951 E_Event_Border_Show *e;
11954 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11955 e_object_unref(E_OBJECT(e->border));
11960 _e_border_event_border_hide_free(void *data __UNUSED__,
11963 E_Event_Border_Hide *e;
11966 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11967 e_object_unref(E_OBJECT(e->border));
11972 _e_border_event_border_iconify_free(void *data __UNUSED__,
11975 E_Event_Border_Iconify *e;
11978 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11979 e_object_unref(E_OBJECT(e->border));
11984 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11987 E_Event_Border_Uniconify *e;
11990 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11991 e_object_unref(E_OBJECT(e->border));
11996 _e_border_event_border_stick_free(void *data __UNUSED__,
11999 E_Event_Border_Stick *e;
12002 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
12003 e_object_unref(E_OBJECT(e->border));
12008 _e_border_event_border_unstick_free(void *data __UNUSED__,
12011 E_Event_Border_Unstick *e;
12014 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
12015 e_object_unref(E_OBJECT(e->border));
12020 _e_border_event_border_zone_set_free(void *data __UNUSED__,
12023 E_Event_Border_Zone_Set *e;
12026 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
12027 e_object_unref(E_OBJECT(e->border));
12028 e_object_unref(E_OBJECT(e->zone));
12033 _e_border_event_border_desk_set_free(void *data __UNUSED__,
12036 E_Event_Border_Desk_Set *e;
12039 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
12040 e_object_unref(E_OBJECT(e->border));
12041 e_object_unref(E_OBJECT(e->desk));
12046 _e_border_event_border_stack_free(void *data __UNUSED__,
12049 E_Event_Border_Stack *e;
12052 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
12053 e_object_unref(E_OBJECT(e->border));
12056 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
12057 e_object_unref(E_OBJECT(e->stack));
12063 _e_border_event_border_icon_change_free(void *data __UNUSED__,
12066 E_Event_Border_Icon_Change *e;
12069 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
12070 e_object_unref(E_OBJECT(e->border));
12075 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
12078 E_Event_Border_Urgent_Change *e;
12081 e_object_unref(E_OBJECT(e->border));
12086 _e_border_event_border_focus_in_free(void *data __UNUSED__,
12089 E_Event_Border_Focus_In *e;
12092 e_object_unref(E_OBJECT(e->border));
12097 _e_border_event_border_focus_out_free(void *data __UNUSED__,
12100 E_Event_Border_Focus_Out *e;
12103 e_object_unref(E_OBJECT(e->border));
12108 _e_border_event_border_property_free(void *data __UNUSED__,
12111 E_Event_Border_Property *e;
12114 e_object_unref(E_OBJECT(e->border));
12119 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12122 E_Event_Border_Fullscreen *e;
12125 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12126 e_object_unref(E_OBJECT(e->border));
12131 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12134 E_Event_Border_Unfullscreen *e;
12137 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12138 e_object_unref(E_OBJECT(e->border));
12142 #ifdef _F_ZONE_WINDOW_ROTATION_
12144 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12147 E_Event_Border_Rotation_Change_Begin *e;
12149 e_object_unref(E_OBJECT(e->border));
12154 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12157 E_Event_Border_Rotation_Change_Cancel *e;
12159 e_object_unref(E_OBJECT(e->border));
12164 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12167 E_Event_Border_Rotation_Change_End *e;
12169 e_object_unref(E_OBJECT(e->border));
12174 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12176 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12177 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12181 e_object_ref(E_OBJECT(bd));
12182 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12184 _e_border_event_border_rotation_change_begin_free,
12191 _e_border_zone_update(E_Border *bd)
12197 /* still within old zone - leave it there */
12198 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12199 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12200 #if _F_BORDER_CLIP_TO_ZONE_
12202 _e_border_shape_input_clip_to_zone(bd);
12207 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12208 /* find a new zone */
12209 con = bd->zone->container;
12210 EINA_LIST_FOREACH(con->zones, l, zone)
12212 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12213 zone->x, zone->y, zone->w, zone->h))
12215 e_border_zone_set(bd, zone);
12216 #if _F_BORDER_CLIP_TO_ZONE_
12217 _e_border_shape_input_clip_to_zone(bd);
12218 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12225 _e_border_resize_begin(E_Border *bd)
12229 if (!bd->lock_user_stacking)
12231 if (e_config->border_raise_on_mouse_action)
12232 e_border_raise(bd);
12234 if ((bd->shaded) || (bd->shading) ||
12235 (bd->fullscreen) || (bd->lock_user_size))
12238 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12239 ret = e_grabinput_get(bd->win, 0, bd->win);
12241 ret = e_grabinput_get(bd->win, 0, 0);
12243 if (grabbed && !ret)
12249 if (bd->client.netwm.sync.request)
12251 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12252 bd->client.netwm.sync.serial = 1;
12253 bd->client.netwm.sync.wait = 0;
12254 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12257 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12264 _e_border_resize_end(E_Border *bd)
12268 e_grabinput_release(bd->win, bd->win);
12271 if (bd->client.netwm.sync.alarm)
12273 E_Border_Pending_Move_Resize *pnd;
12275 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12276 bd->client.netwm.sync.alarm = 0;
12277 /* resize to last geometry if sync alarm for it was not yet handled */
12278 if (bd->pending_move_resize)
12281 bd->changes.pos = 1;
12282 bd->changes.size = 1;
12283 _e_border_client_move_resize_send(bd);
12286 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12290 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12294 /* If this border was maximized, we need to unset Maximized state or
12295 * on restart, E still thinks it's maximized */
12296 if (bd->maximized != E_MAXIMIZE_NONE)
12297 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12298 bd->maximized & E_MAXIMIZE_NONE);
12303 _e_border_resize_update(E_Border *bd)
12305 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12309 _e_border_move_begin(E_Border *bd)
12312 if (!bd->lock_user_stacking)
12314 if (e_config->border_raise_on_mouse_action)
12315 e_border_raise(bd);
12317 if ((bd->fullscreen) || (bd->lock_user_location))
12320 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12321 ret = e_grabinput_get(bd->win, 0, bd->win);
12323 ret = e_grabinput_get(bd->win, 0, 0);
12325 if (grabbed && !ret)
12331 if (bd->client.netwm.sync.request)
12333 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12334 bd->client.netwm.sync.serial = 0;
12335 bd->client.netwm.sync.wait = 0;
12336 bd->client.netwm.sync.time = ecore_loop_time_get();
12339 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12346 _e_border_move_end(E_Border *bd)
12350 e_grabinput_release(bd->win, bd->win);
12354 if (bd->client.netwm.sync.alarm)
12356 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12357 bd->client.netwm.sync.alarm = 0;
12360 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12367 _e_border_move_update(E_Border *bd)
12369 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12373 _e_border_cb_ping_poller(void *data)
12383 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12384 if (bd->kill_timer)
12386 ecore_timer_del(bd->kill_timer);
12387 bd->kill_timer = NULL;
12393 /* if time between last ping and now is greater
12394 * than half the ping interval... */
12395 if ((ecore_loop_time_get() - bd->ping) >
12396 ((e_config->ping_clients_interval *
12397 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12402 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12403 /* FIXME: if below dialog is up - hide it now */
12405 if (bd->delete_requested)
12407 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12408 e_border_act_kill_begin(bd);
12412 bd->ping_poller = NULL;
12414 return ECORE_CALLBACK_CANCEL;
12418 _e_border_cb_kill_timer(void *data)
12423 // dont wait until it's hung -
12426 if (bd->client.netwm.pid > 1)
12427 kill(bd->client.netwm.pid, SIGKILL);
12429 bd->kill_timer = NULL;
12430 return ECORE_CALLBACK_CANCEL;
12434 _e_border_pointer_resize_begin(E_Border *bd)
12436 switch (bd->resize_mode)
12439 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12443 e_pointer_type_push(bd->pointer, bd, "resize_t");
12447 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12451 e_pointer_type_push(bd->pointer, bd, "resize_r");
12455 e_pointer_type_push(bd->pointer, bd, "resize_br");
12459 e_pointer_type_push(bd->pointer, bd, "resize_b");
12463 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12467 e_pointer_type_push(bd->pointer, bd, "resize_l");
12473 _e_border_pointer_resize_end(E_Border *bd)
12475 switch (bd->resize_mode)
12478 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12482 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12486 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12490 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12494 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12498 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12502 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12506 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12512 _e_border_pointer_move_begin(E_Border *bd)
12514 e_pointer_type_push(bd->pointer, bd, "move");
12518 _e_border_pointer_move_end(E_Border *bd)
12520 e_pointer_type_pop(bd->pointer, bd, "move");
12523 static Eina_List *_e_border_hooks = NULL;
12524 static int _e_border_hooks_delete = 0;
12525 static int _e_border_hooks_walking = 0;
12528 _e_border_hooks_clean(void)
12533 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12537 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12544 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12550 _e_border_hooks_walking++;
12551 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12553 if (bh->delete_me) continue;
12554 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12556 _e_border_hooks_walking--;
12557 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12558 _e_border_hooks_clean();
12561 EAPI E_Border_Hook *
12562 e_border_hook_add(E_Border_Hook_Point hookpoint,
12563 void (*func)(void *data,
12569 bh = E_NEW(E_Border_Hook, 1);
12570 if (!bh) return NULL;
12571 bh->hookpoint = hookpoint;
12574 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12579 e_border_hook_del(E_Border_Hook *bh)
12582 if (_e_border_hooks_walking == 0)
12584 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12588 _e_border_hooks_delete++;
12592 e_border_focus_track_freeze(void)
12594 focus_track_frozen++;
12598 e_border_focus_track_thaw(void)
12600 focus_track_frozen--;
12604 e_border_under_pointer_get(E_Desk *desk,
12607 E_Border *bd = NULL, *cbd;
12611 /* We need to ensure that we can get the container window for the
12612 * zone of either the given desk or the desk of the excluded
12613 * window, so return if neither is given */
12615 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12617 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12621 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12623 if (!cbd) continue;
12624 /* If a border was specified which should be excluded from the list
12625 * (because it will be closed shortly for example), skip */
12626 if ((exclude) && (cbd == exclude)) continue;
12627 if ((desk) && (cbd->desk != desk)) continue;
12628 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12630 /* If the layer is higher, the position of the window is higher
12631 * (always on top vs always below) */
12632 if (!bd || (cbd->layer > bd->layer))
12642 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12649 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12650 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12651 (y - warp_y) > 5 || (y - warp_y) < -5)
12653 /* User moved the mouse, so stop warping */
12658 /* We just use the same warp speed as configured
12659 * for the windowlist */
12660 spd = e_config->winlist_warp_speed;
12663 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12664 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12665 if (warp_x == x && warp_y == y)
12667 warp_x = warp_to_x;
12668 warp_y = warp_to_y;
12672 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12673 return ECORE_CALLBACK_RENEW;
12676 ecore_timer_del(warp_timer);
12678 return ECORE_CALLBACK_CANCEL;
12682 e_border_pointer_warp_to_center(E_Border *bd)
12686 /* Do not slide pointer when disabled (probably breaks focus
12687 * on sloppy/mouse focus but requested by users). */
12688 if (!e_config->pointer_slide) return 0;
12689 /* Only warp the pointer if it is not already in the area of
12690 * the given border */
12691 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12692 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12693 (y >= bd->y) && (y <= (bd->y + bd->h)))
12696 warp_to_x = bd->x + (bd->w / 2);
12697 if (warp_to_x < (bd->zone->x + 1))
12698 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12699 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12700 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12702 warp_to_y = bd->y + (bd->h / 2);
12703 if (warp_to_y < (bd->zone->y + 1))
12704 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12705 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12706 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12709 warp_to_win = bd->zone->container->win;
12710 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12712 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12717 e_border_comp_hidden_set(E_Border *bd,
12723 E_OBJECT_CHECK(bd);
12724 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12726 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12729 ecore_x_window_hide(tmp->win);
12731 ecore_x_window_show(tmp->win);
12734 if (bd->comp_hidden == hidden) return;
12736 bd->comp_hidden = hidden;
12738 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12740 ecore_x_composite_window_events_disable(bd->win);
12741 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12745 _e_border_shape_input_rectangle_set(bd);
12746 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12751 e_border_tmp_input_hidden_push(E_Border *bd)
12756 E_OBJECT_CHECK(bd);
12757 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12759 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12760 e_border_tmp_input_hidden_push(tmp);
12762 bd->tmp_input_hidden++;
12763 if (bd->tmp_input_hidden != 1) return;
12765 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12767 ecore_x_composite_window_events_disable(bd->win);
12768 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12772 _e_border_shape_input_rectangle_set(bd);
12773 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12778 e_border_tmp_input_hidden_pop(E_Border *bd)
12783 E_OBJECT_CHECK(bd);
12784 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12786 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12787 e_border_tmp_input_hidden_pop(tmp);
12789 bd->tmp_input_hidden--;
12790 if (bd->tmp_input_hidden != 0) return;
12792 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12794 ecore_x_composite_window_events_disable(bd->win);
12795 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12799 _e_border_shape_input_rectangle_set(bd);
12800 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12805 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12807 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12809 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12810 ((bd->parent->focused) &&
12811 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12816 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12817 e_desk_show(bd->desk);
12819 if (!bd->lock_user_iconify)
12820 e_border_uniconify(bd);
12822 if ((!bd->iconic) && (!bd->sticky))
12823 e_desk_show(bd->desk);
12824 if (!bd->lock_user_stacking) e_border_raise(bd);
12825 if (!bd->lock_focus_out)
12827 /* XXX ooffice does send this request for
12828 config dialogs when the main window gets focus.
12829 causing the pointer to jump back and forth. */
12830 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12831 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12832 ecore_x_pointer_warp(bd->zone->container->win,
12833 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12834 e_border_focus_set(bd, 1, 1);
12838 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/