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
28 # define LOG_TAG "E17"
31 /* These are compatible with netwm */
41 #define RESIZE_NONE 11
43 /* local subsystem functions */
44 static void _e_border_pri_raise(E_Border *bd);
45 static void _e_border_pri_norm(E_Border *bd);
46 static void _e_border_free(E_Border *bd);
47 static void _e_border_del(E_Border *bd);
49 #ifdef PRINT_LOTS_OF_DEBUG
50 #define E_PRINT_BORDER_INFO(X) \
51 _e_border_print(X, __PRETTY_FUNC__)
53 static void _e_border_print(E_Border *bd,
57 /* FIXME: these likely belong in a separate icccm/client handler */
58 /* and the border needs to become a dumb object that just does what its */
60 static Eina_Bool _e_border_cb_window_show_request(void *data,
63 static Eina_Bool _e_border_cb_window_destroy(void *data,
66 static Eina_Bool _e_border_cb_window_hide(void *data,
69 static Eina_Bool _e_border_cb_window_reparent(void *data,
72 static Eina_Bool _e_border_cb_window_configure_request(void *data,
75 static Eina_Bool _e_border_cb_window_resize_request(void *data,
78 static Eina_Bool _e_border_cb_window_gravity(void *data,
81 static Eina_Bool _e_border_cb_window_stack_request(void *data,
84 static Eina_Bool _e_border_cb_window_property(void *data,
87 static Eina_Bool _e_border_cb_window_colormap(void *data,
90 static Eina_Bool _e_border_cb_window_shape(void *data,
93 static Eina_Bool _e_border_cb_window_focus_in(void *data,
96 static Eina_Bool _e_border_cb_window_focus_out(void *data,
99 static Eina_Bool _e_border_cb_client_message(void *data,
103 static Eina_Bool _e_border_cb_window_state_request(void *data,
106 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
109 static Eina_Bool _e_border_cb_desktop_change(void *data,
112 static Eina_Bool _e_border_cb_sync_alarm(void *data,
115 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
118 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
122 static Eina_Bool _e_border_cb_pointer_warp(void *data,
125 static void _e_border_cb_signal_bind(void *data,
127 const char *emission,
129 static Eina_Bool _e_border_cb_mouse_in(void *data,
132 static Eina_Bool _e_border_cb_mouse_out(void *data,
135 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
138 static Eina_Bool _e_border_cb_mouse_down(void *data,
141 static Eina_Bool _e_border_cb_mouse_up(void *data,
144 static Eina_Bool _e_border_cb_mouse_move(void *data,
147 static Eina_Bool _e_border_cb_grab_replay(void *data,
150 static void _e_border_cb_drag_finished(E_Drag *drag,
152 #ifdef _F_USE_DESK_WINDOW_PROFILE_
153 static Eina_Bool _e_border_cb_desk_window_profile_change(void *data,
157 #ifdef _F_ZONE_WINDOW_ROTATION_
158 static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data,
161 static void _e_border_cb_rotation_sync_job(void *data);
162 static void _e_border_cb_rotation_async_job(void *data);
163 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
164 static void _e_border_rotation_change_request(E_Zone *zone);
165 static void _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush);
166 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
167 static void _e_border_rotation_change_done(void);
168 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
176 static void _e_border_rotation_list_remove(E_Border *bd);
177 static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h);
178 static int _e_border_rotation_angle_get(E_Border *bd);
179 static Eina_Bool _e_border_rotation_zone_set(E_Zone *zone);
180 static Eina_Bool _e_border_rotatable_check(E_Border *bd, int ang);
181 static Eina_Bool _e_border_is_vkbd(E_Border *bd);
182 static Eina_Bool _e_border_cb_window_configure(void *data,
185 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
186 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
187 static void _e_border_vkbd_show(E_Border *bd);
188 static void _e_border_vkbd_hide(E_Border *bd);
189 static Eina_Bool _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending);
191 static void _e_border_move_resize_internal(E_Border *bd,
196 Eina_Bool without_border,
199 static void _e_border_eval(E_Border *bd);
200 static void _e_border_eval0(E_Border *bd);
201 static void _e_border_container_layout_hook(E_Container *con);
203 static void _e_border_moveinfo_gather(E_Border *bd,
205 static void _e_border_resize_handle(E_Border *bd);
207 static Eina_Bool _e_border_shade_animator(void *data);
209 static void _e_border_event_border_add_free(void *data,
211 static void _e_border_event_border_remove_free(void *data,
213 static void _e_border_event_border_zone_set_free(void *data,
215 static void _e_border_event_border_desk_set_free(void *data,
217 static void _e_border_event_border_stack_free(void *data,
219 static void _e_border_event_border_icon_change_free(void *data,
221 static void _e_border_event_border_urgent_change_free(void *data,
223 static void _e_border_event_border_focus_in_free(void *data,
225 static void _e_border_event_border_focus_out_free(void *data,
227 static void _e_border_event_border_resize_free(void *data,
229 static void _e_border_event_border_move_free(void *data,
231 static void _e_border_event_border_show_free(void *data,
233 static void _e_border_event_border_hide_free(void *data,
235 static void _e_border_event_border_iconify_free(void *data,
237 static void _e_border_event_border_uniconify_free(void *data,
239 static void _e_border_event_border_stick_free(void *data,
241 static void _e_border_event_border_unstick_free(void *data,
243 static void _e_border_event_border_property_free(void *data,
245 static void _e_border_event_border_fullscreen_free(void *data,
247 static void _e_border_event_border_unfullscreen_free(void *data,
249 #ifdef _F_ZONE_WINDOW_ROTATION_
250 static void _e_border_event_border_rotation_change_begin_free(void *data,
252 static void _e_border_event_border_rotation_change_cancel_free(void *data,
254 static void _e_border_event_border_rotation_change_end_free(void *data,
256 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
259 static void _e_border_zone_update(E_Border *bd);
261 static int _e_border_resize_begin(E_Border *bd);
262 static int _e_border_resize_end(E_Border *bd);
263 static void _e_border_resize_update(E_Border *bd);
265 static int _e_border_move_begin(E_Border *bd);
266 static int _e_border_move_end(E_Border *bd);
267 static void _e_border_move_update(E_Border *bd);
269 static Eina_Bool _e_border_cb_ping_poller(void *data);
270 static Eina_Bool _e_border_cb_kill_timer(void *data);
272 static void _e_border_pointer_resize_begin(E_Border *bd);
273 static void _e_border_pointer_resize_end(E_Border *bd);
274 static void _e_border_pointer_move_begin(E_Border *bd);
275 static void _e_border_pointer_move_end(E_Border *bd);
277 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
280 static void _e_border_client_move_resize_send(E_Border *bd);
282 static void _e_border_frame_replace(E_Border *bd,
285 static void _e_border_shape_input_rectangle_set(E_Border* bd);
286 static void _e_border_show(E_Border *bd);
287 static void _e_border_hide(E_Border *bd);
290 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
291 static void _e_border_latest_stacked_focus (E_Border* bd);
292 static void _e_border_check_stack (E_Border *bd);
293 static void _e_border_focus_top_stack_set (E_Border* bd);
295 #if _F_BORDER_CLIP_TO_ZONE_
296 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
297 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
298 /* local subsystem globals */
299 static Eina_List *handlers = NULL;
300 static Eina_List *borders = NULL;
301 static Eina_Hash *borders_hash = NULL;
302 static E_Border *focused = NULL;
303 static E_Border *focusing = NULL;
304 static Eina_List *focus_next = NULL;
305 static Ecore_X_Time focus_time = 0;
307 static E_Border *bdresize = NULL;
308 static E_Border *bdmove = NULL;
309 static E_Drag *drag_border = NULL;
311 static int grabbed = 0;
313 static Eina_List *focus_stack = NULL;
314 static Eina_List *raise_stack = NULL;
316 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
317 static int screen_size_index = -1;
319 static int focus_track_frozen = 0;
321 static int warp_to = 0;
322 static int warp_to_x = 0;
323 static int warp_to_y = 0;
324 static int warp_x = 0;
325 static int warp_y = 0;
326 static Ecore_X_Window warp_to_win;
327 static Ecore_Timer *warp_timer = NULL;
329 #ifdef _F_ZONE_WINDOW_ROTATION_
330 typedef struct _E_Border_Rotation E_Border_Rotation;
331 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
333 struct _E_Border_Rotation
336 Eina_List *async_list;
338 Eina_Bool wait_prepare_done;
339 Ecore_Timer *prepare_timer;
340 Ecore_Timer *done_timer;
342 Ecore_Job *async_job;
344 Ecore_X_Window vkbd_ctrl_win;
346 E_Border *vkbd_prediction;
348 /* vkbd show/hide preprare */
349 Eina_Bool vkbd_show_prepare_done;
350 Ecore_Timer *vkbd_show_prepare_timer;
351 Ecore_Timer *vkbd_show_timer;
353 Eina_Bool vkbd_hide_prepare_done;
354 Ecore_Timer *vkbd_hide_prepare_timer;
355 Ecore_Timer *vkbd_hide_timer;
361 struct _E_Border_Rotation_Info
366 Eina_Bool win_resize;
369 static E_Border_Rotation rot =
392 EAPI int E_EVENT_BORDER_ADD = 0;
393 EAPI int E_EVENT_BORDER_REMOVE = 0;
394 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
395 EAPI int E_EVENT_BORDER_DESK_SET = 0;
396 EAPI int E_EVENT_BORDER_RESIZE = 0;
397 EAPI int E_EVENT_BORDER_MOVE = 0;
398 EAPI int E_EVENT_BORDER_SHOW = 0;
399 EAPI int E_EVENT_BORDER_HIDE = 0;
400 EAPI int E_EVENT_BORDER_ICONIFY = 0;
401 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
402 EAPI int E_EVENT_BORDER_STICK = 0;
403 EAPI int E_EVENT_BORDER_UNSTICK = 0;
404 EAPI int E_EVENT_BORDER_STACK = 0;
405 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
406 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
407 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
408 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
409 EAPI int E_EVENT_BORDER_PROPERTY = 0;
410 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
411 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
412 #ifdef _F_ZONE_WINDOW_ROTATION_
413 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
414 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
415 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
416 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
419 #define GRAV_SET(bd, grav) \
420 ecore_x_window_gravity_set(bd->bg_win, grav); \
421 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
422 ecore_x_window_gravity_set(bd->client.win, grav);
425 _e_border_sub_borders_new(E_Border *bd)
427 Eina_List *list = NULL, *l;
431 EINA_LIST_FOREACH(bd->transients, l, child)
433 if (!eina_list_data_find(list, child))
434 list = eina_list_append(list, child);
436 bl = e_container_border_list_first(bd->zone->container);
437 while ((child = e_container_border_list_next(bl)))
439 if (e_object_is_del(E_OBJECT(child))) continue;
440 if (child == bd) continue;
442 if ((bd->client.icccm.client_leader) &&
443 (child->client.icccm.client_leader ==
444 bd->client.icccm.client_leader))
446 printf("bd %s in group with %s\n",
447 e_border_name_get(child),
448 e_border_name_get(bd));
449 if (!eina_list_data_find(list, child))
450 list = eina_list_append(list, child);
454 e_container_border_list_free(bl);
458 /* externally accessible functions */
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
473 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
474 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
475 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
476 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
477 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
478 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
479 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
480 #ifdef _F_ZONE_WINDOW_ROTATION_
481 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
484 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
486 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
487 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
488 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
489 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
490 #ifdef _F_USE_DESK_WINDOW_PROFILE_
491 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
493 #ifdef _F_ZONE_WINDOW_ROTATION_
494 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
497 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
499 E_EVENT_BORDER_ADD = ecore_event_type_new();
500 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
501 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
502 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
503 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
504 E_EVENT_BORDER_MOVE = ecore_event_type_new();
505 E_EVENT_BORDER_SHOW = ecore_event_type_new();
506 E_EVENT_BORDER_HIDE = ecore_event_type_new();
507 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
508 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
509 E_EVENT_BORDER_STICK = ecore_event_type_new();
510 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
511 E_EVENT_BORDER_STACK = ecore_event_type_new();
512 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
513 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
514 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
515 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
516 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
517 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
518 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
519 #ifdef _F_ZONE_WINDOW_ROTATION_
520 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
521 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
522 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
523 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
532 e_border_shutdown(void)
534 E_FREE_LIST(handlers, ecore_event_handler_del);
536 if (borders_hash) eina_hash_free(borders_hash);
538 e_int_border_menu_hooks_clear();
544 e_border_new(E_Container *con,
550 Ecore_X_Window_Attributes *att;
551 unsigned int managed, desk[2];
554 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
555 if (!bd) return NULL;
556 ecore_x_window_shadow_tree_flush();
557 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
561 /* FIXME: ewww - round trip */
562 bd->client.argb = ecore_x_window_argb_get(win);
564 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
567 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
568 ecore_x_window_shape_events_select(bd->win, 1);
570 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
571 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
573 bd->bg_ecore_evas = e_canvas_new(bd->win,
574 0, 0, bd->w, bd->h, 1, 0,
576 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
577 e_canvas_add(bd->bg_ecore_evas);
578 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
579 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
580 ecore_x_window_shape_events_select(bd->bg_win, 1);
581 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
582 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
584 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
586 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
587 ecore_x_window_container_manage(bd->client.shell_win);
588 if (!internal) ecore_x_window_client_manage(win);
589 /* FIXME: Round trip. XCB */
590 /* fetch needed to avoid grabbing the server as window may vanish */
591 att = &bd->client.initial_attributes;
592 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
594 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
595 e_canvas_del(bd->bg_ecore_evas);
596 ecore_evas_free(bd->bg_ecore_evas);
597 ecore_x_window_free(bd->client.shell_win);
598 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
599 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
600 ecore_x_window_free(bd->win);
605 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
606 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
608 /* FIXME: if first_map is 1 then we should ignore the first hide event
609 * or ensure the window is already hidden and events flushed before we
610 * create a border for it */
613 // printf("##- FIRST MAP\n");
618 // needed to be 1 for internal windw and on restart.
619 // bd->ignore_first_unmap = 2;
622 bd->client.win = win;
623 bd->zone = e_zone_current_get(con);
625 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
627 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
628 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
629 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
630 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
631 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
632 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
634 bd->client.icccm.title = NULL;
635 bd->client.icccm.name = NULL;
636 bd->client.icccm.class = NULL;
637 bd->client.icccm.icon_name = NULL;
638 bd->client.icccm.machine = NULL;
639 bd->client.icccm.min_w = 1;
640 bd->client.icccm.min_h = 1;
641 bd->client.icccm.max_w = 32767;
642 bd->client.icccm.max_h = 32767;
643 bd->client.icccm.base_w = 0;
644 bd->client.icccm.base_h = 0;
645 bd->client.icccm.step_w = -1;
646 bd->client.icccm.step_h = -1;
647 bd->client.icccm.min_aspect = 0.0;
648 bd->client.icccm.max_aspect = 0.0;
649 bd->client.icccm.accepts_focus = 1;
651 bd->client.netwm.pid = 0;
652 bd->client.netwm.name = NULL;
653 bd->client.netwm.icon_name = NULL;
654 bd->client.netwm.desktop = 0;
655 bd->client.netwm.state.modal = 0;
656 bd->client.netwm.state.sticky = 0;
657 bd->client.netwm.state.shaded = 0;
658 bd->client.netwm.state.hidden = 0;
659 bd->client.netwm.state.maximized_v = 0;
660 bd->client.netwm.state.maximized_h = 0;
661 bd->client.netwm.state.skip_taskbar = 0;
662 bd->client.netwm.state.skip_pager = 0;
663 bd->client.netwm.state.fullscreen = 0;
664 bd->client.netwm.state.stacking = E_STACKING_NONE;
665 bd->client.netwm.action.move = 0;
666 bd->client.netwm.action.resize = 0;
667 bd->client.netwm.action.minimize = 0;
668 bd->client.netwm.action.shade = 0;
669 bd->client.netwm.action.stick = 0;
670 bd->client.netwm.action.maximized_h = 0;
671 bd->client.netwm.action.maximized_v = 0;
672 bd->client.netwm.action.fullscreen = 0;
673 bd->client.netwm.action.change_desktop = 0;
674 bd->client.netwm.action.close = 0;
675 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
681 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
682 bd->client.icccm.fetch.command = 1;
685 Eina_Bool video_parent = EINA_FALSE;
686 Eina_Bool video_position = EINA_FALSE;
689 for (i = 0; i < at_num; i++)
691 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
692 bd->client.icccm.fetch.title = 1;
693 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
694 bd->client.icccm.fetch.name_class = 1;
695 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
696 bd->client.icccm.fetch.icon_name = 1;
697 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
698 bd->client.icccm.fetch.machine = 1;
699 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
700 bd->client.icccm.fetch.hints = 1;
701 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
702 bd->client.icccm.fetch.size_pos_hints = 1;
703 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
704 bd->client.icccm.fetch.protocol = 1;
705 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
706 bd->client.mwm.fetch.hints = 1;
707 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
709 bd->client.icccm.fetch.transient_for = 1;
710 bd->client.netwm.fetch.type = 1;
712 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
713 bd->client.icccm.fetch.client_leader = 1;
714 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
715 bd->client.icccm.fetch.window_role = 1;
716 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
717 bd->client.icccm.fetch.state = 1;
719 /* netwm, loop again, netwm will ignore some icccm, so we
720 * have to be sure that netwm is checked after */
721 for (i = 0; i < at_num; i++)
723 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
726 bd->client.icccm.fetch.title = 0;
727 bd->client.netwm.fetch.name = 1;
729 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
732 bd->client.icccm.fetch.icon_name = 0;
733 bd->client.netwm.fetch.icon_name = 1;
735 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
737 bd->client.netwm.fetch.icon = 1;
739 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
741 bd->client.netwm.fetch.user_time = 1;
743 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
745 DBG("ECORE_X_ATOM_NET_WM_STRUT");
746 bd->client.netwm.fetch.strut = 1;
748 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
750 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
751 bd->client.netwm.fetch.strut = 1;
753 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
756 bd->client.mwm.fetch.hints = 0;
758 bd->client.netwm.fetch.type = 1;
760 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
762 bd->client.netwm.fetch.state = 1;
765 /* other misc atoms */
766 for (i = 0; i < at_num; i++)
768 /* loop to check for own atoms */
769 if (atoms[i] == E_ATOM_WINDOW_STATE)
771 bd->client.e.fetch.state = 1;
773 /* loop to check for qtopia atoms */
774 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
775 bd->client.qtopia.fetch.soft_menu = 1;
776 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
777 bd->client.qtopia.fetch.soft_menus = 1;
778 /* loop to check for vkbd atoms */
779 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
780 bd->client.vkbd.fetch.state = 1;
781 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
782 bd->client.vkbd.fetch.vkbd = 1;
783 /* loop to check for illume atoms */
784 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
785 bd->client.illume.conformant.fetch.conformant = 1;
786 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
787 bd->client.illume.quickpanel.fetch.state = 1;
788 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
789 bd->client.illume.quickpanel.fetch.quickpanel = 1;
790 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
791 bd->client.illume.quickpanel.fetch.priority.major = 1;
792 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
793 bd->client.illume.quickpanel.fetch.priority.minor = 1;
794 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
795 bd->client.illume.quickpanel.fetch.zone = 1;
796 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
797 bd->client.illume.drag.fetch.locked = 1;
798 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
799 bd->client.illume.drag.fetch.drag = 1;
800 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
801 bd->client.illume.win_state.fetch.state = 1;
802 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
803 video_parent = EINA_TRUE;
804 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
805 video_position = EINA_TRUE;
806 #ifdef _F_USE_DESK_WINDOW_PROFILE_
807 /* loop to check for window profile list atom */
808 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
809 bd->client.e.fetch.profile_list = 1;
811 #ifdef _F_ZONE_WINDOW_ROTATION_
812 /* loop to check for wm rotation */
813 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
815 if (e_config->wm_win_rotation)
816 bd->client.e.fetch.rot.support = 1;
818 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
819 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
820 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
821 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
823 if (e_config->wm_win_rotation)
824 bd->client.e.fetch.rot.geom_hint = 1;
826 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
828 if (e_config->wm_win_rotation)
829 bd->client.e.fetch.rot.app_set = 1;
831 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
833 if (e_config->wm_win_rotation)
834 bd->client.e.fetch.rot.preferred_rot = 1;
836 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
838 if (e_config->wm_win_rotation)
839 bd->client.e.fetch.rot.available_rots = 1;
842 #ifdef _F_DEICONIFY_APPROVE_
843 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
845 bd->client.e.state.deiconify_approve.support = 1;
849 if (video_position && video_parent)
851 bd->client.e.state.video = 1;
852 bd->client.e.fetch.video_parent = 1;
853 bd->client.e.fetch.video_position = 1;
854 ecore_x_window_lower(bd->win);
855 ecore_x_composite_window_events_disable(bd->win);
856 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
857 fprintf(stderr, "We found a video window \\o/ %x\n", win);
862 bd->client.border.changed = 1;
864 bd->client.w = att->w;
865 bd->client.h = att->h;
867 bd->w = bd->client.w;
868 bd->h = bd->client.h;
870 bd->resize_mode = RESIZE_NONE;
872 bd->saved.layer = bd->layer;
873 bd->changes.icon = 1;
874 bd->changes.size = 1;
875 bd->changes.shape = 1;
876 bd->changes.shape_input = 1;
878 bd->offer_resistance = 1;
880 /* just to friggin make java happy - we're DELAYING the reparent until
883 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
884 bd->need_reparent = 1;
886 ecore_x_window_border_width_set(win, 0);
887 ecore_x_window_show(bd->event_win);
888 ecore_x_window_show(bd->client.shell_win);
889 bd->shape = e_container_shape_add(con);
894 #ifdef _F_ZONE_WINDOW_ROTATION_
895 bd->client.e.state.rot.preferred_rot = -1;
896 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
897 bd->client.e.state.rot.changes = -1;
898 bd->client.e.state.rot.pending_show = 0;
899 bd->client.e.state.rot.curr = 0;
900 bd->client.e.state.rot.prev = 0;
903 // bd->zone = e_zone_current_get(con);
904 bd->desk = e_desk_current_get(bd->zone);
905 e_container_border_add(bd);
906 borders = eina_list_append(borders, bd);
907 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
911 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
912 "optimisations failing due to bizarre client behavior. will\n"
914 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
915 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
918 ELBF(ELBT_BD, 0, bd->client.win,
919 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
920 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
922 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
923 printf("optimisations failing due to bizarre client behavior. will\n");
924 printf("work around.\n");
925 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
926 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
929 ELBF(ELBT_BD, 0, bd->client.win,
930 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
931 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
934 #ifdef _F_ZONE_WINDOW_ROTATION_
935 if ((rot.vkbd) && (rot.vkbd == bd2))
937 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
938 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
939 rot.vkbd_hide_prepare_done);
941 if (rot.vkbd_hide_prepare_timer)
943 ecore_timer_del(rot.vkbd_hide_prepare_timer);
944 rot.vkbd_hide_prepare_timer = NULL;
946 e_object_unref(E_OBJECT(bd2));
949 _e_border_vkbd_hide(rot.vkbd);
951 if (rot.vkbd_ctrl_win)
953 ELB(ELBT_BD, "SET KBD_OFF", 0);
954 ecore_x_e_virtual_keyboard_state_set
955 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
957 rot.vkbd_hide_prepare_done = EINA_FALSE;
959 if (rot.vkbd_hide_timer)
960 ecore_timer_del(rot.vkbd_hide_timer);
961 rot.vkbd_hide_timer = NULL;
963 rot.vkbd_show_prepare_done = EINA_FALSE;
964 if (rot.vkbd_show_prepare_timer)
965 ecore_timer_del(rot.vkbd_show_prepare_timer);
966 rot.vkbd_show_prepare_timer = NULL;
967 if (rot.vkbd_show_timer)
968 ecore_timer_del(rot.vkbd_show_timer);
969 rot.vkbd_show_timer = NULL;
974 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
975 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
976 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
978 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
979 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
980 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
982 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
983 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
984 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
986 unsigned int zgeom[4];
988 zgeom[0] = bd->zone->x;
989 zgeom[1] = bd->zone->y;
990 zgeom[2] = bd->zone->w;
991 zgeom[3] = bd->zone->h;
992 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
994 e_desk_xy_get(bd->desk, &deskx, &desky);
997 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
998 #ifdef _F_USE_DESK_WINDOW_PROFILE_
999 if (strcmp(bd->desk->window_profile,
1000 e_config->desktop_default_window_profile) != 0)
1002 ecore_x_e_window_profile_set(bd->client.win,
1003 bd->desk->window_profile);
1007 focus_stack = eina_list_append(focus_stack, bd);
1009 bd->pointer = e_pointer_window_new(bd->win, 0);
1014 e_border_res_change_geometry_save(E_Border *bd)
1017 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1019 if (bd->pre_res_change.valid) return;
1020 bd->pre_res_change.valid = 1;
1021 bd->pre_res_change.x = bd->x;
1022 bd->pre_res_change.y = bd->y;
1023 bd->pre_res_change.w = bd->w;
1024 bd->pre_res_change.h = bd->h;
1025 bd->pre_res_change.saved.x = bd->saved.x;
1026 bd->pre_res_change.saved.y = bd->saved.y;
1027 bd->pre_res_change.saved.w = bd->saved.w;
1028 bd->pre_res_change.saved.h = bd->saved.h;
1032 e_border_res_change_geometry_restore(E_Border *bd)
1036 unsigned char valid : 1;
1045 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1046 if (!bd->pre_res_change.valid) return;
1047 if (bd->new_client) return;
1049 ecore_x_window_shadow_tree_flush();
1050 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1054 e_border_unfullscreen(bd);
1055 e_border_fullscreen(bd, e_config->fullscreen_policy);
1057 else if (bd->maximized != E_MAXIMIZE_NONE)
1061 max = bd->maximized;
1062 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1063 e_border_maximize(bd, max);
1067 int x, y, w, h, zx, zy, zw, zh;
1069 bd->saved.x = bd->pre_res_change.saved.x;
1070 bd->saved.y = bd->pre_res_change.saved.y;
1071 bd->saved.w = bd->pre_res_change.saved.w;
1072 bd->saved.h = bd->pre_res_change.saved.h;
1074 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1076 if (bd->saved.w > zw)
1078 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1079 bd->saved.x = zx + zw - bd->saved.w;
1081 if (bd->saved.h > zh)
1083 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1084 bd->saved.y = zy + zh - bd->saved.h;
1086 x = bd->pre_res_change.x;
1087 y = bd->pre_res_change.y;
1088 w = bd->pre_res_change.w;
1089 h = bd->pre_res_change.h;
1094 if ((x + w) > (zx + zw))
1096 if ((y + h) > (zy + zh))
1098 e_border_move_resize(bd, x, y, w, h);
1100 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1104 e_border_zone_set(E_Border *bd,
1107 E_Event_Border_Zone_Set *ev;
1110 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1111 E_OBJECT_CHECK(zone);
1112 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1114 if (bd->zone == zone) return;
1116 /* if the window does not lie in the new zone, move it so that it does */
1117 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1120 /* first guess -- get offset from old zone, and apply to new zone */
1121 x = zone->x + (bd->x - bd->zone->x);
1122 y = zone->y + (bd->y - bd->zone->y);
1124 /* keep window from hanging off bottom and left */
1125 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1126 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1128 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1129 if (x < zone->x) x = zone->x;
1130 if (y < zone->y) y = zone->y;
1132 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1134 /* still not in zone at all, so just move it to closest edge */
1135 if (x < zone->x) x = zone->x;
1136 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1137 if (y < zone->y) y = zone->y;
1138 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1140 e_border_move(bd, x, y);
1145 if (bd->desk->zone != bd->zone)
1146 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1148 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1150 e_object_ref(E_OBJECT(bd));
1151 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1153 e_object_ref(E_OBJECT(zone));
1155 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1157 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1158 // XXXXXXXXXXXXXXXXXXXXXXXXX
1159 // XXX ZZZZZZZZZZZZZZZZZZZzz
1160 // need to adjust this if zone pos/size changes
1162 unsigned int zgeom[4];
1164 zgeom[0] = bd->zone->x;
1165 zgeom[1] = bd->zone->y;
1166 zgeom[2] = bd->zone->w;
1167 zgeom[3] = bd->zone->h;
1168 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1170 e_remember_update(bd);
1174 e_border_desk_set(E_Border *bd,
1177 E_Event_Border_Desk_Set *ev;
1181 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1182 E_OBJECT_CHECK(desk);
1183 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1184 if (bd->desk == desk) return;
1185 ecore_x_window_shadow_tree_flush();
1188 bd->desk->fullscreen_borders--;
1189 desk->fullscreen_borders++;
1191 old_desk = bd->desk;
1193 e_border_zone_set(bd, desk->zone);
1195 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1196 e_hints_window_desktop_set(bd);
1198 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1200 e_object_ref(E_OBJECT(bd));
1201 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1202 ev->desk = old_desk;
1203 e_object_ref(E_OBJECT(old_desk));
1204 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1206 if (bd->ignore_first_unmap != 1)
1208 if ((bd->desk->visible) || (bd->sticky))
1211 e_border_hide(bd, 1);
1214 if (e_config->transient.desktop)
1218 Eina_List *list = _e_border_sub_borders_new(bd);
1220 EINA_LIST_FOREACH(list, l, child)
1222 e_border_desk_set(child, bd->desk);
1224 eina_list_free(list);
1226 e_remember_update(bd);
1229 #ifdef _F_ZONE_WINDOW_ROTATION_
1231 _e_border_vkbd_state_check(E_Border *bd,
1234 Eina_Bool res = EINA_TRUE;
1235 if (!e_config->wm_win_rotation) return EINA_FALSE;
1236 if ((rot.vkbd) && (rot.vkbd == bd))
1240 if ((rot.vkbd_hide_prepare_done) ||
1241 (rot.vkbd_hide_prepare_timer))
1246 if ((rot.vkbd_show_prepare_done) ||
1247 (rot.vkbd_show_prepare_timer))
1255 _e_border_vkbd_show_timeout(void *data)
1257 E_Border *bd = data;
1258 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1259 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1261 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1263 if (rot.vkbd_ctrl_win)
1265 ELB(ELBT_BD, "SET KBD_ON", 0);
1266 ecore_x_e_virtual_keyboard_state_set
1267 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1272 rot.vkbd_show_prepare_done = EINA_FALSE;
1274 if (rot.vkbd_show_prepare_timer)
1275 ecore_timer_del(rot.vkbd_show_prepare_timer);
1276 rot.vkbd_show_prepare_timer = NULL;
1278 if (rot.vkbd_show_timer)
1279 ecore_timer_del(rot.vkbd_show_timer);
1280 rot.vkbd_show_timer = NULL;
1282 return ECORE_CALLBACK_CANCEL;
1286 _e_border_vkbd_hide_timeout(void *data)
1288 E_Border *bd = data;
1289 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1290 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1292 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1294 if (rot.vkbd_ctrl_win)
1296 ELB(ELBT_BD, "SET KBD_OFF", 0);
1297 ecore_x_e_virtual_keyboard_state_set
1298 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1301 e_object_unref(E_OBJECT(bd));
1304 rot.vkbd_hide_prepare_done = EINA_FALSE;
1306 if (rot.vkbd_hide_prepare_timer)
1307 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1308 rot.vkbd_hide_prepare_timer = NULL;
1310 if (rot.vkbd_hide_timer)
1311 ecore_timer_del(rot.vkbd_hide_timer);
1312 rot.vkbd_hide_timer = NULL;
1314 return ECORE_CALLBACK_CANCEL;
1318 _e_border_vkbd_show(E_Border *bd)
1320 if (!e_config->wm_win_rotation) return;
1321 rot.vkbd_show_prepare_done = EINA_TRUE;
1322 if (rot.vkbd_show_prepare_timer)
1323 ecore_timer_del(rot.vkbd_show_prepare_timer);
1324 rot.vkbd_show_prepare_timer = NULL;
1325 if (rot.vkbd_show_timer)
1326 ecore_timer_del(rot.vkbd_show_timer);
1327 rot.vkbd_show_timer = NULL;
1328 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1331 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1336 _e_border_vkbd_hide(E_Border *bd)
1338 if (!e_config->wm_win_rotation) return;
1339 rot.vkbd_hide_prepare_done = EINA_TRUE;
1340 if (rot.vkbd_hide_prepare_timer)
1341 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1342 rot.vkbd_hide_prepare_timer = NULL;
1343 if (rot.vkbd_hide_timer)
1344 ecore_timer_del(rot.vkbd_hide_timer);
1345 rot.vkbd_hide_timer = NULL;
1346 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1348 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1349 e_border_hide(bd, 0);
1350 if (!e_object_is_del(E_OBJECT(bd)))
1352 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1353 e_object_del(E_OBJECT(bd));
1355 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1360 _e_border_vkbd_show_prepare_timeout(void *data)
1362 E_Border *bd = data;
1363 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1364 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1366 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1367 _e_border_vkbd_show(bd);
1369 return ECORE_CALLBACK_CANCEL;
1373 _e_border_vkbd_hide_prepare_timeout(void *data)
1375 E_Border *bd = data;
1376 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1377 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1379 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1380 _e_border_vkbd_hide(bd);
1382 return ECORE_CALLBACK_CANCEL;
1387 e_border_show(E_Border *bd)
1389 E_Event_Border_Show *ev;
1390 unsigned int visible;
1393 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1394 if (bd->visible) return;
1395 #ifdef _F_ZONE_WINDOW_ROTATION_
1396 // newly created window that has to be rotated will be show after rotation done.
1397 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1398 if ((bd->new_client) &&
1399 (bd->client.e.state.rot.changes != -1))
1401 ELB(ELBT_BD, "PENDING SHOW UNTIL GETTING ROT_DONE", bd->client.win);
1402 // if this window is in withdrawn state, set the normal state
1403 // that's because the window in withdrawn state can't render its canvas.
1404 // eventually, this window will not send the message of rotation done,
1405 // even if e17 request to rotation this window.
1406 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1407 e_hints_window_visible_set(bd);
1409 bd->client.e.state.rot.pending_show = 1;
1412 if ((e_config->wm_win_rotation) &&
1413 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1415 (!rot.vkbd_show_prepare_done))
1417 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1418 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1419 if (rot.vkbd_show_prepare_timer)
1420 ecore_timer_del(rot.vkbd_show_prepare_timer);
1421 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1422 _e_border_vkbd_show_prepare_timeout,
1426 ELB(ELBT_BD, "SHOW", bd->client.win);
1428 ecore_x_window_shadow_tree_flush();
1429 e_container_shape_show(bd->shape);
1430 if (!bd->need_reparent)
1431 ecore_x_window_show(bd->client.win);
1432 e_hints_window_visible_set(bd);
1435 bd->changes.visible = 1;
1438 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1439 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1441 ev = E_NEW(E_Event_Border_Show, 1);
1443 e_object_ref(E_OBJECT(bd));
1444 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1445 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1447 #ifdef _F_ZONE_WINDOW_ROTATION_
1448 if ((e_config->wm_win_rotation) &&
1449 ((bd->client.e.state.rot.support) ||
1450 (bd->client.e.state.rot.app_set)))
1452 ELB(ELBT_ROT, "CHECK", bd->client.win);
1453 int rotation = _e_border_rotation_angle_get(bd);
1454 if (rotation != -1) e_border_rotation_set(bd, rotation);
1460 e_border_hide(E_Border *bd,
1463 unsigned int visible;
1466 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1468 #ifdef _F_ZONE_WINDOW_ROTATION_
1469 if ((e_config->wm_win_rotation) &&
1470 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1472 (!rot.vkbd_hide_prepare_done) &&
1475 Eina_Bool need_prepare = EINA_TRUE;
1476 E_Border *child = NULL;
1479 if (e_object_is_del(E_OBJECT(bd->parent)))
1480 need_prepare = EINA_FALSE;
1483 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1484 if (bd->parent->modal == bd)
1486 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1487 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1488 bd->parent->lock_close = 0;
1489 bd->parent->saved.event_mask = 0;
1490 bd->parent->modal = NULL;
1496 need_prepare = EINA_FALSE;
1498 EINA_LIST_FREE(bd->transients, child)
1500 child->parent = NULL;
1503 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1507 e_object_ref(E_OBJECT(bd));
1508 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1509 if (rot.vkbd_hide_prepare_timer)
1510 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1511 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1512 _e_border_vkbd_hide_prepare_timeout,
1518 e_object_ref(E_OBJECT(bd));
1520 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1521 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1523 /* cleanup code from _e_border_vkbd_hide() */
1524 rot.vkbd_hide_prepare_done = EINA_TRUE;
1525 if (rot.vkbd_hide_prepare_timer)
1526 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1527 rot.vkbd_hide_prepare_timer = NULL;
1528 if (rot.vkbd_hide_timer)
1529 ecore_timer_del(rot.vkbd_hide_timer);
1530 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1533 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1535 if (!bd->visible) goto send_event;
1536 ecore_x_window_shadow_tree_flush();
1538 _e_border_move_end(bd);
1539 if (bd->resize_mode != RESIZE_NONE)
1541 _e_border_pointer_resize_end(bd);
1542 bd->resize_mode = RESIZE_NONE;
1543 _e_border_resize_end(bd);
1546 e_container_shape_hide(bd->shape);
1547 if (!bd->iconic) e_hints_window_hidden_set(bd);
1550 bd->changes.visible = 1;
1552 if (!bd->need_reparent)
1554 if ((bd->focused) ||
1555 (e_grabinput_last_focus_win_get() == bd->client.win))
1557 e_border_focus_set(bd, 0, 1);
1565 con = e_container_current_get(e_manager_current_get());
1566 zone = e_zone_current_get(con);
1567 desk = e_desk_current_get(zone);
1570 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1571 e_border_focus_set(bd->parent, 1, 1);
1572 else if (e_config->focus_revert_on_hide_or_close)
1574 /* When using pointer focus, the border under the
1575 * pointer (if any) gets focused, in sloppy/click
1576 * focus the last focused window on the current
1577 * desk gets focus */
1578 if (e_config->focus_policy == E_FOCUS_MOUSE)
1580 pbd = e_border_under_pointer_get(desk, bd);
1582 e_border_focus_set(pbd, 1, 1);
1584 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1585 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1586 (e_config->focus_policy == E_FOCUS_CLICK))
1587 _e_border_latest_stacked_focus(bd);
1591 e_desk_last_focused_focus(desk);
1601 /* Make sure that this border isn't deleted */
1602 bd->await_hide_event++;
1604 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1605 ecore_x_window_hide(bd->client.win);
1610 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1612 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1619 #ifdef _F_ZONE_WINDOW_ROTATION_
1620 _e_border_rotation_list_remove(bd);
1623 E_Event_Border_Hide *ev;
1625 ev = E_NEW(E_Event_Border_Hide, 1);
1627 e_object_ref(E_OBJECT(bd));
1628 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1629 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1634 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1638 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1639 setpriority(PRIO_PROCESS, pid, newpri);
1640 // shouldnt need to do this as default ionice class is "none" (0), and
1641 // this inherits io priority FROM nice level
1642 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1643 // IOPRIO_PRIO_VALUE(2, 5));
1647 char *file, buf[PATH_MAX];
1651 // yes - this is /proc specific... so this may not work on some
1652 // os's - works on linux. too bad for others.
1653 files = ecore_file_ls("/proc");
1654 EINA_LIST_FREE(files, file)
1656 if (isdigit(file[0]))
1658 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1659 f = fopen(buf, "r");
1664 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1670 _pri_adj(pid2, set, adj, EINA_TRUE,
1671 adj_children, do_children);
1673 _pri_adj(pid2, set, adj, use_adj,
1674 adj_children, do_children);
1686 _e_border_pri_raise(E_Border *bd)
1688 if (bd->client.netwm.pid <= 0) return;
1689 if (bd->client.netwm.pid == getpid()) return;
1690 _pri_adj(bd->client.netwm.pid,
1691 e_config->priority - 1, -1, EINA_FALSE,
1692 // EINA_TRUE, EINA_TRUE);
1693 EINA_TRUE, EINA_FALSE);
1694 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1695 // bd->client.netwm.pid, e_border_name_get(bd));
1699 _e_border_pri_norm(E_Border *bd)
1701 if (bd->client.netwm.pid <= 0) return;
1702 if (bd->client.netwm.pid == getpid()) return;
1703 _pri_adj(bd->client.netwm.pid,
1704 e_config->priority, 1, EINA_FALSE,
1705 // EINA_TRUE, EINA_TRUE);
1706 EINA_TRUE, EINA_FALSE);
1707 // printf("WIN: pid %i, title %s (NORMAL)\n",
1708 // bd->client.netwm.pid, e_border_name_get(bd));
1712 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1715 Ecore_Evas *bg_ecore_evas;
1721 bg_ecore_evas = bd->bg_ecore_evas;
1723 /* unregister old frame window */
1724 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1725 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1727 e_focus_setdown(bd);
1728 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1729 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1731 if (bd->icon_object)
1732 evas_object_del(bd->icon_object);
1734 evas_object_del(bd->bg_object);
1735 e_canvas_del(bg_ecore_evas);
1736 ecore_evas_free(bg_ecore_evas);
1739 e_object_del(E_OBJECT(bd->pointer));
1741 /* create new frame */
1743 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1744 bd->x, bd->y, bd->w, bd->h);
1747 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1748 bd->x, bd->y, bd->w, bd->h);
1749 ecore_x_window_shape_events_select(bd->win, 1);
1752 ecore_x_window_configure(bd->win,
1753 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1754 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1756 win, ECORE_X_WINDOW_STACK_BELOW);
1758 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1759 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1762 bd->bg_ecore_evas = e_canvas_new(bd->win,
1763 0, 0, bd->w, bd->h, 1, 0,
1766 e_canvas_add(bd->bg_ecore_evas);
1767 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1769 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1770 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1771 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1773 ecore_x_window_shape_events_select(bd->bg_win, 1);
1775 /* move client with shell win over to new frame */
1776 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1777 bd->client_inset.l, bd->client_inset.t);
1779 bd->pointer = e_pointer_window_new(bd->win, 0);
1781 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1782 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1789 ecore_evas_show(bd->bg_ecore_evas);
1790 ecore_x_window_show(bd->win);
1792 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1793 ecore_x_window_show(tmp->win);
1796 bd->bg_object = edje_object_add(bd->bg_evas);
1797 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1798 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1800 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1802 /* cleanup old frame */
1803 ecore_x_window_free(win);
1807 _e_border_client_move_resize_send(E_Border *bd)
1809 if (bd->internal_ecore_evas)
1810 ecore_evas_managed_move(bd->internal_ecore_evas,
1811 bd->x + bd->fx.x + bd->client_inset.l,
1812 bd->y + bd->fx.y + bd->client_inset.t);
1814 ecore_x_icccm_move_resize_send(bd->client.win,
1815 bd->x + bd->fx.x + bd->client_inset.l,
1816 bd->y + bd->fx.y + bd->client_inset.t,
1822 _e_border_pending_move_resize_add(E_Border *bd,
1829 Eina_Bool without_border,
1830 unsigned int serial)
1832 E_Border_Pending_Move_Resize *pnd;
1834 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1836 pnd->resize = resize;
1838 pnd->without_border = without_border;
1843 pnd->serial = serial;
1844 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1848 _e_border_move_internal(E_Border *bd,
1851 Eina_Bool without_border)
1853 E_Event_Border_Move *ev;
1856 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1858 ecore_x_window_shadow_tree_flush();
1861 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1867 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1869 if (e_config->allow_manip)
1872 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1877 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1882 else if (e_config->allow_manip)
1890 x -= bd->client_inset.l;
1891 y -= bd->client_inset.t;
1893 if (bd->move_intercept_cb)
1896 px = bd->x, py = bd->y;
1897 bd->move_intercept_cb(bd, x, y);
1898 if ((bd->x == px) && (bd->y == py)) return;
1900 else if ((x == bd->x) && (y == bd->y)) return;
1901 bd->pre_res_change.valid = 0;
1905 bd->changes.pos = 1;
1907 if (bd->client.netwm.sync.request)
1909 bd->client.netwm.sync.wait++;
1910 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1913 _e_border_client_move_resize_send(bd);
1914 _e_border_move_update(bd);
1915 ev = E_NEW(E_Event_Border_Move, 1);
1917 e_object_ref(E_OBJECT(bd));
1918 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1919 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1920 _e_border_zone_update(bd);
1924 * Move window to coordinates that already account border decorations.
1926 * This call will consider given position already accounts border
1927 * decorations, so it will not be considered later. This will just
1928 * work properly with borders that have being evaluated and border
1929 * decorations are known (border->client_inset).
1931 * @parm x horizontal position to place window.
1932 * @parm y vertical position to place window.
1934 * @see e_border_move_without_border()
1937 e_border_move(E_Border *bd,
1944 _e_border_move_internal(bd, x, y, 0);
1949 * Set a callback which will be called just prior to updating the
1950 * move coordinates for a border
1953 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1955 bd->move_intercept_cb = cb;
1959 * Move window to coordinates that do not account border decorations yet.
1961 * This call will consider given position does not account border
1962 * decoration, so these values (border->client_inset) will be
1963 * accounted automatically. This is specially useful when it is a new
1964 * client and has not be evaluated yet, in this case
1965 * border->client_inset will be zeroed and no information is known. It
1966 * will mark pending requests so border will be accounted on
1967 * evalutation phase.
1969 * @parm x horizontal position to place window.
1970 * @parm y vertical position to place window.
1972 * @see e_border_move()
1975 e_border_move_without_border(E_Border *bd,
1982 _e_border_move_internal(bd, x, y, 1);
1986 e_border_center(E_Border *bd)
1990 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1992 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1993 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1997 e_border_center_pos_get(E_Border *bd,
2003 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2005 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2006 if (x) *x = zx + (zw - bd->w) / 2;
2007 if (y) *y = zy + (zh - bd->h) / 2;
2011 e_border_fx_offset(E_Border *bd,
2016 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2018 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2022 bd->changes.pos = 1;
2025 if (bd->moving) _e_border_move_update(bd);
2029 _e_border_move_resize_internal(E_Border *bd,
2034 Eina_Bool without_border,
2037 E_Event_Border_Move *mev;
2038 E_Event_Border_Resize *rev;
2041 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2043 ecore_x_window_shadow_tree_flush();
2047 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2053 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2055 if (e_config->allow_manip)
2058 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2064 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2071 if (e_config->allow_manip)
2079 x -= bd->client_inset.l;
2080 y -= bd->client_inset.t;
2081 w += (bd->client_inset.l + bd->client_inset.r);
2082 h += (bd->client_inset.t + bd->client_inset.b);
2085 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2086 (w == bd->w) && (h == bd->h))
2089 bd->pre_res_change.valid = 0;
2092 bd->changes.pos = 1;
2098 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2099 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2101 if ((bd->shaped) || (bd->client.shaped))
2103 bd->need_shape_merge = 1;
2104 bd->need_shape_export = 1;
2106 if (bd->shaped_input)
2108 bd->need_shape_merge = 1;
2111 if (bd->internal_ecore_evas)
2114 bd->changes.size = 1;
2118 if (bdresize && bd->client.netwm.sync.request)
2120 bd->client.netwm.sync.wait++;
2121 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2122 * when no move is intended. The border geometry is set above anyways.
2124 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2125 bd->client.netwm.sync.serial);
2126 ecore_x_netwm_sync_request_send(bd->client.win,
2127 bd->client.netwm.sync.serial++);
2132 bd->changes.size = 1;
2136 _e_border_client_move_resize_send(bd);
2138 _e_border_resize_update(bd);
2141 mev = E_NEW(E_Event_Border_Move, 1);
2143 e_object_ref(E_OBJECT(bd));
2144 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2145 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2148 rev = E_NEW(E_Event_Border_Resize, 1);
2150 e_object_ref(E_OBJECT(bd));
2151 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2152 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2153 _e_border_zone_update(bd);
2157 * Move and resize window to values that already account border decorations.
2159 * This call will consider given values already accounts border
2160 * decorations, so it will not be considered later. This will just
2161 * work properly with borders that have being evaluated and border
2162 * decorations are known (border->client_inset).
2164 * @parm x horizontal position to place window.
2165 * @parm y vertical position to place window.
2166 * @parm w horizontal window size.
2167 * @parm h vertical window size.
2169 * @see e_border_move_resize_without_border()
2172 e_border_move_resize(E_Border *bd,
2181 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2185 * Move and resize window to values that do not account border decorations yet.
2187 * This call will consider given values already accounts border
2188 * decorations, so it will not be considered later. This will just
2189 * work properly with borders that have being evaluated and border
2190 * decorations are known (border->client_inset).
2192 * @parm x horizontal position to place window.
2193 * @parm y vertical position to place window.
2194 * @parm w horizontal window size.
2195 * @parm h vertical window size.
2197 * @see e_border_move_resize()
2200 e_border_move_resize_without_border(E_Border *bd,
2209 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2213 * Resize window to values that already account border decorations.
2215 * This call will consider given size already accounts border
2216 * decorations, so it will not be considered later. This will just
2217 * work properly with borders that have being evaluated and border
2218 * decorations are known (border->client_inset).
2220 * @parm w horizontal window size.
2221 * @parm h vertical window size.
2223 * @see e_border_resize_without_border()
2226 e_border_resize(E_Border *bd,
2233 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2236 #ifdef _F_ZONE_WINDOW_ROTATION_
2238 e_border_rotation_set(E_Border *bd, int rotation)
2240 return _e_border_rotation_set_internal(bd, rotation, NULL);
2245 * Resize window to values that do not account border decorations yet.
2247 * This call will consider given size does not account border
2248 * decoration, so these values (border->client_inset) will be
2249 * accounted automatically. This is specially useful when it is a new
2250 * client and has not be evaluated yet, in this case
2251 * border->client_inset will be zeroed and no information is known. It
2252 * will mark pending requests so border will be accounted on
2253 * evalutation phase.
2255 * @parm w horizontal window size.
2256 * @parm h vertical window size.
2258 * @see e_border_resize()
2261 e_border_resize_without_border(E_Border *bd,
2268 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2272 e_border_layer_set(E_Border *bd,
2278 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2280 ecore_x_window_shadow_tree_flush();
2282 oldraise = e_config->transient.raise;
2286 bd->saved.layer = layer;
2290 if (e_config->transient.layer)
2294 Eina_List *list = _e_border_sub_borders_new(bd);
2296 /* We need to set raise to one, else the child wont
2297 * follow to the new layer. It should be like this,
2298 * even if the user usually doesn't want to raise
2301 e_config->transient.raise = 1;
2302 EINA_LIST_FOREACH(list, l, child)
2304 e_border_layer_set(child, layer);
2308 e_config->transient.raise = oldraise;
2312 e_border_raise(E_Border *bd)
2314 E_Event_Border_Stack *ev;
2315 E_Border *last = NULL, *child;
2319 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2321 ecore_x_window_shadow_tree_flush();
2323 if (e_config->transient.raise)
2325 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2326 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2329 Eina_List *list = _e_border_sub_borders_new(bd);
2331 EINA_LIST_REVERSE_FOREACH(list, l, child)
2333 /* Don't stack iconic transients. If the user wants these shown,
2334 * thats another option.
2339 e_border_stack_below(child, last);
2344 /* First raise the border to find out which border we will end up above */
2345 above = e_container_border_raise(child);
2349 /* We ended up above a border, now we must stack this border to
2350 * generate the stacking event, and to check if this transient
2351 * has other transients etc.
2353 e_border_stack_above(child, above);
2357 /* If we didn't end up above any border, we are on the bottom! */
2358 e_border_lower(child);
2364 eina_list_free(list);
2365 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2369 EINA_LIST_FOREACH(bd->transients, l, child)
2371 /* Don't stack iconic transients. If the user wants these shown,
2372 * thats another option.
2376 child->layer = bd->layer;
2377 if (!last) last = child;
2378 e_border_raise (child);
2385 ev = E_NEW(E_Event_Border_Stack, 1);
2387 e_object_ref(E_OBJECT(bd));
2391 e_container_border_stack_below(bd, last);
2393 e_object_ref(E_OBJECT(last));
2394 ev->type = E_STACKING_BELOW;
2400 /* If we don't have any children, raise this border */
2401 above = e_container_border_raise(bd);
2402 e_border_raise_latest_set(bd);
2405 /* We ended up above a border */
2407 e_object_ref(E_OBJECT(above));
2408 ev->type = E_STACKING_ABOVE;
2412 /* No border to raise above, same as a lower! */
2414 ev->type = E_STACKING_ABOVE;
2418 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2419 e_remember_update(bd);
2423 e_border_lower(E_Border *bd)
2425 E_Event_Border_Stack *ev;
2426 E_Border *last = NULL, *child;
2430 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2432 ecore_x_window_shadow_tree_flush();
2434 if (e_config->transient.lower)
2436 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2437 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2440 Eina_List *list = _e_border_sub_borders_new(bd);
2442 EINA_LIST_REVERSE_FOREACH(list, l, child)
2444 /* Don't stack iconic transients. If the user wants these shown,
2445 * thats another option.
2450 e_border_stack_below(child, last);
2455 /* First lower the border to find out which border we will end up below */
2456 below = e_container_border_lower(child);
2460 /* We ended up below a border, now we must stack this border to
2461 * generate the stacking event, and to check if this transient
2462 * has other transients etc.
2464 e_border_stack_below(child, below);
2468 /* If we didn't end up below any border, we are on top! */
2469 e_border_raise(child);
2475 eina_list_free(list);
2477 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2481 EINA_LIST_FOREACH(bd->transients, l, child)
2483 /* Don't stack iconic transients. If the user wants these shown,
2484 * thats another option.
2488 child->layer = bd->layer;
2489 e_border_lower (child);
2497 ev = E_NEW(E_Event_Border_Stack, 1);
2499 e_object_ref(E_OBJECT(bd));
2503 e_container_border_stack_below(bd, last);
2505 e_object_ref(E_OBJECT(last));
2506 ev->type = E_STACKING_BELOW;
2512 /* If we don't have any children, lower this border */
2513 below = e_container_border_lower(bd);
2516 /* We ended up below a border */
2518 e_object_ref(E_OBJECT(below));
2519 ev->type = E_STACKING_BELOW;
2523 /* No border to hide under, same as a raise! */
2525 ev->type = E_STACKING_BELOW;
2529 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2530 e_remember_update(bd);
2534 e_border_stack_above(E_Border *bd,
2537 /* TODO: Should stack above allow the border to change level */
2538 E_Event_Border_Stack *ev;
2539 E_Border *last = NULL, *child;
2543 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2545 ecore_x_window_shadow_tree_flush();
2547 if (e_config->transient.raise)
2549 Eina_List *list = _e_border_sub_borders_new(bd);
2551 EINA_LIST_REVERSE_FOREACH(list, l, child)
2553 /* Don't stack iconic transients. If the user wants these shown,
2554 * thats another option.
2559 e_border_stack_below(child, last);
2561 e_border_stack_above(child, above);
2565 eina_list_free(list);
2568 ev = E_NEW(E_Event_Border_Stack, 1);
2570 e_object_ref(E_OBJECT(bd));
2574 e_container_border_stack_below(bd, last);
2576 e_object_ref(E_OBJECT(last));
2577 ev->type = E_STACKING_BELOW;
2581 e_container_border_stack_above(bd, above);
2583 e_object_ref(E_OBJECT(above));
2584 ev->type = E_STACKING_ABOVE;
2587 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2588 e_remember_update(bd);
2592 e_border_stack_below(E_Border *bd,
2595 /* TODO: Should stack below allow the border to change level */
2596 E_Event_Border_Stack *ev;
2597 E_Border *last = NULL, *child;
2601 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2603 ecore_x_window_shadow_tree_flush();
2605 if (e_config->transient.lower)
2607 Eina_List *list = _e_border_sub_borders_new(bd);
2609 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2611 /* Don't stack iconic transients. If the user wants these shown,
2612 * thats another option.
2617 e_border_stack_below(child, last);
2619 e_border_stack_below(child, below);
2623 eina_list_free(list);
2626 ev = E_NEW(E_Event_Border_Stack, 1);
2628 e_object_ref(E_OBJECT(bd));
2632 e_container_border_stack_below(bd, last);
2634 e_object_ref(E_OBJECT(last));
2635 ev->type = E_STACKING_BELOW;
2639 e_container_border_stack_below(bd, below);
2641 e_object_ref(E_OBJECT(below));
2642 ev->type = E_STACKING_BELOW;
2645 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2646 e_remember_update(bd);
2650 e_border_focus_latest_set(E_Border *bd)
2652 focus_stack = eina_list_remove(focus_stack, bd);
2653 focus_stack = eina_list_prepend(focus_stack, bd);
2657 e_border_raise_latest_set(E_Border *bd)
2659 raise_stack = eina_list_remove(raise_stack, bd);
2660 raise_stack = eina_list_prepend(raise_stack, bd);
2664 * Sets the focus to the given border if necessary
2665 * There are 3 cases of different focus_policy-configurations:
2667 * - E_FOCUS_CLICK: just set the focus, the most simple one
2669 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2670 * warp the pointer to the window. If this fails (because
2671 * the pointer is already in the window), just set the focus.
2673 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2674 * last window which was focused, if the mouse is on the
2675 * desktop. So, we need to look if there is another window
2676 * under the pointer and warp to pointer to the right
2677 * one if so (also, we set the focus afterwards). In case
2678 * there is no window under pointer, the pointer is on the
2679 * desktop and so we just set the focus.
2682 * This function is to be called when setting the focus was not
2683 * explicitly triggered by the user (by moving the mouse or
2684 * clicking for example), but implicitly (by closing a window,
2685 * the last focused window should get focus).
2689 e_border_focus_set_with_pointer(E_Border *bd)
2691 #ifdef PRINT_LOTS_OF_DEBUG
2692 E_PRINT_BORDER_INFO(bd);
2694 /* note: this is here as it seems there are enough apps that do not even
2695 * expect us to emulate a look of focus but not actually set x input
2696 * focus as we do - so simply abort any focuse set on such windows */
2697 /* be strict about accepting focus hint */
2698 if ((!bd->client.icccm.accepts_focus) &&
2699 (!bd->client.icccm.take_focus)) return;
2700 if (bd->lock_focus_out) return;
2702 e_border_focus_set(bd, 1, 1);
2704 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2705 if (!bd->visible) return;
2707 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2709 if (!e_border_under_pointer_get(bd->desk, bd))
2711 e_border_pointer_warp_to_center(bd);
2716 e_border_pointer_warp_to_center(bd);
2721 e_border_focus_set(E_Border *bd,
2725 E_Border *bd_unfocus = NULL;
2726 Eina_Bool focus_changed = EINA_FALSE;
2729 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2730 /* note: this is here as it seems there are enough apps that do not even
2731 * expect us to emulate a look of focus but not actually set x input
2732 * focus as we do - so simply abort any focuse set on such windows */
2733 /* be strict about accepting focus hint */
2734 if ((!bd->client.icccm.accepts_focus) &&
2735 (!bd->client.icccm.take_focus))
2737 if ((set) && (focus) && (bd->lock_focus_out)) return;
2739 /* dont focus an iconified window. that's silly! */
2744 e_border_uniconify(bd);
2745 if (!focus_track_frozen)
2746 e_border_focus_latest_set(bd);
2749 else if (!bd->visible)
2753 /* FIXME: hack for deskflip animation:
2754 * dont update focus when sliding previous desk */
2755 else if ((!bd->sticky) &&
2756 (bd->desk != e_desk_current_get(bd->desk->zone)))
2762 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2764 e_border_focus_set(bd->modal, focus, set);
2767 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2769 e_border_focus_set(bd->leader->modal, focus, set);
2777 if (bd->visible && bd->changes.visible)
2782 else if ((!bd->focused) ||
2783 (focus_next && (bd != eina_list_data_get(focus_next))))
2787 if ((l = eina_list_data_find_list(focus_next, bd)))
2788 focus_next = eina_list_promote_list(focus_next, l);
2790 focus_next = eina_list_prepend(focus_next, bd);
2792 if ((bd->client.icccm.take_focus) &&
2793 (bd->client.icccm.accepts_focus))
2795 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2796 /* TODO what if the client didn't take focus ? */
2798 else if (!bd->client.icccm.accepts_focus)
2800 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2802 else if (!bd->client.icccm.take_focus)
2804 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2805 /* e_border_focus_set(bd, 1, 0); */
2815 if (focused) bd_unfocus = focused;
2816 if (focusing == bd) focusing = NULL;
2821 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2823 if ((bd2->fullscreen) &&
2825 (bd2->zone == bd->zone) &&
2826 ((bd2->desk == bd->desk) ||
2827 (bd2->sticky) || (bd->sticky)))
2829 Eina_Bool unfocus_is_parent = EINA_FALSE;
2830 E_Border *bd_parent;
2832 bd_parent = bd->parent;
2835 if (bd_parent == bd2)
2837 unfocus_is_parent = EINA_TRUE;
2840 bd_parent = bd->parent;
2842 if ((!unfocus_is_parent) &&
2843 (!e_config->allow_above_fullscreen))
2845 e_border_iconify(bd2);
2850 focus_changed = EINA_TRUE;
2856 focus_next = eina_list_remove(focus_next, bd);
2857 if (bd == focusing) focusing = NULL;
2859 if ((bd->focused) &&
2860 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2862 Eina_Bool wasfocused = EINA_FALSE;
2865 /* should always be the case. anyway */
2869 wasfocused = EINA_TRUE;
2872 if ((set) && (!focus_next) && (!focusing))
2874 e_grabinput_focus(bd->zone->container->bg_win,
2875 E_FOCUS_METHOD_PASSIVE);
2877 if ((bd->fullscreen) && (wasfocused))
2879 Eina_Bool have_vis_child = EINA_FALSE;
2883 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2886 (bd2->zone == bd->zone) &&
2887 ((bd2->desk == bd->desk) ||
2888 (bd2->sticky) || (bd->sticky)))
2890 if (bd2->parent == bd)
2892 have_vis_child = EINA_TRUE;
2897 if ((!have_vis_child) &&
2898 (!e_config->allow_above_fullscreen))
2899 e_border_iconify(bd);
2905 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2906 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2908 E_Event_Border_Focus_Out *ev;
2910 bd_unfocus->focused = 0;
2911 e_focus_event_focus_out(bd_unfocus);
2913 if (bd_unfocus->raise_timer)
2914 ecore_timer_del(bd_unfocus->raise_timer);
2915 bd_unfocus->raise_timer = NULL;
2917 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2918 if (bd_unfocus->icon_object)
2919 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2921 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2922 ev->border = bd_unfocus;
2923 e_object_ref(E_OBJECT(bd_unfocus));
2925 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2926 _e_border_event_border_focus_out_free, NULL);
2927 if ((bd_unfocus->fullscreen) &&
2928 (bd != bd_unfocus) &&
2929 (bd->zone == bd_unfocus->zone) &&
2930 ((bd->desk == bd_unfocus->desk) ||
2931 (bd->sticky) || (bd_unfocus->sticky)))
2933 Eina_Bool unfocus_is_parent = EINA_FALSE;
2934 E_Border *bd_parent;
2936 bd_parent = bd->parent;
2939 if (bd_parent == bd_unfocus)
2941 unfocus_is_parent = EINA_TRUE;
2944 bd_parent = bd->parent;
2946 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2948 e_border_iconify(bd_unfocus);
2955 E_Event_Border_Focus_In *ev;
2957 e_focus_event_focus_in(bd);
2959 if (!focus_track_frozen)
2960 e_border_focus_latest_set(bd);
2962 e_hints_active_window_set(bd->zone->container->manager, bd);
2964 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2965 if (bd->icon_object)
2966 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2968 ev = E_NEW(E_Event_Border_Focus_In, 1);
2970 e_object_ref(E_OBJECT(bd));
2972 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2973 _e_border_event_border_focus_in_free, NULL);
2978 e_border_shade(E_Border *bd,
2981 E_Event_Border_Resize *ev;
2986 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2987 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2988 ((bd->maximized) && (!e_config->allow_manip))) return;
2989 if ((bd->client.border.name) &&
2990 (!strcmp("borderless", bd->client.border.name))) return;
2992 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2993 ecore_x_window_hide(tmp->win);
2995 ecore_x_window_shadow_tree_flush();
2997 bd->shade.x = bd->x;
2998 bd->shade.y = bd->y;
2999 bd->shade.dir = dir;
3001 e_hints_window_shaded_set(bd, 1);
3002 e_hints_window_shade_direction_set(bd, dir);
3004 if (e_config->border_shade_animate)
3006 bd->shade.start = ecore_loop_time_get();
3008 bd->changes.shading = 1;
3011 if (bd->shade.dir == E_DIRECTION_UP ||
3012 bd->shade.dir == E_DIRECTION_LEFT)
3013 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3015 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3017 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3018 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3022 if (bd->shade.dir == E_DIRECTION_UP)
3024 bd->h = bd->client_inset.t + bd->client_inset.b;
3026 else if (bd->shade.dir == E_DIRECTION_DOWN)
3028 bd->h = bd->client_inset.t + bd->client_inset.b;
3029 bd->y = bd->y + bd->client.h;
3030 bd->changes.pos = 1;
3032 else if (bd->shade.dir == E_DIRECTION_LEFT)
3034 bd->w = bd->client_inset.l + bd->client_inset.r;
3036 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3038 bd->w = bd->client_inset.l + bd->client_inset.r;
3039 bd->x = bd->x + bd->client.w;
3040 bd->changes.pos = 1;
3043 if ((bd->shaped) || (bd->client.shaped))
3045 bd->need_shape_merge = 1;
3046 bd->need_shape_export = 1;
3048 if (bd->shaped_input)
3050 bd->need_shape_merge = 1;
3053 bd->changes.size = 1;
3055 bd->changes.shaded = 1;
3057 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3058 e_border_frame_recalc(bd);
3059 ev = E_NEW(E_Event_Border_Resize, 1);
3061 /* The resize is added in the animator when animation complete */
3062 /* For non-animated, we add it immediately with the new size */
3063 e_object_ref(E_OBJECT(bd));
3064 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3065 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3068 e_remember_update(bd);
3072 e_border_unshade(E_Border *bd,
3075 E_Event_Border_Resize *ev;
3080 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3081 if ((!bd->shaded) || (bd->shading))
3084 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3085 ecore_x_window_show(tmp->win);
3087 ecore_x_window_shadow_tree_flush();
3089 bd->shade.dir = dir;
3091 e_hints_window_shaded_set(bd, 0);
3092 e_hints_window_shade_direction_set(bd, dir);
3094 if (bd->shade.dir == E_DIRECTION_UP ||
3095 bd->shade.dir == E_DIRECTION_LEFT)
3097 bd->shade.x = bd->x;
3098 bd->shade.y = bd->y;
3102 bd->shade.x = bd->x - bd->client.w;
3103 bd->shade.y = bd->y - bd->client.h;
3105 if (e_config->border_shade_animate)
3107 bd->shade.start = ecore_loop_time_get();
3109 bd->changes.shading = 1;
3112 if (bd->shade.dir == E_DIRECTION_UP)
3114 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3115 ecore_x_window_move_resize(bd->client.win, 0,
3116 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3118 bd->client.w, bd->client.h);
3120 else if (bd->shade.dir == E_DIRECTION_LEFT)
3122 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3123 ecore_x_window_move_resize(bd->client.win,
3124 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3126 0, bd->client.w, bd->client.h);
3129 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3131 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3132 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3136 if (bd->shade.dir == E_DIRECTION_UP)
3138 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3140 else if (bd->shade.dir == E_DIRECTION_DOWN)
3142 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3143 bd->y = bd->y - bd->client.h;
3144 bd->changes.pos = 1;
3146 else if (bd->shade.dir == E_DIRECTION_LEFT)
3148 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3150 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3152 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3153 bd->x = bd->x - bd->client.w;
3154 bd->changes.pos = 1;
3156 if ((bd->shaped) || (bd->client.shaped))
3158 bd->need_shape_merge = 1;
3159 bd->need_shape_export = 1;
3161 if (bd->shaped_input)
3163 bd->need_shape_merge = 1;
3166 bd->changes.size = 1;
3168 bd->changes.shaded = 1;
3170 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3171 e_border_frame_recalc(bd);
3172 ev = E_NEW(E_Event_Border_Resize, 1);
3174 /* The resize is added in the animator when animation complete */
3175 /* For non-animated, we add it immediately with the new size */
3176 e_object_ref(E_OBJECT(bd));
3177 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3178 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3181 e_remember_update(bd);
3185 _e_border_client_inset_calc(E_Border *bd)
3188 Evas_Coord cx, cy, cw, ch;
3192 evas_object_resize(bd->bg_object, 1000, 1000);
3193 edje_object_message_signal_process(bd->bg_object);
3194 edje_object_calc_force(bd->bg_object);
3195 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3196 bd->client_inset.l = cx;
3197 bd->client_inset.r = 1000 - (cx + cw);
3198 bd->client_inset.t = cy;
3199 bd->client_inset.b = 1000 - (cy + ch);
3203 bd->client_inset.l = 0;
3204 bd->client_inset.r = 0;
3205 bd->client_inset.t = 0;
3206 bd->client_inset.b = 0;
3209 ecore_x_netwm_frame_size_set(bd->client.win,
3210 bd->client_inset.l, bd->client_inset.r,
3211 bd->client_inset.t, bd->client_inset.b);
3212 ecore_x_e_frame_size_set(bd->client.win,
3213 bd->client_inset.l, bd->client_inset.r,
3214 bd->client_inset.t, bd->client_inset.b);
3218 _e_border_maximize(E_Border *bd, E_Maximize max)
3220 int x1, yy1, x2, y2;
3223 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3227 zx = zy = zw = zh = 0;
3229 switch (max & E_MAXIMIZE_TYPE)
3231 case E_MAXIMIZE_NONE:
3235 case E_MAXIMIZE_FULLSCREEN:
3241 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3242 _e_border_client_inset_calc(bd);
3244 e_border_resize_limit(bd, &w, &h);
3245 /* center x-direction */
3246 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3247 /* center y-direction */
3248 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3250 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3251 cy = bd->zone->y + (bd->zone->h / 2);
3254 switch (max & E_MAXIMIZE_DIRECTION)
3256 case E_MAXIMIZE_BOTH:
3257 e_border_move_resize(bd, x1, yy1, w, h);
3260 case E_MAXIMIZE_VERTICAL:
3261 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3264 case E_MAXIMIZE_HORIZONTAL:
3265 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3268 case E_MAXIMIZE_LEFT:
3269 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3272 case E_MAXIMIZE_RIGHT:
3273 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3275 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3276 case E_MAXIMIZE_TOP:
3277 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3279 case E_MAXIMIZE_BOTTOM:
3280 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3286 case E_MAXIMIZE_SMART:
3287 case E_MAXIMIZE_EXPAND:
3289 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3301 if (bd->x < zx) // window left not useful coordinates
3303 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3304 x1 = zx + zw - bd->w;
3305 else // window normal position
3308 if (bd->y < zy) // window top not useful coordinates
3310 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3311 yy1 = zy + zh - bd->h;
3312 else // window normal position
3315 switch (max & E_MAXIMIZE_DIRECTION)
3317 case E_MAXIMIZE_BOTH:
3318 e_border_move_resize(bd, zx, zy, zw, zh);
3321 case E_MAXIMIZE_VERTICAL:
3322 e_border_move_resize(bd, x1, zy, w, zh);
3325 case E_MAXIMIZE_HORIZONTAL:
3326 e_border_move_resize(bd, zx, yy1, zw, h);
3329 case E_MAXIMIZE_LEFT:
3330 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3333 case E_MAXIMIZE_RIGHT:
3334 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3338 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3341 case E_MAXIMIZE_FILL:
3344 x2 = bd->zone->x + bd->zone->w;
3345 y2 = bd->zone->y + bd->zone->h;
3347 /* walk through all shelves */
3348 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3350 /* walk through all windows */
3351 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3357 e_border_resize_limit(bd, &w, &h);
3358 /* center x-direction */
3359 x1 = x1 + (pw - w) / 2;
3360 /* center y-direction */
3361 yy1 = yy1 + (ph - h) / 2;
3363 switch (max & E_MAXIMIZE_DIRECTION)
3365 case E_MAXIMIZE_BOTH:
3366 e_border_move_resize(bd, x1, yy1, w, h);
3369 case E_MAXIMIZE_VERTICAL:
3370 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3373 case E_MAXIMIZE_HORIZONTAL:
3374 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3377 case E_MAXIMIZE_LEFT:
3378 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3381 case E_MAXIMIZE_RIGHT:
3382 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3390 e_border_maximize(E_Border *bd,
3394 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3396 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3398 if ((bd->shaded) || (bd->shading)) return;
3399 ecore_x_window_shadow_tree_flush();
3401 e_border_unfullscreen(bd);
3402 /* Only allow changes in vertical/ horizontal maximization */
3403 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3404 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3407 bd->need_maximize = 1;
3408 bd->maximized &= ~E_MAXIMIZE_TYPE;
3409 bd->maximized |= max;
3413 bd->pre_res_change.valid = 0;
3414 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3416 /* Horizontal hasn't been set */
3417 bd->saved.x = bd->x - bd->zone->x;
3418 bd->saved.w = bd->w;
3420 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3422 /* Vertical hasn't been set */
3423 bd->saved.y = bd->y - bd->zone->y;
3424 bd->saved.h = bd->h;
3427 bd->saved.zone = bd->zone->num;
3428 e_hints_window_size_set(bd);
3432 _e_border_maximize(bd, max);
3435 /* Remove previous type */
3436 bd->maximized &= ~E_MAXIMIZE_TYPE;
3437 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3438 bd->maximized |= max;
3440 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3441 bd->maximized & E_MAXIMIZE_VERTICAL);
3442 e_remember_update(bd);
3446 e_border_unmaximize(E_Border *bd,
3450 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3451 if (!(max & E_MAXIMIZE_DIRECTION))
3453 CRI("BUG: Unmaximize call without direction!");
3457 if ((bd->shaded) || (bd->shading)) return;
3458 ecore_x_window_shadow_tree_flush();
3459 /* Remove directions not used */
3460 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3461 /* Can only remove existing maximization directions */
3463 if (bd->maximized & E_MAXIMIZE_TYPE)
3465 bd->pre_res_change.valid = 0;
3466 bd->need_maximize = 0;
3468 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3472 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3473 _e_border_client_inset_calc(bd);
3476 bd->maximized = E_MAXIMIZE_NONE;
3477 _e_border_move_resize_internal(bd,
3478 bd->zone->x + bd->saved.x,
3479 bd->zone->y + bd->saved.y,
3480 bd->saved.w, bd->saved.h, 0, 1);
3481 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3482 e_hints_window_size_unset(bd);
3493 if (max & E_MAXIMIZE_VERTICAL)
3495 /* Remove vertical */
3497 y = bd->saved.y + bd->zone->y;
3498 bd->saved.h = bd->saved.y = 0;
3499 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3500 bd->maximized &= ~E_MAXIMIZE_LEFT;
3501 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3503 if (max & E_MAXIMIZE_HORIZONTAL)
3505 /* Remove horizontal */
3507 x = bd->saved.x + bd->zone->x;
3508 bd->saved.w = bd->saved.x = 0;
3509 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3512 e_border_resize_limit(bd, &w, &h);
3514 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3516 bd->maximized = E_MAXIMIZE_NONE;
3517 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3518 e_hints_window_size_unset(bd);
3519 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3523 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3524 e_hints_window_size_set(bd);
3527 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3528 bd->maximized & E_MAXIMIZE_VERTICAL);
3530 e_remember_update(bd);
3534 e_border_fullscreen(E_Border *bd,
3535 E_Fullscreen policy)
3537 E_Event_Border_Fullscreen *ev;
3540 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3542 if ((bd->shaded) || (bd->shading)) return;
3543 ecore_x_window_shadow_tree_flush();
3546 bd->need_fullscreen = 1;
3549 if (!bd->fullscreen)
3551 bd->pre_res_change.valid = 0;
3553 bd->saved.x = bd->x - bd->zone->x;
3554 bd->saved.y = bd->y - bd->zone->y;
3555 bd->saved.w = bd->client.w;
3556 bd->saved.h = bd->client.h;
3557 bd->saved.maximized = bd->maximized;
3558 bd->saved.zone = bd->zone->num;
3561 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3562 e_hints_window_size_set(bd);
3564 bd->client_inset.l = 0;
3565 bd->client_inset.r = 0;
3566 bd->client_inset.t = 0;
3567 bd->client_inset.b = 0;
3569 bd->desk->fullscreen_borders++;
3571 /* e_zone_fullscreen_set(bd->zone, 1); */
3572 bd->saved.layer = bd->layer;
3573 if (!e_config->allow_above_fullscreen)
3574 e_border_layer_set(bd, 250);
3576 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3577 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3579 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3581 else if (policy == E_FULLSCREEN_ZOOM)
3583 Ecore_X_Randr_Screen_Size_MM *sizes;
3584 int num_sizes, i, best_size_index = 0;
3586 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3588 &screen_size.height,
3590 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3594 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3595 int best_dist = INT_MAX, dist;
3597 for (i = 0; i < num_sizes; i++)
3599 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3601 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3602 if (dist < best_dist)
3604 best_size.width = sizes[i].width;
3605 best_size.height = sizes[i].height;
3607 best_size_index = i;
3611 if (((best_size.width != -1) && (best_size.height != -1)) &&
3612 ((best_size.width != screen_size.width) ||
3613 (best_size.height != screen_size.height)))
3615 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3617 screen_size_index = best_size_index;
3618 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3622 screen_size.width = -1;
3623 screen_size.height = -1;
3624 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3629 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3633 e_hints_window_fullscreen_set(bd, 1);
3634 e_hints_window_size_unset(bd);
3635 bd->client.border.changed = 1;
3638 bd->fullscreen_policy = policy;
3640 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3642 e_object_ref(E_OBJECT(bd));
3643 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3644 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3646 e_remember_update(bd);
3650 e_border_unfullscreen(E_Border *bd)
3652 E_Event_Border_Unfullscreen *ev;
3655 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3656 if ((bd->shaded) || (bd->shading)) return;
3657 ecore_x_window_shadow_tree_flush();
3660 bd->pre_res_change.valid = 0;
3662 bd->need_fullscreen = 0;
3663 bd->desk->fullscreen_borders--;
3665 if ((screen_size.width != -1) && (screen_size.height != -1))
3667 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3669 screen_size.width = -1;
3670 screen_size.height = -1;
3672 e_border_move_resize(bd,
3673 bd->saved.x + bd->zone->x,
3674 bd->saved.y + bd->zone->y,
3675 bd->saved.w, bd->saved.h);
3677 if (bd->saved.maximized)
3678 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3679 bd->saved.maximized);
3681 e_border_layer_set(bd, bd->saved.layer);
3683 e_hints_window_fullscreen_set(bd, 0);
3684 bd->client.border.changed = 1;
3687 bd->fullscreen_policy = 0;
3689 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3691 e_object_ref(E_OBJECT(bd));
3692 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3693 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3695 e_remember_update(bd);
3699 e_border_iconify(E_Border *bd)
3701 E_Event_Border_Iconify *ev;
3702 unsigned int iconic;
3705 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3706 if (bd->shading) return;
3707 ecore_x_window_shadow_tree_flush();
3711 e_border_hide(bd, 1);
3712 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3713 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3716 e_hints_window_iconic_set(bd);
3717 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3719 ev = E_NEW(E_Event_Border_Iconify, 1);
3721 e_object_ref(E_OBJECT(bd));
3722 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3723 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3725 if (e_config->transient.iconify)
3729 Eina_List *list = _e_border_sub_borders_new(bd);
3731 EINA_LIST_FOREACH(list, l, child)
3733 e_border_iconify(child);
3735 eina_list_free(list);
3737 e_remember_update(bd);
3740 #ifdef _F_DEICONIFY_APPROVE_
3742 _e_border_uniconify_timeout(void *data)
3749 if (!e_object_is_del(E_OBJECT(bd)))
3751 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3752 bd->client.e.state.deiconify_approve.render_done = 1;
3753 if (bd->client.e.state.deiconify_approve.req_list)
3755 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3757 child_bd->client.e.state.deiconify_approve.render_done = 1;
3758 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3761 bd->client.e.state.deiconify_approve.req_list = NULL;
3762 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3763 e_border_uniconify(bd);
3766 return ECORE_CALLBACK_CANCEL;
3770 _e_border_deiconify_approve_send_pending_end(void *data)
3772 E_Border *bd = (E_Border *)data;
3773 E_Border *bd_ancestor;
3775 if (e_config->deiconify_approve)
3777 if (!e_object_is_del(E_OBJECT(bd)))
3779 bd->client.e.state.deiconify_approve.pending_job = NULL;
3781 ELBF(ELBT_BD, 0, bd->client.win,
3782 "SEND DEICONIFY_APPROVE. (PENDING_END) ancestor:%x",
3785 ecore_x_client_message32_send(bd->client.win,
3786 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3787 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3788 bd->client.win, 0, 0, 0, 0);
3789 bd_ancestor = bd->client.e.state.deiconify_approve.ancestor;
3792 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, bd);
3795 if (!bd->client.e.state.deiconify_approve.wait_timer)
3796 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3802 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor, Eina_Bool pending_ancestor)
3804 if (!bd || !bd_ancestor) return;
3806 if (e_config->deiconify_approve)
3808 if (e_config->transient.iconify)
3812 Eina_List *list = _e_border_sub_borders_new(bd);
3813 EINA_LIST_FOREACH(list, l, child)
3815 Eina_Bool pending = EINA_FALSE;
3816 Eina_Bool p = EINA_FALSE;
3818 #ifdef _F_ZONE_WINDOW_ROTATION_
3819 if ((e_config->wm_win_rotation) &&
3820 ((child->client.e.state.rot.support) ||
3821 (child->client.e.state.rot.app_set)))
3823 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3824 int rotation = _e_border_rotation_angle_get(bd);
3825 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3828 if ((pending_ancestor) || (pending)) p = EINA_TRUE;
3830 _e_border_deiconify_approve_send(child, bd_ancestor, p);
3831 if (child->client.e.state.deiconify_approve.support)
3835 ELBF(ELBT_BD, 0, child->client.win,
3836 "SEND DEICONIFY_APPROVE. ancestor:%x pending(%d,%d)",
3837 bd_ancestor->client.win,
3838 pending_ancestor, pending);
3840 ecore_x_client_message32_send(child->client.win,
3841 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3842 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3843 child->client.win, 0, 0, 0, 0);
3844 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3845 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3849 /* queue a deiconify send job to give the chance to other jobs */
3850 ELBF(ELBT_BD, 0, child->client.win,
3851 "SEND DEICONIFY_APPROVE. (PENDING) ancestor:%x",
3852 bd_ancestor->client.win);
3853 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3854 child->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, child);
3858 eina_list_free(list);
3864 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3866 Eina_Bool pending = EINA_FALSE;
3868 if (e_config->deiconify_approve)
3870 #ifdef _F_ZONE_WINDOW_ROTATION_
3871 if ((e_config->wm_win_rotation) &&
3872 ((bd->client.e.state.rot.support) ||
3873 (bd->client.e.state.rot.app_set)))
3875 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3876 int rotation = _e_border_rotation_angle_get(bd);
3877 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3881 if (e_config->transient.iconify)
3883 _e_border_deiconify_approve_send(bd, bd, pending);
3886 if (bd->client.e.state.deiconify_approve.support)
3890 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE.");
3891 ecore_x_client_message32_send(bd->client.win,
3892 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3893 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3894 bd->client.win, 0, 0, 0, 0);
3895 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3899 /* queue a deiconify send job to give the chance to other jobs */
3900 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE. (PENDING)");
3901 bd->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, bd);
3909 e_border_uniconify(E_Border *bd)
3912 E_Event_Border_Uniconify *ev;
3913 unsigned int iconic;
3916 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3918 #ifdef _F_DEICONIFY_APPROVE_
3919 if (e_config->deiconify_approve)
3921 if (bd->client.e.state.deiconify_approve.support)
3923 if (bd->client.e.state.deiconify_approve.wait_timer)
3925 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3929 if (bd->client.e.state.deiconify_approve.pending_job)
3931 ELB(ELBT_BD, "DEICONIFY_APPROVE PENDING_JOB is already running", bd->client.win);
3935 if (bd->client.e.state.deiconify_approve.render_done == 0)
3937 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3938 _e_border_deiconify_approve_send_all_transient(bd);
3942 bd->client.e.state.deiconify_approve.render_done = 0;
3946 #if _F_ZONE_WINDOW_ROTATION_
3947 if (!bd->client.win)
3949 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3954 if (bd->shading) return;
3955 ecore_x_window_shadow_tree_flush();
3960 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3961 desk = e_desk_current_get(bd->desk->zone);
3962 #ifdef _F_USE_EXTENDED_ICONIFY_
3963 if (e_manager_comp_evas_get(bd->zone->container->manager))
3965 if (bd->await_hide_event > 0)
3966 bd->await_hide_event--;
3969 e_border_desk_set(bd, desk);
3971 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3974 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3976 ev = E_NEW(E_Event_Border_Uniconify, 1);
3978 e_object_ref(E_OBJECT(bd));
3979 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3980 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3982 if (e_config->transient.iconify)
3986 Eina_List *list = _e_border_sub_borders_new(bd);
3988 EINA_LIST_FOREACH(list, l, child)
3990 e_border_uniconify(child);
3992 eina_list_free(list);
3994 e_remember_update(bd);
3998 e_border_stick(E_Border *bd)
4000 E_Event_Border_Stick *ev;
4003 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4004 if (bd->sticky) return;
4006 e_hints_window_sticky_set(bd, 1);
4009 if (e_config->transient.desktop)
4013 Eina_List *list = _e_border_sub_borders_new(bd);
4015 EINA_LIST_FOREACH(list, l, child)
4018 e_hints_window_sticky_set(child, 1);
4019 e_border_show(child);
4021 eina_list_free(list);
4024 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
4025 ev = E_NEW(E_Event_Border_Stick, 1);
4027 e_object_ref(E_OBJECT(bd));
4028 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
4029 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
4030 e_remember_update(bd);
4034 e_border_unstick(E_Border *bd)
4036 E_Event_Border_Unstick *ev;
4039 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4040 /* Set the desk before we unstick the border */
4041 if (!bd->sticky) return;
4043 e_hints_window_sticky_set(bd, 0);
4045 if (e_config->transient.desktop)
4049 Eina_List *list = _e_border_sub_borders_new(bd);
4051 EINA_LIST_FOREACH(list, l, child)
4054 e_hints_window_sticky_set(child, 0);
4056 eina_list_free(list);
4059 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
4060 ev = E_NEW(E_Event_Border_Unstick, 1);
4062 e_object_ref(E_OBJECT(bd));
4063 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
4064 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
4066 e_border_desk_set(bd, e_desk_current_get(bd->zone));
4067 e_remember_update(bd);
4071 e_border_pinned_set(E_Border *bd,
4079 bd->borderless = set;
4080 bd->user_skip_winlist = set;
4084 stacking = E_STACKING_BELOW;
4089 stacking = E_STACKING_NONE;
4092 e_border_layer_set(bd, layer);
4093 e_hints_window_stacking_set(bd, stacking);
4095 bd->client.border.changed = 1;
4101 e_border_find_by_client_window(Ecore_X_Window win)
4105 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4106 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4107 (bd->client.win == win))
4113 e_border_find_all_by_client_window(Ecore_X_Window win)
4117 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4118 if ((bd) && (bd->client.win == win))
4124 e_border_find_by_frame_window(Ecore_X_Window win)
4128 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4129 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4130 (bd->bg_win == win))
4136 e_border_find_by_window(Ecore_X_Window win)
4140 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4141 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4148 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4153 EINA_LIST_FOREACH(borders, l, bd)
4155 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4156 (bd->client.netwm.sync.alarm == al))
4163 e_border_focused_get(void)
4169 _e_border_shape_input_rectangle_set(E_Border* bd)
4173 if ((bd->visible) && (bd->shaped_input))
4175 Ecore_X_Rectangle rects[4];
4176 Ecore_X_Window twin, twin2;
4179 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4180 0, 0, bd->w, bd->h);
4183 rects[0].width = bd->w;
4184 rects[0].height = bd->client_inset.t;
4186 rects[1].y = bd->client_inset.t;
4187 rects[1].width = bd->client_inset.l;
4188 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4189 rects[2].x = bd->w - bd->client_inset.r;
4190 rects[2].y = bd->client_inset.t;
4191 rects[2].width = bd->client_inset.r;
4192 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4194 rects[3].y = bd->h - bd->client_inset.b;
4195 rects[3].width = bd->w;
4196 rects[3].height = bd->client_inset.b;
4197 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4199 twin2 = ecore_x_window_override_new
4200 (bd->zone->container->scratch_win, 0, 0,
4201 bd->w - bd->client_inset.l - bd->client_inset.r,
4202 bd->h - bd->client_inset.t - bd->client_inset.b);
4205 if ((bd->shading) || (bd->shaded))
4207 if (bd->shade.dir == E_DIRECTION_UP)
4208 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4210 else if (bd->shade.dir == E_DIRECTION_LEFT)
4211 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4214 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4216 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4217 bd->w - bd->client_inset.l - bd->client_inset.r,
4218 bd->h - bd->client_inset.t - bd->client_inset.b);
4219 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4221 bd->client_inset.t);
4222 ecore_x_window_shape_input_window_set(bd->win, twin);
4223 ecore_x_window_free(twin2);
4224 ecore_x_window_free(twin);
4228 if (bd->visible) // not shaped input
4230 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4231 ecore_x_composite_window_events_enable(bd->win);
4233 ecore_x_composite_window_events_disable(bd->win);
4237 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4238 ecore_x_composite_window_events_enable(bd->win);
4240 ecore_x_composite_window_events_disable(bd->win);
4246 e_border_idler_before(void)
4255 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4257 EINA_LIST_FOREACH(man->containers, cl, con)
4262 // pass 1 - eval0. fetch properties on new or on change and
4263 // call hooks to decide what to do - maybe move/resize
4264 bl = e_container_border_list_last(con);
4265 while ((bd = e_container_border_list_prev(bl)))
4267 if (bd->changed) _e_border_eval0(bd);
4269 e_container_border_list_free(bl);
4271 // layout hook - this is where a hook gets to figure out what to
4273 _e_border_container_layout_hook(con);
4275 // pass 2 - show windows needing show
4276 bl = e_container_border_list_last(con);
4277 while ((bd = e_container_border_list_prev(bl)))
4279 if ((bd->changes.visible) && (bd->visible) &&
4280 (!bd->new_client) && (!bd->changes.pos) &&
4281 (!bd->changes.size))
4284 bd->changes.visible = 0;
4287 e_container_border_list_free(bl);
4289 // pass 3 - hide windows needing hide and eval (main eval)
4290 bl = e_container_border_list_first(con);
4291 while ((bd = e_container_border_list_next(bl)))
4293 if (e_object_is_del(E_OBJECT(bd))) continue;
4295 if ((bd->changes.visible) && (!bd->visible))
4298 bd->changes.visible = 0;
4301 if (bd->changed) _e_border_eval(bd);
4303 if ((bd->changes.visible) && (bd->visible))
4306 bd->changes.visible = 0;
4309 e_container_border_list_free(bl);
4315 E_Border *bd = NULL, *bd2;
4317 EINA_LIST_FREE(focus_next, bd2)
4318 if ((!bd) && (bd2->visible)) bd = bd2;
4322 /* TODO revert focus when lost here ? */
4328 /* already focused. but anyway dont be so strict, this
4329 fcks up illume setting focus on internal windows */
4334 focus_time = ecore_x_current_time_get();
4338 if ((bd->client.icccm.take_focus) &&
4339 (bd->client.icccm.accepts_focus))
4341 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4342 /* TODO what if the client didn't take focus ? */
4344 else if (!bd->client.icccm.accepts_focus)
4346 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4348 else if (!bd->client.icccm.take_focus)
4350 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4351 /* e_border_focus_set(bd, 1, 0); */
4355 #ifdef _F_ZONE_WINDOW_ROTATION_
4356 if ((e_config->wm_win_rotation) &&
4359 Ecore_X_Event_Client_Message *msg = NULL;
4361 EINA_LIST_FREE(rot.msgs, msg)
4363 t = msg->message_type;
4364 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4366 if ((rot.vkbd_ctrl_win) &&
4367 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4370 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4371 if (rot.vkbd_show_prepare_timer)
4372 _e_border_vkbd_show(rot.vkbd);
4374 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4377 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4379 if ((rot.vkbd_ctrl_win) &&
4380 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4383 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4384 if (rot.vkbd_hide_prepare_timer)
4386 _e_border_vkbd_hide(rot.vkbd);
4387 rot.vkbd_hide_prepare_timer = NULL;
4388 e_object_unref(E_OBJECT(rot.vkbd));
4391 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4394 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4396 rot.vkbd_ctrl_win = msg->data.l[0];
4397 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4399 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4401 if ((rot.vkbd_ctrl_win) &&
4402 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4404 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4405 E_Manager *m = e_manager_current_get();
4406 E_Zone *zone = NULL;
4407 if (m) zone = e_util_zone_current_get(m);
4408 if ((zone) && (rot.wait_prepare_done))
4411 _e_border_rotation_change_request(zone);
4412 else if (rot.async_list)
4414 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
4415 rot.async_list = NULL;
4417 if (rot.prepare_timer)
4418 ecore_timer_del(rot.prepare_timer);
4419 rot.prepare_timer = NULL;
4420 rot.wait_prepare_done = EINA_FALSE;
4427 rot.fetch = EINA_FALSE;
4433 e_border_client_list(void)
4435 /* FIXME: This should be a somewhat ordered list */
4439 static Ecore_X_Window action_input_win = 0;
4440 static E_Border *action_border = NULL;
4441 static Ecore_Event_Handler *action_handler_key = NULL;
4442 static Ecore_Event_Handler *action_handler_mouse = NULL;
4443 static Ecore_Timer *action_timer = NULL;
4444 static Ecore_X_Rectangle action_orig;
4447 _e_border_show(E_Border *bd)
4452 ecore_evas_show(bd->bg_ecore_evas);
4460 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4462 _e_border_shape_input_rectangle_set(bd);
4464 // ecore_x_composite_window_events_enable(bd->win);
4465 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4468 ecore_x_window_show(bd->win);
4470 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4471 ecore_x_window_show(tmp->win);
4475 _e_border_hide(E_Border *bd)
4480 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4482 ecore_x_window_hide(bd->win);
4483 ecore_evas_hide(bd->bg_ecore_evas);
4485 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4486 ecore_x_window_hide(tmp->win);
4490 ecore_x_composite_window_events_disable(bd->win);
4491 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4496 _e_border_action_input_win_del(void)
4498 if (!action_input_win)
4501 e_grabinput_release(action_input_win, action_input_win);
4502 ecore_x_window_free(action_input_win);
4503 action_input_win = 0;
4508 _e_border_action_input_win_new(E_Border *bd)
4510 if (!action_input_win)
4512 Ecore_X_Window parent = bd->zone->container->win;
4513 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4514 if (!action_input_win)
4518 ecore_x_window_show(action_input_win);
4519 if (e_grabinput_get(action_input_win, 0, action_input_win))
4522 _e_border_action_input_win_del();
4527 _e_border_action_finish(void)
4529 _e_border_action_input_win_del();
4533 ecore_timer_del(action_timer);
4534 action_timer = NULL;
4537 if (action_handler_key)
4539 ecore_event_handler_del(action_handler_key);
4540 action_handler_key = NULL;
4543 if (action_handler_mouse)
4545 ecore_event_handler_del(action_handler_mouse);
4546 action_handler_mouse = NULL;
4549 action_border = NULL;
4553 _e_border_action_init(E_Border *bd)
4555 action_orig.x = bd->x;
4556 action_orig.y = bd->y;
4557 action_orig.width = bd->w;
4558 action_orig.height = bd->h;
4564 _e_border_action_restore_orig(E_Border *bd)
4566 if (action_border != bd)
4569 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4573 _e_border_key_down_modifier_apply(int modifier,
4576 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4578 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4591 _e_border_action_move_timeout(void *data __UNUSED__)
4593 _e_border_move_end(action_border);
4594 _e_border_action_finish();
4595 return ECORE_CALLBACK_CANCEL;
4599 _e_border_action_move_timeout_add(void)
4602 ecore_timer_del(action_timer);
4603 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4607 _e_border_move_key_down(void *data __UNUSED__,
4608 int type __UNUSED__,
4611 Ecore_Event_Key *ev = event;
4614 if (ev->event_window != action_input_win)
4615 return ECORE_CALLBACK_PASS_ON;
4618 fputs("ERROR: no action_border!\n", stderr);
4622 x = action_border->x;
4623 y = action_border->y;
4625 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4626 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4627 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4628 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4629 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4630 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4631 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4632 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4633 else if (strcmp(ev->key, "Return") == 0)
4635 else if (strcmp(ev->key, "Escape") == 0)
4637 _e_border_action_restore_orig(action_border);
4640 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4641 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4644 e_border_move(action_border, x, y);
4645 _e_border_action_move_timeout_add();
4647 return ECORE_CALLBACK_PASS_ON;
4650 _e_border_move_end(action_border);
4651 _e_border_action_finish();
4652 return ECORE_CALLBACK_DONE;
4656 _e_border_move_mouse_down(void *data __UNUSED__,
4657 int type __UNUSED__,
4660 Ecore_Event_Mouse_Button *ev = event;
4662 if (ev->event_window != action_input_win)
4663 return ECORE_CALLBACK_PASS_ON;
4666 fputs("ERROR: no action_border!\n", stderr);
4668 _e_border_move_end(action_border);
4669 _e_border_action_finish();
4670 return ECORE_CALLBACK_DONE;
4674 e_border_act_move_keyboard(E_Border *bd)
4679 if (!_e_border_move_begin(bd))
4682 if (!_e_border_action_input_win_new(bd))
4684 _e_border_move_end(bd);
4688 _e_border_action_init(bd);
4689 _e_border_action_move_timeout_add();
4690 _e_border_move_update(bd);
4692 if (action_handler_key)
4693 ecore_event_handler_del(action_handler_key);
4694 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4696 if (action_handler_mouse)
4697 ecore_event_handler_del(action_handler_mouse);
4698 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4702 _e_border_action_resize_timeout(void *data __UNUSED__)
4704 _e_border_resize_end(action_border);
4705 _e_border_action_finish();
4706 return ECORE_CALLBACK_CANCEL;
4710 _e_border_action_resize_timeout_add(void)
4713 ecore_timer_del(action_timer);
4714 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4718 _e_border_resize_key_down(void *data __UNUSED__,
4719 int type __UNUSED__,
4722 Ecore_Event_Key *ev = event;
4725 if (ev->event_window != action_input_win)
4726 return ECORE_CALLBACK_PASS_ON;
4729 fputs("ERROR: no action_border!\n", stderr);
4733 w = action_border->w;
4734 h = action_border->h;
4736 dx = e_config->border_keyboard.resize.dx;
4737 if (dx < action_border->client.icccm.step_w)
4738 dx = action_border->client.icccm.step_w;
4739 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4740 if (dx < action_border->client.icccm.step_w)
4741 dx = action_border->client.icccm.step_w;
4743 dy = e_config->border_keyboard.resize.dy;
4744 if (dy < action_border->client.icccm.step_h)
4745 dy = action_border->client.icccm.step_h;
4746 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4747 if (dy < action_border->client.icccm.step_h)
4748 dy = action_border->client.icccm.step_h;
4750 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4752 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4754 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4756 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4758 else if (strcmp(ev->key, "Return") == 0)
4760 else if (strcmp(ev->key, "Escape") == 0)
4762 _e_border_action_restore_orig(action_border);
4765 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4766 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4769 e_border_resize_limit(action_border, &w, &h);
4770 e_border_resize(action_border, w, h);
4771 _e_border_action_resize_timeout_add();
4773 return ECORE_CALLBACK_PASS_ON;
4776 _e_border_resize_end(action_border);
4777 _e_border_action_finish();
4778 return ECORE_CALLBACK_DONE;
4782 _e_border_resize_mouse_down(void *data __UNUSED__,
4783 int type __UNUSED__,
4786 Ecore_Event_Mouse_Button *ev = event;
4788 if (ev->event_window != action_input_win)
4789 return ECORE_CALLBACK_PASS_ON;
4792 fputs("ERROR: no action_border!\n", stderr);
4794 _e_border_resize_end(action_border);
4795 _e_border_action_finish();
4796 return ECORE_CALLBACK_DONE;
4800 e_border_act_resize_keyboard(E_Border *bd)
4805 if (!_e_border_resize_begin(bd))
4808 if (!_e_border_action_input_win_new(bd))
4810 _e_border_resize_end(bd);
4814 _e_border_action_init(bd);
4815 _e_border_action_resize_timeout_add();
4816 _e_border_resize_update(bd);
4818 if (action_handler_key)
4819 ecore_event_handler_del(action_handler_key);
4820 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4822 if (action_handler_mouse)
4823 ecore_event_handler_del(action_handler_mouse);
4824 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4828 e_border_act_move_begin(E_Border *bd,
4829 Ecore_Event_Mouse_Button *ev)
4832 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4833 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4834 if (!_e_border_move_begin(bd))
4837 e_zone_edge_disable();
4839 _e_border_pointer_move_begin(bd);
4844 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4845 _e_border_moveinfo_gather(bd, source);
4850 e_border_act_move_end(E_Border *bd,
4851 Ecore_Event_Mouse_Button *ev __UNUSED__)
4854 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4855 if (!bd->moving) return;
4857 _e_border_pointer_move_end(bd);
4858 e_zone_edge_enable();
4859 _e_border_move_end(bd);
4860 e_zone_flip_coords_handle(bd->zone, -1, -1);
4864 e_border_act_resize_begin(E_Border *bd,
4865 Ecore_Event_Mouse_Button *ev)
4868 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4869 if (bd->lock_user_size) return;
4870 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4871 if (!_e_border_resize_begin(bd))
4873 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4875 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4877 bd->resize_mode = RESIZE_TL;
4878 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4882 bd->resize_mode = RESIZE_BL;
4883 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4888 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4890 bd->resize_mode = RESIZE_TR;
4891 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4895 bd->resize_mode = RESIZE_BR;
4896 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4899 _e_border_pointer_resize_begin(bd);
4904 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4905 _e_border_moveinfo_gather(bd, source);
4910 e_border_act_resize_end(E_Border *bd,
4911 Ecore_Event_Mouse_Button *ev __UNUSED__)
4914 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4915 if (bd->resize_mode != RESIZE_NONE)
4917 _e_border_pointer_resize_end(bd);
4918 bd->resize_mode = RESIZE_NONE;
4919 _e_border_resize_end(bd);
4920 bd->changes.reset_gravity = 1;
4926 e_border_act_menu_begin(E_Border *bd,
4927 Ecore_Event_Mouse_Button *ev,
4931 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4934 e_int_border_menu_show(bd,
4935 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4936 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4943 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4944 e_int_border_menu_show(bd, x, y, key, 0);
4949 e_border_act_close_begin(E_Border *bd)
4952 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4953 if (bd->lock_close) return;
4954 if (bd->client.icccm.delete_request)
4956 bd->delete_requested = 1;
4957 ecore_x_window_delete_request_send(bd->client.win);
4958 if (bd->client.netwm.ping)
4961 else if (e_config->kill_if_close_not_possible)
4963 e_border_act_kill_begin(bd);
4968 e_border_act_kill_begin(E_Border *bd)
4971 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4972 if (bd->internal) return;
4973 if (bd->lock_close) return;
4974 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4976 kill(bd->client.netwm.pid, SIGINT);
4977 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4978 _e_border_cb_kill_timer, bd);
4982 if (!bd->internal) ecore_x_kill(bd->client.win);
4987 e_border_icon_add(E_Border *bd,
4992 E_OBJECT_CHECK_RETURN(bd, NULL);
4993 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4998 if (!bd->internal_icon)
5000 o = e_icon_add(evas);
5001 e_util_icon_theme_set(o, "enlightenment");
5005 if (!bd->internal_icon_key)
5009 ext = strrchr(bd->internal_icon, '.');
5010 if ((ext) && ((!strcmp(ext, ".edj"))))
5012 o = edje_object_add(evas);
5013 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
5014 e_util_icon_theme_set(o, "enlightenment");
5018 o = e_icon_add(evas);
5019 e_icon_file_set(o, bd->internal_icon);
5023 o = e_icon_add(evas);
5024 if (!e_util_icon_theme_set(o, bd->internal_icon))
5025 e_util_icon_theme_set(o, "enlightenment");
5030 o = edje_object_add(evas);
5031 edje_object_file_set(o, bd->internal_icon,
5032 bd->internal_icon_key);
5037 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
5039 if (bd->client.netwm.icons)
5041 o = e_icon_add(evas);
5042 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5043 bd->client.netwm.icons[0].width,
5044 bd->client.netwm.icons[0].height);
5045 e_icon_alpha_set(o, 1);
5051 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
5053 o = e_icon_add(evas);
5056 e_icon_fdo_icon_set(o, bd->desktop->icon);
5060 else if (bd->client.netwm.icons)
5062 o = e_icon_add(evas);
5063 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5064 bd->client.netwm.icons[0].width,
5065 bd->client.netwm.icons[0].height);
5066 e_icon_alpha_set(o, 1);
5071 o = e_icon_add(evas);
5072 e_util_icon_theme_set(o, "unknown");
5077 e_border_button_bindings_ungrab_all(void)
5082 EINA_LIST_FOREACH(borders, l, bd)
5084 e_focus_setdown(bd);
5085 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5086 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5091 e_border_button_bindings_grab_all(void)
5096 EINA_LIST_FOREACH(borders, l, bd)
5098 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5099 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5105 e_border_focus_stack_get(void)
5111 e_border_raise_stack_get(void)
5117 e_border_lost_windows_get(E_Zone *zone)
5119 Eina_List *list = NULL, *l;
5121 int loss_overlap = 5;
5123 E_OBJECT_CHECK_RETURN(zone, NULL);
5124 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5125 EINA_LIST_FOREACH(borders, l, bd)
5130 if ((bd->zone != zone) ||
5131 (bd->zone->container != zone->container))
5134 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5135 bd->zone->y + loss_overlap,
5136 bd->zone->w - (2 * loss_overlap),
5137 bd->zone->h - (2 * loss_overlap),
5138 bd->x, bd->y, bd->w, bd->h))
5140 list = eina_list_append(list, bd);
5142 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5143 bd->zone->w, bd->zone->h,
5144 bd->x, bd->y, bd->w, bd->h)) &&
5147 Ecore_X_Rectangle *rect;
5150 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5156 for (i = 0; i < num; i++)
5158 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5159 bd->zone->y + loss_overlap,
5160 bd->zone->w - (2 * loss_overlap),
5161 bd->zone->h - (2 * loss_overlap),
5162 rect[i].x, rect[i].y,
5163 (int)rect[i].width, (int)rect[i].height))
5171 list = eina_list_append(list, bd);
5179 e_border_ping(E_Border *bd)
5182 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5183 if (!e_config->ping_clients) return;
5185 ecore_x_netwm_ping_send(bd->client.win);
5186 bd->ping = ecore_loop_time_get();
5187 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5188 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5189 e_config->ping_clients_interval,
5190 _e_border_cb_ping_poller, bd);
5194 e_border_move_cancel(void)
5198 if (bdmove->cur_mouse_action)
5203 e_object_ref(E_OBJECT(bd));
5204 if (bd->cur_mouse_action->func.end_mouse)
5205 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5206 else if (bd->cur_mouse_action->func.end)
5207 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5208 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5209 bd->cur_mouse_action = NULL;
5210 e_object_unref(E_OBJECT(bd));
5213 _e_border_move_end(bdmove);
5218 e_border_resize_cancel(void)
5222 if (bdresize->cur_mouse_action)
5227 e_object_ref(E_OBJECT(bd));
5228 if (bd->cur_mouse_action->func.end_mouse)
5229 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5230 else if (bd->cur_mouse_action->func.end)
5231 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5232 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5233 bd->cur_mouse_action = NULL;
5234 e_object_unref(E_OBJECT(bd));
5238 bdresize->resize_mode = RESIZE_NONE;
5239 _e_border_resize_end(bdresize);
5245 e_border_frame_recalc(E_Border *bd)
5247 if (!bd->bg_object) return;
5249 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5250 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5252 _e_border_client_inset_calc(bd);
5254 bd->w += (bd->client_inset.l + bd->client_inset.r);
5255 bd->h += (bd->client_inset.t + bd->client_inset.b);
5258 bd->changes.size = 1;
5259 if ((bd->shaped) || (bd->client.shaped))
5261 bd->need_shape_merge = 1;
5262 bd->need_shape_export = 1;
5264 if (bd->shaped_input)
5266 bd->need_shape_merge = 1;
5268 _e_border_client_move_resize_send(bd);
5272 e_border_immortal_windows_get(void)
5274 Eina_List *list = NULL, *l;
5277 EINA_LIST_FOREACH(borders, l, bd)
5280 list = eina_list_append(list, bd);
5286 e_border_name_get(const E_Border *bd)
5288 E_OBJECT_CHECK_RETURN(bd, "");
5289 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5290 if (bd->client.netwm.name)
5291 return bd->client.netwm.name;
5292 else if (bd->client.icccm.title)
5293 return bd->client.icccm.title;
5298 e_border_signal_move_begin(E_Border *bd,
5300 const char *src __UNUSED__)
5303 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5305 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5306 if (!_e_border_move_begin(bd)) return;
5308 _e_border_pointer_move_begin(bd);
5309 e_zone_edge_disable();
5310 _e_border_moveinfo_gather(bd, sig);
5311 if (bd->cur_mouse_action)
5313 if ((!bd->cur_mouse_action->func.end_mouse) &&
5314 (!bd->cur_mouse_action->func.end))
5315 bd->cur_mouse_action = NULL;
5317 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5319 bd->cur_mouse_action = e_action_find("window_move");
5320 if (bd->cur_mouse_action)
5321 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5325 e_border_signal_move_end(E_Border *bd,
5326 const char *sig __UNUSED__,
5327 const char *src __UNUSED__)
5330 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5331 if (!bd->moving) return;
5333 _e_border_pointer_move_end(bd);
5334 e_zone_edge_enable();
5335 _e_border_move_end(bd);
5336 e_zone_flip_coords_handle(bd->zone, -1, -1);
5340 e_border_resizing_get(E_Border *bd)
5342 E_OBJECT_CHECK_RETURN(bd, 0);
5343 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5344 if (bd->resize_mode == RESIZE_NONE) return 0;
5349 e_border_signal_resize_begin(E_Border *bd,
5352 const char *src __UNUSED__)
5354 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5355 int resize_mode = RESIZE_BR;
5358 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5360 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5361 if (!_e_border_resize_begin(bd))
5363 if (!strcmp(dir, "tl"))
5365 resize_mode = RESIZE_TL;
5366 grav = ECORE_X_GRAVITY_SE;
5368 else if (!strcmp(dir, "t"))
5370 resize_mode = RESIZE_T;
5371 grav = ECORE_X_GRAVITY_S;
5373 else if (!strcmp(dir, "tr"))
5375 resize_mode = RESIZE_TR;
5376 grav = ECORE_X_GRAVITY_SW;
5378 else if (!strcmp(dir, "r"))
5380 resize_mode = RESIZE_R;
5381 grav = ECORE_X_GRAVITY_W;
5383 else if (!strcmp(dir, "br"))
5385 resize_mode = RESIZE_BR;
5386 grav = ECORE_X_GRAVITY_NW;
5388 else if (!strcmp(dir, "b"))
5390 resize_mode = RESIZE_B;
5391 grav = ECORE_X_GRAVITY_N;
5393 else if (!strcmp(dir, "bl"))
5395 resize_mode = RESIZE_BL;
5396 grav = ECORE_X_GRAVITY_NE;
5398 else if (!strcmp(dir, "l"))
5400 resize_mode = RESIZE_L;
5401 grav = ECORE_X_GRAVITY_E;
5403 bd->resize_mode = resize_mode;
5404 _e_border_pointer_resize_begin(bd);
5405 _e_border_moveinfo_gather(bd, sig);
5407 if (bd->cur_mouse_action)
5409 if ((!bd->cur_mouse_action->func.end_mouse) &&
5410 (!bd->cur_mouse_action->func.end))
5411 bd->cur_mouse_action = NULL;
5413 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5415 bd->cur_mouse_action = e_action_find("window_resize");
5416 if (bd->cur_mouse_action)
5417 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5421 e_border_signal_resize_end(E_Border *bd,
5422 const char *dir __UNUSED__,
5423 const char *sig __UNUSED__,
5424 const char *src __UNUSED__)
5427 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5428 if (bd->resize_mode == RESIZE_NONE) return;
5429 _e_border_resize_handle(bd);
5430 _e_border_pointer_resize_end(bd);
5431 bd->resize_mode = RESIZE_NONE;
5432 _e_border_resize_end(bd);
5433 bd->changes.reset_gravity = 1;
5438 e_border_resize_limit(E_Border *bd,
5445 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5446 *w -= bd->client_inset.l + bd->client_inset.r;
5447 *h -= bd->client_inset.t + bd->client_inset.b;
5450 if ((bd->client.icccm.base_w >= 0) &&
5451 (bd->client.icccm.base_h >= 0))
5455 tw = *w - bd->client.icccm.base_w;
5456 th = *h - bd->client.icccm.base_h;
5459 a = (double)(tw) / (double)(th);
5460 if ((bd->client.icccm.min_aspect != 0.0) &&
5461 (a < bd->client.icccm.min_aspect))
5463 th = tw / bd->client.icccm.max_aspect;
5464 *h = th + bd->client.icccm.base_h;
5466 else if ((bd->client.icccm.max_aspect != 0.0) &&
5467 (a > bd->client.icccm.max_aspect))
5469 tw = th * bd->client.icccm.max_aspect;
5470 *w = tw + bd->client.icccm.base_w;
5475 a = (double)*w / (double)*h;
5476 if ((bd->client.icccm.min_aspect != 0.0) &&
5477 (a < bd->client.icccm.min_aspect))
5478 *h = *w / bd->client.icccm.min_aspect;
5479 else if ((bd->client.icccm.max_aspect != 0.0) &&
5480 (a > bd->client.icccm.max_aspect))
5481 *w = *h * bd->client.icccm.max_aspect;
5483 if (bd->client.icccm.step_w > 0)
5485 if (bd->client.icccm.base_w >= 0)
5486 *w = bd->client.icccm.base_w +
5487 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5488 bd->client.icccm.step_w);
5490 *w = bd->client.icccm.min_w +
5491 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5492 bd->client.icccm.step_w);
5494 if (bd->client.icccm.step_h > 0)
5496 if (bd->client.icccm.base_h >= 0)
5497 *h = bd->client.icccm.base_h +
5498 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5499 bd->client.icccm.step_h);
5501 *h = bd->client.icccm.min_h +
5502 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5503 bd->client.icccm.step_h);
5509 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5510 else if (*w < bd->client.icccm.min_w)
5511 *w = bd->client.icccm.min_w;
5512 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5513 else if (*h < bd->client.icccm.min_h)
5514 *h = bd->client.icccm.min_h;
5516 *w += bd->client_inset.l + bd->client_inset.r;
5517 *h += bd->client_inset.t + bd->client_inset.b;
5520 /* local subsystem functions */
5522 _e_border_free(E_Border *bd)
5524 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5527 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5529 bd->client.e.state.video_parent_border->client.e.state.video_child =
5531 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5534 if (bd->client.e.state.video_child)
5538 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5540 tmp->client.e.state.video_parent_border = NULL;
5545 efreet_desktop_free(bd->desktop);
5550 ecore_idle_enterer_del(bd->post_job);
5551 bd->post_job = NULL;
5555 e_object_del(E_OBJECT(bd->pointer));
5559 _e_border_resize_end(bd);
5561 _e_border_move_end(bd);
5562 /* TODO: Other states to end before dying? */
5564 if (bd->cur_mouse_action)
5566 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5567 bd->cur_mouse_action = NULL;
5570 E_FREE(bd->shape_rects);
5571 bd->shape_rects_num = 0;
5573 if (bd->dangling_ref_check)
5575 ecore_timer_del(bd->dangling_ref_check);
5576 bd->dangling_ref_check = NULL;
5581 ecore_timer_del(bd->kill_timer);
5582 bd->kill_timer = NULL;
5584 if (bd->ping_poller)
5586 ecore_poller_del(bd->ping_poller);
5587 bd->ping_poller = NULL;
5589 E_FREE_LIST(bd->pending_move_resize, free);
5591 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5592 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5594 if (bd->border_locks_dialog)
5596 e_object_del(E_OBJECT(bd->border_locks_dialog));
5597 bd->border_locks_dialog = NULL;
5599 if (bd->border_remember_dialog)
5601 e_object_del(E_OBJECT(bd->border_remember_dialog));
5602 bd->border_remember_dialog = NULL;
5604 if (bd->border_border_dialog)
5606 e_object_del(E_OBJECT(bd->border_border_dialog));
5607 bd->border_border_dialog = NULL;
5609 if (bd->border_prop_dialog)
5611 e_object_del(E_OBJECT(bd->border_prop_dialog));
5612 bd->border_prop_dialog = NULL;
5615 e_int_border_menu_del(bd);
5620 focus_next = eina_list_remove(focus_next, bd);
5622 if ((focused == bd) ||
5623 (e_grabinput_last_focus_win_get() == bd->client.win))
5625 if ((!focus_next) && (!focusing))
5627 e_grabinput_focus(bd->zone->container->bg_win,
5628 E_FOCUS_METHOD_PASSIVE);
5629 e_hints_active_window_set(bd->zone->container->manager, NULL);
5634 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5640 bd->remember = NULL;
5641 e_remember_unuse(rem);
5643 if (!bd->already_unparented)
5645 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5646 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5647 ecore_x_window_save_set_del(bd->client.win);
5648 bd->already_unparented = 1;
5650 if (bd->group) eina_list_free(bd->group);
5651 if (bd->transients) eina_list_free(bd->transients);
5652 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5653 if (bd->client.netwm.icons)
5656 for (i = 0; i < bd->client.netwm.num_icons; i++)
5657 free(bd->client.netwm.icons[i].data);
5658 free(bd->client.netwm.icons);
5660 if (bd->client.netwm.extra_types)
5661 free(bd->client.netwm.extra_types);
5662 if (bd->client.border.name)
5663 eina_stringshare_del(bd->client.border.name);
5665 eina_stringshare_del(bd->bordername);
5666 if (bd->client.icccm.name)
5667 eina_stringshare_del(bd->client.icccm.name);
5668 if (bd->client.icccm.class)
5670 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5671 e_bindings_mapping_change_enable(EINA_TRUE);
5672 eina_stringshare_del(bd->client.icccm.class);
5674 if (bd->client.icccm.title)
5675 eina_stringshare_del(bd->client.icccm.title);
5676 if (bd->client.icccm.icon_name)
5677 eina_stringshare_del(bd->client.icccm.icon_name);
5678 if (bd->client.icccm.machine)
5679 eina_stringshare_del(bd->client.icccm.machine);
5680 if (bd->client.icccm.window_role)
5681 eina_stringshare_del(bd->client.icccm.window_role);
5683 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5687 for (i = 0; i < bd->client.icccm.command.argc; i++)
5688 free(bd->client.icccm.command.argv[i]);
5689 free(bd->client.icccm.command.argv);
5691 if (bd->client.netwm.name)
5692 eina_stringshare_del(bd->client.netwm.name);
5693 if (bd->client.netwm.icon_name)
5694 eina_stringshare_del(bd->client.netwm.icon_name);
5695 e_object_del(E_OBJECT(bd->shape));
5696 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5697 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5698 if (bd->icon_object) evas_object_del(bd->icon_object);
5699 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5700 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5702 if (str) eina_stringshare_del(str);
5704 bd->client.e.state.profiles = NULL;
5705 if (bd->client.e.state.profile)
5706 eina_stringshare_del(bd->client.e.state.profile);
5707 bd->client.e.state.profile = NULL;
5709 #ifdef _F_ZONE_WINDOW_ROTATION_
5710 if (e_config->wm_win_rotation)
5712 bd->client.e.fetch.rot.app_set = 0;
5713 bd->client.e.state.rot.preferred_rot = -1;
5715 if (bd->client.e.state.rot.available_rots)
5716 E_FREE(bd->client.e.state.rot.available_rots);
5718 _e_border_rotation_list_remove(bd);
5719 if ((rot.vkbd) && (rot.vkbd == bd))
5721 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5723 if (rot.vkbd_ctrl_win)
5725 ELB(ELBT_BD, "SET KBD_OFF", 0);
5726 ecore_x_e_virtual_keyboard_state_set
5727 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5730 rot.vkbd_hide_prepare_done = EINA_FALSE;
5731 if (rot.vkbd_hide_prepare_timer)
5732 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5733 rot.vkbd_hide_prepare_timer = NULL;
5734 if (rot.vkbd_hide_timer)
5735 ecore_timer_del(rot.vkbd_hide_timer);
5736 rot.vkbd_hide_timer = NULL;
5738 rot.vkbd_show_prepare_done = EINA_FALSE;
5739 if (rot.vkbd_show_prepare_timer)
5740 ecore_timer_del(rot.vkbd_show_prepare_timer);
5741 rot.vkbd_show_prepare_timer = NULL;
5742 if (rot.vkbd_show_timer)
5743 ecore_timer_del(rot.vkbd_show_timer);
5744 rot.vkbd_show_timer = NULL;
5746 else if ((rot.vkbd_prediction) &&
5747 (rot.vkbd_prediction == bd))
5748 rot.vkbd_prediction = NULL;
5751 #ifdef _F_DEICONIFY_APPROVE_
5752 if (bd->client.e.state.deiconify_approve.pending_job)
5754 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5755 bd->client.e.state.deiconify_approve.pending_job = NULL;
5758 evas_object_del(bd->bg_object);
5759 e_canvas_del(bd->bg_ecore_evas);
5760 ecore_evas_free(bd->bg_ecore_evas);
5761 ecore_x_window_free(bd->client.shell_win);
5762 e_focus_setdown(bd);
5763 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5764 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5765 ecore_x_window_free(bd->win);
5767 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5768 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5769 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5770 borders = eina_list_remove(borders, bd);
5771 focus_stack = eina_list_remove(focus_stack, bd);
5772 raise_stack = eina_list_remove(raise_stack, bd);
5774 e_container_border_remove(bd);
5780 _e_border_del_dangling_ref_check(void *data)
5786 printf("EEK EEK border still around 1 second after being deleted!\n");
5787 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5788 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5789 bd->client.icccm.name, bd->client.icccm.class);
5790 // e_object_breadcrumb_debug(E_OBJECT(bd));
5797 _e_border_del(E_Border *bd)
5799 E_Event_Border_Remove *ev;
5802 #ifdef _F_BORDER_HOOK_PATCH_
5803 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5814 focus_next = eina_list_remove(focus_next, bd);
5816 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5818 if ((drag_border) && (drag_border->data == bd))
5820 e_object_del(E_OBJECT(drag_border));
5823 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5825 if (bd->border_locks_dialog)
5827 e_object_del(E_OBJECT(bd->border_locks_dialog));
5828 bd->border_locks_dialog = NULL;
5830 if (bd->border_remember_dialog)
5832 e_object_del(E_OBJECT(bd->border_remember_dialog));
5833 bd->border_remember_dialog = NULL;
5835 if (bd->border_border_dialog)
5837 e_object_del(E_OBJECT(bd->border_border_dialog));
5838 bd->border_border_dialog = NULL;
5840 if (bd->border_prop_dialog)
5842 e_object_del(E_OBJECT(bd->border_prop_dialog));
5843 bd->border_prop_dialog = NULL;
5846 e_int_border_menu_del(bd);
5848 if (bd->raise_timer)
5850 ecore_timer_del(bd->raise_timer);
5851 bd->raise_timer = NULL;
5853 if (!bd->already_unparented)
5855 ecore_x_window_reparent(bd->client.win,
5856 bd->zone->container->manager->root,
5857 bd->x + bd->client_inset.l,
5858 bd->y + bd->client_inset.t);
5859 ecore_x_window_save_set_del(bd->client.win);
5860 bd->already_unparented = 1;
5861 // bd->client.win = 0;
5863 bd->already_unparented = 1;
5865 if ((!bd->new_client) && (!stopping))
5867 ev = E_NEW(E_Event_Border_Remove, 1);
5869 e_object_ref(E_OBJECT(bd));
5870 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5871 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5876 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5877 if (bd->parent->modal == bd)
5879 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5880 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5881 bd->parent->lock_close = 0;
5882 bd->parent->saved.event_mask = 0;
5883 bd->parent->modal = NULL;
5887 EINA_LIST_FREE(bd->transients, child)
5889 child->parent = NULL;
5892 #ifdef _F_DEICONIFY_APPROVE_
5893 bd->client.e.state.deiconify_approve.render_done = 0;
5895 E_Border *ancestor_bd;
5896 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5897 if ((ancestor_bd) &&
5898 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5900 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5901 bd->client.e.state.deiconify_approve.ancestor = NULL;
5903 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5904 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5906 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5908 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5909 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5910 e_border_uniconify(ancestor_bd);
5915 if (bd->client.e.state.deiconify_approve.wait_timer)
5917 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5918 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5921 if (bd->client.e.state.deiconify_approve.pending_job)
5923 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5924 bd->client.e.state.deiconify_approve.pending_job = NULL;
5927 if (bd->client.e.state.deiconify_approve.req_list)
5929 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5931 child->client.e.state.deiconify_approve.render_done = 0;
5932 child->client.e.state.deiconify_approve.ancestor = NULL;
5937 #ifdef _F_ZONE_WINDOW_ROTATION_
5938 if (rot.list) _e_border_rotation_list_remove(bd);
5942 E_Border_Rotation_Info *info = NULL;
5944 EINA_LIST_FOREACH(rot.async_list, l, info)
5947 rot.async_list = eina_list_remove(rot.async_list, info);
5955 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5956 if (bd->leader->modal == bd)
5957 bd->leader->modal = NULL;
5960 EINA_LIST_FREE(bd->group, child)
5962 child->leader = NULL;
5966 #ifdef PRINT_LOTS_OF_DEBUG
5968 _e_border_print(E_Border *bd,
5977 "\tBorderless: %s\n",
5978 bd, bd->client.icccm.name, bd->client.icccm.title,
5979 bd->borderless ? "TRUE" : "FALSE");
5985 _e_border_cb_window_show_request(void *data __UNUSED__,
5986 int ev_type __UNUSED__,
5991 Ecore_X_Event_Window_Show_Request *e;
5994 bd = e_border_find_by_client_window(e->win);
5995 if (!bd) return ECORE_CALLBACK_PASS_ON;
5997 if ((e_config->wm_win_rotation) &&
5998 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
6000 (rot.vkbd_hide_prepare_timer))
6002 con = bd->zone->container;
6003 bd = e_border_new(con, e->win, 0, 0);
6008 if (!bd->lock_client_iconify)
6009 e_border_uniconify(bd);
6013 /* FIXME: make border "urgent" for a bit - it wants attention */
6014 /* e_border_show(bd); */
6015 if (!bd->lock_client_stacking)
6018 return ECORE_CALLBACK_PASS_ON;
6022 _e_border_cb_window_destroy(void *data __UNUSED__,
6023 int ev_type __UNUSED__,
6027 Ecore_X_Event_Window_Destroy *e;
6030 bd = e_border_find_by_client_window(e->win);
6031 if (!bd) return ECORE_CALLBACK_PASS_ON;
6032 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
6033 #ifdef _F_ZONE_WINDOW_ROTATION_
6034 if (e_config->wm_win_rotation)
6036 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6038 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
6039 if (!rot.vkbd_hide_prepare_timer)
6041 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6042 e_border_hide(bd, 0);
6043 if (!rot.vkbd_hide_prepare_timer)
6045 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6046 e_object_del(E_OBJECT(bd));
6049 return ECORE_CALLBACK_PASS_ON;
6053 e_border_hide(bd, 0);
6054 e_object_del(E_OBJECT(bd));
6055 return ECORE_CALLBACK_PASS_ON;
6059 _e_border_cb_window_hide(void *data __UNUSED__,
6060 int ev_type __UNUSED__,
6063 E_Border *bd = NULL;
6064 Ecore_X_Event_Window_Hide *e;
6067 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
6068 // not interested in hide events from windows other than the window in question
6069 if (e->win != e->event_win)
6071 bd = e_border_find_by_client_window(e->win);
6072 if (!bd) return ECORE_CALLBACK_PASS_ON;
6073 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
6077 (bd->zone->container->manager->root == e->event_win)))
6078 return ECORE_CALLBACK_PASS_ON;
6081 if (!bd) bd = e_border_find_by_client_window(e->win);
6082 // printf(" bd = %p\n", bd);
6085 if (ecore_x_window_visible_get(e->win))
6087 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
6088 ecore_x_window_hide(e->win);
6090 return ECORE_CALLBACK_PASS_ON;
6093 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6094 if (bd->ignore_first_unmap > 0)
6096 bd->ignore_first_unmap--;
6097 return ECORE_CALLBACK_PASS_ON;
6099 /* Don't delete hidden or iconified windows */
6100 #ifdef _F_USE_EXTENDED_ICONIFY_
6101 if (bd->await_hide_event > 0)
6103 if ((bd->iconic) || (bd->await_hide_event > 0))
6106 // printf(" Don't delete hidden or iconified windows\n");
6107 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6108 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6109 if (bd->await_hide_event > 0)
6111 bd->await_hide_event--;
6115 // printf(" hide really\n");
6116 /* Only hide the border if it is visible */
6117 if (bd->visible) e_border_hide(bd, 1);
6122 // printf(" hide2\n");
6123 #ifdef _F_USE_EXTENDED_ICONIFY_
6131 #ifdef _F_ZONE_WINDOW_ROTATION_
6132 if (e_config->wm_win_rotation)
6134 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6136 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6137 if (!rot.vkbd_hide_prepare_timer)
6139 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6140 e_border_hide(bd, 0);
6141 if (!rot.vkbd_hide_prepare_timer)
6143 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6144 e_object_del(E_OBJECT(bd));
6147 return ECORE_CALLBACK_PASS_ON;
6151 e_border_hide(bd, 0);
6152 e_object_del(E_OBJECT(bd));
6154 return ECORE_CALLBACK_PASS_ON;
6158 _e_border_cb_window_reparent(void *data __UNUSED__,
6159 int ev_type __UNUSED__,
6160 void *ev __UNUSED__)
6164 Ecore_X_Event_Window_Reparent *e;
6167 bd = e_border_find_by_client_window(e->win);
6169 if (e->parent == bd->client.shell_win) return 1;
6170 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6174 e_border_hide(bd, 0);
6175 e_object_del(E_OBJECT(bd));
6177 return ECORE_CALLBACK_PASS_ON;
6181 _e_border_cb_window_configure_request(void *data __UNUSED__,
6182 int ev_type __UNUSED__,
6186 Ecore_X_Event_Window_Configure_Request *e;
6189 bd = e_border_find_by_client_window(e->win);
6192 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6193 if (!e_util_container_window_find(e->win))
6194 ecore_x_window_configure(e->win, e->value_mask,
6195 e->x, e->y, e->w, e->h, e->border,
6196 e->abovewin, e->detail);
6197 return ECORE_CALLBACK_PASS_ON;
6200 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6201 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6207 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6209 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6211 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6212 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6218 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6219 w = e->w + bd->client_inset.l + bd->client_inset.r;
6220 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6221 h = e->h + bd->client_inset.t + bd->client_inset.b;
6222 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6224 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6226 bd->saved.x = x - bd->zone->x;
6227 bd->saved.y = y - bd->zone->y;
6232 e_border_move_resize(bd, x, y, w, h);
6234 else if (!bd->lock_client_location)
6236 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6238 bd->saved.x = x - bd->zone->x;
6239 bd->saved.y = y - bd->zone->y;
6242 e_border_move(bd, x, y);
6244 else if (!bd->lock_client_size)
6246 if ((bd->shaded) || (bd->shading))
6252 if ((bd->shade.dir == E_DIRECTION_UP) ||
6253 (bd->shade.dir == E_DIRECTION_DOWN))
6255 e_border_resize(bd, w, bd->h);
6260 e_border_resize(bd, bd->w, h);
6266 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6272 e_border_resize(bd, w, h);
6278 if (!bd->lock_client_location)
6280 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6282 bd->saved.x = x - bd->zone->x;
6283 bd->saved.y = y - bd->zone->y;
6286 e_border_move(bd, x, y);
6290 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6291 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6297 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6298 w = e->w + bd->client_inset.l + bd->client_inset.r;
6299 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6300 h = e->h + bd->client_inset.t + bd->client_inset.b;
6301 #ifdef _F_ZONE_WINDOW_ROTATION_
6302 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6304 if (!bd->lock_client_size)
6306 if ((bd->shaded) || (bd->shading))
6312 if ((bd->shade.dir == E_DIRECTION_UP) ||
6313 (bd->shade.dir == E_DIRECTION_DOWN))
6315 e_border_resize(bd, w, bd->h);
6320 e_border_resize(bd, bd->w, h);
6326 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6331 zx = zy = zw = zh = 0;
6334 * This code does resize and move a window on a
6335 * X configure request into an useful geometry.
6336 * This is really useful for size jumping file dialogs.
6341 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6343 if (e_config->geometry_auto_resize_limit == 1)
6352 e_border_resize(bd, w, h);
6354 if (e_config->geometry_auto_move == 1)
6356 /* z{x,y,w,h} are only set here; FIXME! */
6359 // move window horizontal if resize to not useful geometry
6360 if (bd->x + bd->w > zx + zw)
6361 rx = zx + zw - bd->w;
6362 else if (bd->x < zx)
6365 // move window vertical if resize to not useful geometry
6366 if (bd->y + bd->h > zy + zh)
6367 ry = zy + zh - bd->h;
6368 else if (bd->y < zy)
6371 e_border_move(bd, rx, ry);
6377 if (!bd->lock_client_stacking)
6379 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6380 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6384 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6386 obd = e_border_find_by_client_window(e->abovewin);
6389 e_border_stack_above(bd, obd);
6393 ecore_x_window_configure(bd->win,
6394 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6395 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6397 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6398 /* FIXME: need to rebuiuld border list from current stacking */
6401 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6403 obd = e_border_find_by_client_window(e->abovewin);
6406 e_border_stack_below(bd, obd);
6410 ecore_x_window_configure(bd->win,
6411 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6412 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6414 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6415 /* FIXME: need to rebuiuld border list from current stacking */
6418 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6422 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6426 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6431 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6433 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6437 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6441 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6445 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6449 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6456 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6457 _e_border_client_move_resize_send(bd);
6458 return ECORE_CALLBACK_PASS_ON;
6462 _e_border_cb_window_resize_request(void *data __UNUSED__,
6463 int ev_type __UNUSED__,
6467 Ecore_X_Event_Window_Resize_Request *e;
6470 bd = e_border_find_by_client_window(e->win);
6473 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6474 ecore_x_window_resize(e->win, e->w, e->h);
6475 return ECORE_CALLBACK_PASS_ON;
6480 w = e->w + bd->client_inset.l + bd->client_inset.r;
6481 h = e->h + bd->client_inset.t + bd->client_inset.b;
6482 if ((bd->shaded) || (bd->shading))
6488 if ((bd->shade.dir == E_DIRECTION_UP) ||
6489 (bd->shade.dir == E_DIRECTION_DOWN))
6491 e_border_resize(bd, w, bd->h);
6496 e_border_resize(bd, bd->w, h);
6501 e_border_resize(bd, w, h);
6504 _e_border_client_move_resize_send(bd);
6505 return ECORE_CALLBACK_PASS_ON;
6509 _e_border_cb_window_gravity(void *data __UNUSED__,
6510 int ev_type __UNUSED__,
6511 void *ev __UNUSED__)
6514 // Ecore_X_Event_Window_Gravity *e;
6517 // bd = e_border_find_by_client_window(e->win);
6518 // if (!bd) return 1;
6523 _e_border_cb_window_stack_request(void *data __UNUSED__,
6524 int ev_type __UNUSED__,
6528 Ecore_X_Event_Window_Stack_Request *e;
6531 bd = e_border_find_by_client_window(e->win);
6534 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6535 if (!e_util_container_window_find(e->win))
6537 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6538 ecore_x_window_raise(e->win);
6539 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6540 ecore_x_window_lower(e->win);
6542 return ECORE_CALLBACK_PASS_ON;
6544 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6546 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6548 return ECORE_CALLBACK_PASS_ON;
6552 _e_border_cb_window_property(void *data __UNUSED__,
6553 int ev_type __UNUSED__,
6557 Ecore_X_Event_Window_Property *e;
6560 bd = e_border_find_by_client_window(e->win);
6561 if (!bd) return ECORE_CALLBACK_PASS_ON;
6562 if (e->atom == ECORE_X_ATOM_WM_NAME)
6564 if ((!bd->client.netwm.name) &&
6565 (!bd->client.netwm.fetch.name))
6567 bd->client.icccm.fetch.title = 1;
6571 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6573 bd->client.netwm.fetch.name = 1;
6576 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6578 bd->client.icccm.fetch.name_class = 1;
6581 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6583 if ((!bd->client.netwm.icon_name) &&
6584 (!bd->client.netwm.fetch.icon_name))
6586 bd->client.icccm.fetch.icon_name = 1;
6590 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6592 bd->client.netwm.fetch.icon_name = 1;
6595 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6597 bd->client.icccm.fetch.machine = 1;
6600 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6602 bd->client.icccm.fetch.protocol = 1;
6605 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6607 bd->client.icccm.fetch.hints = 1;
6610 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6612 bd->client.icccm.fetch.size_pos_hints = 1;
6615 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6618 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6619 (!bd->client.netwm.fetch.type))
6622 bd->client.mwm.fetch.hints = 1;
6628 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6630 bd->client.icccm.fetch.transient_for = 1;
6633 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6635 bd->client.icccm.fetch.client_leader = 1;
6638 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6640 bd->client.icccm.fetch.window_role = 1;
6643 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6645 bd->client.netwm.fetch.icon = 1;
6648 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6650 bd->client.qtopia.fetch.soft_menu = 1;
6653 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6655 bd->client.qtopia.fetch.soft_menus = 1;
6658 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6660 bd->client.vkbd.fetch.state = 1;
6663 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6665 bd->client.vkbd.fetch.vkbd = 1;
6668 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6670 bd->client.illume.conformant.fetch.conformant = 1;
6673 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6675 bd->client.illume.quickpanel.fetch.state = 1;
6678 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6680 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6683 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6685 bd->client.illume.quickpanel.fetch.priority.major = 1;
6688 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6690 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6693 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6695 bd->client.illume.quickpanel.fetch.zone = 1;
6698 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6700 bd->client.illume.drag.fetch.locked = 1;
6703 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6705 bd->client.illume.drag.fetch.drag = 1;
6708 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6710 bd->client.illume.win_state.fetch.state = 1;
6714 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6716 bd->client.netwm.fetch.user_time = 1;
6719 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6721 bd->client.netwm.fetch.strut = 1;
6724 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6726 bd->client.netwm.fetch.strut = 1;
6730 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6732 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6734 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6736 bd->client.e.fetch.video_position = 1;
6739 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6741 bd->client.e.fetch.video_parent = 1;
6744 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6746 bd->client.netwm.fetch.state = 1;
6749 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6750 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6752 bd->client.e.fetch.profile_list = 1;
6756 #ifdef _F_ZONE_WINDOW_ROTATION_
6757 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6759 if (e_config->wm_win_rotation)
6761 bd->client.e.fetch.rot.support = 1;
6765 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6766 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6767 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6768 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6770 if (e_config->wm_win_rotation)
6772 bd->client.e.fetch.rot.geom_hint = 1;
6776 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6778 if (e_config->wm_win_rotation)
6780 bd->client.e.fetch.rot.app_set = 1;
6784 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6786 if (e_config->wm_win_rotation)
6788 bd->client.e.fetch.rot.preferred_rot = 1;
6792 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6794 if (e_config->wm_win_rotation)
6796 bd->client.e.fetch.rot.available_rots = 1;
6802 return ECORE_CALLBACK_PASS_ON;
6806 _e_border_cb_window_colormap(void *data __UNUSED__,
6807 int ev_type __UNUSED__,
6811 Ecore_X_Event_Window_Colormap *e;
6814 bd = e_border_find_by_client_window(e->win);
6815 if (!bd) return ECORE_CALLBACK_PASS_ON;
6816 return ECORE_CALLBACK_PASS_ON;
6820 _e_border_cb_window_shape(void *data __UNUSED__,
6821 int ev_type __UNUSED__,
6825 Ecore_X_Event_Window_Shape *e;
6828 bd = e_border_find_by_client_window(e->win);
6830 if (e->type == ECORE_X_SHAPE_INPUT)
6834 bd->need_shape_merge = 1;
6835 // YYY bd->shaped_input = 1;
6836 bd->changes.shape_input = 1;
6840 return ECORE_CALLBACK_PASS_ON;
6845 bd->changes.shape = 1;
6847 return ECORE_CALLBACK_PASS_ON;
6849 bd = e_border_find_by_window(e->win);
6852 bd->need_shape_export = 1;
6854 return ECORE_CALLBACK_PASS_ON;
6856 bd = e_border_find_by_frame_window(e->win);
6859 bd->need_shape_merge = 1;
6861 return ECORE_CALLBACK_PASS_ON;
6863 return ECORE_CALLBACK_PASS_ON;
6867 _e_border_cb_window_focus_in(void *data __UNUSED__,
6868 int ev_type __UNUSED__,
6872 Ecore_X_Event_Window_Focus_In *e;
6875 bd = e_border_find_by_client_window(e->win);
6876 if (!bd) return ECORE_CALLBACK_PASS_ON;
6877 #ifdef INOUTDEBUG_FOCUS
6882 const char *modes[] = {
6884 "MODE_WHILE_GRABBED",
6888 const char *details[] = {
6892 "DETAIL_NON_LINEAR",
6893 "DETAIL_NON_LINEAR_VIRTUAL",
6895 "DETAIL_POINTER_ROOT",
6896 "DETAIL_DETAIL_NONE"
6900 ct[strlen(ct) - 1] = 0;
6901 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6906 details[e->detail]);
6908 DBG("%s cb focus in %d %d\n",
6909 e_border_name_get(bd),
6910 bd->client.icccm.accepts_focus,
6911 bd->client.icccm.take_focus);
6914 _e_border_pri_raise(bd);
6915 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6917 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6919 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6921 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6924 /* ignore focus in from !take_focus windows, we just gave it em */
6925 /* if (!bd->client.icccm.take_focus)
6926 * return ECORE_CALLBACK_PASS_ON; */
6928 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6929 if (e->time >= focus_time)
6930 e_border_focus_set(bd, 1, 0);
6931 return ECORE_CALLBACK_PASS_ON;
6935 _e_border_cb_window_focus_out(void *data __UNUSED__,
6936 int ev_type __UNUSED__,
6940 Ecore_X_Event_Window_Focus_Out *e;
6943 bd = e_border_find_by_client_window(e->win);
6944 if (!bd) return ECORE_CALLBACK_PASS_ON;
6945 #ifdef INOUTDEBUG_FOCUS
6950 const char *modes[] = {
6952 "MODE_WHILE_GRABBED",
6956 const char *details[] = {
6960 "DETAIL_NON_LINEAR",
6961 "DETAIL_NON_LINEAR_VIRTUAL",
6963 "DETAIL_POINTER_ROOT",
6964 "DETAIL_DETAIL_NONE"
6968 ct[strlen(ct) - 1] = 0;
6969 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6974 details[e->detail]);
6976 DBG("%s cb focus out %d %d",
6977 e_border_name_get(bd),
6978 bd->client.icccm.accepts_focus,
6979 bd->client.icccm.take_focus);
6982 _e_border_pri_norm(bd);
6983 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6985 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6986 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6987 return ECORE_CALLBACK_PASS_ON;
6988 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6989 return ECORE_CALLBACK_PASS_ON;
6991 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6993 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6994 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6995 return ECORE_CALLBACK_PASS_ON;
6996 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6997 return ECORE_CALLBACK_PASS_ON;
6998 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6999 return ECORE_CALLBACK_PASS_ON;
7000 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
7001 return ECORE_CALLBACK_PASS_ON;
7003 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
7005 /* for firefox/thunderbird (xul) menu walking */
7006 /* NB: why did i disable this before? */
7007 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7008 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
7009 return ECORE_CALLBACK_PASS_ON;
7011 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
7013 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
7014 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7015 return ECORE_CALLBACK_PASS_ON;
7017 e_border_focus_set(bd, 0, 0);
7018 return ECORE_CALLBACK_PASS_ON;
7021 #if _F_BORDER_CLIP_TO_ZONE_
7023 _e_border_shape_input_clip_to_zone(E_Border *bd)
7025 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
7029 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
7030 bd->zone->w, bd->zone->h,
7031 bd->x, bd->y, bd->w, bd->h)))
7034 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
7035 E_RECTS_CLIP_TO_RECT(x, y, w, h,
7036 bd->zone->x, bd->zone->y,
7037 bd->zone->w, bd->zone->h);
7040 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
7041 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
7045 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
7046 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
7049 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
7052 _e_border_cb_client_message(void *data __UNUSED__,
7053 int ev_type __UNUSED__,
7056 Ecore_X_Event_Client_Message *e;
7060 #ifdef _F_DEICONIFY_APPROVE_
7061 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
7063 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
7065 bd = e_border_find_by_client_window(e->win);
7068 if (bd->client.e.state.deiconify_approve.support)
7070 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
7071 bd->client.e.state.deiconify_approve.render_done = 1;
7073 E_Border *ancestor_bd;
7074 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
7077 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
7078 bd->client.e.state.deiconify_approve.ancestor = NULL;
7085 ELBF(ELBT_BD, 0, bd->client.win,
7086 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
7088 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
7089 (ancestor_bd->client.e.state.deiconify_approve.render_done))
7091 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7093 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7094 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7096 if (bd->client.e.state.deiconify_approve.wait_timer)
7098 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7099 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7102 e_border_uniconify(ancestor_bd);
7106 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7107 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7111 if (bd != ancestor_bd)
7113 if (bd->client.e.state.deiconify_approve.wait_timer)
7115 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7116 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7121 return ECORE_CALLBACK_PASS_ON;
7125 #ifdef _F_ZONE_WINDOW_ROTATION_
7126 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7128 bd = e_border_find_by_client_window(e->win);
7131 if (e_config->wm_win_rotation)
7133 Ecore_X_Event_Client_Message *msg = NULL;
7134 Ecore_X_Atom t = e->message_type;
7135 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7136 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7137 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7138 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7140 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7141 if (!msg) return ECORE_CALLBACK_PASS_ON;
7144 msg->message_type = e->message_type;
7145 msg->data.l[0] = e->data.l[0];
7146 msg->data.l[1] = e->data.l[1];
7147 msg->data.l[2] = e->data.l[2];
7148 msg->data.l[3] = e->data.l[3];
7149 msg->data.l[4] = e->data.l[4];
7150 rot.msgs = eina_list_append(rot.msgs, msg);
7152 rot.fetch = EINA_TRUE;
7155 return ECORE_CALLBACK_PASS_ON;
7158 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7160 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7161 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7163 if (e_config->wm_win_rotation)
7165 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7167 _e_border_rotation_list_remove(bd);
7168 if (bd->client.e.state.rot.pending_show)
7170 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7172 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7173 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
7174 _e_border_check_stack(bd);
7176 bd->client.e.state.rot.pending_show = 0;
7182 return ECORE_CALLBACK_PASS_ON;
7186 _e_border_cb_window_state_request(void *data __UNUSED__,
7187 int ev_type __UNUSED__,
7191 Ecore_X_Event_Window_State_Request *e;
7195 bd = e_border_find_by_client_window(e->win);
7196 if (!bd) return ECORE_CALLBACK_PASS_ON;
7198 for (i = 0; i < 2; i++)
7199 e_hints_window_state_update(bd, e->state[i], e->action);
7201 return ECORE_CALLBACK_PASS_ON;
7205 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7206 int ev_type __UNUSED__,
7210 Ecore_X_Event_Window_Move_Resize_Request *e;
7213 bd = e_border_find_by_client_window(e->win);
7214 if (!bd) return ECORE_CALLBACK_PASS_ON;
7216 if ((bd->shaded) || (bd->shading) ||
7217 (bd->fullscreen) || (bd->moving) ||
7218 (bd->resize_mode != RESIZE_NONE))
7219 return ECORE_CALLBACK_PASS_ON;
7221 if ((e->button >= 1) && (e->button <= 3))
7223 bd->mouse.last_down[e->button - 1].mx = e->x;
7224 bd->mouse.last_down[e->button - 1].my = e->y;
7225 bd->mouse.last_down[e->button - 1].x = bd->x;
7226 bd->mouse.last_down[e->button - 1].y = bd->y;
7227 bd->mouse.last_down[e->button - 1].w = bd->w;
7228 bd->mouse.last_down[e->button - 1].h = bd->h;
7232 bd->moveinfo.down.x = bd->x;
7233 bd->moveinfo.down.y = bd->y;
7234 bd->moveinfo.down.w = bd->w;
7235 bd->moveinfo.down.h = bd->h;
7237 bd->mouse.current.mx = e->x;
7238 bd->mouse.current.my = e->y;
7239 bd->moveinfo.down.button = e->button;
7240 bd->moveinfo.down.mx = e->x;
7241 bd->moveinfo.down.my = e->y;
7244 if (!bd->lock_user_stacking)
7247 if (e->direction == MOVE)
7249 bd->cur_mouse_action = e_action_find("window_move");
7250 if (bd->cur_mouse_action)
7252 if ((!bd->cur_mouse_action->func.end_mouse) &&
7253 (!bd->cur_mouse_action->func.end))
7254 bd->cur_mouse_action = NULL;
7255 if (bd->cur_mouse_action)
7257 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7258 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7261 return ECORE_CALLBACK_PASS_ON;
7264 if (!_e_border_resize_begin(bd))
7265 return ECORE_CALLBACK_PASS_ON;
7267 switch (e->direction)
7270 bd->resize_mode = RESIZE_TL;
7271 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7275 bd->resize_mode = RESIZE_T;
7276 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7280 bd->resize_mode = RESIZE_TR;
7281 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7285 bd->resize_mode = RESIZE_R;
7286 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7290 bd->resize_mode = RESIZE_BR;
7291 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7295 bd->resize_mode = RESIZE_B;
7296 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7300 bd->resize_mode = RESIZE_BL;
7301 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7305 bd->resize_mode = RESIZE_L;
7306 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7310 return ECORE_CALLBACK_PASS_ON;
7313 bd->cur_mouse_action = e_action_find("window_resize");
7314 if (bd->cur_mouse_action)
7316 if ((!bd->cur_mouse_action->func.end_mouse) &&
7317 (!bd->cur_mouse_action->func.end))
7318 bd->cur_mouse_action = NULL;
7320 if (bd->cur_mouse_action)
7321 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7323 return ECORE_CALLBACK_PASS_ON;
7327 _e_border_cb_desktop_change(void *data __UNUSED__,
7328 int ev_type __UNUSED__,
7332 Ecore_X_Event_Desktop_Change *e;
7335 bd = e_border_find_by_client_window(e->win);
7338 if (e->desk == 0xffffffff)
7340 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7344 desk = e_desk_at_pos_get(bd->zone, e->desk);
7346 e_border_desk_set(bd, desk);
7351 ecore_x_netwm_desktop_set(e->win, e->desk);
7353 return ECORE_CALLBACK_PASS_ON;
7357 _e_border_cb_sync_alarm(void *data __UNUSED__,
7358 int ev_type __UNUSED__,
7362 Ecore_X_Event_Sync_Alarm *e;
7363 unsigned int serial;
7366 bd = e_border_find_by_alarm(e->alarm);
7367 if (!bd) return ECORE_CALLBACK_PASS_ON;
7369 if (bd->client.netwm.sync.wait)
7370 bd->client.netwm.sync.wait--;
7372 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7374 E_Border_Pending_Move_Resize *pnd = NULL;
7376 /* skip pending for which we didn't get a reply */
7377 while (bd->pending_move_resize)
7379 pnd = bd->pending_move_resize->data;
7380 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7382 if (serial == pnd->serial)
7394 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7395 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7400 bd->changes.size = 1;
7401 bd->changes.pos = 1;
7404 evas_render(bd->bg_evas);
7406 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7407 &bd->mouse.current.mx,
7408 &bd->mouse.current.my);
7410 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7411 _e_border_resize_handle(bd);
7413 return ECORE_CALLBACK_PASS_ON;
7417 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7418 int ev_type __UNUSED__,
7419 void *ev __UNUSED__)
7424 /* mark all borders for desktop/icon updates */
7425 EINA_LIST_FOREACH(borders, l, bd)
7429 efreet_desktop_free(bd->desktop);
7432 bd->changes.icon = 1;
7436 e_init_status_set(_("Desktop files scan done"));
7439 return ECORE_CALLBACK_PASS_ON;
7443 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7444 int ev_type __UNUSED__,
7445 void *ev __UNUSED__)
7450 /* mark all borders for desktop/icon updates */
7451 EINA_LIST_FOREACH(borders, l, bd)
7453 bd->changes.icon = 1;
7456 return ECORE_CALLBACK_PASS_ON;
7460 _e_border_cb_pointer_warp(void *data __UNUSED__,
7461 int ev_type __UNUSED__,
7464 E_Event_Pointer_Warp *e;
7467 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7468 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7469 return ECORE_CALLBACK_PASS_ON;
7473 _e_border_cb_signal_bind(void *data,
7474 Evas_Object *obj __UNUSED__,
7475 const char *emission,
7481 if (e_dnd_active()) return;
7482 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7487 _e_border_cb_mouse_in(void *data,
7488 int type __UNUSED__,
7491 Ecore_X_Event_Mouse_In *ev;
7496 #ifdef INOUTDEBUG_MOUSE
7501 const char *modes[] = {
7503 "MODE_WHILE_GRABBED",
7507 const char *details[] = {
7511 "DETAIL_NON_LINEAR",
7512 "DETAIL_NON_LINEAR_VIRTUAL",
7514 "DETAIL_POINTER_ROOT",
7515 "DETAIL_DETAIL_NONE"
7519 ct[strlen(ct) - 1] = 0;
7520 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7521 ev->win, ev->event_win,
7524 details[ev->detail]);
7527 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7528 if (ev->event_win == bd->win)
7530 e_focus_event_mouse_in(bd);
7533 if ((ev->win != bd->win) &&
7534 (ev->win != bd->event_win) &&
7535 (ev->event_win != bd->win) &&
7536 (ev->event_win != bd->event_win))
7537 return ECORE_CALLBACK_PASS_ON;
7539 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7541 bd->mouse.current.mx = ev->root.x;
7542 bd->mouse.current.my = ev->root.y;
7543 if (!bd->bg_evas_in)
7545 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7546 bd->bg_evas_in = EINA_TRUE;
7548 return ECORE_CALLBACK_PASS_ON;
7552 _e_border_cb_mouse_out(void *data,
7553 int type __UNUSED__,
7556 Ecore_X_Event_Mouse_Out *ev;
7561 #ifdef INOUTDEBUG_MOUSE
7566 const char *modes[] = {
7568 "MODE_WHILE_GRABBED",
7572 const char *details[] = {
7576 "DETAIL_NON_LINEAR",
7577 "DETAIL_NON_LINEAR_VIRTUAL",
7579 "DETAIL_POINTER_ROOT",
7580 "DETAIL_DETAIL_NONE"
7584 ct[strlen(ct) - 1] = 0;
7585 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7586 ev->win, ev->event_win,
7589 details[ev->detail]);
7592 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7593 if (ev->event_win == bd->win)
7596 return ECORE_CALLBACK_PASS_ON;
7597 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7598 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7599 return ECORE_CALLBACK_PASS_ON;
7600 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7601 return ECORE_CALLBACK_PASS_ON;
7602 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7603 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7604 return ECORE_CALLBACK_PASS_ON;
7605 e_focus_event_mouse_out(bd);
7608 if ((ev->win != bd->win) &&
7609 (ev->win != bd->event_win) &&
7610 (ev->event_win != bd->win) &&
7611 (ev->event_win != bd->event_win))
7612 return ECORE_CALLBACK_PASS_ON;
7614 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7616 bd->mouse.current.mx = ev->root.x;
7617 bd->mouse.current.my = ev->root.y;
7620 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7621 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7622 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7624 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7625 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7626 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7627 bd->bg_evas_in = EINA_FALSE;
7630 return ECORE_CALLBACK_PASS_ON;
7634 _e_border_cb_mouse_wheel(void *data,
7635 int type __UNUSED__,
7638 Ecore_Event_Mouse_Wheel *ev;
7643 if ((ev->event_window == bd->win) ||
7644 (ev->event_window == bd->event_win))
7646 bd->mouse.current.mx = ev->root.x;
7647 bd->mouse.current.my = ev->root.y;
7648 if (!bd->cur_mouse_action)
7649 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7652 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7653 return ECORE_CALLBACK_PASS_ON;
7657 _e_border_cb_mouse_down(void *data,
7658 int type __UNUSED__,
7661 Ecore_Event_Mouse_Button *ev;
7666 if ((ev->event_window == bd->win) ||
7667 (ev->event_window == bd->event_win))
7669 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7671 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7672 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7673 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7674 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7675 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7676 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7680 bd->moveinfo.down.x = bd->x + bd->fx.x;
7681 bd->moveinfo.down.y = bd->y + bd->fx.y;
7682 bd->moveinfo.down.w = bd->w;
7683 bd->moveinfo.down.h = bd->h;
7685 bd->mouse.current.mx = ev->root.x;
7686 bd->mouse.current.my = ev->root.y;
7687 if (!bd->cur_mouse_action)
7689 bd->cur_mouse_action =
7690 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7692 if (bd->cur_mouse_action)
7694 if ((!bd->cur_mouse_action->func.end_mouse) &&
7695 (!bd->cur_mouse_action->func.end))
7696 bd->cur_mouse_action = NULL;
7697 if (bd->cur_mouse_action)
7698 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7701 e_focus_event_mouse_down(bd);
7703 if (ev->window != ev->event_window)
7707 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7711 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7713 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7714 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7715 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7716 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7717 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7718 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7722 bd->moveinfo.down.x = bd->x + bd->fx.x;
7723 bd->moveinfo.down.y = bd->y + bd->fx.y;
7724 bd->moveinfo.down.w = bd->w;
7725 bd->moveinfo.down.h = bd->h;
7727 bd->mouse.current.mx = ev->root.x;
7728 bd->mouse.current.my = ev->root.y;
7733 else if (bd->resize_mode != RESIZE_NONE)
7739 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7741 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7742 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7743 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7745 return ECORE_CALLBACK_PASS_ON;
7749 _e_border_cb_mouse_up(void *data,
7750 int type __UNUSED__,
7753 Ecore_Event_Mouse_Button *ev;
7758 if ((ev->event_window == bd->win) ||
7759 (ev->event_window == bd->event_win))
7761 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7763 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7764 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7765 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7766 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7768 bd->mouse.current.mx = ev->root.x;
7769 bd->mouse.current.my = ev->root.y;
7770 /* also we dont pass the same params that went in - then again that */
7771 /* should be ok as we are just ending the action if it has an end */
7772 if (bd->cur_mouse_action)
7774 if (bd->cur_mouse_action->func.end_mouse)
7775 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7776 else if (bd->cur_mouse_action->func.end)
7777 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7778 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7779 bd->cur_mouse_action = NULL;
7783 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7784 e_focus_event_mouse_up(bd);
7787 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7788 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7790 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7791 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7792 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7793 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7795 bd->mouse.current.mx = ev->root.x;
7796 bd->mouse.current.my = ev->root.y;
7800 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7801 return ECORE_CALLBACK_PASS_ON;
7805 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7807 #ifdef _F_BORDER_CLIP_TO_ZONE_
7808 int new_x_max, new_y_max;
7809 int new_x_min, new_y_min;
7810 int margin_x, margin_y;
7812 margin_x = bd->w - 100;
7813 margin_y = bd->h - 100;
7815 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7816 new_x_min = bd->zone->x - margin_x;
7817 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7818 new_y_min = bd->zone->y - margin_y;
7820 if (x >= new_x_max) *new_x = new_x_max;
7821 else if (x <= new_x_min) *new_x = new_x_min;
7823 if (y >= new_y_max) *new_y = new_y_max;
7824 else if (y <= new_y_min) *new_y = new_y_min;
7829 _e_border_cb_mouse_move(void *data,
7830 int type __UNUSED__,
7833 Ecore_Event_Mouse_Move *ev;
7838 if ((ev->window != bd->event_win) &&
7839 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7840 bd->mouse.current.mx = ev->root.x;
7841 bd->mouse.current.my = ev->root.y;
7844 int x, y, new_x, new_y;
7846 Eina_List *skiplist = NULL;
7848 // FIXME: remove? sync what for when only moving?
7849 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7850 bd->client.netwm.sync.wait = 0;
7851 if ((bd->client.netwm.sync.request) &&
7852 (bd->client.netwm.sync.alarm) &&
7853 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7855 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7857 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7858 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7859 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7860 (bd->mouse.current.my - bd->moveinfo.down.my);
7864 x = bd->moveinfo.down.x +
7865 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7866 y = bd->moveinfo.down.y +
7867 (bd->mouse.current.my - bd->moveinfo.down.my);
7872 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7873 skiplist = eina_list_append(skiplist, bd);
7874 e_resist_container_border_position(bd->zone->container, skiplist,
7875 bd->x, bd->y, bd->w, bd->h,
7877 &new_x, &new_y, &new_w, &new_h);
7878 eina_list_free(skiplist);
7880 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7882 /* if (e_config->window_out_of_vscreen_limits_partly) */
7884 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7887 skiplist = eina_list_append(skiplist, bd);
7888 e_resist_container_border_position(bd->zone->container, skiplist,
7889 bd->x, bd->y, bd->w, bd->h,
7891 &new_x, &new_y, &new_w, &new_h);
7892 eina_list_free(skiplist);
7895 bd->shelf_fix.x = 0;
7896 bd->shelf_fix.y = 0;
7897 bd->shelf_fix.modified = 0;
7898 e_border_move(bd, new_x, new_y);
7899 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7901 else if (bd->resize_mode != RESIZE_NONE)
7903 if ((bd->client.netwm.sync.request) &&
7904 (bd->client.netwm.sync.alarm))
7906 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7908 E_Border_Pending_Move_Resize *pnd;
7910 if (bd->pending_move_resize)
7912 bd->changes.pos = 1;
7913 bd->changes.size = 1;
7915 _e_border_client_move_resize_send(bd);
7917 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7920 bd->client.netwm.sync.wait = 0;
7922 /* sync.wait is incremented when resize_handle sends
7923 * sync-request and decremented by sync-alarm cb. so
7924 * we resize here either on initial resize, timeout or
7925 * when no new resize-request was added by sync-alarm cb.
7927 if (!bd->client.netwm.sync.wait)
7928 _e_border_resize_handle(bd);
7931 _e_border_resize_handle(bd);
7937 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7939 bd->drag.x = ev->root.x;
7940 bd->drag.y = ev->root.y;
7946 dx = bd->drag.x - ev->root.x;
7947 dy = bd->drag.y - ev->root.y;
7948 if (((dx * dx) + (dy * dy)) >
7949 (e_config->drag_resist * e_config->drag_resist))
7952 if (bd->icon_object)
7954 Evas_Object *o = NULL;
7955 Evas_Coord x, y, w, h;
7956 const char *drag_types[] = { "enlightenment/border" };
7958 e_object_ref(E_OBJECT(bd));
7959 evas_object_geometry_get(bd->icon_object,
7961 drag_border = e_drag_new(bd->zone->container,
7962 bd->x + bd->fx.x + x,
7963 bd->y + bd->fx.y + y,
7964 drag_types, 1, bd, -1,
7966 _e_border_cb_drag_finished);
7967 o = e_border_icon_add(bd, drag_border->evas);
7970 /* FIXME: fallback icon for drag */
7971 o = evas_object_rectangle_add(drag_border->evas);
7972 evas_object_color_set(o, 255, 255, 255, 255);
7974 e_drag_object_set(drag_border, o);
7976 e_drag_resize(drag_border, w, h);
7977 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7983 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7985 return ECORE_CALLBACK_PASS_ON;
7989 _e_border_cb_grab_replay(void *data __UNUSED__,
7993 Ecore_Event_Mouse_Button *ev;
7995 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7997 if ((e_config->pass_click_on)
7998 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7999 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
8004 bd = e_border_find_by_window(ev->event_window);
8007 if (bd->cur_mouse_action)
8008 return ECORE_CALLBACK_DONE;
8009 if (ev->event_window == bd->win)
8011 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
8012 E_OBJECT(bd), ev, NULL))
8013 return ECORE_CALLBACK_PASS_ON;
8017 return ECORE_CALLBACK_DONE;
8021 _e_border_cb_drag_finished(E_Drag *drag,
8022 int dropped __UNUSED__)
8027 e_object_unref(E_OBJECT(bd));
8031 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8033 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
8034 int ev_type __UNUSED__,
8037 E_Event_Desk_Window_Profile_Change *e;
8042 EINA_LIST_FOREACH(borders, l, bd)
8044 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
8046 bd->client.e.fetch.profile_list = 1;
8050 return ECORE_CALLBACK_PASS_ON;
8054 #ifdef _F_ZONE_WINDOW_ROTATION_
8056 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
8057 int ev_type __UNUSED__,
8060 E_Event_Zone_Rotation_Change_Begin *e = ev;
8062 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8063 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
8065 if (!_e_border_rotation_zone_set(e->zone))
8067 /* there is no border which supports window manager rotation */
8068 e_zone_rotation_update_cancel(e->zone);
8070 return ECORE_CALLBACK_PASS_ON;
8074 _e_border_cb_rotation_sync_job(void *data)
8076 E_Zone *zone = data;
8078 E_Border_Rotation_Info *info = NULL;
8080 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
8084 EINA_LIST_FOREACH(rot.list, l, info)
8085 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
8086 if (!rot.wait_prepare_done)
8088 _e_border_rotation_change_request(zone);
8095 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
8096 ecore_job_del(rot.sync_job);
8097 rot.sync_job = NULL;
8102 _e_border_cb_rotation_async_job(void *data)
8104 E_Zone *zone = data;
8106 if (rot.list) goto end;
8108 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
8110 if (!rot.wait_prepare_done)
8112 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8113 rot.async_list = NULL;
8120 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8121 ecore_job_del(rot.async_job);
8122 rot.async_job = NULL;
8127 _e_border_rotation_change_prepare_timeout(void *data)
8129 E_Zone *zone = data;
8130 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8132 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8134 if ((zone) && (rot.wait_prepare_done))
8138 _e_border_rotation_change_request(zone);
8139 if (rot.prepare_timer)
8140 ecore_timer_del(rot.prepare_timer);
8141 rot.prepare_timer = NULL;
8142 rot.wait_prepare_done = EINA_FALSE;
8145 return ECORE_CALLBACK_CANCEL;
8149 _e_border_rotation_change_request(E_Zone *zone)
8151 if (!e_config->wm_win_rotation) return;
8152 if (!rot.list) return;
8153 if (eina_list_count(rot.list) <= 0) return;
8154 if (zone->rot.block_count) return;
8156 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8157 rot.prepare_timer = NULL;
8158 rot.wait_prepare_done = EINA_FALSE;
8160 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8163 ecore_timer_del(rot.done_timer);
8164 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8165 rot.done_timer = ecore_timer_add(5.0f,
8166 _e_border_rotation_change_done_timeout,
8171 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8174 E_Border_Rotation_Info *info =NULL;
8177 EINA_LIST_FOREACH (list, l, info)
8179 if (!info->bd) continue;
8180 if ((info->bd->client.e.state.rot.wait_for_done) &&
8181 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8183 _e_border_event_border_rotation_change_begin_send(info->bd);
8186 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8187 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8189 info->x = x; info->y = y;
8190 info->w = w; info->h = h;
8192 ELBF(ELBT_ROT, 1, info->bd->client.win,
8193 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8194 info->ang, info->win_resize, info->w, info->h);
8197 SECURE_SLOGD("[ROTATION] SEND PREP_ROT, win:0x%08x a%d resize%d %dx%d",
8198 info->bd->client.win, info->ang, info->win_resize,
8202 ecore_x_e_window_rotation_change_prepare_send
8203 (info->bd->client.win, info->ang,
8204 info->win_resize, info->w, info->h);
8206 if (!info->bd->client.e.state.rot.pending_change_request)
8208 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8210 SECURE_SLOGD("[ROTATION] SEND REQ_ROT, win:0x%08x, rot:%d",
8211 info->bd->client.win, info->ang);
8213 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8215 info->bd->client.e.state.rot.wait_for_done = 1;
8216 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8222 EINA_LIST_FREE(list, info)
8228 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8230 E_Border_Rotation_Info *info = NULL;
8232 if (send_request) _e_border_rotation_change_request(zone);
8235 EINA_LIST_FREE(rot.list, info)
8242 _e_border_rotation_list_remove(E_Border *bd)
8244 Eina_List *l = NULL;
8245 E_Border_Rotation_Info *info = NULL;
8246 E_Event_Border_Rotation_Change_End *ev = NULL;
8247 Eina_Bool found = EINA_FALSE;
8249 if (!e_config->wm_win_rotation) return;
8251 EINA_LIST_FOREACH(rot.list, l, info)
8255 rot.list = eina_list_remove(rot.list, info);
8261 if (bd->client.e.state.rot.wait_for_done)
8263 bd->client.e.state.rot.wait_for_done = 0;
8265 /* if we make the border event in the _e_border_free function,
8266 * then we may meet a crash problem, only work this at least e_border_hide.
8268 if (!e_object_is_del(E_OBJECT(bd)))
8270 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8274 e_object_ref(E_OBJECT(bd));
8275 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8277 _e_border_event_border_rotation_change_end_free,
8283 (eina_list_count(rot.list) == 0))
8285 _e_border_rotation_change_done();
8291 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8293 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8294 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8295 _e_border_rotation_change_done();
8296 return ECORE_CALLBACK_CANCEL;
8300 _e_border_rotation_change_done(void)
8302 E_Manager *m = NULL;
8303 E_Border_Rotation_Info *info = NULL;
8305 if (!e_config->wm_win_rotation) return;
8307 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8308 rot.prepare_timer = NULL;
8310 rot.wait_prepare_done = EINA_FALSE;
8312 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8313 rot.done_timer = NULL;
8315 EINA_LIST_FREE(rot.list, info)
8319 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8320 if (info->bd->client.e.state.rot.pending_show)
8322 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8323 e_border_show(info->bd);
8324 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8325 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8326 _e_border_check_stack(info->bd);
8328 info->bd->client.e.state.rot.pending_show = 0;
8330 info->bd->client.e.state.rot.wait_for_done = 0;
8335 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8338 rot.async_list = NULL;
8340 m = e_manager_current_get();
8341 e_manager_comp_screen_unlock(m);
8342 e_zone_rotation_update_done(e_util_zone_current_get(m));
8346 _prev_angle_get(Ecore_X_Window win)
8348 int ret, count = 0, ang = -1;
8349 unsigned char* data = NULL;
8351 ret = ecore_x_window_prop_property_get
8352 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8353 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8355 if ((ret) && (data) && (count))
8356 ang = ((int *)data)[0];
8357 if (data) free(data);
8361 /* get proper rotation value using preferred rotation and list of available rotations */
8363 _e_border_rotation_get(E_Border *bd,
8367 int current_ang = bd->client.e.state.rot.curr;
8369 Eina_Bool found = EINA_FALSE;
8370 Eina_Bool found_curr_ang = EINA_FALSE;
8372 if (!e_config->wm_win_rotation) return ang;
8373 if (!bd->client.e.state.rot.app_set) return ang;
8375 if (bd->client.e.state.rot.preferred_rot != -1)
8377 ang = bd->client.e.state.rot.preferred_rot;
8378 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8380 else if ((bd->client.e.state.rot.available_rots) &&
8381 (bd->client.e.state.rot.count))
8383 for (i = 0; i < bd->client.e.state.rot.count; i++)
8385 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8391 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8392 found_curr_ang = EINA_TRUE;
8395 /* do nothing. this window wants to maintain current state.
8396 * for example, window's available_rots: 0, 90, 270,
8397 * current zone rotation request: 180. the WM does nothing
8402 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8403 ang = bd->client.e.state.rot.curr;
8405 ang = bd->client.e.state.rot.available_rots[0];
8410 /* In this case, border doesn't have a list of
8411 * available rotations, thus WM should request
8412 * rotation with '0' degree to the application.
8421 _e_border_rotation_angle_get(E_Border *bd)
8423 E_Zone *zone = bd->zone;
8428 if (!e_config->wm_win_rotation) return ret;
8429 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8431 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8433 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8434 // should follow the state of rotation of zone.
8436 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8437 will_ang = bd->parent->client.e.state.rot.curr;
8438 else will_ang = zone->rot.curr;
8440 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8442 ELBF(ELBT_ROT, 1, bd->client.win,
8443 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8444 (rot.vkbd == bd) ? "vkbd" : "prediction",
8445 bd->parent ? bd->parent->client.win : 0,
8446 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8447 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8448 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8452 will_ang = bd->parent->client.e.state.rot.curr;
8453 if ((!bd->parent->client.e.state.rot.support) &&
8454 (!bd->parent->client.e.state.rot.app_set))
8461 if ((!bd->client.e.state.rot.app_set) &&
8462 (!bd->client.e.state.rot.support))
8464 /* hack for magnifier and keyboard popup */
8465 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8466 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8468 ELB(ELBT_BD, "MAG", bd->client.win);
8470 if ((rot.vkbd) && (rot.vkbd->visible))
8471 will_ang = rot.vkbd->client.e.state.rot.curr;
8475 if (bd->client.e.state.rot.app_set)
8477 /* utility type window should be rotated according to
8478 * rotation of the transient_for window.
8481 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8483 will_ang = bd->parent->client.e.state.rot.curr;
8484 if ((!bd->parent->client.e.state.rot.support) &&
8485 (!bd->parent->client.e.state.rot.app_set))
8487 /* if transient_for window doesn't support rotation feature,
8488 * then this window should't be rotated.
8489 * TODO: need to check whether window supports '0' degree or not.
8492 ELBF(ELBT_ROT, 0, bd->client.win,
8493 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8494 will_ang, bd->parent->client.win);
8498 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8499 ELBF(ELBT_ROT, 0, bd->client.win,
8500 "GET ROT ang:%d Transient_For:0x%08x",
8501 will_ang, bd->parent->client.win);
8506 will_ang = _e_border_rotation_get(bd, will_ang);
8507 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8508 will_ang, bd->parent ? bd->parent->client.win : 0,
8509 bd->client.netwm.type);
8515 _ang = _prev_angle_get(bd->client.win);
8517 bd->client.e.state.rot.curr = _ang;
8518 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8521 if (bd->client.e.state.rot.curr != will_ang)
8529 _e_border_rotation_zone_set(E_Zone *zone)
8531 E_Border_List *l = NULL;
8532 E_Border *bd = NULL;
8533 Eina_Bool ret = EINA_FALSE;
8535 if (!e_config->wm_win_rotation) return EINA_FALSE;
8537 l = e_container_border_list_last(zone->container);
8540 /* step 1. make the list needs to be rotated. */
8541 while ((bd = e_container_border_list_prev(l)))
8545 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8546 // it will be rotated when parent do rotate itself.
8549 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8551 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8552 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8553 // if it's not normal type window, will be rotated by illume.
8555 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8557 if ((!bd->visible) ||
8558 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8559 bd->x, bd->y, bd->w, bd->h))) continue;
8561 if (_e_border_rotatable_check(bd, zone->rot.curr))
8563 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8564 bd->client.e.state.rot.curr, zone->rot.curr);
8566 ret = e_border_rotation_set(bd, zone->rot.curr);
8569 if (l) e_container_border_list_free(l);
8575 _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
8577 E_Zone *zone = bd->zone;
8578 E_Border_Rotation_Info *info = NULL;
8579 Eina_List *list, *l;
8582 if (rotation < 0) return EINA_FALSE;
8583 if (pending) *pending = EINA_FALSE;
8585 /* step 1. check if rotation */
8586 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8588 /* step 2. add to async/sync list */
8589 if ((!zone->rot.block_count) &&
8591 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8593 // send rotation change request later.
8594 // and no need to wait message of rotation done.
8597 info = E_NEW(E_Border_Rotation_Info, 1);
8598 if (!info) return EINA_FALSE;
8599 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8601 info->ang = rotation;
8602 rot.async_list = eina_list_append(rot.async_list, info);
8604 // add job for sending event.
8607 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8608 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8614 info = E_NEW(E_Border_Rotation_Info, 1);
8615 if (!info) return EINA_FALSE;
8616 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8618 info->ang = rotation;
8619 rot.list = eina_list_append(rot.list, info);
8621 // add job for sending event.
8624 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8625 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8628 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8630 // but, DO NOT lock the screen when rotation block state.
8631 if ((!zone->rot.block_count) &&
8632 ((eina_list_count(rot.list) == 2)))
8633 e_manager_comp_screen_lock(e_manager_current_get());
8636 if (pending) *pending = EINA_TRUE;
8638 /* step 3. search rotatable window in this window's child */
8639 list = _e_border_sub_borders_new(bd);
8640 EINA_LIST_FOREACH(list, l, child)
8642 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8643 // it shouldn't be rotated by rotation state of parent window.
8644 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8645 if (_e_border_rotatable_check(child, rotation))
8647 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8648 bd->client.e.state.rot.curr, rotation);
8649 e_border_rotation_set(child, rotation);
8653 /* step 4. if there is vkbd window, send message to prepare rotation */
8654 if (_e_border_is_vkbd(bd))
8656 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8657 if (rot.prepare_timer)
8658 ecore_timer_del(rot.prepare_timer);
8659 rot.prepare_timer = NULL;
8662 ecore_timer_del(rot.done_timer);
8663 rot.done_timer = NULL;
8665 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8666 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8669 rot.prepare_timer = ecore_timer_add(4.0f,
8670 _e_border_rotation_change_prepare_timeout,
8673 rot.wait_prepare_done = EINA_TRUE;
8676 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8677 bd->client.e.state.rot.curr = rotation;
8682 // check if border is rotatable in ang.
8684 _e_border_rotatable_check(E_Border *bd, int ang)
8686 Eina_Bool ret = EINA_FALSE;
8688 if (!bd) return ret;
8689 if (ang < 0) return ret;
8690 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8691 if (e_object_is_del(E_OBJECT(bd))) return ret;
8693 // same with current angle of window, then false return.
8694 if (ang == bd->client.e.state.rot.curr) return ret;
8696 /* basically WM allows only fullscreen window to rotate */
8697 if (bd->client.e.state.rot.preferred_rot == -1)
8701 if (bd->client.e.state.rot.app_set)
8703 if (bd->client.e.state.rot.available_rots &&
8704 bd->client.e.state.rot.count)
8706 Eina_Bool found = EINA_FALSE;
8707 for (i = 0; i < bd->client.e.state.rot.count; i++)
8709 if (bd->client.e.state.rot.available_rots[i] == ang)
8714 if (found) ret = EINA_TRUE;
8719 ELB(ELBT_ROT, "DO ROT", 0);
8723 // if it has preferred rotation angle,
8724 // it will be rotated at border's evaluation time.
8726 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8731 /* check whether virtual keyboard is visible on the zone */
8733 _e_border_is_vkbd(E_Border *bd)
8735 if (!e_config->wm_win_rotation) return EINA_FALSE;
8737 if ((rot.vkbd_ctrl_win) &&
8739 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8740 (rot.vkbd->zone == bd->zone) &&
8741 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8742 bd->zone->w, bd->zone->h,
8743 rot.vkbd->x, rot.vkbd->y,
8744 rot.vkbd->w, rot.vkbd->h)))
8752 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8755 int min_title_width=96;
8757 if (!bd) return EINA_FALSE;
8758 if (!x || !y) return EINA_FALSE;
8763 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8764 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8765 // guaranteeing the minimum size of titlebar shown, min_title_width
8766 // so user can initiate drag&drop action after rotation changed.
8767 if (bd->client.e.state.rot.curr == 0)
8769 if (bd->client.e.state.rot.prev == 90)
8771 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8774 else if (bd->client.e.state.rot.prev == 270)
8777 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8779 else if (bd->client.e.state.rot.prev == 180)
8781 new_x = bd->zone->w - bd->x - bd->w;
8782 new_y = bd->zone->h - bd->y - bd->h;
8785 if(new_x + bd->w < min_title_width)
8787 new_x = min_title_width - bd->w;
8789 else if(new_x > bd->zone->w - min_title_width)
8791 new_x = bd->zone->w - min_title_width;
8794 else if (bd->client.e.state.rot.curr == 90)
8796 if (bd->client.e.state.rot.prev == 0)
8799 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8801 else if (bd->client.e.state.rot.prev == 270)
8803 new_x = bd->zone->w - bd->x - bd->w;
8804 new_y = bd->zone->h - bd->y - bd->h;
8806 else if (bd->client.e.state.rot.prev == 180)
8808 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8809 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8812 if(new_y > bd->zone->h - min_title_width)
8814 new_y = bd->zone->h - min_title_width;
8816 else if(new_y < min_title_width - bd->w)
8818 new_y = min_title_width - bd->w;
8821 else if (bd->client.e.state.rot.curr == 270)
8823 if (bd->client.e.state.rot.prev == 0)
8825 new_x = bd->zone->w - bd->h - (bd->y / 2);
8828 else if (bd->client.e.state.rot.prev == 90)
8830 new_x = bd->zone->w - bd->x - bd->w;
8831 new_y = bd->zone->h - bd->y - bd->h;
8833 else if (bd->client.e.state.rot.prev == 180)
8835 new_x = bd->zone->w - bd->x - bd->w;
8836 new_y = bd->zone->h - bd->y - bd->h;
8838 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8839 new_y = (bd->zone->w - bd->x - bd->w) * 2;
8842 if(new_y > bd->zone->h - min_title_width)
8844 new_y = bd->zone->h - min_title_width;
8846 else if( new_y + bd->w < min_title_width)
8848 new_y = min_title_width - bd->w ;
8851 else if (bd->client.e.state.rot.curr == 180)
8853 if (bd->client.e.state.rot.prev == 0)
8855 new_x = bd->zone->w - bd->x - bd->w;
8856 new_y = bd->zone->h - bd->y - bd->h;
8858 else if (bd->client.e.state.rot.prev == 90)
8860 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
8861 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8863 else if (bd->client.e.state.rot.prev == 270)
8865 new_x = bd->zone->w - (bd->y / 2) - bd->h;
8866 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
8869 if(new_x + bd->w < min_title_width)
8871 new_x = min_title_width - bd->w;
8873 else if(new_x > bd->zone->w - min_title_width)
8875 new_x = bd->zone->w - min_title_width;
8879 ELBF(ELBT_ROT, 0, bd->client.win,
8880 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
8881 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
8882 bd->x, bd->y, new_x, new_y);
8884 if ((new_x == *x) &&
8896 #define SIZE_EQUAL_TO_ZONE(a, z) \
8897 ((((a)->w) == ((z)->w)) && \
8898 (((a)->h) == ((z)->h)))
8900 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8902 E_Zone *zone = bd->zone;
8905 Eina_Bool move = EINA_FALSE;
8906 Eina_Bool hint = EINA_FALSE;
8907 Eina_Bool resize = EINA_FALSE;
8914 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8916 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8917 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8918 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8920 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8921 &_x, &_y, &_w, &_h, &move);
8924 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8926 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8927 bd->client.icccm.name, _x, _y, _w, _h);
8931 _x = bd->x; _y = bd->y;
8932 _w = bd->w; _h = bd->h;
8934 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
8935 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
8939 rot_dif = bd->client.e.state.rot.prev - rotation;
8940 if (rot_dif < 0) rot_dif = -rot_dif;
8949 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8950 EINA_TRUE, EINA_TRUE);
8951 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8952 bd->client.icccm.name, _x, _y, _w, _h);
8957 if (!resize && move)
8958 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
8973 _e_border_cb_window_configure(void *data __UNUSED__,
8974 int ev_type __UNUSED__,
8977 Ecore_X_Event_Window_Configure *e = ev;
8978 E_Border_Rotation_Info *info = NULL;
8980 Eina_Bool found = EINA_FALSE;
8982 if (!e) return ECORE_CALLBACK_PASS_ON;
8983 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8985 E_Border *bd = e_border_find_by_client_window(e->win);
8986 if (!bd) return ECORE_CALLBACK_PASS_ON;
8988 if (bd->client.e.state.rot.pending_change_request)
8990 if ((e->w == bd->w) && (e->h == bd->h))
8992 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8993 bd->client.e.state.rot.pending_change_request = 0;
8995 if ((bd->client.e.state.rot.wait_for_done) &&
8996 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8998 // if this window is rotation dependent window and zone is blocked to rotate,
8999 // then skip here, request will be sent after cancel block.
9000 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
9001 (bd->zone->rot.block_count)) goto end;
9003 EINA_LIST_FOREACH(rot.list, l, info)
9004 if (info->bd == bd) found = EINA_TRUE;
9005 // send request message if it's async rotation window,
9006 // even if wait prepare done.
9007 if ((found) && (rot.wait_prepare_done)) goto end;
9009 ELBF(ELBT_ROT, 0, bd->client.win,
9010 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
9011 bd->client.e.state.rot.curr,
9014 SECURE_SLOGD("[ROTATION] SEND REQ_ROT(CONFIGURE_NOTI), win:0x%08x, rot:%d",
9015 bd->client.win, bd->client.e.state.rot.curr);
9017 ecore_x_e_window_rotation_change_request_send(bd->client.win,
9018 bd->client.e.state.rot.curr);
9019 bd->client.e.state.rot.wait_for_done = 1;
9020 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
9025 return ECORE_CALLBACK_PASS_ON;
9029 _e_border_rotation_geom_get(E_Border *bd,
9038 if (!e_config->wm_win_rotation) return EINA_FALSE;
9040 Eina_Bool res = EINA_FALSE;
9041 Eina_Bool _move = EINA_TRUE;
9051 if (move) *move = EINA_TRUE;
9053 if (bd->client.e.state.rot.geom_hint)
9058 _w = bd->client.e.state.rot.geom[0].w;
9059 _h = bd->client.e.state.rot.geom[0].h;
9060 if (_w == 0) _w = bd->w;
9061 if (_h == 0) _h = bd->h;
9062 _x = 0; _y = zone->h - _h;
9065 _w = bd->client.e.state.rot.geom[1].w;
9066 _h = bd->client.e.state.rot.geom[1].h;
9067 if (_w == 0) _w = bd->w;
9068 if (_h == 0) _h = bd->h;
9069 _x = zone->w - _w; _y = 0;
9072 _w = bd->client.e.state.rot.geom[2].w;
9073 _h = bd->client.e.state.rot.geom[2].h;
9074 if (_w == 0) _w = bd->w;
9075 if (_h == 0) _h = bd->h;
9079 _w = bd->client.e.state.rot.geom[3].w;
9080 _h = bd->client.e.state.rot.geom[3].h;
9081 if (_w == 0) _w = bd->w;
9082 if (_h == 0) _h = bd->h;
9092 if (!((rot.vkbd) && (rot.vkbd == bd)))
9096 if (move) *move = EINA_FALSE;
9104 _x = 0; _y = 0; _w = 0; _h = 0;
9109 if (move) _move = *move;
9111 ELBF(ELBT_ROT, 1, bd->client.win,
9112 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
9113 ang, _x, _y, _w, _h, _move);
9121 _e_border_post_move_resize_job(void *data)
9125 bd = (E_Border *)data;
9131 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9132 ecore_x_window_move(tmp->win,
9134 bd->client_inset.l +
9136 tmp->client.e.state.video_position.x,
9138 bd->client_inset.t +
9140 tmp->client.e.state.video_position.y);
9142 if (bd->client.e.state.video)
9146 parent = bd->client.e.state.video_parent_border;
9147 ecore_x_window_move(bd->win,
9149 parent->client_inset.l +
9151 bd->client.e.state.video_position.x,
9153 parent->client_inset.t +
9155 bd->client.e.state.video_position.y);
9157 else if ((bd->post_move) && (bd->post_resize))
9159 ecore_x_window_move_resize(bd->win,
9164 else if (bd->post_move)
9166 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9168 else if (bd->post_resize)
9170 ecore_x_window_resize(bd->win, bd->w, bd->h);
9173 if (bd->client.e.state.video)
9175 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9177 bd->client.e.state.video_parent_border->x +
9178 bd->client.e.state.video_parent_border->client_inset.l +
9179 bd->client.e.state.video_parent_border->fx.x +
9180 bd->client.e.state.video_position.x,
9181 bd->client.e.state.video_parent_border->y +
9182 bd->client.e.state.video_parent_border->client_inset.t +
9183 bd->client.e.state.video_parent_border->fx.y +
9184 bd->client.e.state.video_position.y,
9192 bd->post_job = NULL;
9198 bd->post_resize = 0;
9199 bd->post_job = NULL;
9200 return ECORE_CALLBACK_CANCEL;
9204 _e_border_container_layout_hook(E_Container *con)
9206 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9210 _e_border_eval0(E_Border *bd)
9212 int change_urgent = 0;
9214 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9215 Eina_Bool need_desk_set = EINA_FALSE;
9217 #ifdef _F_ZONE_WINDOW_ROTATION_
9218 Eina_Bool need_rotation_set = EINA_FALSE;
9220 if ((e_config->wm_win_rotation) &&
9221 (bd->client.icccm.fetch.transient_for))
9223 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9224 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9226 need_rotation_set = EINA_TRUE;
9227 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9232 if (e_object_is_del(E_OBJECT(bd)))
9234 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9239 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9241 bd->changes.border = 0;
9243 /* fetch any info queued to be fetched */
9244 if (bd->client.netwm.fetch.state)
9246 e_hints_window_state_get(bd);
9247 bd->client.netwm.fetch.state = 0;
9250 if (bd->client.icccm.fetch.client_leader)
9252 /* TODO: What do to if the client leader isn't mapped yet? */
9253 E_Border *bd_leader = NULL;
9255 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9256 if (bd->client.icccm.client_leader)
9257 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9260 if (bd->leader != bd_leader)
9262 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9263 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9269 /* If this border is the leader of the group, don't register itself */
9270 if ((bd_leader) && (bd_leader != bd))
9272 bd_leader->group = eina_list_append(bd_leader->group, bd);
9273 bd->leader = bd_leader;
9274 /* Only set the window modal to the leader it there is no parent */
9275 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9276 ((!bd->parent) || (bd->parent->modal != bd)))
9278 bd->leader->modal = bd;
9279 if (bd->leader->focused)
9280 e_border_focus_set(bd, 1, 1);
9286 EINA_LIST_FOREACH(bd->leader->group, l, child)
9288 if ((child != bd) && (child->focused))
9289 e_border_focus_set(bd, 1, 1);
9294 bd->client.icccm.fetch.client_leader = 0;
9297 if (bd->client.icccm.fetch.title)
9299 char *title = ecore_x_icccm_title_get(bd->client.win);
9300 eina_stringshare_replace(&bd->client.icccm.title, title);
9301 if (title) free(title);
9304 edje_object_part_text_set(bd->bg_object, "e.text.title",
9305 bd->client.icccm.title);
9306 bd->client.icccm.fetch.title = 0;
9309 if (bd->client.netwm.fetch.name)
9312 ecore_x_netwm_name_get(bd->client.win, &name);
9313 eina_stringshare_replace(&bd->client.netwm.name, name);
9314 if (name) free(name);
9317 edje_object_part_text_set(bd->bg_object, "e.text.title",
9318 bd->client.netwm.name);
9319 bd->client.netwm.fetch.name = 0;
9322 if (bd->client.icccm.fetch.name_class)
9324 const char *pname, *pclass;
9325 char *nname, *nclass;
9327 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9328 pname = bd->client.icccm.name;
9329 pclass = bd->client.icccm.class;
9330 bd->client.icccm.name = eina_stringshare_add(nname);
9331 bd->client.icccm.class = eina_stringshare_add(nclass);
9332 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9333 e_bindings_mapping_change_enable(EINA_FALSE);
9334 #ifdef _F_ZONE_WINDOW_ROTATION_
9335 if (e_config->wm_win_rotation)
9337 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9339 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9340 (!strcmp(bd->client.icccm.class, "ISF")))
9342 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9343 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9346 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9347 (!strcmp(bd->client.icccm.class, "ISF")))
9349 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9350 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9351 rot.vkbd_prediction = bd;
9353 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9354 (!strcmp(bd->client.icccm.class, "ISF")))
9356 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9357 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9359 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9360 (!strcmp(bd->client.icccm.class, "ISF")))
9362 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9363 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9368 if (nname) free(nname);
9369 if (nclass) free(nclass);
9371 if (!((bd->client.icccm.name == pname) &&
9372 (bd->client.icccm.class == pclass)))
9373 bd->changes.icon = 1;
9375 if (pname) eina_stringshare_del(pname);
9376 if (pclass) eina_stringshare_del(pclass);
9377 bd->client.icccm.fetch.name_class = 0;
9378 bd->changes.icon = 1;
9381 if (bd->client.icccm.fetch.state)
9383 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9384 bd->client.icccm.fetch.state = 0;
9387 if (bd->client.e.fetch.state)
9389 e_hints_window_e_state_get(bd);
9390 bd->client.e.fetch.state = 0;
9393 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9394 if (bd->client.e.fetch.profile_list)
9396 const char **profiles = NULL;
9400 if (bd->client.e.state.profile)
9401 eina_stringshare_del(bd->client.e.state.profile);
9402 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9404 if (str) eina_stringshare_del(str);
9406 bd->client.e.state.profile = NULL;
9407 bd->client.e.state.profiles = NULL;
9408 bd->client.e.state.profile_list = 0;
9410 if (ecore_x_e_window_profile_list_get(bd->client.win,
9413 bd->client.e.state.profile_list = 1;
9414 for (i = 0; i < num; i++)
9416 str = eina_stringshare_add(profiles[i]);
9417 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9420 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9421 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9423 need_desk_set = EINA_TRUE;
9427 if (strcmp(bd->desk->window_profile,
9428 e_config->desktop_default_window_profile) != 0)
9430 ecore_x_e_window_profile_set(bd->client.win,
9431 bd->desk->window_profile);
9437 for (i = 0; i < num; i++)
9438 if (profiles[i]) free(profiles[i]);
9442 bd->client.e.fetch.profile_list = 0;
9445 #ifdef _F_ZONE_WINDOW_ROTATION_
9446 if ((e_config->wm_win_rotation) &&
9447 (bd->client.e.fetch.rot.support))
9450 unsigned int support = 0;
9452 ret = ecore_x_window_prop_card32_get
9454 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9457 bd->client.e.state.rot.support = 0;
9458 if ((ret == 1) && (support == 1))
9459 bd->client.e.state.rot.support = 1;
9461 if (bd->client.e.state.rot.support)
9462 need_rotation_set = EINA_TRUE;
9464 bd->client.e.fetch.rot.support = 0;
9466 if ((e_config->wm_win_rotation) &&
9467 (bd->client.e.fetch.rot.geom_hint))
9469 Eina_Rectangle r[4];
9471 bd->client.e.state.rot.geom_hint = 0;
9472 for (i = 0; i < 4; i++)
9474 r[i].x = bd->client.e.state.rot.geom[i].x;
9475 r[i].y = bd->client.e.state.rot.geom[i].y;
9476 r[i].w = bd->client.e.state.rot.geom[i].w;
9477 r[i].h = bd->client.e.state.rot.geom[i].h;
9479 bd->client.e.state.rot.geom[i].x = 0;
9480 bd->client.e.state.rot.geom[i].y = 0;
9481 bd->client.e.state.rot.geom[i].w = 0;
9482 bd->client.e.state.rot.geom[i].h = 0;
9485 for (i = 0; i < 4; i++)
9487 x = 0; y = 0; w = 0; h = 0;
9488 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9490 bd->client.e.state.rot.geom_hint = 1;
9491 bd->client.e.state.rot.geom[i].x = x;
9492 bd->client.e.state.rot.geom[i].y = y;
9493 bd->client.e.state.rot.geom[i].w = w;
9494 bd->client.e.state.rot.geom[i].h = h;
9496 if (!((r[i].x == x) && (r[i].y == y) &&
9497 (r[i].w == w) && (r[i].h == h)))
9499 need_rotation_set = EINA_TRUE;
9503 bd->client.e.fetch.rot.geom_hint = 0;
9505 if ((e_config->wm_win_rotation) &&
9506 (bd->client.e.fetch.rot.app_set))
9508 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9509 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9510 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9512 if (_prev_app_set != bd->client.e.state.rot.app_set)
9513 need_rotation_set = EINA_TRUE;
9515 bd->client.e.fetch.rot.app_set = 0;
9517 if ((e_config->wm_win_rotation) &&
9518 (bd->client.e.fetch.rot.preferred_rot))
9520 int r = 0, _prev_preferred_rot;
9521 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9522 bd->client.e.state.rot.preferred_rot = -1;
9523 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9525 bd->client.e.state.rot.preferred_rot = r;
9526 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9530 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9533 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9534 need_rotation_set = EINA_TRUE;
9536 bd->client.e.fetch.rot.preferred_rot = 0;
9538 if ((e_config->wm_win_rotation) &&
9539 (bd->client.e.fetch.rot.available_rots))
9541 Eina_Bool res, diff = EINA_FALSE;
9543 unsigned int count = 0, i = 0;
9544 int _prev_rots[4] = { -1, };
9546 if (bd->client.e.state.rot.available_rots)
9549 bd->client.e.state.rot.available_rots,
9550 (sizeof(int) * bd->client.e.state.rot.count));
9552 E_FREE(bd->client.e.state.rot.available_rots);
9555 bd->client.e.state.rot.count = 0;
9557 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9559 if ((res) && (count > 0) && (rots))
9561 bd->client.e.state.rot.available_rots = rots;
9562 bd->client.e.state.rot.count = count;
9564 for (i = 0; i < count; i++)
9566 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9567 if ((!diff) && (_prev_rots[i] != rots[i]))
9569 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9570 count, i, _prev_rots[i], rots[i]);
9577 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9581 if (diff) need_rotation_set = EINA_TRUE;
9582 bd->client.e.fetch.rot.available_rots = 0;
9585 if (bd->client.netwm.fetch.type)
9587 e_hints_window_type_get(bd);
9588 if ((!bd->lock_border) || (!bd->client.border.name))
9589 bd->client.border.changed = 1;
9591 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9593 if (!bd->client.netwm.state.skip_pager)
9595 bd->client.netwm.state.skip_pager = 1;
9596 bd->client.netwm.update.state = 1;
9598 if (!bd->client.netwm.state.skip_taskbar)
9600 bd->client.netwm.state.skip_taskbar = 1;
9601 bd->client.netwm.update.state = 1;
9604 bd->client.netwm.fetch.type = 0;
9606 if (bd->client.icccm.fetch.machine)
9608 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9610 if ((!machine) && (bd->client.icccm.client_leader))
9611 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9613 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9614 if (machine) free(machine);
9616 bd->client.icccm.fetch.machine = 0;
9619 if (bd->client.icccm.fetch.command)
9621 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9625 for (i = 0; i < bd->client.icccm.command.argc; i++)
9626 free(bd->client.icccm.command.argv[i]);
9627 free(bd->client.icccm.command.argv);
9629 bd->client.icccm.command.argc = 0;
9630 bd->client.icccm.command.argv = NULL;
9631 ecore_x_icccm_command_get(bd->client.win,
9632 &(bd->client.icccm.command.argc),
9633 &(bd->client.icccm.command.argv));
9634 if ((bd->client.icccm.client_leader) &&
9635 (!bd->client.icccm.command.argv))
9636 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9637 &(bd->client.icccm.command.argc),
9638 &(bd->client.icccm.command.argv));
9639 bd->client.icccm.fetch.command = 0;
9642 if (bd->client.icccm.fetch.hints)
9644 Eina_Bool accepts_focus, is_urgent;
9646 accepts_focus = EINA_TRUE;
9647 is_urgent = EINA_FALSE;
9648 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9649 if (ecore_x_icccm_hints_get(bd->client.win,
9651 &bd->client.icccm.initial_state,
9652 &bd->client.icccm.icon_pixmap,
9653 &bd->client.icccm.icon_mask,
9654 &bd->client.icccm.icon_window,
9655 &bd->client.icccm.window_group,
9658 bd->client.icccm.accepts_focus = accepts_focus;
9659 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9661 bd->client.icccm.urgent = is_urgent;
9663 /* If this is a new window, set the state as requested. */
9664 if ((bd->new_client) &&
9665 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9667 e_border_iconify(bd);
9668 e_border_hide(bd, 1);
9671 bd->client.icccm.fetch.hints = 0;
9674 if (bd->client.icccm.fetch.size_pos_hints)
9676 Eina_Bool request_pos;
9678 request_pos = EINA_FALSE;
9679 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9681 &bd->client.icccm.gravity,
9682 &bd->client.icccm.min_w,
9683 &bd->client.icccm.min_h,
9684 &bd->client.icccm.max_w,
9685 &bd->client.icccm.max_h,
9686 &bd->client.icccm.base_w,
9687 &bd->client.icccm.base_h,
9688 &bd->client.icccm.step_w,
9689 &bd->client.icccm.step_h,
9690 &bd->client.icccm.min_aspect,
9691 &bd->client.icccm.max_aspect))
9693 bd->client.icccm.request_pos = request_pos;
9698 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9699 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9700 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9701 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9702 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9703 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9704 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9705 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9706 // if doing a resize, fix it up
9707 if (bd->resize_mode != RESIZE_NONE)
9709 int x, y, w, h, new_w, new_h;
9717 e_border_resize_limit(bd, &new_w, &new_h);
9718 if ((bd->resize_mode == RESIZE_TL) ||
9719 (bd->resize_mode == RESIZE_L) ||
9720 (bd->resize_mode == RESIZE_BL))
9722 if ((bd->resize_mode == RESIZE_TL) ||
9723 (bd->resize_mode == RESIZE_T) ||
9724 (bd->resize_mode == RESIZE_TR))
9726 e_border_move_resize(bd, x, y, new_w, new_h);
9728 bd->client.icccm.fetch.size_pos_hints = 0;
9731 if (bd->client.icccm.fetch.protocol)
9734 Ecore_X_WM_Protocol *proto;
9736 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9739 for (i = 0; i < num; i++)
9741 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9742 bd->client.icccm.delete_request = 1;
9743 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9744 bd->client.icccm.take_focus = 1;
9745 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9746 bd->client.netwm.ping = 1;
9747 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9749 bd->client.netwm.sync.request = 1;
9750 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9751 &bd->client.netwm.sync.counter))
9752 bd->client.netwm.sync.request = 0;
9757 if (bd->client.netwm.ping)
9761 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9762 bd->ping_poller = NULL;
9764 bd->client.icccm.fetch.protocol = 0;
9766 if (bd->client.icccm.fetch.transient_for)
9768 /* TODO: What do to if the transient for isn't mapped yet? */
9769 E_Border *bd_parent = NULL;
9770 #ifdef _F_DEICONIFY_APPROVE_
9771 Eina_Bool change_parent = EINA_FALSE;
9774 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9775 if (bd->client.icccm.transient_for)
9776 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9777 /* If we already have a parent, remove it */
9780 if (bd_parent != bd->parent)
9782 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9783 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9789 if ((bd_parent) && (bd_parent != bd) &&
9790 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9792 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9793 bd->parent = bd_parent;
9794 #ifdef _F_DEICONIFY_APPROVE_
9795 change_parent = EINA_TRUE;
9800 e_border_layer_set(bd, bd->parent->layer);
9801 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9803 Ecore_X_Window_Attributes attr;
9804 bd->parent->modal = bd;
9805 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9806 bd->parent->saved.event_mask = attr.event_mask.mine;
9807 bd->parent->lock_close = 1;
9808 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9809 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9812 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9813 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9817 #ifdef _F_DEICONIFY_APPROVE_
9820 bd->client.e.state.deiconify_approve.render_done = 0;
9822 E_Border *ancestor_bd;
9823 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9824 if ((ancestor_bd) &&
9825 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9827 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9828 bd->client.e.state.deiconify_approve.ancestor = NULL;
9830 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9831 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9833 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9835 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9836 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9837 e_border_uniconify(ancestor_bd);
9843 bd->client.icccm.fetch.transient_for = 0;
9846 if (bd->client.icccm.fetch.window_role)
9848 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9849 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9850 if (role) free(role);
9852 bd->client.icccm.fetch.window_role = 0;
9855 if (bd->client.icccm.fetch.icon_name)
9857 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9858 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9859 if (icon_name) free(icon_name);
9861 bd->client.icccm.fetch.icon_name = 0;
9864 if (bd->client.netwm.fetch.icon_name)
9867 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9868 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9869 if (icon_name) free(icon_name);
9871 bd->client.netwm.fetch.icon_name = 0;
9874 if (bd->client.netwm.fetch.icon)
9877 if (bd->client.netwm.icons)
9879 for (i = 0; i < bd->client.netwm.num_icons; i++)
9881 free(bd->client.netwm.icons[i].data);
9882 bd->client.netwm.icons[i].data = NULL;
9884 free(bd->client.netwm.icons);
9886 bd->client.netwm.icons = NULL;
9887 bd->client.netwm.num_icons = 0;
9888 if (ecore_x_netwm_icons_get(bd->client.win,
9889 &bd->client.netwm.icons,
9890 &bd->client.netwm.num_icons))
9892 // unless the rest of e17 uses border icons OTHER than icon #0
9893 // then free the rest that we don't need anymore.
9894 for (i = 1; i < bd->client.netwm.num_icons; i++)
9896 free(bd->client.netwm.icons[i].data);
9897 bd->client.netwm.icons[i].data = NULL;
9899 bd->client.netwm.num_icons = 1;
9900 bd->changes.icon = 1;
9902 bd->client.netwm.fetch.icon = 0;
9904 if (bd->client.netwm.fetch.user_time)
9906 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9907 bd->client.netwm.fetch.user_time = 0;
9909 if (bd->client.netwm.fetch.strut)
9911 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9912 &bd->client.netwm.strut.left,
9913 &bd->client.netwm.strut.right,
9914 &bd->client.netwm.strut.top,
9915 &bd->client.netwm.strut.bottom,
9916 &bd->client.netwm.strut.left_start_y,
9917 &bd->client.netwm.strut.left_end_y,
9918 &bd->client.netwm.strut.right_start_y,
9919 &bd->client.netwm.strut.right_end_y,
9920 &bd->client.netwm.strut.top_start_x,
9921 &bd->client.netwm.strut.top_end_x,
9922 &bd->client.netwm.strut.bottom_start_x,
9923 &bd->client.netwm.strut.bottom_end_x))
9925 ecore_x_netwm_strut_get(bd->client.win,
9926 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9927 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9929 bd->client.netwm.strut.left_start_y = 0;
9930 bd->client.netwm.strut.left_end_y = 0;
9931 bd->client.netwm.strut.right_start_y = 0;
9932 bd->client.netwm.strut.right_end_y = 0;
9933 bd->client.netwm.strut.top_start_x = 0;
9934 bd->client.netwm.strut.top_end_x = 0;
9935 bd->client.netwm.strut.bottom_start_x = 0;
9936 bd->client.netwm.strut.bottom_end_x = 0;
9938 bd->client.netwm.fetch.strut = 0;
9940 if (bd->client.qtopia.fetch.soft_menu)
9942 e_hints_window_qtopia_soft_menu_get(bd);
9943 bd->client.qtopia.fetch.soft_menu = 0;
9946 if (bd->client.qtopia.fetch.soft_menus)
9948 e_hints_window_qtopia_soft_menus_get(bd);
9949 bd->client.qtopia.fetch.soft_menus = 0;
9952 if (bd->client.vkbd.fetch.state)
9954 e_hints_window_virtual_keyboard_state_get(bd);
9955 bd->client.vkbd.fetch.state = 0;
9958 if (bd->client.vkbd.fetch.vkbd)
9960 e_hints_window_virtual_keyboard_get(bd);
9961 bd->client.vkbd.fetch.vkbd = 0;
9964 if (bd->client.illume.conformant.fetch.conformant)
9966 bd->client.illume.conformant.conformant =
9967 ecore_x_e_illume_conformant_get(bd->client.win);
9968 bd->client.illume.conformant.fetch.conformant = 0;
9970 if (bd->client.illume.quickpanel.fetch.state)
9972 bd->client.illume.quickpanel.state =
9973 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9974 bd->client.illume.quickpanel.fetch.state = 0;
9976 if (bd->client.illume.quickpanel.fetch.quickpanel)
9978 bd->client.illume.quickpanel.quickpanel =
9979 ecore_x_e_illume_quickpanel_get(bd->client.win);
9980 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9982 if (bd->client.illume.quickpanel.fetch.priority.major)
9984 bd->client.illume.quickpanel.priority.major =
9985 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9986 bd->client.illume.quickpanel.fetch.priority.major = 0;
9988 if (bd->client.illume.quickpanel.fetch.priority.minor)
9990 bd->client.illume.quickpanel.priority.minor =
9991 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9992 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9994 if (bd->client.illume.quickpanel.fetch.zone)
9996 bd->client.illume.quickpanel.zone =
9997 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9998 bd->client.illume.quickpanel.fetch.zone = 0;
10000 if (bd->client.illume.drag.fetch.drag)
10002 bd->client.illume.drag.drag =
10003 ecore_x_e_illume_drag_get(bd->client.win);
10004 bd->client.illume.drag.fetch.drag = 0;
10006 if (bd->client.illume.drag.fetch.locked)
10008 bd->client.illume.drag.locked =
10009 ecore_x_e_illume_drag_locked_get(bd->client.win);
10010 bd->client.illume.drag.fetch.locked = 0;
10012 if (bd->client.illume.win_state.fetch.state)
10014 bd->client.illume.win_state.state =
10015 ecore_x_e_illume_window_state_get(bd->client.win);
10016 bd->client.illume.win_state.fetch.state = 0;
10018 if (bd->changes.shape)
10020 Ecore_X_Rectangle *rects;
10023 bd->changes.shape = 0;
10024 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
10027 int cw = 0, ch = 0;
10029 /* This doesn't fix the race, but makes it smaller. we detect
10030 * this and if cw and ch != client w/h then mark this as needing
10031 * a shape change again to fixup next event loop.
10033 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10034 if ((cw != bd->client.w) || (ch != bd->client.h))
10035 bd->changes.shape = 1;
10037 (rects[0].x == 0) &&
10038 (rects[0].y == 0) &&
10039 ((int)rects[0].width == cw) &&
10040 ((int)rects[0].height == ch))
10042 if (bd->client.shaped)
10044 bd->client.shaped = 0;
10045 if (!bd->bordername)
10046 bd->client.border.changed = 1;
10051 if (!bd->client.shaped)
10053 bd->client.shaped = 1;
10054 if (!bd->bordername)
10055 bd->client.border.changed = 1;
10062 // FIXME: no rects i think can mean... totally empty window
10063 bd->client.shaped = 0;
10064 if (!bd->bordername)
10065 bd->client.border.changed = 1;
10067 bd->need_shape_merge = 1;
10069 if (bd->changes.shape_input)
10071 Ecore_X_Rectangle *rects;
10074 bd->changes.shape_input = 0;
10075 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
10078 int cw = 0, ch = 0;
10080 /* This doesn't fix the race, but makes it smaller. we detect
10081 * this and if cw and ch != client w/h then mark this as needing
10082 * a shape change again to fixup next event loop.
10084 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10085 if ((cw != bd->client.w) || (ch != bd->client.h))
10086 bd->changes.shape_input = 1;
10088 (rects[0].x == 0) &&
10089 (rects[0].y == 0) &&
10090 ((int)rects[0].width == cw) &&
10091 ((int)rects[0].height == ch))
10093 if (bd->shaped_input)
10095 bd->shaped_input = 0;
10096 if (!bd->bordername)
10097 bd->client.border.changed = 1;
10102 if (!bd->shaped_input)
10104 bd->shaped_input = 1;
10105 if (!bd->bordername)
10106 bd->client.border.changed = 1;
10113 bd->shaped_input = 1;
10114 if (!bd->bordername)
10115 bd->client.border.changed = 1;
10117 bd->need_shape_merge = 1;
10119 if (bd->client.mwm.fetch.hints)
10123 bd->client.mwm.exists =
10124 ecore_x_mwm_hints_get(bd->client.win,
10125 &bd->client.mwm.func,
10126 &bd->client.mwm.decor,
10127 &bd->client.mwm.input);
10128 pb = bd->client.mwm.borderless;
10129 bd->client.mwm.borderless = 0;
10130 if (bd->client.mwm.exists)
10132 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
10133 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10134 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10135 bd->client.mwm.borderless = 1;
10137 if (bd->client.mwm.borderless != pb)
10139 if ((!bd->lock_border) || (!bd->client.border.name))
10140 bd->client.border.changed = 1;
10142 bd->client.mwm.fetch.hints = 0;
10145 if (bd->client.e.fetch.video_parent)
10147 /* unlinking child/parent */
10148 if (bd->client.e.state.video_parent_border != NULL)
10150 bd->client.e.state.video_parent_border->client.e.state.video_child =
10152 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10156 ecore_x_window_prop_card32_get(bd->client.win,
10157 ECORE_X_ATOM_E_VIDEO_PARENT,
10158 &bd->client.e.state.video_parent,
10161 /* linking child/parent */
10162 if (bd->client.e.state.video_parent != 0)
10167 EINA_LIST_FOREACH(borders, l, tmp)
10168 if (tmp->client.win == bd->client.e.state.video_parent)
10170 /* fprintf(stderr, "child added to parent \\o/\n"); */
10171 bd->client.e.state.video_parent_border = tmp;
10172 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10174 if (bd->desk != tmp->desk)
10175 e_border_desk_set(bd, tmp->desk);
10180 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10182 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10185 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10187 unsigned int xy[2];
10189 ecore_x_window_prop_card32_get(bd->client.win,
10190 ECORE_X_ATOM_E_VIDEO_POSITION,
10193 bd->client.e.state.video_position.x = xy[0];
10194 bd->client.e.state.video_position.y = xy[1];
10195 bd->client.e.state.video_position.updated = 1;
10196 bd->client.e.fetch.video_position = 0;
10197 bd->x = bd->client.e.state.video_position.x;
10198 bd->y = bd->client.e.state.video_position.y;
10200 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10202 if (bd->client.netwm.update.state)
10204 e_hints_window_state_set(bd);
10205 /* Some stats might change the border, like modal */
10206 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10207 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10209 bd->client.border.changed = 1;
10213 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10215 bd->parent->modal = bd;
10216 if (bd->parent->focused)
10217 e_border_focus_set(bd, 1, 1);
10220 else if (bd->leader)
10222 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10224 bd->leader->modal = bd;
10225 if (bd->leader->focused)
10226 e_border_focus_set(bd, 1, 1);
10232 EINA_LIST_FOREACH(bd->leader->group, l, child)
10234 if ((child != bd) && (child->focused))
10235 e_border_focus_set(bd, 1, 1);
10240 bd->client.netwm.update.state = 0;
10243 if (bd->new_client)
10245 E_Event_Border_Add *ev;
10246 E_Exec_Instance *inst;
10248 ev = E_NEW(E_Event_Border_Add, 1);
10250 e_object_ref(E_OBJECT(bd));
10251 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10252 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10254 if ((!bd->lock_border) || (!bd->client.border.name))
10255 bd->client.border.changed = 1;
10260 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10261 ((bd->client.icccm.client_leader > 0) &&
10262 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10265 if (!strncmp(str, "E_START|", 8))
10269 id = atoi(str + 8);
10270 if (id > 0) bd->client.netwm.startup_id = id;
10275 /* It's ok not to have fetch flag, should only be set on startup
10276 * * and not changed. */
10277 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10279 if (bd->client.icccm.client_leader)
10281 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10282 bd->client.netwm.pid = -1;
10285 bd->client.netwm.pid = -1;
10288 if (!bd->re_manage)
10290 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10291 bd->client.netwm.pid);
10292 if ((inst) && (inst->used == 0))
10298 zone = e_container_zone_number_get(bd->zone->container,
10300 if (zone) e_border_zone_set(bd, zone);
10301 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10303 if (desk) e_border_desk_set(bd, desk);
10304 e_exec_instance_found(inst);
10307 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10309 E_Border *bdl = NULL;
10314 if (bd->leader) bdl = bd->leader;
10321 bl = e_container_border_list_first(bd->zone->container);
10322 while ((child = e_container_border_list_next(bl)))
10324 if (child == bd) continue;
10325 if (e_object_is_del(E_OBJECT(child))) continue;
10326 if ((bd->client.icccm.client_leader) &&
10327 (child->client.icccm.client_leader ==
10328 bd->client.icccm.client_leader))
10334 e_container_border_list_free(bl);
10339 e_border_zone_set(bd, bdl->zone);
10341 e_border_desk_set(bd, bdl->desk);
10343 e_border_stick(bd);
10349 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10352 E_Container *con = bd->zone->container;
10353 E_Desk *desk = NULL;
10356 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10358 desk = e_container_desk_window_profile_get(con, str);
10361 if (bd->desk != desk)
10363 bd->client.e.state.profile = eina_stringshare_add(str);
10364 if (bd->zone != desk->zone)
10365 e_border_zone_set(bd, desk->zone);
10366 e_border_desk_set(bd, desk);
10374 /* PRE_POST_FETCH calls e_remember apply for new client */
10375 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10376 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10377 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10379 #ifdef _F_ZONE_WINDOW_ROTATION_
10380 if (e_config->wm_win_rotation)
10382 if ((need_rotation_set) &&
10383 (bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_NORMAL))
10385 Eina_Bool hint = EINA_FALSE;
10387 int x, y, w, h, move;
10389 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10390 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10392 if (bd->client.e.state.rot.changes == -1)
10394 ang = bd->client.e.state.rot.curr;
10396 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10399 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10400 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10401 bd->client.icccm.name, x, y, w, h);
10404 else bd->changed = 1;
10409 if (bd->need_reparent)
10412 ecore_x_window_save_set_add(bd->client.win);
10413 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10416 if ((bd->new_client) && (bd->internal) &&
10417 (bd->internal_ecore_evas))
10418 ecore_evas_show(bd->internal_ecore_evas);
10419 ecore_x_window_show(bd->client.win);
10421 bd->need_reparent = 0;
10424 if ((bd->client.border.changed) && (!bd->shaded) &&
10425 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10427 const char *bordername;
10429 if (bd->fullscreen)
10430 bordername = "borderless";
10431 else if (bd->bordername)
10432 bordername = bd->bordername;
10433 else if ((bd->client.mwm.borderless) || (bd->borderless))
10434 bordername = "borderless";
10435 else if (((bd->client.icccm.transient_for != 0) ||
10436 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10437 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10438 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10439 bordername = "noresize_dialog";
10440 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10441 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10442 bordername = "noresize";
10443 else if (bd->client.shaped)
10444 bordername = "shaped";
10445 else if ((!bd->client.icccm.accepts_focus) &&
10446 (!bd->client.icccm.take_focus))
10447 bordername = "nofocus";
10448 else if (bd->client.icccm.urgent)
10449 bordername = "urgent";
10450 else if ((bd->client.icccm.transient_for != 0) ||
10451 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10452 bordername = "dialog";
10453 else if (bd->client.netwm.state.modal)
10454 bordername = "modal";
10455 else if ((bd->client.netwm.state.skip_taskbar) ||
10456 (bd->client.netwm.state.skip_pager))
10457 bordername = "skipped";
10458 else if ((bd->internal) && (bd->client.icccm.class) &&
10459 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10460 bordername = "internal_fileman";
10462 bordername = e_config->theme_default_border_style;
10463 if (!bordername) bordername = "default";
10465 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10471 bd->changes.border = 1;
10472 eina_stringshare_replace(&bd->client.border.name, bordername);
10476 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10477 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10478 bd->changes.size = 1;
10479 evas_object_del(bd->bg_object);
10481 o = edje_object_add(bd->bg_evas);
10482 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10483 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10484 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10486 if (bd->client.border.name != e_config->theme_default_border_style)
10488 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10489 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10493 ok = e_theme_edje_object_set(o, "base/theme/borders",
10494 "e/widgets/border/default/border");
10497 /* Reset default border style to default */
10498 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10499 e_config_save_queue();
10507 const char *shape_option, *argb_option;
10512 if ((e_config->use_composite) && (!bd->client.argb))
10514 argb_option = edje_object_data_get(o, "argb");
10515 if ((argb_option) && (!strcmp(argb_option, "1")))
10518 if (use_argb != bd->argb)
10519 _e_border_frame_replace(bd, use_argb);
10526 shape_option = edje_object_data_get(o, "shaped");
10527 if ((shape_option) && (!strcmp(shape_option, "1")))
10531 if (bd->client.netwm.name)
10532 edje_object_part_text_set(o, "e.text.title",
10533 bd->client.netwm.name);
10534 else if (bd->client.icccm.title)
10535 edje_object_part_text_set(o, "e.text.title",
10536 bd->client.icccm.title);
10540 evas_object_del(o);
10541 bd->bg_object = NULL;
10544 _e_border_client_inset_calc(bd);
10546 bd->w += (bd->client_inset.l + bd->client_inset.r);
10547 bd->h += (bd->client_inset.t + bd->client_inset.b);
10548 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10549 bd->changes.size = 1;
10550 /* really needed ? */
10551 ecore_x_window_move(bd->client.shell_win,
10552 bd->client_inset.l,
10553 bd->client_inset.t);
10555 if (bd->maximized != E_MAXIMIZE_NONE)
10557 E_Maximize maximized = bd->maximized;
10559 /* to force possible resizes */
10560 bd->maximized = E_MAXIMIZE_NONE;
10562 _e_border_maximize(bd, maximized);
10564 /* restore maximized state */
10565 bd->maximized = maximized;
10567 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10568 bd->maximized & E_MAXIMIZE_VERTICAL);
10572 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10573 _e_border_cb_signal_bind, bd);
10576 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10577 if (bd->icon_object)
10578 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10581 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10583 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10585 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10586 // FIXME: in eval -do differently
10587 // edje_object_message_signal_process(bd->bg_object);
10588 // e_border_frame_recalc(bd);
10590 evas_object_move(bd->bg_object, 0, 0);
10591 evas_object_resize(bd->bg_object, bd->w, bd->h);
10592 evas_object_show(bd->bg_object);
10595 bd->client.border.changed = 0;
10597 if (bd->icon_object)
10601 evas_object_show(bd->icon_object);
10602 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10605 evas_object_hide(bd->icon_object);
10609 if (rem_change) e_remember_update(bd);
10613 E_Event_Border_Urgent_Change *ev;
10615 if (bd->client.icccm.urgent)
10616 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10618 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10620 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10622 e_object_ref(E_OBJECT(bd));
10623 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10624 _e_border_event_border_urgent_change_free, NULL);
10627 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10630 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10632 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10634 E_Border* temp_bd = NULL;
10635 E_Border* top_focusable_bd = NULL;
10636 Eina_Bool is_fully_obscured = EINA_FALSE;
10637 Ecore_X_XRegion *visible_region = NULL;
10638 Ecore_X_XRegion *win_region = NULL;
10639 Ecore_X_Rectangle visible_rect, win_rect;
10642 // set the entire visible region as a root geometry
10643 visible_rect.x = bd->zone->x;
10644 visible_rect.y = bd->zone->y;
10645 visible_rect.width = bd->zone->w;
10646 visible_rect.height = bd->zone->h;
10648 visible_region = ecore_x_xregion_new();
10649 if (!visible_region) return;
10651 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10653 bl = e_container_border_list_last(bd->zone->container);
10654 while ((temp_bd = e_container_border_list_prev(bl)))
10656 if (temp_bd == bd) break;
10658 if (temp_bd == focused) continue;
10659 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10660 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10661 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10662 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10663 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10664 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10665 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10666 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10667 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10669 if (!top_focusable_bd)
10671 top_focusable_bd = temp_bd;
10674 win_rect.x = temp_bd->x;
10675 win_rect.y = temp_bd->y;
10676 win_rect.width = temp_bd->w;
10677 win_rect.height = temp_bd->h;
10679 // if it stick out or is bigger than the entire visible region,
10680 // clip it by the entire visible's geometry.
10681 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10682 win_rect.width, win_rect.height,
10683 visible_rect.x, visible_rect.y,
10684 (int)(visible_rect.width), (int)(visible_rect.height));
10686 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10688 win_region = ecore_x_xregion_new();
10691 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10692 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10693 ecore_x_xregion_free(win_region);
10696 if (ecore_x_xregion_is_empty(visible_region))
10698 is_fully_obscured = EINA_TRUE;
10706 if (is_fully_obscured == EINA_TRUE)
10708 e_border_focus_set(top_focusable_bd, 1, 1);
10712 e_border_focus_set(bd, 1, 1);
10715 if (visible_region) ecore_x_xregion_free(visible_region);
10716 e_container_border_list_free(bl);
10720 _e_border_latest_stacked_focus(E_Border *bd)
10723 int root_w, root_h;
10725 root_w = bd->zone->w;
10726 root_h = bd->zone->h;
10729 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10731 if (bd == temp_bd) continue;
10732 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10733 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10735 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10736 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10737 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10738 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10739 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10740 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10741 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10743 _e_border_latest_stacked_focus_check_set(temp_bd);
10750 _e_border_check_stack (E_Border *bd)
10752 E_Border* temp_bd = NULL;
10753 E_Border* top_bd = NULL;
10754 int passed_focus = 0;
10756 int root_w = bd->zone->w;
10757 int root_h = bd->zone->h;
10760 bl = e_container_border_list_last(bd->zone->container);
10761 while ((temp_bd = e_container_border_list_prev(bl)))
10763 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10764 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10765 if ((temp_bd != bd) &&
10766 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10768 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10769 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10770 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10771 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10772 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10773 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10774 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10780 e_border_focus_set_with_pointer(bd);
10787 e_border_focus_set_with_pointer(top_bd);
10796 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10798 if (!bd->lock_focus_out)
10800 e_border_focus_latest_set(bd);
10812 if (temp_bd == focused)
10818 e_container_border_list_free(bl);
10822 _e_border_focus_top_stack_set(E_Border* bd)
10825 int root_w, root_h;
10827 root_w = bd->zone->w;
10828 root_h = bd->zone->h;
10831 bl = e_container_border_list_last(bd->zone->container);
10832 while ((temp_bd = e_container_border_list_prev(bl)))
10834 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10835 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10836 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10838 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10839 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10840 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10841 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10842 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10843 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10844 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10846 if (!temp_bd->focused)
10848 /* this border is the top of the latest stack */
10849 e_border_focus_set (temp_bd, 1, 1);
10854 e_container_border_list_free(bl);
10859 _e_border_eval(E_Border *bd)
10861 E_Event_Border_Property *event;
10862 E_Border_Pending_Move_Resize *pnd;
10863 int rem_change = 0;
10864 int send_event = 1;
10866 if (e_object_is_del(E_OBJECT(bd)))
10868 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10873 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10875 if (bd->new_client)
10877 int zx = 0, zy = 0, zw = 0, zh = 0;
10880 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10883 * Limit maximum size of windows to useful geometry
10885 // TODO: temoporary limited maximize algorithm
10897 if ((rw != bd->w) || (rh != bd->h))
10901 e_border_resize (bd, bd->w, bd->h);
10907 bd->x -= bd->client_inset.l;
10908 bd->y -= bd->client_inset.t;
10909 bd->changes.pos = 1;
10912 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10915 Ecore_X_Window_Attributes *att;
10918 att = &bd->client.initial_attributes;
10919 bw = att->border * 2;
10920 switch (bd->client.icccm.gravity)
10922 case ECORE_X_GRAVITY_N:
10923 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10927 case ECORE_X_GRAVITY_NE:
10928 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10932 case ECORE_X_GRAVITY_E:
10933 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10934 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10937 case ECORE_X_GRAVITY_SE:
10938 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10939 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10942 case ECORE_X_GRAVITY_S:
10943 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10944 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10947 case ECORE_X_GRAVITY_SW:
10949 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10952 case ECORE_X_GRAVITY_W:
10954 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10957 case ECORE_X_GRAVITY_CENTER:
10958 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10959 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10962 case ECORE_X_GRAVITY_NW:
10969 * This ensures that windows that like to open with a x/y
10970 * position smaller than returned by e_zone_useful_geometry_get()
10971 * are moved to useful positions.
10974 if (e_config->geometry_auto_move)
10982 if (bd->x + bd->w > zx + zw)
10983 bd->x = zx + zw - bd->w;
10985 if (bd->y + bd->h > zy + zh)
10986 bd->y = zy + zh - bd->h;
10989 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10991 bd->changes.pos = 1;
10997 bd->changes.pos = 1;
11003 /* FIXME: special placement for dialogs etc. etc. etc goes
11005 /* FIXME: what if parent is not on this desktop - or zone? */
11006 if ((bd->parent) && (bd->parent->visible))
11008 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
11009 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
11010 bd->changes.pos = 1;
11014 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
11016 /* TODO: Place in center of group */
11019 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11021 bd->x = zx + ((zw - bd->w) / 2);
11022 bd->y = zy + ((zh - bd->h) / 2);
11023 bd->changes.pos = 1;
11029 Eina_List *skiplist = NULL;
11033 new_x = zx + (rand() % (zw - bd->w));
11037 new_y = zy + (rand() % (zh - bd->h));
11041 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
11043 skiplist = eina_list_append(skiplist, bd);
11045 e_place_desk_region_smart(bd->desk, skiplist,
11046 bd->x, bd->y, bd->w, bd->h,
11049 e_place_zone_region_smart(bd->zone, skiplist,
11050 bd->x, bd->y, bd->w, bd->h,
11052 eina_list_free(skiplist);
11054 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
11056 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
11061 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
11062 bd->client_inset.t, &new_x, &new_y);
11066 bd->changes.pos = 1;
11069 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11071 if ((!bd->lock_client_location) && (pnd->move))
11075 bd->changes.pos = 1;
11077 if (pnd->without_border)
11079 bd->x -= bd->client_inset.l;
11080 bd->y -= bd->client_inset.t;
11083 if ((!bd->lock_client_size) && (pnd->resize))
11085 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
11086 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
11087 bd->client.w = pnd->w;
11088 bd->client.h = pnd->h;
11089 bd->changes.size = 1;
11095 /* Recreate state */
11096 e_hints_window_init(bd);
11097 if ((bd->client.e.state.centered) &&
11098 ((!bd->remember) ||
11099 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
11101 bd->x = zx + (zw - bd->w) / 2;
11102 bd->y = zy + (zh - bd->h) / 2;
11103 bd->changes.pos = 1;
11107 _e_border_client_move_resize_send(bd);
11109 /* if the explicit geometry request asks for the app to be
11110 * in another zone - well move it there */
11114 zone = e_container_zone_at_point_get(bd->zone->container,
11115 bd->x + (bd->w / 2),
11116 bd->y + (bd->h / 2));
11118 zone = e_container_zone_at_point_get(bd->zone->container,
11122 zone = e_container_zone_at_point_get(bd->zone->container,
11126 zone = e_container_zone_at_point_get(bd->zone->container,
11128 bd->y + bd->h - 1);
11130 zone = e_container_zone_at_point_get(bd->zone->container,
11132 bd->y + bd->h - 1);
11133 if ((zone) && (zone != bd->zone))
11134 e_border_zone_set(bd, zone);
11138 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11140 /* effect changes to the window border itself */
11141 if ((bd->changes.shading))
11143 /* show at start of unshade (but don't hide until end of shade) */
11145 ecore_x_window_raise(bd->client.shell_win);
11146 bd->changes.shading = 0;
11149 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11152 ecore_x_window_lower(bd->client.shell_win);
11154 ecore_x_window_raise(bd->client.shell_win);
11155 bd->changes.shaded = 0;
11158 else if ((bd->changes.shaded) && (bd->changes.pos))
11161 ecore_x_window_lower(bd->client.shell_win);
11163 ecore_x_window_raise(bd->client.shell_win);
11164 bd->changes.size = 1;
11165 bd->changes.shaded = 0;
11168 else if ((bd->changes.shaded) && (bd->changes.size))
11171 ecore_x_window_lower(bd->client.shell_win);
11173 ecore_x_window_raise(bd->client.shell_win);
11174 bd->changes.shaded = 0;
11177 else if (bd->changes.shaded)
11180 ecore_x_window_lower(bd->client.shell_win);
11182 ecore_x_window_raise(bd->client.shell_win);
11183 bd->changes.size = 1;
11184 bd->changes.shaded = 0;
11188 if (bd->changes.size)
11190 int x = 0, y = 0, xx = 0, yy = 0;
11192 if ((bd->shaded) && (!bd->shading))
11194 evas_obscured_clear(bd->bg_evas);
11198 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11199 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11201 evas_obscured_clear(bd->bg_evas);
11202 evas_obscured_rectangle_add(bd->bg_evas,
11203 bd->client_inset.l, bd->client_inset.t, xx, yy);
11207 if (bd->shade.dir == E_DIRECTION_UP)
11209 y = yy - bd->client.h;
11211 else if (bd->shade.dir == E_DIRECTION_LEFT)
11213 x = xx - bd->client.w;
11218 if (bd->client.e.state.video)
11220 if (bd->client.e.state.video_position.updated)
11222 ecore_x_window_move(bd->win,
11223 bd->client.e.state.video_parent_border->x +
11224 bd->client.e.state.video_parent_border->client_inset.l +
11225 bd->client.e.state.video_parent_border->fx.x +
11226 bd->client.e.state.video_position.x,
11227 bd->client.e.state.video_parent_border->y +
11228 bd->client.e.state.video_parent_border->client_inset.t +
11229 bd->client.e.state.video_parent_border->fx.y +
11230 bd->client.e.state.video_position.y);
11231 bd->client.e.state.video_position.updated = 0;
11234 else if (!bd->changes.pos)
11236 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11237 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11238 bd->post_resize = 1;
11245 ecore_x_window_move_resize(bd->win,
11250 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11251 ecore_x_window_move(tmp->win,
11252 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11253 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11256 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11258 if ((!bd->shaded) || (bd->shading))
11259 ecore_x_window_move_resize(bd->client.shell_win,
11260 bd->client_inset.l, bd->client_inset.t, xx, yy);
11262 if (bd->internal_ecore_evas)
11263 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11264 else if (!bd->client.e.state.video)
11265 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11267 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11268 evas_object_resize(bd->bg_object, bd->w, bd->h);
11269 e_container_shape_resize(bd->shape, bd->w, bd->h);
11270 if (bd->changes.pos)
11271 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11273 _e_border_client_move_resize_send(bd);
11275 bd->changes.pos = 0;
11276 bd->changes.size = 0;
11279 else if (bd->changes.pos)
11281 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11282 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11285 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11287 _e_border_client_move_resize_send(bd);
11289 bd->changes.pos = 0;
11293 if (bd->changes.reset_gravity)
11295 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11296 bd->changes.reset_gravity = 0;
11300 if (bd->need_shape_merge)
11302 _e_border_shape_input_rectangle_set(bd);
11303 if ((bd->shaped) || (bd->client.shaped))
11305 Ecore_X_Window twin, twin2;
11308 twin = ecore_x_window_override_new
11309 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11311 ecore_x_window_shape_window_set(twin, bd->bg_win);
11314 Ecore_X_Rectangle rects[4];
11318 rects[0].width = bd->w;
11319 rects[0].height = bd->client_inset.t;
11321 rects[1].y = bd->client_inset.t;
11322 rects[1].width = bd->client_inset.l;
11323 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11324 rects[2].x = bd->w - bd->client_inset.r;
11325 rects[2].y = bd->client_inset.t;
11326 rects[2].width = bd->client_inset.r;
11327 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11329 rects[3].y = bd->h - bd->client_inset.b;
11330 rects[3].width = bd->w;
11331 rects[3].height = bd->client_inset.b;
11332 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11334 twin2 = ecore_x_window_override_new
11335 (bd->zone->container->scratch_win, 0, 0,
11336 bd->w - bd->client_inset.l - bd->client_inset.r,
11337 bd->h - bd->client_inset.t - bd->client_inset.b);
11340 if ((bd->shading) || (bd->shaded))
11342 if (bd->shade.dir == E_DIRECTION_UP)
11343 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11344 else if (bd->shade.dir == E_DIRECTION_LEFT)
11345 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11347 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11349 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11350 bd->w - bd->client_inset.l - bd->client_inset.r,
11351 bd->h - bd->client_inset.t - bd->client_inset.b);
11352 ecore_x_window_shape_window_add_xy(twin, twin2,
11353 bd->client_inset.l,
11354 bd->client_inset.t);
11355 ecore_x_window_free(twin2);
11356 ecore_x_window_shape_window_set(bd->win, twin);
11357 ecore_x_window_free(twin);
11360 ecore_x_window_shape_mask_set(bd->win, 0);
11361 // bd->need_shape_export = 1;
11362 bd->need_shape_merge = 0;
11365 if (bd->need_shape_export)
11367 Ecore_X_Rectangle *rects, *orects;
11370 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11376 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11380 orects = bd->shape_rects;
11382 for (i = 0; i < num; i++)
11384 if (rects[i].x < 0)
11386 rects[i].width -= rects[i].x;
11389 if ((rects[i].x + (int)rects[i].width) > bd->w)
11390 rects[i].width = rects[i].width - rects[i].x;
11391 if (rects[i].y < 0)
11393 rects[i].height -= rects[i].y;
11396 if ((rects[i].y + (int)rects[i].height) > bd->h)
11397 rects[i].height = rects[i].height - rects[i].y;
11399 if ((orects[i].x != rects[i].x) ||
11400 (orects[i].y != rects[i].y) ||
11401 (orects[i].width != rects[i].width) ||
11402 (orects[i].height != rects[i].height))
11411 if (bd->client.shaped)
11412 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11414 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11415 E_FREE(bd->shape_rects);
11416 bd->shape_rects = rects;
11417 bd->shape_rects_num = num;
11418 e_container_shape_rects_set(bd->shape, rects, num);
11425 E_FREE(bd->shape_rects);
11426 bd->shape_rects = NULL;
11427 bd->shape_rects_num = 0;
11428 e_container_shape_rects_set(bd->shape, NULL, 0);
11430 bd->need_shape_export = 0;
11433 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11437 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11438 if ((!bd->placed) && (!bd->re_manage) &&
11439 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11440 (!((bd->client.icccm.transient_for != 0) ||
11441 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11442 (!bdmove) && (!bdresize))
11444 /* Set this window into moving state */
11446 bd->cur_mouse_action = e_action_find("window_move");
11447 if (bd->cur_mouse_action)
11449 if ((!bd->cur_mouse_action->func.end_mouse) &&
11450 (!bd->cur_mouse_action->func.end))
11451 bd->cur_mouse_action = NULL;
11452 if (bd->cur_mouse_action)
11454 bd->x = x - (bd->w >> 1);
11455 bd->y = y - (bd->client_inset.t >> 1);
11457 bd->changes.pos = 1;
11459 _e_border_client_move_resize_send(bd);
11464 _e_border_show(bd);
11466 if (bd->cur_mouse_action)
11468 bd->moveinfo.down.x = bd->x + bd->fx.x;
11469 bd->moveinfo.down.y = bd->y + bd->fx.y;
11470 bd->moveinfo.down.w = bd->w;
11471 bd->moveinfo.down.h = bd->h;
11472 bd->mouse.current.mx = x;
11473 bd->mouse.current.my = y;
11474 bd->moveinfo.down.button = 0;
11475 bd->moveinfo.down.mx = x;
11476 bd->moveinfo.down.my = y;
11479 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11480 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11481 if (e_config->border_raise_on_mouse_action)
11482 e_border_raise(bd);
11483 e_border_focus_set(bd, 1, 1);
11485 bd->changes.visible = 0;
11489 if (bd->changes.icon)
11493 efreet_desktop_free(bd->desktop);
11494 bd->desktop = NULL;
11496 if (bd->icon_object)
11498 evas_object_del(bd->icon_object);
11499 bd->icon_object = NULL;
11501 if (bd->remember && bd->remember->prop.desktop_file)
11503 const char *desktop = bd->remember->prop.desktop_file;
11505 bd->desktop = efreet_desktop_get(desktop);
11507 bd->desktop = efreet_util_desktop_name_find(desktop);
11511 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11512 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11513 bd->client.icccm.class);
11517 /* libreoffice and maybe others match window class
11518 with .desktop file name */
11519 if (bd->client.icccm.class)
11522 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11523 bd->desktop = efreet_util_desktop_file_id_find(buf);
11528 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11529 bd->client.netwm.pid);
11530 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11532 if (!bd->desktop && bd->client.icccm.name)
11534 /* this works for most cases as fallback. useful when app is
11535 run from a shell */
11536 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11538 if (!bd->desktop && bd->client.icccm.transient_for)
11540 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11541 if (bd2 && bd2->desktop)
11543 efreet_desktop_ref(bd2->desktop);
11544 bd->desktop = bd2->desktop;
11549 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11550 bd->desktop->orig_path);
11553 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11554 if ((bd->focused) && (bd->icon_object))
11555 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11558 evas_object_show(bd->icon_object);
11559 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11562 evas_object_hide(bd->icon_object);
11565 E_Event_Border_Icon_Change *ev;
11567 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11569 e_object_ref(E_OBJECT(bd));
11570 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11571 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11572 _e_border_event_border_icon_change_free, NULL);
11574 bd->changes.icon = 0;
11577 bd->new_client = 0;
11579 bd->changes.stack = 0;
11580 bd->changes.prop = 0;
11582 if (bd->client.e.state.rot.changes != -1)
11584 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11585 bd->client.e.state.rot.changes = -1;
11588 if ((bd->take_focus) || (bd->want_focus))
11590 bd->take_focus = 0;
11591 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11592 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11593 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11596 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11599 bd->want_focus = 0;
11600 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11601 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11602 _e_border_check_stack(bd);
11605 e_border_focus_set_with_pointer(bd);
11607 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11609 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11610 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11611 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11612 e_border_focused_get())))
11614 e_border_focus_set_with_pointer(bd);
11619 /* focus window by default when it is the only one on desk */
11620 E_Border *bd2 = NULL;
11622 EINA_LIST_FOREACH(focus_stack, l, bd2)
11624 if (bd == bd2) continue;
11625 if ((!bd2->iconic) && (bd2->visible) &&
11626 ((bd->desk == bd2->desk) || bd2->sticky))
11632 e_border_focus_set_with_pointer(bd);
11637 if (bd->need_maximize)
11640 max = bd->maximized;
11641 bd->maximized = E_MAXIMIZE_NONE;
11642 e_border_maximize(bd, max);
11643 bd->need_maximize = 0;
11646 if (bd->need_fullscreen)
11648 e_border_fullscreen(bd, e_config->fullscreen_policy);
11649 bd->need_fullscreen = 0;
11653 e_remember_update(bd);
11655 if (send_event) // FIXME: send only if a property changed - above need to
11656 { // check on that. for now - always send.
11657 event = E_NEW(E_Event_Border_Property, 1);
11658 event->border = bd;
11659 e_object_ref(E_OBJECT(bd));
11660 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11662 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11666 _e_border_moveinfo_gather(E_Border *bd,
11667 const char *source)
11669 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11670 else if (e_util_glob_match(source, "mouse,*,2"))
11671 bd->moveinfo.down.button = 2;
11672 else if (e_util_glob_match(source, "mouse,*,3"))
11673 bd->moveinfo.down.button = 3;
11674 else bd->moveinfo.down.button = 0;
11675 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11677 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11678 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11682 bd->moveinfo.down.mx = bd->mouse.current.mx;
11683 bd->moveinfo.down.my = bd->mouse.current.my;
11688 _e_border_resize_handle(E_Border *bd)
11691 int new_x, new_y, new_w, new_h;
11693 Eina_List *skiplist = NULL;
11700 if ((bd->resize_mode == RESIZE_TR) ||
11701 (bd->resize_mode == RESIZE_R) ||
11702 (bd->resize_mode == RESIZE_BR))
11704 if ((bd->moveinfo.down.button >= 1) &&
11705 (bd->moveinfo.down.button <= 3))
11706 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11707 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11709 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11711 else if ((bd->resize_mode == RESIZE_TL) ||
11712 (bd->resize_mode == RESIZE_L) ||
11713 (bd->resize_mode == RESIZE_BL))
11715 if ((bd->moveinfo.down.button >= 1) &&
11716 (bd->moveinfo.down.button <= 3))
11717 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11718 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11720 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11723 if ((bd->resize_mode == RESIZE_TL) ||
11724 (bd->resize_mode == RESIZE_T) ||
11725 (bd->resize_mode == RESIZE_TR))
11727 if ((bd->moveinfo.down.button >= 1) &&
11728 (bd->moveinfo.down.button <= 3))
11729 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11730 (bd->mouse.current.my - bd->moveinfo.down.my);
11732 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11734 else if ((bd->resize_mode == RESIZE_BL) ||
11735 (bd->resize_mode == RESIZE_B) ||
11736 (bd->resize_mode == RESIZE_BR))
11738 if ((bd->moveinfo.down.button >= 1) &&
11739 (bd->moveinfo.down.button <= 3))
11740 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11741 (bd->mouse.current.my - bd->moveinfo.down.my);
11743 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11749 if ((bd->resize_mode == RESIZE_TL) ||
11750 (bd->resize_mode == RESIZE_L) ||
11751 (bd->resize_mode == RESIZE_BL))
11753 if ((bd->resize_mode == RESIZE_TL) ||
11754 (bd->resize_mode == RESIZE_T) ||
11755 (bd->resize_mode == RESIZE_TR))
11758 skiplist = eina_list_append(skiplist, bd);
11759 e_resist_container_border_position(bd->zone->container, skiplist,
11760 bd->x, bd->y, bd->w, bd->h,
11762 &new_x, &new_y, &new_w, &new_h);
11763 eina_list_free(skiplist);
11767 e_border_resize_limit(bd, &new_w, &new_h);
11768 if ((bd->resize_mode == RESIZE_TL) ||
11769 (bd->resize_mode == RESIZE_L) ||
11770 (bd->resize_mode == RESIZE_BL))
11771 new_x += (w - new_w);
11772 if ((bd->resize_mode == RESIZE_TL) ||
11773 (bd->resize_mode == RESIZE_T) ||
11774 (bd->resize_mode == RESIZE_TR))
11775 new_y += (h - new_h);
11777 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11781 _e_border_shade_animator(void *data)
11783 E_Border *bd = data;
11785 double dur = bd->client.h / e_config->border_shade_speed;
11787 dt = ecore_loop_time_get() - bd->shade.start;
11790 if (val < 0.0) val = 0.0;
11791 else if (val > 1.0) val = 1.0;
11793 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11796 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11797 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11799 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11802 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11803 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11805 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11808 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11809 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11811 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11814 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11815 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11817 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11820 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11821 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11823 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11826 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11827 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11829 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11832 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11833 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11835 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11838 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11839 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11841 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11844 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11845 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11850 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11851 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11854 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11855 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11856 else if (bd->shade.val > .999)
11857 bd->shade.val = 1.0;
11859 if (bd->shade.dir == E_DIRECTION_UP)
11860 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11861 else if (bd->shade.dir == E_DIRECTION_DOWN)
11863 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11864 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11865 bd->changes.pos = 1;
11867 else if (bd->shade.dir == E_DIRECTION_LEFT)
11868 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11869 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11871 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11872 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11873 bd->changes.pos = 1;
11876 if ((bd->shaped) || (bd->client.shaped))
11878 bd->need_shape_merge = 1;
11879 bd->need_shape_export = 1;
11881 if (bd->shaped_input)
11883 bd->need_shape_merge = 1;
11885 bd->changes.size = 1;
11891 E_Event_Border_Resize *ev;
11894 bd->shaded = !(bd->shaded);
11895 bd->changes.size = 1;
11896 bd->changes.shaded = 1;
11897 bd->changes.shading = 1;
11899 bd->shade.anim = NULL;
11902 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11904 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11905 edje_object_message_signal_process(bd->bg_object);
11906 e_border_frame_recalc(bd);
11908 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11909 ev = E_NEW(E_Event_Border_Resize, 1);
11911 e_object_ref(E_OBJECT(bd));
11912 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11913 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11914 return ECORE_CALLBACK_CANCEL;
11916 return ECORE_CALLBACK_RENEW;
11920 _e_border_event_border_resize_free(void *data __UNUSED__,
11923 E_Event_Border_Resize *e;
11926 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11927 e_object_unref(E_OBJECT(e->border));
11932 _e_border_event_border_move_free(void *data __UNUSED__,
11935 E_Event_Border_Move *e;
11938 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11939 e_object_unref(E_OBJECT(e->border));
11944 _e_border_event_border_add_free(void *data __UNUSED__,
11947 E_Event_Border_Add *e;
11950 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11951 e_object_unref(E_OBJECT(e->border));
11956 _e_border_event_border_remove_free(void *data __UNUSED__,
11959 E_Event_Border_Remove *e;
11962 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11963 e_object_unref(E_OBJECT(e->border));
11968 _e_border_event_border_show_free(void *data __UNUSED__,
11971 E_Event_Border_Show *e;
11974 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11975 e_object_unref(E_OBJECT(e->border));
11980 _e_border_event_border_hide_free(void *data __UNUSED__,
11983 E_Event_Border_Hide *e;
11986 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11987 e_object_unref(E_OBJECT(e->border));
11992 _e_border_event_border_iconify_free(void *data __UNUSED__,
11995 E_Event_Border_Iconify *e;
11998 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11999 e_object_unref(E_OBJECT(e->border));
12004 _e_border_event_border_uniconify_free(void *data __UNUSED__,
12007 E_Event_Border_Uniconify *e;
12010 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
12011 e_object_unref(E_OBJECT(e->border));
12016 _e_border_event_border_stick_free(void *data __UNUSED__,
12019 E_Event_Border_Stick *e;
12022 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
12023 e_object_unref(E_OBJECT(e->border));
12028 _e_border_event_border_unstick_free(void *data __UNUSED__,
12031 E_Event_Border_Unstick *e;
12034 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
12035 e_object_unref(E_OBJECT(e->border));
12040 _e_border_event_border_zone_set_free(void *data __UNUSED__,
12043 E_Event_Border_Zone_Set *e;
12046 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
12047 e_object_unref(E_OBJECT(e->border));
12048 e_object_unref(E_OBJECT(e->zone));
12053 _e_border_event_border_desk_set_free(void *data __UNUSED__,
12056 E_Event_Border_Desk_Set *e;
12059 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
12060 e_object_unref(E_OBJECT(e->border));
12061 e_object_unref(E_OBJECT(e->desk));
12066 _e_border_event_border_stack_free(void *data __UNUSED__,
12069 E_Event_Border_Stack *e;
12072 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
12073 e_object_unref(E_OBJECT(e->border));
12076 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
12077 e_object_unref(E_OBJECT(e->stack));
12083 _e_border_event_border_icon_change_free(void *data __UNUSED__,
12086 E_Event_Border_Icon_Change *e;
12089 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
12090 e_object_unref(E_OBJECT(e->border));
12095 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
12098 E_Event_Border_Urgent_Change *e;
12101 e_object_unref(E_OBJECT(e->border));
12106 _e_border_event_border_focus_in_free(void *data __UNUSED__,
12109 E_Event_Border_Focus_In *e;
12112 e_object_unref(E_OBJECT(e->border));
12117 _e_border_event_border_focus_out_free(void *data __UNUSED__,
12120 E_Event_Border_Focus_Out *e;
12123 e_object_unref(E_OBJECT(e->border));
12128 _e_border_event_border_property_free(void *data __UNUSED__,
12131 E_Event_Border_Property *e;
12134 e_object_unref(E_OBJECT(e->border));
12139 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12142 E_Event_Border_Fullscreen *e;
12145 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12146 e_object_unref(E_OBJECT(e->border));
12151 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12154 E_Event_Border_Unfullscreen *e;
12157 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12158 e_object_unref(E_OBJECT(e->border));
12162 #ifdef _F_ZONE_WINDOW_ROTATION_
12164 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12167 E_Event_Border_Rotation_Change_Begin *e;
12169 e_object_unref(E_OBJECT(e->border));
12174 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12177 E_Event_Border_Rotation_Change_Cancel *e;
12179 e_object_unref(E_OBJECT(e->border));
12184 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12187 E_Event_Border_Rotation_Change_End *e;
12189 e_object_unref(E_OBJECT(e->border));
12194 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12196 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12197 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12201 e_object_ref(E_OBJECT(bd));
12202 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12204 _e_border_event_border_rotation_change_begin_free,
12211 _e_border_zone_update(E_Border *bd)
12217 /* still within old zone - leave it there */
12218 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12219 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12220 #if _F_BORDER_CLIP_TO_ZONE_
12222 _e_border_shape_input_clip_to_zone(bd);
12227 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12228 /* find a new zone */
12229 con = bd->zone->container;
12230 EINA_LIST_FOREACH(con->zones, l, zone)
12232 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12233 zone->x, zone->y, zone->w, zone->h))
12235 e_border_zone_set(bd, zone);
12236 #if _F_BORDER_CLIP_TO_ZONE_
12237 _e_border_shape_input_clip_to_zone(bd);
12238 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12245 _e_border_resize_begin(E_Border *bd)
12249 if (!bd->lock_user_stacking)
12251 if (e_config->border_raise_on_mouse_action)
12252 e_border_raise(bd);
12254 if ((bd->shaded) || (bd->shading) ||
12255 (bd->fullscreen) || (bd->lock_user_size))
12258 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12259 ret = e_grabinput_get(bd->win, 0, bd->win);
12261 ret = e_grabinput_get(bd->win, 0, 0);
12263 if (grabbed && !ret)
12269 if (bd->client.netwm.sync.request)
12271 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12272 bd->client.netwm.sync.serial = 1;
12273 bd->client.netwm.sync.wait = 0;
12274 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12277 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12284 _e_border_resize_end(E_Border *bd)
12288 e_grabinput_release(bd->win, bd->win);
12291 if (bd->client.netwm.sync.alarm)
12293 E_Border_Pending_Move_Resize *pnd;
12295 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12296 bd->client.netwm.sync.alarm = 0;
12297 /* resize to last geometry if sync alarm for it was not yet handled */
12298 if (bd->pending_move_resize)
12301 bd->changes.pos = 1;
12302 bd->changes.size = 1;
12303 _e_border_client_move_resize_send(bd);
12306 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12310 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12314 /* If this border was maximized, we need to unset Maximized state or
12315 * on restart, E still thinks it's maximized */
12316 if (bd->maximized != E_MAXIMIZE_NONE)
12317 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12318 bd->maximized & E_MAXIMIZE_NONE);
12323 _e_border_resize_update(E_Border *bd)
12325 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12329 _e_border_move_begin(E_Border *bd)
12332 if (!bd->lock_user_stacking)
12334 if (e_config->border_raise_on_mouse_action)
12335 e_border_raise(bd);
12337 if ((bd->fullscreen) || (bd->lock_user_location))
12340 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12341 ret = e_grabinput_get(bd->win, 0, bd->win);
12343 ret = e_grabinput_get(bd->win, 0, 0);
12345 if (grabbed && !ret)
12351 if (bd->client.netwm.sync.request)
12353 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12354 bd->client.netwm.sync.serial = 0;
12355 bd->client.netwm.sync.wait = 0;
12356 bd->client.netwm.sync.time = ecore_loop_time_get();
12359 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12366 _e_border_move_end(E_Border *bd)
12370 e_grabinput_release(bd->win, bd->win);
12374 if (bd->client.netwm.sync.alarm)
12376 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12377 bd->client.netwm.sync.alarm = 0;
12380 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12387 _e_border_move_update(E_Border *bd)
12389 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12393 _e_border_cb_ping_poller(void *data)
12403 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12404 if (bd->kill_timer)
12406 ecore_timer_del(bd->kill_timer);
12407 bd->kill_timer = NULL;
12413 /* if time between last ping and now is greater
12414 * than half the ping interval... */
12415 if ((ecore_loop_time_get() - bd->ping) >
12416 ((e_config->ping_clients_interval *
12417 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12422 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12423 /* FIXME: if below dialog is up - hide it now */
12425 if (bd->delete_requested)
12427 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12428 e_border_act_kill_begin(bd);
12432 bd->ping_poller = NULL;
12434 return ECORE_CALLBACK_CANCEL;
12438 _e_border_cb_kill_timer(void *data)
12443 // dont wait until it's hung -
12446 if (bd->client.netwm.pid > 1)
12447 kill(bd->client.netwm.pid, SIGKILL);
12449 bd->kill_timer = NULL;
12450 return ECORE_CALLBACK_CANCEL;
12454 _e_border_pointer_resize_begin(E_Border *bd)
12456 switch (bd->resize_mode)
12459 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12463 e_pointer_type_push(bd->pointer, bd, "resize_t");
12467 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12471 e_pointer_type_push(bd->pointer, bd, "resize_r");
12475 e_pointer_type_push(bd->pointer, bd, "resize_br");
12479 e_pointer_type_push(bd->pointer, bd, "resize_b");
12483 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12487 e_pointer_type_push(bd->pointer, bd, "resize_l");
12493 _e_border_pointer_resize_end(E_Border *bd)
12495 switch (bd->resize_mode)
12498 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12502 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12506 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12510 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12514 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12518 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12522 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12526 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12532 _e_border_pointer_move_begin(E_Border *bd)
12534 e_pointer_type_push(bd->pointer, bd, "move");
12538 _e_border_pointer_move_end(E_Border *bd)
12540 e_pointer_type_pop(bd->pointer, bd, "move");
12543 static Eina_List *_e_border_hooks = NULL;
12544 static int _e_border_hooks_delete = 0;
12545 static int _e_border_hooks_walking = 0;
12548 _e_border_hooks_clean(void)
12553 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12557 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12564 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12570 _e_border_hooks_walking++;
12571 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12573 if (bh->delete_me) continue;
12574 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12576 _e_border_hooks_walking--;
12577 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12578 _e_border_hooks_clean();
12581 EAPI E_Border_Hook *
12582 e_border_hook_add(E_Border_Hook_Point hookpoint,
12583 void (*func)(void *data,
12589 bh = E_NEW(E_Border_Hook, 1);
12590 if (!bh) return NULL;
12591 bh->hookpoint = hookpoint;
12594 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12599 e_border_hook_del(E_Border_Hook *bh)
12602 if (_e_border_hooks_walking == 0)
12604 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12608 _e_border_hooks_delete++;
12612 e_border_focus_track_freeze(void)
12614 focus_track_frozen++;
12618 e_border_focus_track_thaw(void)
12620 focus_track_frozen--;
12624 e_border_under_pointer_get(E_Desk *desk,
12627 E_Border *bd = NULL, *cbd;
12631 /* We need to ensure that we can get the container window for the
12632 * zone of either the given desk or the desk of the excluded
12633 * window, so return if neither is given */
12635 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12637 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12641 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12643 if (!cbd) continue;
12644 /* If a border was specified which should be excluded from the list
12645 * (because it will be closed shortly for example), skip */
12646 if ((exclude) && (cbd == exclude)) continue;
12647 if ((desk) && (cbd->desk != desk)) continue;
12648 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12650 /* If the layer is higher, the position of the window is higher
12651 * (always on top vs always below) */
12652 if (!bd || (cbd->layer > bd->layer))
12662 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12669 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12670 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12671 (y - warp_y) > 5 || (y - warp_y) < -5)
12673 /* User moved the mouse, so stop warping */
12678 /* We just use the same warp speed as configured
12679 * for the windowlist */
12680 spd = e_config->winlist_warp_speed;
12683 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12684 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12685 if (warp_x == x && warp_y == y)
12687 warp_x = warp_to_x;
12688 warp_y = warp_to_y;
12692 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12693 return ECORE_CALLBACK_RENEW;
12696 ecore_timer_del(warp_timer);
12698 return ECORE_CALLBACK_CANCEL;
12702 e_border_pointer_warp_to_center(E_Border *bd)
12706 /* Do not slide pointer when disabled (probably breaks focus
12707 * on sloppy/mouse focus but requested by users). */
12708 if (!e_config->pointer_slide) return 0;
12709 /* Only warp the pointer if it is not already in the area of
12710 * the given border */
12711 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12712 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12713 (y >= bd->y) && (y <= (bd->y + bd->h)))
12716 warp_to_x = bd->x + (bd->w / 2);
12717 if (warp_to_x < (bd->zone->x + 1))
12718 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12719 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12720 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12722 warp_to_y = bd->y + (bd->h / 2);
12723 if (warp_to_y < (bd->zone->y + 1))
12724 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12725 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12726 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12729 warp_to_win = bd->zone->container->win;
12730 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12732 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12737 e_border_comp_hidden_set(E_Border *bd,
12743 E_OBJECT_CHECK(bd);
12744 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12746 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12749 ecore_x_window_hide(tmp->win);
12751 ecore_x_window_show(tmp->win);
12754 if (bd->comp_hidden == hidden) return;
12756 bd->comp_hidden = hidden;
12758 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12760 ecore_x_composite_window_events_disable(bd->win);
12761 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12765 _e_border_shape_input_rectangle_set(bd);
12766 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12771 e_border_tmp_input_hidden_push(E_Border *bd)
12776 E_OBJECT_CHECK(bd);
12777 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12779 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12780 e_border_tmp_input_hidden_push(tmp);
12782 bd->tmp_input_hidden++;
12783 if (bd->tmp_input_hidden != 1) return;
12785 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12787 ecore_x_composite_window_events_disable(bd->win);
12788 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12792 _e_border_shape_input_rectangle_set(bd);
12793 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12798 e_border_tmp_input_hidden_pop(E_Border *bd)
12803 E_OBJECT_CHECK(bd);
12804 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12806 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12807 e_border_tmp_input_hidden_pop(tmp);
12809 bd->tmp_input_hidden--;
12810 if (bd->tmp_input_hidden != 0) return;
12812 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12814 ecore_x_composite_window_events_disable(bd->win);
12815 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12819 _e_border_shape_input_rectangle_set(bd);
12820 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12825 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12827 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12829 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12830 ((bd->parent->focused) &&
12831 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12836 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12837 e_desk_show(bd->desk);
12839 if (!bd->lock_user_iconify)
12840 e_border_uniconify(bd);
12842 if ((!bd->iconic) && (!bd->sticky))
12843 e_desk_show(bd->desk);
12844 if (!bd->lock_user_stacking) e_border_raise(bd);
12845 if (!bd->lock_focus_out)
12847 /* XXX ooffice does send this request for
12848 config dialogs when the main window gets focus.
12849 causing the pointer to jump back and forth. */
12850 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12851 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12852 ecore_x_pointer_warp(bd->zone->container->win,
12853 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12854 e_border_focus_set(bd, 1, 1);
12858 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/