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_ */
299 #ifdef _F_DEICONIFY_APPROVE_
300 static void _e_border_msg_handler(void *data,
308 /* local subsystem globals */
309 static Eina_List *handlers = NULL;
310 static Eina_List *borders = NULL;
311 static Eina_Hash *borders_hash = NULL;
312 static E_Border *focused = NULL;
313 static E_Border *focusing = NULL;
314 static Eina_List *focus_next = NULL;
315 static Ecore_X_Time focus_time = 0;
317 static E_Border *bdresize = NULL;
318 static E_Border *bdmove = NULL;
319 static E_Drag *drag_border = NULL;
321 static int grabbed = 0;
323 static Eina_List *focus_stack = NULL;
324 static Eina_List *raise_stack = NULL;
326 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
327 static int screen_size_index = -1;
329 static int focus_track_frozen = 0;
331 static int warp_to = 0;
332 static int warp_to_x = 0;
333 static int warp_to_y = 0;
334 static int warp_x = 0;
335 static int warp_y = 0;
336 static Ecore_X_Window warp_to_win;
337 static Ecore_Timer *warp_timer = NULL;
339 #ifdef _F_DEICONIFY_APPROVE_
340 static E_Msg_Handler *_msg_handler = NULL;
343 #ifdef _F_ZONE_WINDOW_ROTATION_
344 typedef struct _E_Border_Rotation E_Border_Rotation;
345 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
347 struct _E_Border_Rotation
350 Eina_List *async_list;
352 Eina_Bool wait_prepare_done;
353 Ecore_Timer *prepare_timer;
354 Ecore_Timer *done_timer;
356 Ecore_Job *async_job;
358 Ecore_X_Window vkbd_ctrl_win;
360 E_Border *vkbd_prediction;
362 /* vkbd show/hide preprare */
363 Eina_Bool vkbd_show_prepare_done;
364 Ecore_Timer *vkbd_show_prepare_timer;
365 Ecore_Timer *vkbd_show_timer;
367 Eina_Bool vkbd_hide_prepare_done;
368 Ecore_Timer *vkbd_hide_prepare_timer;
369 Ecore_Timer *vkbd_hide_timer;
375 struct _E_Border_Rotation_Info
380 Eina_Bool win_resize;
383 static E_Border_Rotation rot =
406 EAPI int E_EVENT_BORDER_ADD = 0;
407 EAPI int E_EVENT_BORDER_REMOVE = 0;
408 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
409 EAPI int E_EVENT_BORDER_DESK_SET = 0;
410 EAPI int E_EVENT_BORDER_RESIZE = 0;
411 EAPI int E_EVENT_BORDER_MOVE = 0;
412 EAPI int E_EVENT_BORDER_SHOW = 0;
413 EAPI int E_EVENT_BORDER_HIDE = 0;
414 EAPI int E_EVENT_BORDER_ICONIFY = 0;
415 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
416 EAPI int E_EVENT_BORDER_STICK = 0;
417 EAPI int E_EVENT_BORDER_UNSTICK = 0;
418 EAPI int E_EVENT_BORDER_STACK = 0;
419 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
420 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
421 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
422 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
423 EAPI int E_EVENT_BORDER_PROPERTY = 0;
424 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
425 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
426 #ifdef _F_ZONE_WINDOW_ROTATION_
427 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
428 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
429 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
430 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
433 #define GRAV_SET(bd, grav) \
434 ecore_x_window_gravity_set(bd->bg_win, grav); \
435 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
436 ecore_x_window_gravity_set(bd->client.win, grav);
439 _e_border_sub_borders_new(E_Border *bd)
441 Eina_List *list = NULL, *l;
445 EINA_LIST_FOREACH(bd->transients, l, child)
447 if (!eina_list_data_find(list, child))
448 list = eina_list_append(list, child);
450 bl = e_container_border_list_first(bd->zone->container);
451 while ((child = e_container_border_list_next(bl)))
453 if (e_object_is_del(E_OBJECT(child))) continue;
454 if (child == bd) continue;
456 if ((bd->client.icccm.client_leader) &&
457 (child->client.icccm.client_leader ==
458 bd->client.icccm.client_leader))
460 printf("bd %s in group with %s\n",
461 e_border_name_get(child),
462 e_border_name_get(bd));
463 if (!eina_list_data_find(list, child))
464 list = eina_list_append(list, child);
468 e_container_border_list_free(bl);
472 /* externally accessible functions */
476 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
477 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
478 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
479 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
480 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
483 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
484 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
485 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
486 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
487 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
488 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
489 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
490 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
491 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
492 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
493 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
494 #ifdef _F_ZONE_WINDOW_ROTATION_
495 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
498 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
500 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
501 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
502 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
503 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
504 #ifdef _F_USE_DESK_WINDOW_PROFILE_
505 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
507 #ifdef _F_ZONE_WINDOW_ROTATION_
508 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
511 #ifdef _F_DEICONIFY_APPROVE_
512 _msg_handler = e_msg_handler_add(_e_border_msg_handler, NULL);
515 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
517 E_EVENT_BORDER_ADD = ecore_event_type_new();
518 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
519 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
520 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
521 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
522 E_EVENT_BORDER_MOVE = ecore_event_type_new();
523 E_EVENT_BORDER_SHOW = ecore_event_type_new();
524 E_EVENT_BORDER_HIDE = ecore_event_type_new();
525 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
526 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
527 E_EVENT_BORDER_STICK = ecore_event_type_new();
528 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
529 E_EVENT_BORDER_STACK = ecore_event_type_new();
530 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
531 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
532 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
533 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
534 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
535 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
536 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
537 #ifdef _F_ZONE_WINDOW_ROTATION_
538 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
539 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
540 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
541 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
550 e_border_shutdown(void)
552 E_FREE_LIST(handlers, ecore_event_handler_del);
554 if (borders_hash) eina_hash_free(borders_hash);
556 e_int_border_menu_hooks_clear();
562 e_border_new(E_Container *con,
568 Ecore_X_Window_Attributes *att;
569 unsigned int managed, desk[2];
572 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
573 if (!bd) return NULL;
574 ecore_x_window_shadow_tree_flush();
575 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
579 /* FIXME: ewww - round trip */
580 bd->client.argb = ecore_x_window_argb_get(win);
582 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
585 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
586 ecore_x_window_shape_events_select(bd->win, 1);
588 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
589 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
591 bd->bg_ecore_evas = e_canvas_new(bd->win,
592 0, 0, bd->w, bd->h, 1, 0,
594 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
595 e_canvas_add(bd->bg_ecore_evas);
596 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
597 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
598 ecore_x_window_shape_events_select(bd->bg_win, 1);
599 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
600 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
602 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
604 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
605 ecore_x_window_container_manage(bd->client.shell_win);
606 if (!internal) ecore_x_window_client_manage(win);
607 /* FIXME: Round trip. XCB */
608 /* fetch needed to avoid grabbing the server as window may vanish */
609 att = &bd->client.initial_attributes;
610 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
612 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
613 e_canvas_del(bd->bg_ecore_evas);
614 ecore_evas_free(bd->bg_ecore_evas);
615 ecore_x_window_free(bd->client.shell_win);
616 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
617 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
618 ecore_x_window_free(bd->win);
623 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
624 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
626 /* FIXME: if first_map is 1 then we should ignore the first hide event
627 * or ensure the window is already hidden and events flushed before we
628 * create a border for it */
631 // printf("##- FIRST MAP\n");
636 // needed to be 1 for internal windw and on restart.
637 // bd->ignore_first_unmap = 2;
640 bd->client.win = win;
641 bd->zone = e_zone_current_get(con);
643 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
645 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
646 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
647 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
648 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
649 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
650 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
652 bd->client.icccm.title = NULL;
653 bd->client.icccm.name = NULL;
654 bd->client.icccm.class = NULL;
655 bd->client.icccm.icon_name = NULL;
656 bd->client.icccm.machine = NULL;
657 bd->client.icccm.min_w = 1;
658 bd->client.icccm.min_h = 1;
659 bd->client.icccm.max_w = 32767;
660 bd->client.icccm.max_h = 32767;
661 bd->client.icccm.base_w = 0;
662 bd->client.icccm.base_h = 0;
663 bd->client.icccm.step_w = -1;
664 bd->client.icccm.step_h = -1;
665 bd->client.icccm.min_aspect = 0.0;
666 bd->client.icccm.max_aspect = 0.0;
667 bd->client.icccm.accepts_focus = 1;
669 bd->client.netwm.pid = 0;
670 bd->client.netwm.name = NULL;
671 bd->client.netwm.icon_name = NULL;
672 bd->client.netwm.desktop = 0;
673 bd->client.netwm.state.modal = 0;
674 bd->client.netwm.state.sticky = 0;
675 bd->client.netwm.state.shaded = 0;
676 bd->client.netwm.state.hidden = 0;
677 bd->client.netwm.state.maximized_v = 0;
678 bd->client.netwm.state.maximized_h = 0;
679 bd->client.netwm.state.skip_taskbar = 0;
680 bd->client.netwm.state.skip_pager = 0;
681 bd->client.netwm.state.fullscreen = 0;
682 bd->client.netwm.state.stacking = E_STACKING_NONE;
683 bd->client.netwm.action.move = 0;
684 bd->client.netwm.action.resize = 0;
685 bd->client.netwm.action.minimize = 0;
686 bd->client.netwm.action.shade = 0;
687 bd->client.netwm.action.stick = 0;
688 bd->client.netwm.action.maximized_h = 0;
689 bd->client.netwm.action.maximized_v = 0;
690 bd->client.netwm.action.fullscreen = 0;
691 bd->client.netwm.action.change_desktop = 0;
692 bd->client.netwm.action.close = 0;
693 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
699 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
700 bd->client.icccm.fetch.command = 1;
703 Eina_Bool video_parent = EINA_FALSE;
704 Eina_Bool video_position = EINA_FALSE;
707 for (i = 0; i < at_num; i++)
709 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
710 bd->client.icccm.fetch.title = 1;
711 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
712 bd->client.icccm.fetch.name_class = 1;
713 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
714 bd->client.icccm.fetch.icon_name = 1;
715 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
716 bd->client.icccm.fetch.machine = 1;
717 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
718 bd->client.icccm.fetch.hints = 1;
719 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
720 bd->client.icccm.fetch.size_pos_hints = 1;
721 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
722 bd->client.icccm.fetch.protocol = 1;
723 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
724 bd->client.mwm.fetch.hints = 1;
725 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
727 bd->client.icccm.fetch.transient_for = 1;
728 bd->client.netwm.fetch.type = 1;
730 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
731 bd->client.icccm.fetch.client_leader = 1;
732 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
733 bd->client.icccm.fetch.window_role = 1;
734 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
735 bd->client.icccm.fetch.state = 1;
737 /* netwm, loop again, netwm will ignore some icccm, so we
738 * have to be sure that netwm is checked after */
739 for (i = 0; i < at_num; i++)
741 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
744 bd->client.icccm.fetch.title = 0;
745 bd->client.netwm.fetch.name = 1;
747 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
750 bd->client.icccm.fetch.icon_name = 0;
751 bd->client.netwm.fetch.icon_name = 1;
753 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
755 bd->client.netwm.fetch.icon = 1;
757 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
759 bd->client.netwm.fetch.user_time = 1;
761 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
763 DBG("ECORE_X_ATOM_NET_WM_STRUT");
764 bd->client.netwm.fetch.strut = 1;
766 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
768 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
769 bd->client.netwm.fetch.strut = 1;
771 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
774 bd->client.mwm.fetch.hints = 0;
776 bd->client.netwm.fetch.type = 1;
778 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
780 bd->client.netwm.fetch.state = 1;
783 /* other misc atoms */
784 for (i = 0; i < at_num; i++)
786 /* loop to check for own atoms */
787 if (atoms[i] == E_ATOM_WINDOW_STATE)
789 bd->client.e.fetch.state = 1;
791 /* loop to check for qtopia atoms */
792 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
793 bd->client.qtopia.fetch.soft_menu = 1;
794 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
795 bd->client.qtopia.fetch.soft_menus = 1;
796 /* loop to check for vkbd atoms */
797 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
798 bd->client.vkbd.fetch.state = 1;
799 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
800 bd->client.vkbd.fetch.vkbd = 1;
801 /* loop to check for illume atoms */
802 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
803 bd->client.illume.conformant.fetch.conformant = 1;
804 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
805 bd->client.illume.quickpanel.fetch.state = 1;
806 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
807 bd->client.illume.quickpanel.fetch.quickpanel = 1;
808 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
809 bd->client.illume.quickpanel.fetch.priority.major = 1;
810 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
811 bd->client.illume.quickpanel.fetch.priority.minor = 1;
812 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
813 bd->client.illume.quickpanel.fetch.zone = 1;
814 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
815 bd->client.illume.drag.fetch.locked = 1;
816 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
817 bd->client.illume.drag.fetch.drag = 1;
818 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
819 bd->client.illume.win_state.fetch.state = 1;
820 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
821 video_parent = EINA_TRUE;
822 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
823 video_position = EINA_TRUE;
824 #ifdef _F_USE_DESK_WINDOW_PROFILE_
825 /* loop to check for window profile list atom */
826 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
827 bd->client.e.fetch.profile_list = 1;
829 #ifdef _F_ZONE_WINDOW_ROTATION_
830 /* loop to check for wm rotation */
831 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
833 if (e_config->wm_win_rotation)
834 bd->client.e.fetch.rot.support = 1;
836 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
837 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
838 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
839 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
841 if (e_config->wm_win_rotation)
842 bd->client.e.fetch.rot.geom_hint = 1;
844 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
846 if (e_config->wm_win_rotation)
847 bd->client.e.fetch.rot.app_set = 1;
849 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
851 if (e_config->wm_win_rotation)
852 bd->client.e.fetch.rot.preferred_rot = 1;
854 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
856 if (e_config->wm_win_rotation)
857 bd->client.e.fetch.rot.available_rots = 1;
860 #ifdef _F_DEICONIFY_APPROVE_
861 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
863 bd->client.e.state.deiconify_approve.support = 1;
867 if (video_position && video_parent)
869 bd->client.e.state.video = 1;
870 bd->client.e.fetch.video_parent = 1;
871 bd->client.e.fetch.video_position = 1;
872 ecore_x_window_lower(bd->win);
873 ecore_x_composite_window_events_disable(bd->win);
874 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
875 fprintf(stderr, "We found a video window \\o/ %x\n", win);
880 bd->client.border.changed = 1;
882 bd->client.w = att->w;
883 bd->client.h = att->h;
885 #ifdef _F_FIX_POSITION_PROBLEM_
889 bd->w = bd->client.w;
890 bd->h = bd->client.h;
892 bd->resize_mode = RESIZE_NONE;
894 bd->saved.layer = bd->layer;
895 bd->changes.icon = 1;
896 bd->changes.size = 1;
897 bd->changes.shape = 1;
898 bd->changes.shape_input = 1;
900 bd->offer_resistance = 1;
902 /* just to friggin make java happy - we're DELAYING the reparent until
905 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
906 bd->need_reparent = 1;
908 ecore_x_window_border_width_set(win, 0);
909 ecore_x_window_show(bd->event_win);
910 ecore_x_window_show(bd->client.shell_win);
911 bd->shape = e_container_shape_add(con);
916 #ifdef _F_ZONE_WINDOW_ROTATION_
917 bd->client.e.state.rot.preferred_rot = -1;
918 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
919 bd->client.e.state.rot.changes = -1;
920 bd->client.e.state.rot.pending_show = 0;
921 bd->client.e.state.rot.curr = 0;
922 bd->client.e.state.rot.prev = 0;
925 // bd->zone = e_zone_current_get(con);
926 bd->desk = e_desk_current_get(bd->zone);
927 e_container_border_add(bd);
928 borders = eina_list_append(borders, bd);
929 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
933 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
934 "optimisations failing due to bizarre client behavior. will\n"
936 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
937 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
940 ELBF(ELBT_BD, 0, bd->client.win,
941 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
942 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
944 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
945 printf("optimisations failing due to bizarre client behavior. will\n");
946 printf("work around.\n");
947 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
948 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
951 ELBF(ELBT_BD, 0, bd->client.win,
952 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
953 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
956 #ifdef _F_ZONE_WINDOW_ROTATION_
957 if ((rot.vkbd) && (rot.vkbd == bd2))
959 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
960 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
961 rot.vkbd_hide_prepare_done);
963 if (rot.vkbd_hide_prepare_timer)
965 ecore_timer_del(rot.vkbd_hide_prepare_timer);
966 rot.vkbd_hide_prepare_timer = NULL;
968 e_object_unref(E_OBJECT(bd2));
971 _e_border_vkbd_hide(rot.vkbd);
973 if (rot.vkbd_ctrl_win)
975 ELB(ELBT_BD, "SET KBD_OFF", 0);
976 ecore_x_e_virtual_keyboard_state_set
977 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
979 rot.vkbd_hide_prepare_done = EINA_FALSE;
981 if (rot.vkbd_hide_timer)
982 ecore_timer_del(rot.vkbd_hide_timer);
983 rot.vkbd_hide_timer = NULL;
985 rot.vkbd_show_prepare_done = EINA_FALSE;
986 if (rot.vkbd_show_prepare_timer)
987 ecore_timer_del(rot.vkbd_show_prepare_timer);
988 rot.vkbd_show_prepare_timer = NULL;
989 if (rot.vkbd_show_timer)
990 ecore_timer_del(rot.vkbd_show_timer);
991 rot.vkbd_show_timer = NULL;
996 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
997 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
998 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
1000 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
1001 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1002 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1004 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
1005 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
1006 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
1008 unsigned int zgeom[4];
1010 zgeom[0] = bd->zone->x;
1011 zgeom[1] = bd->zone->y;
1012 zgeom[2] = bd->zone->w;
1013 zgeom[3] = bd->zone->h;
1014 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1016 e_desk_xy_get(bd->desk, &deskx, &desky);
1019 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
1020 #ifdef _F_USE_DESK_WINDOW_PROFILE_
1021 if (strcmp(bd->desk->window_profile,
1022 e_config->desktop_default_window_profile) != 0)
1024 ecore_x_e_window_profile_set(bd->client.win,
1025 bd->desk->window_profile);
1029 focus_stack = eina_list_append(focus_stack, bd);
1031 bd->pointer = e_pointer_window_new(bd->win, 0);
1036 e_border_res_change_geometry_save(E_Border *bd)
1039 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1041 if (bd->pre_res_change.valid) return;
1042 bd->pre_res_change.valid = 1;
1043 bd->pre_res_change.x = bd->x;
1044 bd->pre_res_change.y = bd->y;
1045 bd->pre_res_change.w = bd->w;
1046 bd->pre_res_change.h = bd->h;
1047 bd->pre_res_change.saved.x = bd->saved.x;
1048 bd->pre_res_change.saved.y = bd->saved.y;
1049 bd->pre_res_change.saved.w = bd->saved.w;
1050 bd->pre_res_change.saved.h = bd->saved.h;
1054 e_border_res_change_geometry_restore(E_Border *bd)
1058 unsigned char valid : 1;
1067 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1068 if (!bd->pre_res_change.valid) return;
1069 if (bd->new_client) return;
1071 ecore_x_window_shadow_tree_flush();
1072 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1076 e_border_unfullscreen(bd);
1077 e_border_fullscreen(bd, e_config->fullscreen_policy);
1079 else if (bd->maximized != E_MAXIMIZE_NONE)
1083 max = bd->maximized;
1084 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1085 e_border_maximize(bd, max);
1089 int x, y, w, h, zx, zy, zw, zh;
1091 bd->saved.x = bd->pre_res_change.saved.x;
1092 bd->saved.y = bd->pre_res_change.saved.y;
1093 bd->saved.w = bd->pre_res_change.saved.w;
1094 bd->saved.h = bd->pre_res_change.saved.h;
1096 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1098 if (bd->saved.w > zw)
1100 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1101 bd->saved.x = zx + zw - bd->saved.w;
1103 if (bd->saved.h > zh)
1105 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1106 bd->saved.y = zy + zh - bd->saved.h;
1108 x = bd->pre_res_change.x;
1109 y = bd->pre_res_change.y;
1110 w = bd->pre_res_change.w;
1111 h = bd->pre_res_change.h;
1116 if ((x + w) > (zx + zw))
1118 if ((y + h) > (zy + zh))
1120 e_border_move_resize(bd, x, y, w, h);
1122 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1126 e_border_zone_set(E_Border *bd,
1129 E_Event_Border_Zone_Set *ev;
1132 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1133 E_OBJECT_CHECK(zone);
1134 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1136 if (bd->zone == zone) return;
1138 /* if the window does not lie in the new zone, move it so that it does */
1139 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1142 /* first guess -- get offset from old zone, and apply to new zone */
1143 x = zone->x + (bd->x - bd->zone->x);
1144 y = zone->y + (bd->y - bd->zone->y);
1146 /* keep window from hanging off bottom and left */
1147 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1148 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1150 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1151 if (x < zone->x) x = zone->x;
1152 if (y < zone->y) y = zone->y;
1154 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1156 /* still not in zone at all, so just move it to closest edge */
1157 if (x < zone->x) x = zone->x;
1158 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1159 if (y < zone->y) y = zone->y;
1160 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1162 e_border_move(bd, x, y);
1167 if (bd->desk->zone != bd->zone)
1168 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1170 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1172 e_object_ref(E_OBJECT(bd));
1173 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1175 e_object_ref(E_OBJECT(zone));
1177 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1179 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1180 // XXXXXXXXXXXXXXXXXXXXXXXXX
1181 // XXX ZZZZZZZZZZZZZZZZZZZzz
1182 // need to adjust this if zone pos/size changes
1184 unsigned int zgeom[4];
1186 zgeom[0] = bd->zone->x;
1187 zgeom[1] = bd->zone->y;
1188 zgeom[2] = bd->zone->w;
1189 zgeom[3] = bd->zone->h;
1190 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1192 e_remember_update(bd);
1196 e_border_desk_set(E_Border *bd,
1199 E_Event_Border_Desk_Set *ev;
1203 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1204 E_OBJECT_CHECK(desk);
1205 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1206 if (bd->desk == desk) return;
1207 ecore_x_window_shadow_tree_flush();
1210 bd->desk->fullscreen_borders--;
1211 desk->fullscreen_borders++;
1213 old_desk = bd->desk;
1215 e_border_zone_set(bd, desk->zone);
1217 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1218 e_hints_window_desktop_set(bd);
1220 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1222 e_object_ref(E_OBJECT(bd));
1223 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1224 ev->desk = old_desk;
1225 e_object_ref(E_OBJECT(old_desk));
1226 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1228 if (bd->ignore_first_unmap != 1)
1230 if ((bd->desk->visible) || (bd->sticky))
1233 e_border_hide(bd, 1);
1236 if (e_config->transient.desktop)
1240 Eina_List *list = _e_border_sub_borders_new(bd);
1242 EINA_LIST_FOREACH(list, l, child)
1244 e_border_desk_set(child, bd->desk);
1246 eina_list_free(list);
1248 e_remember_update(bd);
1251 #ifdef _F_ZONE_WINDOW_ROTATION_
1253 _e_border_vkbd_state_check(E_Border *bd,
1256 Eina_Bool res = EINA_TRUE;
1257 if (!e_config->wm_win_rotation) return EINA_FALSE;
1258 if ((rot.vkbd) && (rot.vkbd == bd))
1262 if ((rot.vkbd_hide_prepare_done) ||
1263 (rot.vkbd_hide_prepare_timer))
1268 if ((rot.vkbd_show_prepare_done) ||
1269 (rot.vkbd_show_prepare_timer))
1277 _e_border_vkbd_show_timeout(void *data)
1279 E_Border *bd = data;
1280 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1281 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1283 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1285 if (rot.vkbd_ctrl_win)
1287 ELB(ELBT_BD, "SET KBD_ON", 0);
1288 ecore_x_e_virtual_keyboard_state_set
1289 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1294 rot.vkbd_show_prepare_done = EINA_FALSE;
1296 if (rot.vkbd_show_prepare_timer)
1297 ecore_timer_del(rot.vkbd_show_prepare_timer);
1298 rot.vkbd_show_prepare_timer = NULL;
1300 if (rot.vkbd_show_timer)
1301 ecore_timer_del(rot.vkbd_show_timer);
1302 rot.vkbd_show_timer = NULL;
1304 return ECORE_CALLBACK_CANCEL;
1308 _e_border_vkbd_hide_timeout(void *data)
1310 E_Border *bd = data;
1311 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1312 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1314 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1316 if (rot.vkbd_ctrl_win)
1318 ELB(ELBT_BD, "SET KBD_OFF", 0);
1319 ecore_x_e_virtual_keyboard_state_set
1320 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1323 e_object_unref(E_OBJECT(bd));
1326 rot.vkbd_hide_prepare_done = EINA_FALSE;
1328 if (rot.vkbd_hide_prepare_timer)
1329 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1330 rot.vkbd_hide_prepare_timer = NULL;
1332 if (rot.vkbd_hide_timer)
1333 ecore_timer_del(rot.vkbd_hide_timer);
1334 rot.vkbd_hide_timer = NULL;
1336 return ECORE_CALLBACK_CANCEL;
1340 _e_border_vkbd_show(E_Border *bd)
1342 if (!e_config->wm_win_rotation) return;
1343 rot.vkbd_show_prepare_done = EINA_TRUE;
1344 if (rot.vkbd_show_prepare_timer)
1345 ecore_timer_del(rot.vkbd_show_prepare_timer);
1346 rot.vkbd_show_prepare_timer = NULL;
1347 if (rot.vkbd_show_timer)
1348 ecore_timer_del(rot.vkbd_show_timer);
1349 rot.vkbd_show_timer = NULL;
1350 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1353 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1358 _e_border_vkbd_hide(E_Border *bd)
1360 if (!e_config->wm_win_rotation) return;
1361 rot.vkbd_hide_prepare_done = EINA_TRUE;
1362 if (rot.vkbd_hide_prepare_timer)
1363 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1364 rot.vkbd_hide_prepare_timer = NULL;
1365 if (rot.vkbd_hide_timer)
1366 ecore_timer_del(rot.vkbd_hide_timer);
1367 rot.vkbd_hide_timer = NULL;
1368 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1370 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1371 e_border_hide(bd, 0);
1372 if (!e_object_is_del(E_OBJECT(bd)))
1374 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1375 e_object_del(E_OBJECT(bd));
1377 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1382 _e_border_vkbd_show_prepare_timeout(void *data)
1384 E_Border *bd = data;
1385 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1386 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1388 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1389 _e_border_vkbd_show(bd);
1391 return ECORE_CALLBACK_CANCEL;
1395 _e_border_vkbd_hide_prepare_timeout(void *data)
1397 E_Border *bd = data;
1398 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1399 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1401 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1402 _e_border_vkbd_hide(bd);
1404 return ECORE_CALLBACK_CANCEL;
1409 e_border_show(E_Border *bd)
1411 E_Event_Border_Show *ev;
1412 unsigned int visible;
1415 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1416 if (bd->visible) return;
1417 #ifdef _F_ZONE_WINDOW_ROTATION_
1418 // newly created window that has to be rotated will be show after rotation done.
1419 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1420 if ((bd->new_client) &&
1421 (bd->client.e.state.rot.changes != -1))
1423 ELB(ELBT_BD, "PENDING SHOW UNTIL GETTING ROT_DONE", bd->client.win);
1424 // if this window is in withdrawn state, set the normal state
1425 // that's because the window in withdrawn state can't render its canvas.
1426 // eventually, this window will not send the message of rotation done,
1427 // even if e17 request to rotation this window.
1428 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1429 e_hints_window_visible_set(bd);
1431 bd->client.e.state.rot.pending_show = 1;
1434 if ((e_config->wm_win_rotation) &&
1435 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1437 (!rot.vkbd_show_prepare_done))
1439 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1440 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1441 if (rot.vkbd_show_prepare_timer)
1442 ecore_timer_del(rot.vkbd_show_prepare_timer);
1443 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1444 _e_border_vkbd_show_prepare_timeout,
1448 ELB(ELBT_BD, "SHOW", bd->client.win);
1450 ecore_x_window_shadow_tree_flush();
1451 e_container_shape_show(bd->shape);
1452 if (!bd->need_reparent)
1453 ecore_x_window_show(bd->client.win);
1454 e_hints_window_visible_set(bd);
1457 bd->changes.visible = 1;
1460 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1461 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1463 ev = E_NEW(E_Event_Border_Show, 1);
1465 e_object_ref(E_OBJECT(bd));
1466 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1467 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1469 #ifdef _F_ZONE_WINDOW_ROTATION_
1470 if ((e_config->wm_win_rotation) &&
1471 ((bd->client.e.state.rot.support) ||
1472 (bd->client.e.state.rot.app_set)))
1474 ELB(ELBT_ROT, "CHECK", bd->client.win);
1475 int rotation = _e_border_rotation_angle_get(bd);
1476 if (rotation != -1) e_border_rotation_set(bd, rotation);
1482 e_border_hide(E_Border *bd,
1485 unsigned int visible;
1488 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1490 #ifdef _F_ZONE_WINDOW_ROTATION_
1491 if ((e_config->wm_win_rotation) &&
1492 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1494 (!rot.vkbd_hide_prepare_done) &&
1497 Eina_Bool need_prepare = EINA_TRUE;
1498 E_Border *child = NULL;
1501 if (e_object_is_del(E_OBJECT(bd->parent)))
1502 need_prepare = EINA_FALSE;
1505 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1506 if (bd->parent->modal == bd)
1508 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1509 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1510 bd->parent->lock_close = 0;
1511 bd->parent->saved.event_mask = 0;
1512 bd->parent->modal = NULL;
1518 need_prepare = EINA_FALSE;
1520 EINA_LIST_FREE(bd->transients, child)
1522 child->parent = NULL;
1525 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1529 e_object_ref(E_OBJECT(bd));
1530 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1531 if (rot.vkbd_hide_prepare_timer)
1532 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1533 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1534 _e_border_vkbd_hide_prepare_timeout,
1540 e_object_ref(E_OBJECT(bd));
1542 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1543 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1545 /* cleanup code from _e_border_vkbd_hide() */
1546 rot.vkbd_hide_prepare_done = EINA_TRUE;
1547 if (rot.vkbd_hide_prepare_timer)
1548 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1549 rot.vkbd_hide_prepare_timer = NULL;
1550 if (rot.vkbd_hide_timer)
1551 ecore_timer_del(rot.vkbd_hide_timer);
1552 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1555 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1557 if (!bd->visible) goto send_event;
1558 ecore_x_window_shadow_tree_flush();
1560 _e_border_move_end(bd);
1561 if (bd->resize_mode != RESIZE_NONE)
1563 _e_border_pointer_resize_end(bd);
1564 bd->resize_mode = RESIZE_NONE;
1565 _e_border_resize_end(bd);
1568 e_container_shape_hide(bd->shape);
1569 if (!bd->iconic) e_hints_window_hidden_set(bd);
1572 bd->changes.visible = 1;
1574 if (!bd->need_reparent)
1576 if ((bd->focused) ||
1577 (e_grabinput_last_focus_win_get() == bd->client.win))
1579 e_border_focus_set(bd, 0, 1);
1587 con = e_container_current_get(e_manager_current_get());
1588 zone = e_zone_current_get(con);
1589 desk = e_desk_current_get(zone);
1592 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1593 e_border_focus_set(bd->parent, 1, 1);
1594 else if (e_config->focus_revert_on_hide_or_close)
1596 /* When using pointer focus, the border under the
1597 * pointer (if any) gets focused, in sloppy/click
1598 * focus the last focused window on the current
1599 * desk gets focus */
1600 if (e_config->focus_policy == E_FOCUS_MOUSE)
1602 pbd = e_border_under_pointer_get(desk, bd);
1604 e_border_focus_set(pbd, 1, 1);
1606 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1607 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1608 (e_config->focus_policy == E_FOCUS_CLICK))
1609 _e_border_latest_stacked_focus(bd);
1613 e_desk_last_focused_focus(desk);
1623 /* Make sure that this border isn't deleted */
1624 bd->await_hide_event++;
1626 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1627 ecore_x_window_hide(bd->client.win);
1632 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1634 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1641 #ifdef _F_ZONE_WINDOW_ROTATION_
1642 _e_border_rotation_list_remove(bd);
1645 E_Event_Border_Hide *ev;
1647 ev = E_NEW(E_Event_Border_Hide, 1);
1649 e_object_ref(E_OBJECT(bd));
1650 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1651 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1656 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1660 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1661 setpriority(PRIO_PROCESS, pid, newpri);
1662 // shouldnt need to do this as default ionice class is "none" (0), and
1663 // this inherits io priority FROM nice level
1664 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1665 // IOPRIO_PRIO_VALUE(2, 5));
1669 char *file, buf[PATH_MAX];
1673 // yes - this is /proc specific... so this may not work on some
1674 // os's - works on linux. too bad for others.
1675 files = ecore_file_ls("/proc");
1676 EINA_LIST_FREE(files, file)
1678 if (isdigit(file[0]))
1680 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1681 f = fopen(buf, "r");
1686 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1692 _pri_adj(pid2, set, adj, EINA_TRUE,
1693 adj_children, do_children);
1695 _pri_adj(pid2, set, adj, use_adj,
1696 adj_children, do_children);
1708 _e_border_pri_raise(E_Border *bd)
1710 if (bd->client.netwm.pid <= 0) return;
1711 if (bd->client.netwm.pid == getpid()) return;
1712 _pri_adj(bd->client.netwm.pid,
1713 e_config->priority - 1, -1, EINA_FALSE,
1714 // EINA_TRUE, EINA_TRUE);
1715 EINA_TRUE, EINA_FALSE);
1716 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1717 // bd->client.netwm.pid, e_border_name_get(bd));
1721 _e_border_pri_norm(E_Border *bd)
1723 if (bd->client.netwm.pid <= 0) return;
1724 if (bd->client.netwm.pid == getpid()) return;
1725 _pri_adj(bd->client.netwm.pid,
1726 e_config->priority, 1, EINA_FALSE,
1727 // EINA_TRUE, EINA_TRUE);
1728 EINA_TRUE, EINA_FALSE);
1729 // printf("WIN: pid %i, title %s (NORMAL)\n",
1730 // bd->client.netwm.pid, e_border_name_get(bd));
1734 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1737 Ecore_Evas *bg_ecore_evas;
1743 bg_ecore_evas = bd->bg_ecore_evas;
1745 /* unregister old frame window */
1746 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1747 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1749 e_focus_setdown(bd);
1750 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1751 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1753 if (bd->icon_object)
1754 evas_object_del(bd->icon_object);
1756 evas_object_del(bd->bg_object);
1757 e_canvas_del(bg_ecore_evas);
1758 ecore_evas_free(bg_ecore_evas);
1761 e_object_del(E_OBJECT(bd->pointer));
1763 /* create new frame */
1765 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1766 bd->x, bd->y, bd->w, bd->h);
1769 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1770 bd->x, bd->y, bd->w, bd->h);
1771 ecore_x_window_shape_events_select(bd->win, 1);
1774 ecore_x_window_configure(bd->win,
1775 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1776 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1778 win, ECORE_X_WINDOW_STACK_BELOW);
1780 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1781 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1784 bd->bg_ecore_evas = e_canvas_new(bd->win,
1785 0, 0, bd->w, bd->h, 1, 0,
1788 e_canvas_add(bd->bg_ecore_evas);
1789 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1791 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1792 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1793 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1795 ecore_x_window_shape_events_select(bd->bg_win, 1);
1797 /* move client with shell win over to new frame */
1798 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1799 bd->client_inset.l, bd->client_inset.t);
1801 bd->pointer = e_pointer_window_new(bd->win, 0);
1803 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1804 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1811 ecore_evas_show(bd->bg_ecore_evas);
1812 ecore_x_window_show(bd->win);
1814 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1815 ecore_x_window_show(tmp->win);
1818 bd->bg_object = edje_object_add(bd->bg_evas);
1819 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1820 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1822 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1824 /* cleanup old frame */
1825 ecore_x_window_free(win);
1829 _e_border_client_move_resize_send(E_Border *bd)
1831 if (bd->internal_ecore_evas)
1832 ecore_evas_managed_move(bd->internal_ecore_evas,
1833 bd->x + bd->fx.x + bd->client_inset.l,
1834 bd->y + bd->fx.y + bd->client_inset.t);
1836 ecore_x_icccm_move_resize_send(bd->client.win,
1837 bd->x + bd->fx.x + bd->client_inset.l,
1838 bd->y + bd->fx.y + bd->client_inset.t,
1844 _e_border_pending_move_resize_add(E_Border *bd,
1851 Eina_Bool without_border,
1852 unsigned int serial)
1854 E_Border_Pending_Move_Resize *pnd;
1856 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1858 pnd->resize = resize;
1860 pnd->without_border = without_border;
1865 pnd->serial = serial;
1866 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1870 _e_border_move_internal(E_Border *bd,
1873 Eina_Bool without_border)
1875 E_Event_Border_Move *ev;
1878 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1880 ecore_x_window_shadow_tree_flush();
1883 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1889 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1891 if (e_config->allow_manip)
1894 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1899 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1904 else if (e_config->allow_manip)
1912 x -= bd->client_inset.l;
1913 y -= bd->client_inset.t;
1915 if (bd->move_intercept_cb)
1918 px = bd->x, py = bd->y;
1919 bd->move_intercept_cb(bd, x, y);
1920 if ((bd->x == px) && (bd->y == py)) return;
1922 else if ((x == bd->x) && (y == bd->y)) return;
1923 bd->pre_res_change.valid = 0;
1927 bd->changes.pos = 1;
1929 if (bd->client.netwm.sync.request)
1931 bd->client.netwm.sync.wait++;
1932 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1935 _e_border_client_move_resize_send(bd);
1936 _e_border_move_update(bd);
1937 ev = E_NEW(E_Event_Border_Move, 1);
1939 e_object_ref(E_OBJECT(bd));
1940 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1941 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1942 _e_border_zone_update(bd);
1946 * Move window to coordinates that already account border decorations.
1948 * This call will consider given position already accounts border
1949 * decorations, so it will not be considered later. This will just
1950 * work properly with borders that have being evaluated and border
1951 * decorations are known (border->client_inset).
1953 * @parm x horizontal position to place window.
1954 * @parm y vertical position to place window.
1956 * @see e_border_move_without_border()
1959 e_border_move(E_Border *bd,
1966 _e_border_move_internal(bd, x, y, 0);
1971 * Set a callback which will be called just prior to updating the
1972 * move coordinates for a border
1975 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1977 bd->move_intercept_cb = cb;
1981 * Move window to coordinates that do not account border decorations yet.
1983 * This call will consider given position does not account border
1984 * decoration, so these values (border->client_inset) will be
1985 * accounted automatically. This is specially useful when it is a new
1986 * client and has not be evaluated yet, in this case
1987 * border->client_inset will be zeroed and no information is known. It
1988 * will mark pending requests so border will be accounted on
1989 * evalutation phase.
1991 * @parm x horizontal position to place window.
1992 * @parm y vertical position to place window.
1994 * @see e_border_move()
1997 e_border_move_without_border(E_Border *bd,
2004 _e_border_move_internal(bd, x, y, 1);
2008 e_border_center(E_Border *bd)
2012 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2014 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
2015 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
2019 e_border_center_pos_get(E_Border *bd,
2025 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2027 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2028 if (x) *x = zx + (zw - bd->w) / 2;
2029 if (y) *y = zy + (zh - bd->h) / 2;
2033 e_border_fx_offset(E_Border *bd,
2038 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2040 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2044 bd->changes.pos = 1;
2047 if (bd->moving) _e_border_move_update(bd);
2051 _e_border_move_resize_internal(E_Border *bd,
2056 Eina_Bool without_border,
2059 E_Event_Border_Move *mev;
2060 E_Event_Border_Resize *rev;
2063 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2065 ecore_x_window_shadow_tree_flush();
2069 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2075 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2077 if (e_config->allow_manip)
2080 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2086 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2093 if (e_config->allow_manip)
2101 x -= bd->client_inset.l;
2102 y -= bd->client_inset.t;
2103 w += (bd->client_inset.l + bd->client_inset.r);
2104 h += (bd->client_inset.t + bd->client_inset.b);
2107 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2108 (w == bd->w) && (h == bd->h))
2111 bd->pre_res_change.valid = 0;
2114 bd->changes.pos = 1;
2120 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2121 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2123 if ((bd->shaped) || (bd->client.shaped))
2125 bd->need_shape_merge = 1;
2126 bd->need_shape_export = 1;
2128 if (bd->shaped_input)
2130 bd->need_shape_merge = 1;
2133 if (bd->internal_ecore_evas)
2136 bd->changes.size = 1;
2140 if (bdresize && bd->client.netwm.sync.request)
2142 bd->client.netwm.sync.wait++;
2143 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2144 * when no move is intended. The border geometry is set above anyways.
2146 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2147 bd->client.netwm.sync.serial);
2148 ecore_x_netwm_sync_request_send(bd->client.win,
2149 bd->client.netwm.sync.serial++);
2154 bd->changes.size = 1;
2158 _e_border_client_move_resize_send(bd);
2160 _e_border_resize_update(bd);
2163 mev = E_NEW(E_Event_Border_Move, 1);
2165 e_object_ref(E_OBJECT(bd));
2166 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2167 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2170 rev = E_NEW(E_Event_Border_Resize, 1);
2172 e_object_ref(E_OBJECT(bd));
2173 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2174 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2175 _e_border_zone_update(bd);
2179 * Move and resize window to values that already account border decorations.
2181 * This call will consider given values already accounts border
2182 * decorations, so it will not be considered later. This will just
2183 * work properly with borders that have being evaluated and border
2184 * decorations are known (border->client_inset).
2186 * @parm x horizontal position to place window.
2187 * @parm y vertical position to place window.
2188 * @parm w horizontal window size.
2189 * @parm h vertical window size.
2191 * @see e_border_move_resize_without_border()
2194 e_border_move_resize(E_Border *bd,
2203 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2207 * Move and resize window to values that do not account border decorations yet.
2209 * This call will consider given values already accounts border
2210 * decorations, so it will not be considered later. This will just
2211 * work properly with borders that have being evaluated and border
2212 * decorations are known (border->client_inset).
2214 * @parm x horizontal position to place window.
2215 * @parm y vertical position to place window.
2216 * @parm w horizontal window size.
2217 * @parm h vertical window size.
2219 * @see e_border_move_resize()
2222 e_border_move_resize_without_border(E_Border *bd,
2231 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2235 * Resize window to values that already account border decorations.
2237 * This call will consider given size already accounts border
2238 * decorations, so it will not be considered later. This will just
2239 * work properly with borders that have being evaluated and border
2240 * decorations are known (border->client_inset).
2242 * @parm w horizontal window size.
2243 * @parm h vertical window size.
2245 * @see e_border_resize_without_border()
2248 e_border_resize(E_Border *bd,
2255 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2258 #ifdef _F_ZONE_WINDOW_ROTATION_
2260 e_border_rotation_set(E_Border *bd, int rotation)
2262 return _e_border_rotation_set_internal(bd, rotation, NULL);
2267 * Resize window to values that do not account border decorations yet.
2269 * This call will consider given size does not account border
2270 * decoration, so these values (border->client_inset) will be
2271 * accounted automatically. This is specially useful when it is a new
2272 * client and has not be evaluated yet, in this case
2273 * border->client_inset will be zeroed and no information is known. It
2274 * will mark pending requests so border will be accounted on
2275 * evalutation phase.
2277 * @parm w horizontal window size.
2278 * @parm h vertical window size.
2280 * @see e_border_resize()
2283 e_border_resize_without_border(E_Border *bd,
2290 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2294 e_border_layer_set(E_Border *bd,
2300 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2302 ecore_x_window_shadow_tree_flush();
2304 oldraise = e_config->transient.raise;
2308 bd->saved.layer = layer;
2312 if (e_config->transient.layer)
2316 Eina_List *list = _e_border_sub_borders_new(bd);
2318 /* We need to set raise to one, else the child wont
2319 * follow to the new layer. It should be like this,
2320 * even if the user usually doesn't want to raise
2323 e_config->transient.raise = 1;
2324 EINA_LIST_FOREACH(list, l, child)
2326 e_border_layer_set(child, layer);
2330 e_config->transient.raise = oldraise;
2334 e_border_raise(E_Border *bd)
2336 E_Event_Border_Stack *ev;
2337 E_Border *last = NULL, *child;
2341 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2343 ecore_x_window_shadow_tree_flush();
2345 if (e_config->transient.raise)
2347 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2348 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2351 Eina_List *list = _e_border_sub_borders_new(bd);
2353 EINA_LIST_REVERSE_FOREACH(list, l, child)
2355 /* Don't stack iconic transients. If the user wants these shown,
2356 * thats another option.
2361 e_border_stack_below(child, last);
2366 /* First raise the border to find out which border we will end up above */
2367 above = e_container_border_raise(child);
2371 /* We ended up above a border, now we must stack this border to
2372 * generate the stacking event, and to check if this transient
2373 * has other transients etc.
2375 e_border_stack_above(child, above);
2379 /* If we didn't end up above any border, we are on the bottom! */
2380 e_border_lower(child);
2386 eina_list_free(list);
2387 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2391 EINA_LIST_FOREACH(bd->transients, l, child)
2393 /* Don't stack iconic transients. If the user wants these shown,
2394 * thats another option.
2398 child->layer = bd->layer;
2399 if (!last) last = child;
2400 e_border_raise (child);
2407 ev = E_NEW(E_Event_Border_Stack, 1);
2409 e_object_ref(E_OBJECT(bd));
2413 e_container_border_stack_below(bd, last);
2415 e_object_ref(E_OBJECT(last));
2416 ev->type = E_STACKING_BELOW;
2422 /* If we don't have any children, raise this border */
2423 above = e_container_border_raise(bd);
2424 e_border_raise_latest_set(bd);
2427 /* We ended up above a border */
2429 e_object_ref(E_OBJECT(above));
2430 ev->type = E_STACKING_ABOVE;
2434 /* No border to raise above, same as a lower! */
2436 ev->type = E_STACKING_ABOVE;
2440 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2441 e_remember_update(bd);
2445 e_border_lower(E_Border *bd)
2447 E_Event_Border_Stack *ev;
2448 E_Border *last = NULL, *child;
2452 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2454 ecore_x_window_shadow_tree_flush();
2456 if (e_config->transient.lower)
2458 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2459 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2462 Eina_List *list = _e_border_sub_borders_new(bd);
2464 EINA_LIST_REVERSE_FOREACH(list, l, child)
2466 /* Don't stack iconic transients. If the user wants these shown,
2467 * thats another option.
2472 e_border_stack_below(child, last);
2477 /* First lower the border to find out which border we will end up below */
2478 below = e_container_border_lower(child);
2482 /* We ended up below a border, now we must stack this border to
2483 * generate the stacking event, and to check if this transient
2484 * has other transients etc.
2486 e_border_stack_below(child, below);
2490 /* If we didn't end up below any border, we are on top! */
2491 e_border_raise(child);
2497 eina_list_free(list);
2499 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2503 EINA_LIST_FOREACH(bd->transients, l, child)
2505 /* Don't stack iconic transients. If the user wants these shown,
2506 * thats another option.
2510 child->layer = bd->layer;
2511 e_border_lower (child);
2519 ev = E_NEW(E_Event_Border_Stack, 1);
2521 e_object_ref(E_OBJECT(bd));
2525 e_container_border_stack_below(bd, last);
2527 e_object_ref(E_OBJECT(last));
2528 ev->type = E_STACKING_BELOW;
2534 /* If we don't have any children, lower this border */
2535 below = e_container_border_lower(bd);
2538 /* We ended up below a border */
2540 e_object_ref(E_OBJECT(below));
2541 ev->type = E_STACKING_BELOW;
2545 /* No border to hide under, same as a raise! */
2547 ev->type = E_STACKING_BELOW;
2551 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2552 e_remember_update(bd);
2556 e_border_stack_above(E_Border *bd,
2559 /* TODO: Should stack above allow the border to change level */
2560 E_Event_Border_Stack *ev;
2561 E_Border *last = NULL, *child;
2565 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2567 ecore_x_window_shadow_tree_flush();
2569 if (e_config->transient.raise)
2571 Eina_List *list = _e_border_sub_borders_new(bd);
2573 EINA_LIST_REVERSE_FOREACH(list, l, child)
2575 /* Don't stack iconic transients. If the user wants these shown,
2576 * thats another option.
2581 e_border_stack_below(child, last);
2583 e_border_stack_above(child, above);
2587 eina_list_free(list);
2590 ev = E_NEW(E_Event_Border_Stack, 1);
2592 e_object_ref(E_OBJECT(bd));
2596 e_container_border_stack_below(bd, last);
2598 e_object_ref(E_OBJECT(last));
2599 ev->type = E_STACKING_BELOW;
2603 e_container_border_stack_above(bd, above);
2605 e_object_ref(E_OBJECT(above));
2606 ev->type = E_STACKING_ABOVE;
2609 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2610 e_remember_update(bd);
2614 e_border_stack_below(E_Border *bd,
2617 /* TODO: Should stack below allow the border to change level */
2618 E_Event_Border_Stack *ev;
2619 E_Border *last = NULL, *child;
2623 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2625 ecore_x_window_shadow_tree_flush();
2627 if (e_config->transient.lower)
2629 Eina_List *list = _e_border_sub_borders_new(bd);
2631 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2633 /* Don't stack iconic transients. If the user wants these shown,
2634 * thats another option.
2639 e_border_stack_below(child, last);
2641 e_border_stack_below(child, below);
2645 eina_list_free(list);
2648 ev = E_NEW(E_Event_Border_Stack, 1);
2650 e_object_ref(E_OBJECT(bd));
2654 e_container_border_stack_below(bd, last);
2656 e_object_ref(E_OBJECT(last));
2657 ev->type = E_STACKING_BELOW;
2661 e_container_border_stack_below(bd, below);
2663 e_object_ref(E_OBJECT(below));
2664 ev->type = E_STACKING_BELOW;
2667 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2668 e_remember_update(bd);
2672 e_border_focus_latest_set(E_Border *bd)
2674 focus_stack = eina_list_remove(focus_stack, bd);
2675 focus_stack = eina_list_prepend(focus_stack, bd);
2679 e_border_raise_latest_set(E_Border *bd)
2681 raise_stack = eina_list_remove(raise_stack, bd);
2682 raise_stack = eina_list_prepend(raise_stack, bd);
2686 * Sets the focus to the given border if necessary
2687 * There are 3 cases of different focus_policy-configurations:
2689 * - E_FOCUS_CLICK: just set the focus, the most simple one
2691 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2692 * warp the pointer to the window. If this fails (because
2693 * the pointer is already in the window), just set the focus.
2695 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2696 * last window which was focused, if the mouse is on the
2697 * desktop. So, we need to look if there is another window
2698 * under the pointer and warp to pointer to the right
2699 * one if so (also, we set the focus afterwards). In case
2700 * there is no window under pointer, the pointer is on the
2701 * desktop and so we just set the focus.
2704 * This function is to be called when setting the focus was not
2705 * explicitly triggered by the user (by moving the mouse or
2706 * clicking for example), but implicitly (by closing a window,
2707 * the last focused window should get focus).
2711 e_border_focus_set_with_pointer(E_Border *bd)
2713 #ifdef PRINT_LOTS_OF_DEBUG
2714 E_PRINT_BORDER_INFO(bd);
2716 /* note: this is here as it seems there are enough apps that do not even
2717 * expect us to emulate a look of focus but not actually set x input
2718 * focus as we do - so simply abort any focuse set on such windows */
2719 /* be strict about accepting focus hint */
2720 if ((!bd->client.icccm.accepts_focus) &&
2721 (!bd->client.icccm.take_focus)) return;
2722 if (bd->lock_focus_out) return;
2724 e_border_focus_set(bd, 1, 1);
2726 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2727 if (!bd->visible) return;
2729 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2731 if (!e_border_under_pointer_get(bd->desk, bd))
2733 e_border_pointer_warp_to_center(bd);
2738 e_border_pointer_warp_to_center(bd);
2743 e_border_focus_set(E_Border *bd,
2747 E_Border *bd_unfocus = NULL;
2748 Eina_Bool focus_changed = EINA_FALSE;
2751 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2752 /* note: this is here as it seems there are enough apps that do not even
2753 * expect us to emulate a look of focus but not actually set x input
2754 * focus as we do - so simply abort any focuse set on such windows */
2755 /* be strict about accepting focus hint */
2756 if ((!bd->client.icccm.accepts_focus) &&
2757 (!bd->client.icccm.take_focus))
2759 if ((set) && (focus) && (bd->lock_focus_out)) return;
2761 /* dont focus an iconified window. that's silly! */
2766 e_border_uniconify(bd);
2767 if (!focus_track_frozen)
2768 e_border_focus_latest_set(bd);
2771 else if (!bd->visible)
2775 /* FIXME: hack for deskflip animation:
2776 * dont update focus when sliding previous desk */
2777 else if ((!bd->sticky) &&
2778 (bd->desk != e_desk_current_get(bd->desk->zone)))
2784 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2786 e_border_focus_set(bd->modal, focus, set);
2789 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2791 e_border_focus_set(bd->leader->modal, focus, set);
2799 if (bd->visible && bd->changes.visible)
2804 else if ((!bd->focused) ||
2805 (focus_next && (bd != eina_list_data_get(focus_next))))
2809 if ((l = eina_list_data_find_list(focus_next, bd)))
2810 focus_next = eina_list_promote_list(focus_next, l);
2812 focus_next = eina_list_prepend(focus_next, bd);
2814 if ((bd->client.icccm.take_focus) &&
2815 (bd->client.icccm.accepts_focus))
2817 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2818 /* TODO what if the client didn't take focus ? */
2820 else if (!bd->client.icccm.accepts_focus)
2822 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2824 else if (!bd->client.icccm.take_focus)
2826 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2827 /* e_border_focus_set(bd, 1, 0); */
2837 if (focused) bd_unfocus = focused;
2838 if (focusing == bd) focusing = NULL;
2843 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2845 if ((bd2->fullscreen) &&
2847 (bd2->zone == bd->zone) &&
2848 ((bd2->desk == bd->desk) ||
2849 (bd2->sticky) || (bd->sticky)))
2851 Eina_Bool unfocus_is_parent = EINA_FALSE;
2852 E_Border *bd_parent;
2854 bd_parent = bd->parent;
2857 if (bd_parent == bd2)
2859 unfocus_is_parent = EINA_TRUE;
2862 bd_parent = bd->parent;
2864 if ((!unfocus_is_parent) &&
2865 (!e_config->allow_above_fullscreen))
2867 e_border_iconify(bd2);
2872 focus_changed = EINA_TRUE;
2878 focus_next = eina_list_remove(focus_next, bd);
2879 if (bd == focusing) focusing = NULL;
2881 if ((bd->focused) &&
2882 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2884 Eina_Bool wasfocused = EINA_FALSE;
2887 /* should always be the case. anyway */
2891 wasfocused = EINA_TRUE;
2894 if ((set) && (!focus_next) && (!focusing))
2896 e_grabinput_focus(bd->zone->container->bg_win,
2897 E_FOCUS_METHOD_PASSIVE);
2899 if ((bd->fullscreen) && (wasfocused))
2901 Eina_Bool have_vis_child = EINA_FALSE;
2905 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2908 (bd2->zone == bd->zone) &&
2909 ((bd2->desk == bd->desk) ||
2910 (bd2->sticky) || (bd->sticky)))
2912 if (bd2->parent == bd)
2914 have_vis_child = EINA_TRUE;
2919 if ((!have_vis_child) &&
2920 (!e_config->allow_above_fullscreen))
2921 e_border_iconify(bd);
2927 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2928 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2930 E_Event_Border_Focus_Out *ev;
2932 bd_unfocus->focused = 0;
2933 e_focus_event_focus_out(bd_unfocus);
2935 if (bd_unfocus->raise_timer)
2936 ecore_timer_del(bd_unfocus->raise_timer);
2937 bd_unfocus->raise_timer = NULL;
2939 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2940 if (bd_unfocus->icon_object)
2941 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2943 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2944 ev->border = bd_unfocus;
2945 e_object_ref(E_OBJECT(bd_unfocus));
2947 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2948 _e_border_event_border_focus_out_free, NULL);
2949 if ((bd_unfocus->fullscreen) &&
2950 (bd != bd_unfocus) &&
2951 (bd->zone == bd_unfocus->zone) &&
2952 ((bd->desk == bd_unfocus->desk) ||
2953 (bd->sticky) || (bd_unfocus->sticky)))
2955 Eina_Bool unfocus_is_parent = EINA_FALSE;
2956 E_Border *bd_parent;
2958 bd_parent = bd->parent;
2961 if (bd_parent == bd_unfocus)
2963 unfocus_is_parent = EINA_TRUE;
2966 bd_parent = bd->parent;
2968 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2970 e_border_iconify(bd_unfocus);
2977 E_Event_Border_Focus_In *ev;
2979 e_focus_event_focus_in(bd);
2981 if (!focus_track_frozen)
2982 e_border_focus_latest_set(bd);
2984 e_hints_active_window_set(bd->zone->container->manager, bd);
2986 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2987 if (bd->icon_object)
2988 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2990 ev = E_NEW(E_Event_Border_Focus_In, 1);
2992 e_object_ref(E_OBJECT(bd));
2994 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2995 _e_border_event_border_focus_in_free, NULL);
3000 e_border_shade(E_Border *bd,
3003 E_Event_Border_Resize *ev;
3008 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3009 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
3010 ((bd->maximized) && (!e_config->allow_manip))) return;
3011 if ((bd->client.border.name) &&
3012 (!strcmp("borderless", bd->client.border.name))) return;
3014 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3015 ecore_x_window_hide(tmp->win);
3017 ecore_x_window_shadow_tree_flush();
3019 bd->shade.x = bd->x;
3020 bd->shade.y = bd->y;
3021 bd->shade.dir = dir;
3023 e_hints_window_shaded_set(bd, 1);
3024 e_hints_window_shade_direction_set(bd, dir);
3026 if (e_config->border_shade_animate)
3028 bd->shade.start = ecore_loop_time_get();
3030 bd->changes.shading = 1;
3033 if (bd->shade.dir == E_DIRECTION_UP ||
3034 bd->shade.dir == E_DIRECTION_LEFT)
3035 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3037 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3039 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3040 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3044 if (bd->shade.dir == E_DIRECTION_UP)
3046 bd->h = bd->client_inset.t + bd->client_inset.b;
3048 else if (bd->shade.dir == E_DIRECTION_DOWN)
3050 bd->h = bd->client_inset.t + bd->client_inset.b;
3051 bd->y = bd->y + bd->client.h;
3052 bd->changes.pos = 1;
3054 else if (bd->shade.dir == E_DIRECTION_LEFT)
3056 bd->w = bd->client_inset.l + bd->client_inset.r;
3058 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3060 bd->w = bd->client_inset.l + bd->client_inset.r;
3061 bd->x = bd->x + bd->client.w;
3062 bd->changes.pos = 1;
3065 if ((bd->shaped) || (bd->client.shaped))
3067 bd->need_shape_merge = 1;
3068 bd->need_shape_export = 1;
3070 if (bd->shaped_input)
3072 bd->need_shape_merge = 1;
3075 bd->changes.size = 1;
3077 bd->changes.shaded = 1;
3079 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3080 e_border_frame_recalc(bd);
3081 ev = E_NEW(E_Event_Border_Resize, 1);
3083 /* The resize is added in the animator when animation complete */
3084 /* For non-animated, we add it immediately with the new size */
3085 e_object_ref(E_OBJECT(bd));
3086 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3087 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3090 e_remember_update(bd);
3094 e_border_unshade(E_Border *bd,
3097 E_Event_Border_Resize *ev;
3102 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3103 if ((!bd->shaded) || (bd->shading))
3106 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3107 ecore_x_window_show(tmp->win);
3109 ecore_x_window_shadow_tree_flush();
3111 bd->shade.dir = dir;
3113 e_hints_window_shaded_set(bd, 0);
3114 e_hints_window_shade_direction_set(bd, dir);
3116 if (bd->shade.dir == E_DIRECTION_UP ||
3117 bd->shade.dir == E_DIRECTION_LEFT)
3119 bd->shade.x = bd->x;
3120 bd->shade.y = bd->y;
3124 bd->shade.x = bd->x - bd->client.w;
3125 bd->shade.y = bd->y - bd->client.h;
3127 if (e_config->border_shade_animate)
3129 bd->shade.start = ecore_loop_time_get();
3131 bd->changes.shading = 1;
3134 if (bd->shade.dir == E_DIRECTION_UP)
3136 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3137 ecore_x_window_move_resize(bd->client.win, 0,
3138 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3140 bd->client.w, bd->client.h);
3142 else if (bd->shade.dir == E_DIRECTION_LEFT)
3144 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3145 ecore_x_window_move_resize(bd->client.win,
3146 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3148 0, bd->client.w, bd->client.h);
3151 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3153 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3154 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3158 if (bd->shade.dir == E_DIRECTION_UP)
3160 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3162 else if (bd->shade.dir == E_DIRECTION_DOWN)
3164 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3165 bd->y = bd->y - bd->client.h;
3166 bd->changes.pos = 1;
3168 else if (bd->shade.dir == E_DIRECTION_LEFT)
3170 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3172 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3174 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3175 bd->x = bd->x - bd->client.w;
3176 bd->changes.pos = 1;
3178 if ((bd->shaped) || (bd->client.shaped))
3180 bd->need_shape_merge = 1;
3181 bd->need_shape_export = 1;
3183 if (bd->shaped_input)
3185 bd->need_shape_merge = 1;
3188 bd->changes.size = 1;
3190 bd->changes.shaded = 1;
3192 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3193 e_border_frame_recalc(bd);
3194 ev = E_NEW(E_Event_Border_Resize, 1);
3196 /* The resize is added in the animator when animation complete */
3197 /* For non-animated, we add it immediately with the new size */
3198 e_object_ref(E_OBJECT(bd));
3199 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3200 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3203 e_remember_update(bd);
3207 _e_border_client_inset_calc(E_Border *bd)
3210 Evas_Coord cx, cy, cw, ch;
3214 evas_object_resize(bd->bg_object, 1000, 1000);
3215 edje_object_message_signal_process(bd->bg_object);
3216 edje_object_calc_force(bd->bg_object);
3217 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3218 bd->client_inset.l = cx;
3219 bd->client_inset.r = 1000 - (cx + cw);
3220 bd->client_inset.t = cy;
3221 bd->client_inset.b = 1000 - (cy + ch);
3225 bd->client_inset.l = 0;
3226 bd->client_inset.r = 0;
3227 bd->client_inset.t = 0;
3228 bd->client_inset.b = 0;
3231 ecore_x_netwm_frame_size_set(bd->client.win,
3232 bd->client_inset.l, bd->client_inset.r,
3233 bd->client_inset.t, bd->client_inset.b);
3234 ecore_x_e_frame_size_set(bd->client.win,
3235 bd->client_inset.l, bd->client_inset.r,
3236 bd->client_inset.t, bd->client_inset.b);
3240 _e_border_maximize(E_Border *bd, E_Maximize max)
3242 int x1, yy1, x2, y2;
3245 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3249 zx = zy = zw = zh = 0;
3251 switch (max & E_MAXIMIZE_TYPE)
3253 case E_MAXIMIZE_NONE:
3257 case E_MAXIMIZE_FULLSCREEN:
3263 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3264 _e_border_client_inset_calc(bd);
3266 e_border_resize_limit(bd, &w, &h);
3267 /* center x-direction */
3268 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3269 /* center y-direction */
3270 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3272 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3273 cy = bd->zone->y + (bd->zone->h / 2);
3276 switch (max & E_MAXIMIZE_DIRECTION)
3278 case E_MAXIMIZE_BOTH:
3279 e_border_move_resize(bd, x1, yy1, w, h);
3282 case E_MAXIMIZE_VERTICAL:
3283 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3286 case E_MAXIMIZE_HORIZONTAL:
3287 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3290 case E_MAXIMIZE_LEFT:
3291 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3294 case E_MAXIMIZE_RIGHT:
3295 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3297 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3298 case E_MAXIMIZE_TOP:
3299 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3301 case E_MAXIMIZE_BOTTOM:
3302 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3308 case E_MAXIMIZE_SMART:
3309 case E_MAXIMIZE_EXPAND:
3311 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3323 if (bd->x < zx) // window left not useful coordinates
3325 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3326 x1 = zx + zw - bd->w;
3327 else // window normal position
3330 if (bd->y < zy) // window top not useful coordinates
3332 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3333 yy1 = zy + zh - bd->h;
3334 else // window normal position
3337 switch (max & E_MAXIMIZE_DIRECTION)
3339 case E_MAXIMIZE_BOTH:
3340 e_border_move_resize(bd, zx, zy, zw, zh);
3343 case E_MAXIMIZE_VERTICAL:
3344 e_border_move_resize(bd, x1, zy, w, zh);
3347 case E_MAXIMIZE_HORIZONTAL:
3348 e_border_move_resize(bd, zx, yy1, zw, h);
3351 case E_MAXIMIZE_LEFT:
3352 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3355 case E_MAXIMIZE_RIGHT:
3356 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3360 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3363 case E_MAXIMIZE_FILL:
3366 x2 = bd->zone->x + bd->zone->w;
3367 y2 = bd->zone->y + bd->zone->h;
3369 /* walk through all shelves */
3370 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3372 /* walk through all windows */
3373 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3379 e_border_resize_limit(bd, &w, &h);
3380 /* center x-direction */
3381 x1 = x1 + (pw - w) / 2;
3382 /* center y-direction */
3383 yy1 = yy1 + (ph - h) / 2;
3385 switch (max & E_MAXIMIZE_DIRECTION)
3387 case E_MAXIMIZE_BOTH:
3388 e_border_move_resize(bd, x1, yy1, w, h);
3391 case E_MAXIMIZE_VERTICAL:
3392 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3395 case E_MAXIMIZE_HORIZONTAL:
3396 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3399 case E_MAXIMIZE_LEFT:
3400 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3403 case E_MAXIMIZE_RIGHT:
3404 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3412 e_border_maximize(E_Border *bd,
3416 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3418 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3420 if ((bd->shaded) || (bd->shading)) return;
3421 ecore_x_window_shadow_tree_flush();
3423 e_border_unfullscreen(bd);
3424 /* Only allow changes in vertical/ horizontal maximization */
3425 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3426 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3429 bd->need_maximize = 1;
3430 bd->maximized &= ~E_MAXIMIZE_TYPE;
3431 bd->maximized |= max;
3435 bd->pre_res_change.valid = 0;
3436 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3438 /* Horizontal hasn't been set */
3439 bd->saved.x = bd->x - bd->zone->x;
3440 bd->saved.w = bd->w;
3442 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3444 /* Vertical hasn't been set */
3445 bd->saved.y = bd->y - bd->zone->y;
3446 bd->saved.h = bd->h;
3449 bd->saved.zone = bd->zone->num;
3450 e_hints_window_size_set(bd);
3454 _e_border_maximize(bd, max);
3457 /* Remove previous type */
3458 bd->maximized &= ~E_MAXIMIZE_TYPE;
3459 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3460 bd->maximized |= max;
3462 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3463 bd->maximized & E_MAXIMIZE_VERTICAL);
3464 e_remember_update(bd);
3468 e_border_unmaximize(E_Border *bd,
3472 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3473 if (!(max & E_MAXIMIZE_DIRECTION))
3475 CRI("BUG: Unmaximize call without direction!");
3479 if ((bd->shaded) || (bd->shading)) return;
3480 ecore_x_window_shadow_tree_flush();
3481 /* Remove directions not used */
3482 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3483 /* Can only remove existing maximization directions */
3485 if (bd->maximized & E_MAXIMIZE_TYPE)
3487 bd->pre_res_change.valid = 0;
3488 bd->need_maximize = 0;
3490 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3494 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3495 _e_border_client_inset_calc(bd);
3498 bd->maximized = E_MAXIMIZE_NONE;
3499 _e_border_move_resize_internal(bd,
3500 bd->zone->x + bd->saved.x,
3501 bd->zone->y + bd->saved.y,
3502 bd->saved.w, bd->saved.h, 0, 1);
3503 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3504 e_hints_window_size_unset(bd);
3515 if (max & E_MAXIMIZE_VERTICAL)
3517 /* Remove vertical */
3519 y = bd->saved.y + bd->zone->y;
3520 bd->saved.h = bd->saved.y = 0;
3521 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3522 bd->maximized &= ~E_MAXIMIZE_LEFT;
3523 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3525 if (max & E_MAXIMIZE_HORIZONTAL)
3527 /* Remove horizontal */
3529 x = bd->saved.x + bd->zone->x;
3530 bd->saved.w = bd->saved.x = 0;
3531 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3534 e_border_resize_limit(bd, &w, &h);
3536 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3538 bd->maximized = E_MAXIMIZE_NONE;
3539 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3540 e_hints_window_size_unset(bd);
3541 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3545 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3546 e_hints_window_size_set(bd);
3549 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3550 bd->maximized & E_MAXIMIZE_VERTICAL);
3552 e_remember_update(bd);
3556 e_border_fullscreen(E_Border *bd,
3557 E_Fullscreen policy)
3559 E_Event_Border_Fullscreen *ev;
3562 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3564 if ((bd->shaded) || (bd->shading)) return;
3565 ecore_x_window_shadow_tree_flush();
3568 bd->need_fullscreen = 1;
3571 if (!bd->fullscreen)
3573 bd->pre_res_change.valid = 0;
3575 bd->saved.x = bd->x - bd->zone->x;
3576 bd->saved.y = bd->y - bd->zone->y;
3577 bd->saved.w = bd->client.w;
3578 bd->saved.h = bd->client.h;
3579 bd->saved.maximized = bd->maximized;
3580 bd->saved.zone = bd->zone->num;
3583 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3584 e_hints_window_size_set(bd);
3586 bd->client_inset.l = 0;
3587 bd->client_inset.r = 0;
3588 bd->client_inset.t = 0;
3589 bd->client_inset.b = 0;
3591 bd->desk->fullscreen_borders++;
3593 /* e_zone_fullscreen_set(bd->zone, 1); */
3594 bd->saved.layer = bd->layer;
3595 if (!e_config->allow_above_fullscreen)
3596 e_border_layer_set(bd, 250);
3598 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3599 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3601 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3603 else if (policy == E_FULLSCREEN_ZOOM)
3605 Ecore_X_Randr_Screen_Size_MM *sizes;
3606 int num_sizes, i, best_size_index = 0;
3608 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3610 &screen_size.height,
3612 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3616 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3617 int best_dist = INT_MAX, dist;
3619 for (i = 0; i < num_sizes; i++)
3621 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3623 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3624 if (dist < best_dist)
3626 best_size.width = sizes[i].width;
3627 best_size.height = sizes[i].height;
3629 best_size_index = i;
3633 if (((best_size.width != -1) && (best_size.height != -1)) &&
3634 ((best_size.width != screen_size.width) ||
3635 (best_size.height != screen_size.height)))
3637 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3639 screen_size_index = best_size_index;
3640 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3644 screen_size.width = -1;
3645 screen_size.height = -1;
3646 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3651 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3655 e_hints_window_fullscreen_set(bd, 1);
3656 e_hints_window_size_unset(bd);
3657 bd->client.border.changed = 1;
3660 bd->fullscreen_policy = policy;
3662 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3664 e_object_ref(E_OBJECT(bd));
3665 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3666 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3668 e_remember_update(bd);
3672 e_border_unfullscreen(E_Border *bd)
3674 E_Event_Border_Unfullscreen *ev;
3677 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3678 if ((bd->shaded) || (bd->shading)) return;
3679 ecore_x_window_shadow_tree_flush();
3682 bd->pre_res_change.valid = 0;
3684 bd->need_fullscreen = 0;
3685 bd->desk->fullscreen_borders--;
3687 if ((screen_size.width != -1) && (screen_size.height != -1))
3689 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3691 screen_size.width = -1;
3692 screen_size.height = -1;
3694 e_border_move_resize(bd,
3695 bd->saved.x + bd->zone->x,
3696 bd->saved.y + bd->zone->y,
3697 bd->saved.w, bd->saved.h);
3699 if (bd->saved.maximized)
3700 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3701 bd->saved.maximized);
3703 e_border_layer_set(bd, bd->saved.layer);
3705 e_hints_window_fullscreen_set(bd, 0);
3706 bd->client.border.changed = 1;
3709 bd->fullscreen_policy = 0;
3711 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3713 e_object_ref(E_OBJECT(bd));
3714 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3715 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3717 e_remember_update(bd);
3721 e_border_iconify(E_Border *bd)
3723 E_Event_Border_Iconify *ev;
3724 unsigned int iconic;
3727 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3728 if (bd->shading) return;
3729 ecore_x_window_shadow_tree_flush();
3733 e_border_hide(bd, 1);
3734 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3735 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3738 e_hints_window_iconic_set(bd);
3739 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3741 ev = E_NEW(E_Event_Border_Iconify, 1);
3743 e_object_ref(E_OBJECT(bd));
3744 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3745 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3747 if (e_config->transient.iconify)
3751 Eina_List *list = _e_border_sub_borders_new(bd);
3753 EINA_LIST_FOREACH(list, l, child)
3755 e_border_iconify(child);
3757 eina_list_free(list);
3759 e_remember_update(bd);
3762 #ifdef _F_DEICONIFY_APPROVE_
3764 _e_border_uniconify_timeout(void *data)
3771 if (!e_object_is_del(E_OBJECT(bd)))
3773 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3774 bd->client.e.state.deiconify_approve.render_done = 1;
3775 if (bd->client.e.state.deiconify_approve.req_list)
3777 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3779 child_bd->client.e.state.deiconify_approve.render_done = 1;
3780 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3783 bd->client.e.state.deiconify_approve.req_list = NULL;
3784 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3785 e_border_uniconify(bd);
3788 return ECORE_CALLBACK_CANCEL;
3792 _e_border_deiconify_approve_send_pending_end(void *data)
3794 E_Border *bd = (E_Border *)data;
3795 E_Border *bd_ancestor;
3797 if (e_config->deiconify_approve)
3799 if (!e_object_is_del(E_OBJECT(bd)))
3801 bd->client.e.state.deiconify_approve.pending_job = NULL;
3803 ELBF(ELBT_BD, 0, bd->client.win,
3804 "SEND DEICONIFY_APPROVE. (PENDING_END) ancestor:%x",
3807 ecore_x_client_message32_send(bd->client.win,
3808 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3809 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3810 bd->client.win, 0, 0, 0, 0);
3811 bd_ancestor = bd->client.e.state.deiconify_approve.ancestor;
3814 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, bd);
3817 if (!bd->client.e.state.deiconify_approve.wait_timer)
3818 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3824 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor, Eina_Bool pending_ancestor)
3826 if (!bd || !bd_ancestor) return;
3828 if (e_config->deiconify_approve)
3830 if (e_config->transient.iconify)
3834 Eina_List *list = _e_border_sub_borders_new(bd);
3835 EINA_LIST_FOREACH(list, l, child)
3837 Eina_Bool pending = EINA_FALSE;
3838 Eina_Bool p = EINA_FALSE;
3840 #ifdef _F_ZONE_WINDOW_ROTATION_
3841 if ((e_config->wm_win_rotation) &&
3842 ((child->client.e.state.rot.support) ||
3843 (child->client.e.state.rot.app_set)))
3845 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3846 int rotation = _e_border_rotation_angle_get(bd);
3847 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3850 if ((pending_ancestor) || (pending)) p = EINA_TRUE;
3852 _e_border_deiconify_approve_send(child, bd_ancestor, p);
3853 if (child->client.e.state.deiconify_approve.support)
3857 ELBF(ELBT_BD, 0, child->client.win,
3858 "SEND DEICONIFY_APPROVE. ancestor:%x pending(%d,%d)",
3859 bd_ancestor->client.win,
3860 pending_ancestor, pending);
3862 ecore_x_client_message32_send(child->client.win,
3863 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3864 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3865 child->client.win, 0, 0, 0, 0);
3866 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3867 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3871 /* queue a deiconify send job to give the chance to other jobs */
3872 ELBF(ELBT_BD, 0, child->client.win,
3873 "SEND DEICONIFY_APPROVE. (PENDING) ancestor:%x",
3874 bd_ancestor->client.win);
3875 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3876 child->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, child);
3880 eina_list_free(list);
3886 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3888 Eina_Bool pending = EINA_FALSE;
3890 if (e_config->deiconify_approve)
3892 #ifdef _F_ZONE_WINDOW_ROTATION_
3893 if ((e_config->wm_win_rotation) &&
3894 ((bd->client.e.state.rot.support) ||
3895 (bd->client.e.state.rot.app_set)))
3897 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3898 int rotation = _e_border_rotation_angle_get(bd);
3899 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3903 if (e_config->transient.iconify)
3905 _e_border_deiconify_approve_send(bd, bd, pending);
3908 if (bd->client.e.state.deiconify_approve.support)
3912 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE.");
3913 ecore_x_client_message32_send(bd->client.win,
3914 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3915 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3916 bd->client.win, 0, 0, 0, 0);
3917 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3921 /* queue a deiconify send job to give the chance to other jobs */
3922 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE. (PENDING)");
3923 bd->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, bd);
3931 e_border_uniconify(E_Border *bd)
3934 E_Event_Border_Uniconify *ev;
3935 unsigned int iconic;
3938 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3940 #ifdef _F_DEICONIFY_APPROVE_
3941 if (e_config->deiconify_approve)
3943 if (bd->client.e.state.deiconify_approve.support)
3945 if (bd->client.e.state.deiconify_approve.wait_timer)
3947 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3951 if (bd->client.e.state.deiconify_approve.pending_job)
3953 ELB(ELBT_BD, "DEICONIFY_APPROVE PENDING_JOB is already running", bd->client.win);
3957 if (bd->client.e.state.deiconify_approve.render_done == 0)
3959 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3960 _e_border_deiconify_approve_send_all_transient(bd);
3964 bd->client.e.state.deiconify_approve.render_done = 0;
3968 #if _F_ZONE_WINDOW_ROTATION_
3969 if (!bd->client.win)
3971 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3976 if (bd->shading) return;
3977 ecore_x_window_shadow_tree_flush();
3982 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3983 desk = e_desk_current_get(bd->desk->zone);
3984 #ifdef _F_USE_EXTENDED_ICONIFY_
3985 if (e_manager_comp_evas_get(bd->zone->container->manager))
3987 if (bd->await_hide_event > 0)
3988 bd->await_hide_event--;
3991 e_border_desk_set(bd, desk);
3993 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3996 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3998 ev = E_NEW(E_Event_Border_Uniconify, 1);
4000 e_object_ref(E_OBJECT(bd));
4001 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
4002 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
4004 if (e_config->transient.iconify)
4008 Eina_List *list = _e_border_sub_borders_new(bd);
4010 EINA_LIST_FOREACH(list, l, child)
4012 e_border_uniconify(child);
4014 eina_list_free(list);
4016 e_remember_update(bd);
4020 e_border_stick(E_Border *bd)
4022 E_Event_Border_Stick *ev;
4025 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4026 if (bd->sticky) return;
4028 e_hints_window_sticky_set(bd, 1);
4031 if (e_config->transient.desktop)
4035 Eina_List *list = _e_border_sub_borders_new(bd);
4037 EINA_LIST_FOREACH(list, l, child)
4040 e_hints_window_sticky_set(child, 1);
4041 e_border_show(child);
4043 eina_list_free(list);
4046 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
4047 ev = E_NEW(E_Event_Border_Stick, 1);
4049 e_object_ref(E_OBJECT(bd));
4050 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
4051 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
4052 e_remember_update(bd);
4056 e_border_unstick(E_Border *bd)
4058 E_Event_Border_Unstick *ev;
4061 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4062 /* Set the desk before we unstick the border */
4063 if (!bd->sticky) return;
4065 e_hints_window_sticky_set(bd, 0);
4067 if (e_config->transient.desktop)
4071 Eina_List *list = _e_border_sub_borders_new(bd);
4073 EINA_LIST_FOREACH(list, l, child)
4076 e_hints_window_sticky_set(child, 0);
4078 eina_list_free(list);
4081 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
4082 ev = E_NEW(E_Event_Border_Unstick, 1);
4084 e_object_ref(E_OBJECT(bd));
4085 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
4086 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
4088 e_border_desk_set(bd, e_desk_current_get(bd->zone));
4089 e_remember_update(bd);
4093 e_border_pinned_set(E_Border *bd,
4101 bd->borderless = set;
4102 bd->user_skip_winlist = set;
4106 stacking = E_STACKING_BELOW;
4111 stacking = E_STACKING_NONE;
4114 e_border_layer_set(bd, layer);
4115 e_hints_window_stacking_set(bd, stacking);
4117 bd->client.border.changed = 1;
4123 e_border_find_by_client_window(Ecore_X_Window win)
4127 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4128 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4129 (bd->client.win == win))
4135 e_border_find_all_by_client_window(Ecore_X_Window win)
4139 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4140 if ((bd) && (bd->client.win == win))
4146 e_border_find_by_frame_window(Ecore_X_Window win)
4150 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4151 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4152 (bd->bg_win == win))
4158 e_border_find_by_window(Ecore_X_Window win)
4162 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4163 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4170 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4175 EINA_LIST_FOREACH(borders, l, bd)
4177 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4178 (bd->client.netwm.sync.alarm == al))
4185 e_border_focused_get(void)
4191 _e_border_shape_input_rectangle_set(E_Border* bd)
4195 if ((bd->visible) && (bd->shaped_input))
4197 Ecore_X_Rectangle rects[4];
4198 Ecore_X_Window twin, twin2;
4201 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4202 0, 0, bd->w, bd->h);
4205 rects[0].width = bd->w;
4206 rects[0].height = bd->client_inset.t;
4208 rects[1].y = bd->client_inset.t;
4209 rects[1].width = bd->client_inset.l;
4210 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4211 rects[2].x = bd->w - bd->client_inset.r;
4212 rects[2].y = bd->client_inset.t;
4213 rects[2].width = bd->client_inset.r;
4214 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4216 rects[3].y = bd->h - bd->client_inset.b;
4217 rects[3].width = bd->w;
4218 rects[3].height = bd->client_inset.b;
4219 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4221 twin2 = ecore_x_window_override_new
4222 (bd->zone->container->scratch_win, 0, 0,
4223 bd->w - bd->client_inset.l - bd->client_inset.r,
4224 bd->h - bd->client_inset.t - bd->client_inset.b);
4227 if ((bd->shading) || (bd->shaded))
4229 if (bd->shade.dir == E_DIRECTION_UP)
4230 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4232 else if (bd->shade.dir == E_DIRECTION_LEFT)
4233 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4236 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4238 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4239 bd->w - bd->client_inset.l - bd->client_inset.r,
4240 bd->h - bd->client_inset.t - bd->client_inset.b);
4241 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4243 bd->client_inset.t);
4244 ecore_x_window_shape_input_window_set(bd->win, twin);
4245 ecore_x_window_free(twin2);
4246 ecore_x_window_free(twin);
4250 if (bd->visible) // not shaped input
4252 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4253 ecore_x_composite_window_events_enable(bd->win);
4255 ecore_x_composite_window_events_disable(bd->win);
4259 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4260 ecore_x_composite_window_events_enable(bd->win);
4262 ecore_x_composite_window_events_disable(bd->win);
4268 e_border_idler_before(void)
4277 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4279 EINA_LIST_FOREACH(man->containers, cl, con)
4284 // pass 1 - eval0. fetch properties on new or on change and
4285 // call hooks to decide what to do - maybe move/resize
4286 bl = e_container_border_list_last(con);
4287 while ((bd = e_container_border_list_prev(bl)))
4289 if (bd->changed) _e_border_eval0(bd);
4291 e_container_border_list_free(bl);
4293 // layout hook - this is where a hook gets to figure out what to
4295 _e_border_container_layout_hook(con);
4297 // pass 2 - show windows needing show
4298 bl = e_container_border_list_last(con);
4299 while ((bd = e_container_border_list_prev(bl)))
4301 if ((bd->changes.visible) && (bd->visible) &&
4302 (!bd->new_client) && (!bd->changes.pos) &&
4303 (!bd->changes.size))
4306 bd->changes.visible = 0;
4309 e_container_border_list_free(bl);
4311 // pass 3 - hide windows needing hide and eval (main eval)
4312 bl = e_container_border_list_first(con);
4313 while ((bd = e_container_border_list_next(bl)))
4315 if (e_object_is_del(E_OBJECT(bd))) continue;
4317 if ((bd->changes.visible) && (!bd->visible))
4320 bd->changes.visible = 0;
4323 if (bd->changed) _e_border_eval(bd);
4325 if ((bd->changes.visible) && (bd->visible))
4328 bd->changes.visible = 0;
4331 e_container_border_list_free(bl);
4337 E_Border *bd = NULL, *bd2;
4339 EINA_LIST_FREE(focus_next, bd2)
4340 if ((!bd) && (bd2->visible)) bd = bd2;
4344 /* TODO revert focus when lost here ? */
4350 /* already focused. but anyway dont be so strict, this
4351 fcks up illume setting focus on internal windows */
4356 focus_time = ecore_x_current_time_get();
4360 if ((bd->client.icccm.take_focus) &&
4361 (bd->client.icccm.accepts_focus))
4363 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4364 /* TODO what if the client didn't take focus ? */
4366 else if (!bd->client.icccm.accepts_focus)
4368 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4370 else if (!bd->client.icccm.take_focus)
4372 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4373 /* e_border_focus_set(bd, 1, 0); */
4377 #ifdef _F_ZONE_WINDOW_ROTATION_
4378 if ((e_config->wm_win_rotation) &&
4381 Ecore_X_Event_Client_Message *msg = NULL;
4383 EINA_LIST_FREE(rot.msgs, msg)
4385 t = msg->message_type;
4386 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4388 if ((rot.vkbd_ctrl_win) &&
4389 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4392 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4393 if (rot.vkbd_show_prepare_timer)
4394 _e_border_vkbd_show(rot.vkbd);
4396 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4399 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4401 if ((rot.vkbd_ctrl_win) &&
4402 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4405 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4406 if (rot.vkbd_hide_prepare_timer)
4408 _e_border_vkbd_hide(rot.vkbd);
4409 rot.vkbd_hide_prepare_timer = NULL;
4410 e_object_unref(E_OBJECT(rot.vkbd));
4413 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4416 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4418 rot.vkbd_ctrl_win = msg->data.l[0];
4419 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4421 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4423 if ((rot.vkbd_ctrl_win) &&
4424 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4426 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4427 E_Manager *m = e_manager_current_get();
4428 E_Zone *zone = NULL;
4429 if (m) zone = e_util_zone_current_get(m);
4430 if ((zone) && (rot.wait_prepare_done))
4433 _e_border_rotation_change_request(zone);
4434 else if (rot.async_list)
4436 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
4437 rot.async_list = NULL;
4439 if (rot.prepare_timer)
4440 ecore_timer_del(rot.prepare_timer);
4441 rot.prepare_timer = NULL;
4442 rot.wait_prepare_done = EINA_FALSE;
4449 rot.fetch = EINA_FALSE;
4455 e_border_client_list(void)
4457 /* FIXME: This should be a somewhat ordered list */
4461 static Ecore_X_Window action_input_win = 0;
4462 static E_Border *action_border = NULL;
4463 static Ecore_Event_Handler *action_handler_key = NULL;
4464 static Ecore_Event_Handler *action_handler_mouse = NULL;
4465 static Ecore_Timer *action_timer = NULL;
4466 static Ecore_X_Rectangle action_orig;
4469 _e_border_show(E_Border *bd)
4474 ecore_evas_show(bd->bg_ecore_evas);
4482 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4484 _e_border_shape_input_rectangle_set(bd);
4486 // ecore_x_composite_window_events_enable(bd->win);
4487 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4490 ecore_x_window_show(bd->win);
4492 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4493 ecore_x_window_show(tmp->win);
4497 _e_border_hide(E_Border *bd)
4502 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4504 ecore_x_window_hide(bd->win);
4505 ecore_evas_hide(bd->bg_ecore_evas);
4507 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4508 ecore_x_window_hide(tmp->win);
4512 ecore_x_composite_window_events_disable(bd->win);
4513 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4518 _e_border_action_input_win_del(void)
4520 if (!action_input_win)
4523 e_grabinput_release(action_input_win, action_input_win);
4524 ecore_x_window_free(action_input_win);
4525 action_input_win = 0;
4530 _e_border_action_input_win_new(E_Border *bd)
4532 if (!action_input_win)
4534 Ecore_X_Window parent = bd->zone->container->win;
4535 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4536 if (!action_input_win)
4540 ecore_x_window_show(action_input_win);
4541 if (e_grabinput_get(action_input_win, 0, action_input_win))
4544 _e_border_action_input_win_del();
4549 _e_border_action_finish(void)
4551 _e_border_action_input_win_del();
4555 ecore_timer_del(action_timer);
4556 action_timer = NULL;
4559 if (action_handler_key)
4561 ecore_event_handler_del(action_handler_key);
4562 action_handler_key = NULL;
4565 if (action_handler_mouse)
4567 ecore_event_handler_del(action_handler_mouse);
4568 action_handler_mouse = NULL;
4571 action_border = NULL;
4575 _e_border_action_init(E_Border *bd)
4577 action_orig.x = bd->x;
4578 action_orig.y = bd->y;
4579 action_orig.width = bd->w;
4580 action_orig.height = bd->h;
4586 _e_border_action_restore_orig(E_Border *bd)
4588 if (action_border != bd)
4591 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4595 _e_border_key_down_modifier_apply(int modifier,
4598 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4600 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4613 _e_border_action_move_timeout(void *data __UNUSED__)
4615 _e_border_move_end(action_border);
4616 _e_border_action_finish();
4617 return ECORE_CALLBACK_CANCEL;
4621 _e_border_action_move_timeout_add(void)
4624 ecore_timer_del(action_timer);
4625 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4629 _e_border_move_key_down(void *data __UNUSED__,
4630 int type __UNUSED__,
4633 Ecore_Event_Key *ev = event;
4636 if (ev->event_window != action_input_win)
4637 return ECORE_CALLBACK_PASS_ON;
4640 fputs("ERROR: no action_border!\n", stderr);
4644 x = action_border->x;
4645 y = action_border->y;
4647 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4648 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4649 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4650 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4651 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4652 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4653 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4654 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4655 else if (strcmp(ev->key, "Return") == 0)
4657 else if (strcmp(ev->key, "Escape") == 0)
4659 _e_border_action_restore_orig(action_border);
4662 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4663 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4666 e_border_move(action_border, x, y);
4667 _e_border_action_move_timeout_add();
4669 return ECORE_CALLBACK_PASS_ON;
4672 _e_border_move_end(action_border);
4673 _e_border_action_finish();
4674 return ECORE_CALLBACK_DONE;
4678 _e_border_move_mouse_down(void *data __UNUSED__,
4679 int type __UNUSED__,
4682 Ecore_Event_Mouse_Button *ev = event;
4684 if (ev->event_window != action_input_win)
4685 return ECORE_CALLBACK_PASS_ON;
4688 fputs("ERROR: no action_border!\n", stderr);
4690 _e_border_move_end(action_border);
4691 _e_border_action_finish();
4692 return ECORE_CALLBACK_DONE;
4696 e_border_act_move_keyboard(E_Border *bd)
4701 if (!_e_border_move_begin(bd))
4704 if (!_e_border_action_input_win_new(bd))
4706 _e_border_move_end(bd);
4710 _e_border_action_init(bd);
4711 _e_border_action_move_timeout_add();
4712 _e_border_move_update(bd);
4714 if (action_handler_key)
4715 ecore_event_handler_del(action_handler_key);
4716 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4718 if (action_handler_mouse)
4719 ecore_event_handler_del(action_handler_mouse);
4720 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4724 _e_border_action_resize_timeout(void *data __UNUSED__)
4726 _e_border_resize_end(action_border);
4727 _e_border_action_finish();
4728 return ECORE_CALLBACK_CANCEL;
4732 _e_border_action_resize_timeout_add(void)
4735 ecore_timer_del(action_timer);
4736 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4740 _e_border_resize_key_down(void *data __UNUSED__,
4741 int type __UNUSED__,
4744 Ecore_Event_Key *ev = event;
4747 if (ev->event_window != action_input_win)
4748 return ECORE_CALLBACK_PASS_ON;
4751 fputs("ERROR: no action_border!\n", stderr);
4755 w = action_border->w;
4756 h = action_border->h;
4758 dx = e_config->border_keyboard.resize.dx;
4759 if (dx < action_border->client.icccm.step_w)
4760 dx = action_border->client.icccm.step_w;
4761 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4762 if (dx < action_border->client.icccm.step_w)
4763 dx = action_border->client.icccm.step_w;
4765 dy = e_config->border_keyboard.resize.dy;
4766 if (dy < action_border->client.icccm.step_h)
4767 dy = action_border->client.icccm.step_h;
4768 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4769 if (dy < action_border->client.icccm.step_h)
4770 dy = action_border->client.icccm.step_h;
4772 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4774 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4776 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4778 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4780 else if (strcmp(ev->key, "Return") == 0)
4782 else if (strcmp(ev->key, "Escape") == 0)
4784 _e_border_action_restore_orig(action_border);
4787 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4788 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4791 e_border_resize_limit(action_border, &w, &h);
4792 e_border_resize(action_border, w, h);
4793 _e_border_action_resize_timeout_add();
4795 return ECORE_CALLBACK_PASS_ON;
4798 _e_border_resize_end(action_border);
4799 _e_border_action_finish();
4800 return ECORE_CALLBACK_DONE;
4804 _e_border_resize_mouse_down(void *data __UNUSED__,
4805 int type __UNUSED__,
4808 Ecore_Event_Mouse_Button *ev = event;
4810 if (ev->event_window != action_input_win)
4811 return ECORE_CALLBACK_PASS_ON;
4814 fputs("ERROR: no action_border!\n", stderr);
4816 _e_border_resize_end(action_border);
4817 _e_border_action_finish();
4818 return ECORE_CALLBACK_DONE;
4822 e_border_act_resize_keyboard(E_Border *bd)
4827 if (!_e_border_resize_begin(bd))
4830 if (!_e_border_action_input_win_new(bd))
4832 _e_border_resize_end(bd);
4836 _e_border_action_init(bd);
4837 _e_border_action_resize_timeout_add();
4838 _e_border_resize_update(bd);
4840 if (action_handler_key)
4841 ecore_event_handler_del(action_handler_key);
4842 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4844 if (action_handler_mouse)
4845 ecore_event_handler_del(action_handler_mouse);
4846 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4850 e_border_act_move_begin(E_Border *bd,
4851 Ecore_Event_Mouse_Button *ev)
4854 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4855 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4856 if (!_e_border_move_begin(bd))
4859 e_zone_edge_disable();
4861 _e_border_pointer_move_begin(bd);
4866 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4867 _e_border_moveinfo_gather(bd, source);
4872 e_border_act_move_end(E_Border *bd,
4873 Ecore_Event_Mouse_Button *ev __UNUSED__)
4876 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4877 if (!bd->moving) return;
4879 _e_border_pointer_move_end(bd);
4880 e_zone_edge_enable();
4881 _e_border_move_end(bd);
4882 e_zone_flip_coords_handle(bd->zone, -1, -1);
4886 e_border_act_resize_begin(E_Border *bd,
4887 Ecore_Event_Mouse_Button *ev)
4890 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4891 if (bd->lock_user_size) return;
4892 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4893 if (!_e_border_resize_begin(bd))
4895 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4897 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4899 bd->resize_mode = RESIZE_TL;
4900 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4904 bd->resize_mode = RESIZE_BL;
4905 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4910 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4912 bd->resize_mode = RESIZE_TR;
4913 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4917 bd->resize_mode = RESIZE_BR;
4918 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4921 _e_border_pointer_resize_begin(bd);
4926 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4927 _e_border_moveinfo_gather(bd, source);
4932 e_border_act_resize_end(E_Border *bd,
4933 Ecore_Event_Mouse_Button *ev __UNUSED__)
4936 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4937 if (bd->resize_mode != RESIZE_NONE)
4939 _e_border_pointer_resize_end(bd);
4940 bd->resize_mode = RESIZE_NONE;
4941 _e_border_resize_end(bd);
4942 bd->changes.reset_gravity = 1;
4948 e_border_act_menu_begin(E_Border *bd,
4949 Ecore_Event_Mouse_Button *ev,
4953 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4956 e_int_border_menu_show(bd,
4957 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4958 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4965 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4966 e_int_border_menu_show(bd, x, y, key, 0);
4971 e_border_act_close_begin(E_Border *bd)
4974 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4975 if (bd->lock_close) return;
4976 if (bd->client.icccm.delete_request)
4978 bd->delete_requested = 1;
4979 ecore_x_window_delete_request_send(bd->client.win);
4980 if (bd->client.netwm.ping)
4983 else if (e_config->kill_if_close_not_possible)
4985 e_border_act_kill_begin(bd);
4990 e_border_act_kill_begin(E_Border *bd)
4993 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4994 if (bd->internal) return;
4995 if (bd->lock_close) return;
4996 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4998 kill(bd->client.netwm.pid, SIGINT);
4999 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
5000 _e_border_cb_kill_timer, bd);
5004 if (!bd->internal) ecore_x_kill(bd->client.win);
5009 e_border_icon_add(E_Border *bd,
5014 E_OBJECT_CHECK_RETURN(bd, NULL);
5015 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
5020 if (!bd->internal_icon)
5022 o = e_icon_add(evas);
5023 e_util_icon_theme_set(o, "enlightenment");
5027 if (!bd->internal_icon_key)
5031 ext = strrchr(bd->internal_icon, '.');
5032 if ((ext) && ((!strcmp(ext, ".edj"))))
5034 o = edje_object_add(evas);
5035 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
5036 e_util_icon_theme_set(o, "enlightenment");
5040 o = e_icon_add(evas);
5041 e_icon_file_set(o, bd->internal_icon);
5045 o = e_icon_add(evas);
5046 if (!e_util_icon_theme_set(o, bd->internal_icon))
5047 e_util_icon_theme_set(o, "enlightenment");
5052 o = edje_object_add(evas);
5053 edje_object_file_set(o, bd->internal_icon,
5054 bd->internal_icon_key);
5059 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
5061 if (bd->client.netwm.icons)
5063 o = e_icon_add(evas);
5064 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5065 bd->client.netwm.icons[0].width,
5066 bd->client.netwm.icons[0].height);
5067 e_icon_alpha_set(o, 1);
5073 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
5075 o = e_icon_add(evas);
5078 e_icon_fdo_icon_set(o, bd->desktop->icon);
5082 else if (bd->client.netwm.icons)
5084 o = e_icon_add(evas);
5085 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5086 bd->client.netwm.icons[0].width,
5087 bd->client.netwm.icons[0].height);
5088 e_icon_alpha_set(o, 1);
5093 o = e_icon_add(evas);
5094 e_util_icon_theme_set(o, "unknown");
5099 e_border_button_bindings_ungrab_all(void)
5104 EINA_LIST_FOREACH(borders, l, bd)
5106 e_focus_setdown(bd);
5107 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5108 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5113 e_border_button_bindings_grab_all(void)
5118 EINA_LIST_FOREACH(borders, l, bd)
5120 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5121 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5127 e_border_focus_stack_get(void)
5133 e_border_raise_stack_get(void)
5139 e_border_lost_windows_get(E_Zone *zone)
5141 Eina_List *list = NULL, *l;
5143 int loss_overlap = 5;
5145 E_OBJECT_CHECK_RETURN(zone, NULL);
5146 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5147 EINA_LIST_FOREACH(borders, l, bd)
5152 if ((bd->zone != zone) ||
5153 (bd->zone->container != zone->container))
5156 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5157 bd->zone->y + loss_overlap,
5158 bd->zone->w - (2 * loss_overlap),
5159 bd->zone->h - (2 * loss_overlap),
5160 bd->x, bd->y, bd->w, bd->h))
5162 list = eina_list_append(list, bd);
5164 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5165 bd->zone->w, bd->zone->h,
5166 bd->x, bd->y, bd->w, bd->h)) &&
5169 Ecore_X_Rectangle *rect;
5172 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5178 for (i = 0; i < num; i++)
5180 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5181 bd->zone->y + loss_overlap,
5182 bd->zone->w - (2 * loss_overlap),
5183 bd->zone->h - (2 * loss_overlap),
5184 rect[i].x, rect[i].y,
5185 (int)rect[i].width, (int)rect[i].height))
5193 list = eina_list_append(list, bd);
5201 e_border_ping(E_Border *bd)
5204 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5205 if (!e_config->ping_clients) return;
5207 ecore_x_netwm_ping_send(bd->client.win);
5208 bd->ping = ecore_loop_time_get();
5209 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5210 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5211 e_config->ping_clients_interval,
5212 _e_border_cb_ping_poller, bd);
5216 e_border_move_cancel(void)
5220 if (bdmove->cur_mouse_action)
5225 e_object_ref(E_OBJECT(bd));
5226 if (bd->cur_mouse_action->func.end_mouse)
5227 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5228 else if (bd->cur_mouse_action->func.end)
5229 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5230 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5231 bd->cur_mouse_action = NULL;
5232 e_object_unref(E_OBJECT(bd));
5235 _e_border_move_end(bdmove);
5240 e_border_resize_cancel(void)
5244 if (bdresize->cur_mouse_action)
5249 e_object_ref(E_OBJECT(bd));
5250 if (bd->cur_mouse_action->func.end_mouse)
5251 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5252 else if (bd->cur_mouse_action->func.end)
5253 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5254 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5255 bd->cur_mouse_action = NULL;
5256 e_object_unref(E_OBJECT(bd));
5260 bdresize->resize_mode = RESIZE_NONE;
5261 _e_border_resize_end(bdresize);
5267 e_border_frame_recalc(E_Border *bd)
5269 if (!bd->bg_object) return;
5271 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5272 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5274 _e_border_client_inset_calc(bd);
5276 bd->w += (bd->client_inset.l + bd->client_inset.r);
5277 bd->h += (bd->client_inset.t + bd->client_inset.b);
5280 bd->changes.size = 1;
5281 if ((bd->shaped) || (bd->client.shaped))
5283 bd->need_shape_merge = 1;
5284 bd->need_shape_export = 1;
5286 if (bd->shaped_input)
5288 bd->need_shape_merge = 1;
5290 _e_border_client_move_resize_send(bd);
5294 e_border_immortal_windows_get(void)
5296 Eina_List *list = NULL, *l;
5299 EINA_LIST_FOREACH(borders, l, bd)
5302 list = eina_list_append(list, bd);
5308 e_border_name_get(const E_Border *bd)
5310 E_OBJECT_CHECK_RETURN(bd, "");
5311 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5312 if (bd->client.netwm.name)
5313 return bd->client.netwm.name;
5314 else if (bd->client.icccm.title)
5315 return bd->client.icccm.title;
5320 e_border_signal_move_begin(E_Border *bd,
5322 const char *src __UNUSED__)
5325 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5327 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5328 if (!_e_border_move_begin(bd)) return;
5330 _e_border_pointer_move_begin(bd);
5331 e_zone_edge_disable();
5332 _e_border_moveinfo_gather(bd, sig);
5333 if (bd->cur_mouse_action)
5335 if ((!bd->cur_mouse_action->func.end_mouse) &&
5336 (!bd->cur_mouse_action->func.end))
5337 bd->cur_mouse_action = NULL;
5339 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5341 bd->cur_mouse_action = e_action_find("window_move");
5342 if (bd->cur_mouse_action)
5343 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5347 e_border_signal_move_end(E_Border *bd,
5348 const char *sig __UNUSED__,
5349 const char *src __UNUSED__)
5352 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5353 if (!bd->moving) return;
5355 _e_border_pointer_move_end(bd);
5356 e_zone_edge_enable();
5357 _e_border_move_end(bd);
5358 e_zone_flip_coords_handle(bd->zone, -1, -1);
5362 e_border_resizing_get(E_Border *bd)
5364 E_OBJECT_CHECK_RETURN(bd, 0);
5365 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5366 if (bd->resize_mode == RESIZE_NONE) return 0;
5371 e_border_signal_resize_begin(E_Border *bd,
5374 const char *src __UNUSED__)
5376 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5377 int resize_mode = RESIZE_BR;
5380 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5382 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5383 if (!_e_border_resize_begin(bd))
5385 if (!strcmp(dir, "tl"))
5387 resize_mode = RESIZE_TL;
5388 grav = ECORE_X_GRAVITY_SE;
5390 else if (!strcmp(dir, "t"))
5392 resize_mode = RESIZE_T;
5393 grav = ECORE_X_GRAVITY_S;
5395 else if (!strcmp(dir, "tr"))
5397 resize_mode = RESIZE_TR;
5398 grav = ECORE_X_GRAVITY_SW;
5400 else if (!strcmp(dir, "r"))
5402 resize_mode = RESIZE_R;
5403 grav = ECORE_X_GRAVITY_W;
5405 else if (!strcmp(dir, "br"))
5407 resize_mode = RESIZE_BR;
5408 grav = ECORE_X_GRAVITY_NW;
5410 else if (!strcmp(dir, "b"))
5412 resize_mode = RESIZE_B;
5413 grav = ECORE_X_GRAVITY_N;
5415 else if (!strcmp(dir, "bl"))
5417 resize_mode = RESIZE_BL;
5418 grav = ECORE_X_GRAVITY_NE;
5420 else if (!strcmp(dir, "l"))
5422 resize_mode = RESIZE_L;
5423 grav = ECORE_X_GRAVITY_E;
5425 bd->resize_mode = resize_mode;
5426 _e_border_pointer_resize_begin(bd);
5427 _e_border_moveinfo_gather(bd, sig);
5429 if (bd->cur_mouse_action)
5431 if ((!bd->cur_mouse_action->func.end_mouse) &&
5432 (!bd->cur_mouse_action->func.end))
5433 bd->cur_mouse_action = NULL;
5435 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5437 bd->cur_mouse_action = e_action_find("window_resize");
5438 if (bd->cur_mouse_action)
5439 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5443 e_border_signal_resize_end(E_Border *bd,
5444 const char *dir __UNUSED__,
5445 const char *sig __UNUSED__,
5446 const char *src __UNUSED__)
5449 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5450 if (bd->resize_mode == RESIZE_NONE) return;
5451 _e_border_resize_handle(bd);
5452 _e_border_pointer_resize_end(bd);
5453 bd->resize_mode = RESIZE_NONE;
5454 _e_border_resize_end(bd);
5455 bd->changes.reset_gravity = 1;
5460 e_border_resize_limit(E_Border *bd,
5467 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5468 *w -= bd->client_inset.l + bd->client_inset.r;
5469 *h -= bd->client_inset.t + bd->client_inset.b;
5472 if ((bd->client.icccm.base_w >= 0) &&
5473 (bd->client.icccm.base_h >= 0))
5477 tw = *w - bd->client.icccm.base_w;
5478 th = *h - bd->client.icccm.base_h;
5481 a = (double)(tw) / (double)(th);
5482 if ((bd->client.icccm.min_aspect != 0.0) &&
5483 (a < bd->client.icccm.min_aspect))
5485 th = tw / bd->client.icccm.max_aspect;
5486 *h = th + bd->client.icccm.base_h;
5488 else if ((bd->client.icccm.max_aspect != 0.0) &&
5489 (a > bd->client.icccm.max_aspect))
5491 tw = th * bd->client.icccm.max_aspect;
5492 *w = tw + bd->client.icccm.base_w;
5497 a = (double)*w / (double)*h;
5498 if ((bd->client.icccm.min_aspect != 0.0) &&
5499 (a < bd->client.icccm.min_aspect))
5500 *h = *w / bd->client.icccm.min_aspect;
5501 else if ((bd->client.icccm.max_aspect != 0.0) &&
5502 (a > bd->client.icccm.max_aspect))
5503 *w = *h * bd->client.icccm.max_aspect;
5505 if (bd->client.icccm.step_w > 0)
5507 if (bd->client.icccm.base_w >= 0)
5508 *w = bd->client.icccm.base_w +
5509 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5510 bd->client.icccm.step_w);
5512 *w = bd->client.icccm.min_w +
5513 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5514 bd->client.icccm.step_w);
5516 if (bd->client.icccm.step_h > 0)
5518 if (bd->client.icccm.base_h >= 0)
5519 *h = bd->client.icccm.base_h +
5520 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5521 bd->client.icccm.step_h);
5523 *h = bd->client.icccm.min_h +
5524 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5525 bd->client.icccm.step_h);
5531 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5532 else if (*w < bd->client.icccm.min_w)
5533 *w = bd->client.icccm.min_w;
5534 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5535 else if (*h < bd->client.icccm.min_h)
5536 *h = bd->client.icccm.min_h;
5538 *w += bd->client_inset.l + bd->client_inset.r;
5539 *h += bd->client_inset.t + bd->client_inset.b;
5542 /* local subsystem functions */
5544 _e_border_free(E_Border *bd)
5546 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5549 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5551 bd->client.e.state.video_parent_border->client.e.state.video_child =
5553 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5556 if (bd->client.e.state.video_child)
5560 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5562 tmp->client.e.state.video_parent_border = NULL;
5567 efreet_desktop_free(bd->desktop);
5572 ecore_idle_enterer_del(bd->post_job);
5573 bd->post_job = NULL;
5577 e_object_del(E_OBJECT(bd->pointer));
5581 _e_border_resize_end(bd);
5583 _e_border_move_end(bd);
5584 /* TODO: Other states to end before dying? */
5586 if (bd->cur_mouse_action)
5588 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5589 bd->cur_mouse_action = NULL;
5592 E_FREE(bd->shape_rects);
5593 bd->shape_rects_num = 0;
5595 if (bd->dangling_ref_check)
5597 ecore_timer_del(bd->dangling_ref_check);
5598 bd->dangling_ref_check = NULL;
5603 ecore_timer_del(bd->kill_timer);
5604 bd->kill_timer = NULL;
5606 if (bd->ping_poller)
5608 ecore_poller_del(bd->ping_poller);
5609 bd->ping_poller = NULL;
5611 E_FREE_LIST(bd->pending_move_resize, free);
5613 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5614 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5616 if (bd->border_locks_dialog)
5618 e_object_del(E_OBJECT(bd->border_locks_dialog));
5619 bd->border_locks_dialog = NULL;
5621 if (bd->border_remember_dialog)
5623 e_object_del(E_OBJECT(bd->border_remember_dialog));
5624 bd->border_remember_dialog = NULL;
5626 if (bd->border_border_dialog)
5628 e_object_del(E_OBJECT(bd->border_border_dialog));
5629 bd->border_border_dialog = NULL;
5631 if (bd->border_prop_dialog)
5633 e_object_del(E_OBJECT(bd->border_prop_dialog));
5634 bd->border_prop_dialog = NULL;
5637 e_int_border_menu_del(bd);
5642 focus_next = eina_list_remove(focus_next, bd);
5644 if ((focused == bd) ||
5645 (e_grabinput_last_focus_win_get() == bd->client.win))
5647 if ((!focus_next) && (!focusing))
5649 e_grabinput_focus(bd->zone->container->bg_win,
5650 E_FOCUS_METHOD_PASSIVE);
5651 e_hints_active_window_set(bd->zone->container->manager, NULL);
5656 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5662 bd->remember = NULL;
5663 e_remember_unuse(rem);
5665 if (!bd->already_unparented)
5667 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5668 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5669 ecore_x_window_save_set_del(bd->client.win);
5670 bd->already_unparented = 1;
5672 if (bd->group) eina_list_free(bd->group);
5673 if (bd->transients) eina_list_free(bd->transients);
5674 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5675 if (bd->client.netwm.icons)
5678 for (i = 0; i < bd->client.netwm.num_icons; i++)
5679 free(bd->client.netwm.icons[i].data);
5680 free(bd->client.netwm.icons);
5682 if (bd->client.netwm.extra_types)
5683 free(bd->client.netwm.extra_types);
5684 if (bd->client.border.name)
5685 eina_stringshare_del(bd->client.border.name);
5687 eina_stringshare_del(bd->bordername);
5688 if (bd->client.icccm.name)
5689 eina_stringshare_del(bd->client.icccm.name);
5690 if (bd->client.icccm.class)
5692 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5693 e_bindings_mapping_change_enable(EINA_TRUE);
5694 eina_stringshare_del(bd->client.icccm.class);
5696 if (bd->client.icccm.title)
5697 eina_stringshare_del(bd->client.icccm.title);
5698 if (bd->client.icccm.icon_name)
5699 eina_stringshare_del(bd->client.icccm.icon_name);
5700 if (bd->client.icccm.machine)
5701 eina_stringshare_del(bd->client.icccm.machine);
5702 if (bd->client.icccm.window_role)
5703 eina_stringshare_del(bd->client.icccm.window_role);
5705 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5709 for (i = 0; i < bd->client.icccm.command.argc; i++)
5710 free(bd->client.icccm.command.argv[i]);
5711 free(bd->client.icccm.command.argv);
5713 if (bd->client.netwm.name)
5714 eina_stringshare_del(bd->client.netwm.name);
5715 if (bd->client.netwm.icon_name)
5716 eina_stringshare_del(bd->client.netwm.icon_name);
5717 e_object_del(E_OBJECT(bd->shape));
5718 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5719 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5720 if (bd->icon_object) evas_object_del(bd->icon_object);
5721 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5722 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5724 if (str) eina_stringshare_del(str);
5726 bd->client.e.state.profiles = NULL;
5727 if (bd->client.e.state.profile)
5728 eina_stringshare_del(bd->client.e.state.profile);
5729 bd->client.e.state.profile = NULL;
5731 #ifdef _F_ZONE_WINDOW_ROTATION_
5732 if (e_config->wm_win_rotation)
5734 bd->client.e.fetch.rot.app_set = 0;
5735 bd->client.e.state.rot.preferred_rot = -1;
5737 if (bd->client.e.state.rot.available_rots)
5738 E_FREE(bd->client.e.state.rot.available_rots);
5740 _e_border_rotation_list_remove(bd);
5741 if ((rot.vkbd) && (rot.vkbd == bd))
5743 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5745 if (rot.vkbd_ctrl_win)
5747 ELB(ELBT_BD, "SET KBD_OFF", 0);
5748 ecore_x_e_virtual_keyboard_state_set
5749 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5752 rot.vkbd_hide_prepare_done = EINA_FALSE;
5753 if (rot.vkbd_hide_prepare_timer)
5754 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5755 rot.vkbd_hide_prepare_timer = NULL;
5756 if (rot.vkbd_hide_timer)
5757 ecore_timer_del(rot.vkbd_hide_timer);
5758 rot.vkbd_hide_timer = NULL;
5760 rot.vkbd_show_prepare_done = EINA_FALSE;
5761 if (rot.vkbd_show_prepare_timer)
5762 ecore_timer_del(rot.vkbd_show_prepare_timer);
5763 rot.vkbd_show_prepare_timer = NULL;
5764 if (rot.vkbd_show_timer)
5765 ecore_timer_del(rot.vkbd_show_timer);
5766 rot.vkbd_show_timer = NULL;
5768 else if ((rot.vkbd_prediction) &&
5769 (rot.vkbd_prediction == bd))
5770 rot.vkbd_prediction = NULL;
5773 #ifdef _F_DEICONIFY_APPROVE_
5774 if (bd->client.e.state.deiconify_approve.pending_job)
5776 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5777 bd->client.e.state.deiconify_approve.pending_job = NULL;
5780 evas_object_del(bd->bg_object);
5781 e_canvas_del(bd->bg_ecore_evas);
5782 ecore_evas_free(bd->bg_ecore_evas);
5783 ecore_x_window_free(bd->client.shell_win);
5784 e_focus_setdown(bd);
5785 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5786 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5787 ecore_x_window_free(bd->win);
5789 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5790 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5791 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5792 borders = eina_list_remove(borders, bd);
5793 focus_stack = eina_list_remove(focus_stack, bd);
5794 raise_stack = eina_list_remove(raise_stack, bd);
5796 e_container_border_remove(bd);
5802 _e_border_del_dangling_ref_check(void *data)
5808 printf("EEK EEK border still around 1 second after being deleted!\n");
5809 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5810 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5811 bd->client.icccm.name, bd->client.icccm.class);
5812 // e_object_breadcrumb_debug(E_OBJECT(bd));
5819 _e_border_del(E_Border *bd)
5821 E_Event_Border_Remove *ev;
5824 #ifdef _F_BORDER_HOOK_PATCH_
5825 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5836 focus_next = eina_list_remove(focus_next, bd);
5838 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5840 if ((drag_border) && (drag_border->data == bd))
5842 e_object_del(E_OBJECT(drag_border));
5845 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5847 if (bd->border_locks_dialog)
5849 e_object_del(E_OBJECT(bd->border_locks_dialog));
5850 bd->border_locks_dialog = NULL;
5852 if (bd->border_remember_dialog)
5854 e_object_del(E_OBJECT(bd->border_remember_dialog));
5855 bd->border_remember_dialog = NULL;
5857 if (bd->border_border_dialog)
5859 e_object_del(E_OBJECT(bd->border_border_dialog));
5860 bd->border_border_dialog = NULL;
5862 if (bd->border_prop_dialog)
5864 e_object_del(E_OBJECT(bd->border_prop_dialog));
5865 bd->border_prop_dialog = NULL;
5868 e_int_border_menu_del(bd);
5870 if (bd->raise_timer)
5872 ecore_timer_del(bd->raise_timer);
5873 bd->raise_timer = NULL;
5875 if (!bd->already_unparented)
5877 ecore_x_window_reparent(bd->client.win,
5878 bd->zone->container->manager->root,
5879 bd->x + bd->client_inset.l,
5880 bd->y + bd->client_inset.t);
5881 ecore_x_window_save_set_del(bd->client.win);
5882 bd->already_unparented = 1;
5883 // bd->client.win = 0;
5885 bd->already_unparented = 1;
5887 if ((!bd->new_client) && (!stopping))
5889 ev = E_NEW(E_Event_Border_Remove, 1);
5891 e_object_ref(E_OBJECT(bd));
5892 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5893 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5898 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5899 if (bd->parent->modal == bd)
5901 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5902 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5903 bd->parent->lock_close = 0;
5904 bd->parent->saved.event_mask = 0;
5905 bd->parent->modal = NULL;
5909 EINA_LIST_FREE(bd->transients, child)
5911 child->parent = NULL;
5914 #ifdef _F_DEICONIFY_APPROVE_
5915 bd->client.e.state.deiconify_approve.render_done = 0;
5917 E_Border *ancestor_bd;
5918 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5919 if ((ancestor_bd) &&
5920 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5922 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5923 bd->client.e.state.deiconify_approve.ancestor = NULL;
5925 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5926 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5928 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5930 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5931 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5932 e_border_uniconify(ancestor_bd);
5937 if (bd->client.e.state.deiconify_approve.wait_timer)
5939 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5940 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5943 if (bd->client.e.state.deiconify_approve.pending_job)
5945 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5946 bd->client.e.state.deiconify_approve.pending_job = NULL;
5949 if (bd->client.e.state.deiconify_approve.req_list)
5951 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5953 child->client.e.state.deiconify_approve.render_done = 0;
5954 child->client.e.state.deiconify_approve.ancestor = NULL;
5959 #ifdef _F_ZONE_WINDOW_ROTATION_
5960 if (rot.list) _e_border_rotation_list_remove(bd);
5964 E_Border_Rotation_Info *info = NULL;
5966 EINA_LIST_FOREACH(rot.async_list, l, info)
5969 rot.async_list = eina_list_remove(rot.async_list, info);
5977 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5978 if (bd->leader->modal == bd)
5979 bd->leader->modal = NULL;
5982 EINA_LIST_FREE(bd->group, child)
5984 child->leader = NULL;
5988 #ifdef PRINT_LOTS_OF_DEBUG
5990 _e_border_print(E_Border *bd,
5999 "\tBorderless: %s\n",
6000 bd, bd->client.icccm.name, bd->client.icccm.title,
6001 bd->borderless ? "TRUE" : "FALSE");
6007 _e_border_cb_window_show_request(void *data __UNUSED__,
6008 int ev_type __UNUSED__,
6013 Ecore_X_Event_Window_Show_Request *e;
6016 bd = e_border_find_by_client_window(e->win);
6017 if (!bd) return ECORE_CALLBACK_PASS_ON;
6019 #ifdef _F_ZONE_WINDOW_ROTATION_
6020 if ((e_config->wm_win_rotation) &&
6021 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
6023 (rot.vkbd_hide_prepare_timer))
6025 con = bd->zone->container;
6026 bd = e_border_new(con, e->win, 0, 0);
6032 if (!bd->lock_client_iconify)
6033 e_border_uniconify(bd);
6037 /* FIXME: make border "urgent" for a bit - it wants attention */
6038 /* e_border_show(bd); */
6039 if (!bd->lock_client_stacking)
6042 return ECORE_CALLBACK_PASS_ON;
6046 _e_border_cb_window_destroy(void *data __UNUSED__,
6047 int ev_type __UNUSED__,
6051 Ecore_X_Event_Window_Destroy *e;
6054 bd = e_border_find_by_client_window(e->win);
6055 if (!bd) return ECORE_CALLBACK_PASS_ON;
6056 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
6057 #ifdef _F_ZONE_WINDOW_ROTATION_
6058 if (e_config->wm_win_rotation)
6060 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6062 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
6063 if (!rot.vkbd_hide_prepare_timer)
6065 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6066 e_border_hide(bd, 0);
6067 if (!rot.vkbd_hide_prepare_timer)
6069 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6070 e_object_del(E_OBJECT(bd));
6073 return ECORE_CALLBACK_PASS_ON;
6078 #ifdef _F_DEICONIFY_APPROVE_
6079 if (e_config->deiconify_approve)
6081 if (bd->client.e.state.pending_event.pending)
6083 bd->client.e.state.pending_event.destroy.pending = 1;
6084 bd->client.e.state.pending_event.destroy.win = e->win;
6085 bd->client.e.state.pending_event.destroy.event_win = e->event_win;
6086 ELB(ELBT_BD, "PENDING destroy event", bd->client.win);
6087 return ECORE_CALLBACK_CANCEL;
6091 ELB(ELBT_BD, "Real Destroy", bd->client.win);
6094 e_border_hide(bd, 0);
6095 e_object_del(E_OBJECT(bd));
6096 return ECORE_CALLBACK_PASS_ON;
6099 #ifdef _F_DEICONIFY_APPROVE_
6101 _e_border_find_below_win(E_Border* bd)
6109 passed = EINA_FALSE;
6113 bl = e_container_border_list_last(bd->zone->container);
6114 while ((temp_bd = e_container_border_list_prev(bl)))
6116 /* skip if it's the same border */
6123 if (e_object_is_del(E_OBJECT(temp_bd))) continue;
6125 /* skip if it's not on this zone */
6126 if (temp_bd->zone != bd->zone) continue;
6128 if (E_CONTAINS(temp_bd->x, temp_bd->y, temp_bd->w, temp_bd->h, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
6130 if (!temp_bd->client.argb && temp_bd->visible)
6137 if (!passed) continue;
6139 if ((!temp_bd->client.argb) &&
6140 (temp_bd->x == temp_bd->zone->x) &&
6141 (temp_bd->y == temp_bd->zone->y) &&
6142 (temp_bd->w == temp_bd->zone->w) &&
6143 (temp_bd->h == temp_bd->zone->h))
6145 if (temp_bd->visible)
6151 if (ecore_x_window_visible_get(temp_bd->client.win))
6158 e_container_border_list_free(bl);
6165 _e_border_cb_window_hide(void *data __UNUSED__,
6166 int ev_type __UNUSED__,
6169 E_Border *bd = NULL;
6170 Ecore_X_Event_Window_Hide *e;
6173 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
6174 // not interested in hide events from windows other than the window in question
6175 if (e->win != e->event_win)
6177 bd = e_border_find_by_client_window(e->win);
6178 if (!bd) return ECORE_CALLBACK_PASS_ON;
6179 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
6183 (bd->zone->container->manager->root == e->event_win)))
6184 return ECORE_CALLBACK_PASS_ON;
6187 if (!bd) bd = e_border_find_by_client_window(e->win);
6188 // printf(" bd = %p\n", bd);
6191 if (ecore_x_window_visible_get(e->win))
6193 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
6194 ecore_x_window_hide(e->win);
6196 return ECORE_CALLBACK_PASS_ON;
6199 #ifdef _F_DEICONIFY_APPROVE_
6200 if (e_config->deiconify_approve)
6202 if (bd->client.e.state.pending_event.done)
6205 if (bd->client.e.state.pending_event.pending)
6207 return ECORE_CALLBACK_CANCEL;
6210 if (!E_CONTAINS(bd->x, bd->y, bd->w, bd->h, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
6214 // 1. find below non-alpha full size win
6215 below_bd = _e_border_find_below_win(bd);
6219 // 2. check those rotation
6220 bd->client.e.state.pending_event.pending = 1;
6221 bd->client.e.state.pending_event.hold_bd = below_bd;
6223 bd->client.e.state.pending_event.hide.pending = 1;
6224 bd->client.e.state.pending_event.hide.win = e->win;
6225 bd->client.e.state.pending_event.hide.event_win = e->event_win;
6226 bd->client.e.state.pending_event.hide.send_event = e->send_event;
6228 below_bd->client.e.state.deiconify_approve.pending_bd = bd;
6229 ELBF(ELBT_ROT, 0, bd->client.win, "below_win:%x, below_win's wait_bd:%x", below_bd->client.win, below_bd->client.e.state.deiconify_approve.pending_bd->client.win);
6231 // 3. if not same then uniconify
6232 e_border_uniconify(below_bd);
6234 ELB(ELBT_BD, "PENDING hide event", bd->client.win);
6235 return ECORE_CALLBACK_CANCEL;
6240 bd->client.e.state.pending_event.done = 0;
6241 bd->client.e.state.pending_event.pending = 0;
6242 ELB(ELBT_BD, "Real hide", bd->client.win);
6245 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6246 if (bd->ignore_first_unmap > 0)
6248 bd->ignore_first_unmap--;
6249 return ECORE_CALLBACK_PASS_ON;
6251 /* Don't delete hidden or iconified windows */
6252 #ifdef _F_USE_EXTENDED_ICONIFY_
6253 if (bd->await_hide_event > 0)
6255 if ((bd->iconic) || (bd->await_hide_event > 0))
6258 // printf(" Don't delete hidden or iconified windows\n");
6259 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6260 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6261 if (bd->await_hide_event > 0)
6263 bd->await_hide_event--;
6267 // printf(" hide really\n");
6268 /* Only hide the border if it is visible */
6269 if (bd->visible) e_border_hide(bd, 1);
6274 // printf(" hide2\n");
6275 #ifdef _F_USE_EXTENDED_ICONIFY_
6283 #ifdef _F_ZONE_WINDOW_ROTATION_
6284 if (e_config->wm_win_rotation)
6286 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6288 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6289 if (!rot.vkbd_hide_prepare_timer)
6291 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6292 e_border_hide(bd, 0);
6293 if (!rot.vkbd_hide_prepare_timer)
6295 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6296 e_object_del(E_OBJECT(bd));
6299 return ECORE_CALLBACK_PASS_ON;
6303 e_border_hide(bd, 0);
6304 e_object_del(E_OBJECT(bd));
6306 return ECORE_CALLBACK_PASS_ON;
6310 _e_border_cb_window_reparent(void *data __UNUSED__,
6311 int ev_type __UNUSED__,
6312 void *ev __UNUSED__)
6316 Ecore_X_Event_Window_Reparent *e;
6319 bd = e_border_find_by_client_window(e->win);
6321 if (e->parent == bd->client.shell_win) return 1;
6322 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6326 e_border_hide(bd, 0);
6327 e_object_del(E_OBJECT(bd));
6329 return ECORE_CALLBACK_PASS_ON;
6333 _e_border_cb_window_configure_request(void *data __UNUSED__,
6334 int ev_type __UNUSED__,
6338 Ecore_X_Event_Window_Configure_Request *e;
6341 bd = e_border_find_by_client_window(e->win);
6344 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6345 if (!e_util_container_window_find(e->win))
6346 ecore_x_window_configure(e->win, e->value_mask,
6347 e->x, e->y, e->w, e->h, e->border,
6348 e->abovewin, e->detail);
6349 return ECORE_CALLBACK_PASS_ON;
6352 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6353 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6359 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6361 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6363 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6364 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6370 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6371 w = e->w + bd->client_inset.l + bd->client_inset.r;
6372 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6373 h = e->h + bd->client_inset.t + bd->client_inset.b;
6374 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6376 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6378 bd->saved.x = x - bd->zone->x;
6379 bd->saved.y = y - bd->zone->y;
6384 e_border_move_resize(bd, x, y, w, h);
6386 else if (!bd->lock_client_location)
6388 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6390 bd->saved.x = x - bd->zone->x;
6391 bd->saved.y = y - bd->zone->y;
6394 e_border_move(bd, x, y);
6396 else if (!bd->lock_client_size)
6398 if ((bd->shaded) || (bd->shading))
6404 if ((bd->shade.dir == E_DIRECTION_UP) ||
6405 (bd->shade.dir == E_DIRECTION_DOWN))
6407 e_border_resize(bd, w, bd->h);
6412 e_border_resize(bd, bd->w, h);
6418 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6424 e_border_resize(bd, w, h);
6430 if (!bd->lock_client_location)
6432 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6434 bd->saved.x = x - bd->zone->x;
6435 bd->saved.y = y - bd->zone->y;
6438 e_border_move(bd, x, y);
6442 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6443 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6449 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6450 w = e->w + bd->client_inset.l + bd->client_inset.r;
6451 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6452 h = e->h + bd->client_inset.t + bd->client_inset.b;
6453 #ifdef _F_ZONE_WINDOW_ROTATION_
6454 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6456 if (!bd->lock_client_size)
6458 if ((bd->shaded) || (bd->shading))
6464 if ((bd->shade.dir == E_DIRECTION_UP) ||
6465 (bd->shade.dir == E_DIRECTION_DOWN))
6467 e_border_resize(bd, w, bd->h);
6472 e_border_resize(bd, bd->w, h);
6478 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6483 zx = zy = zw = zh = 0;
6486 * This code does resize and move a window on a
6487 * X configure request into an useful geometry.
6488 * This is really useful for size jumping file dialogs.
6493 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6495 if (e_config->geometry_auto_resize_limit == 1)
6504 e_border_resize(bd, w, h);
6506 if (e_config->geometry_auto_move == 1)
6508 /* z{x,y,w,h} are only set here; FIXME! */
6511 // move window horizontal if resize to not useful geometry
6512 if (bd->x + bd->w > zx + zw)
6513 rx = zx + zw - bd->w;
6514 else if (bd->x < zx)
6517 // move window vertical if resize to not useful geometry
6518 if (bd->y + bd->h > zy + zh)
6519 ry = zy + zh - bd->h;
6520 else if (bd->y < zy)
6523 e_border_move(bd, rx, ry);
6529 if (!bd->lock_client_stacking)
6531 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6532 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6536 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6538 obd = e_border_find_by_client_window(e->abovewin);
6541 e_border_stack_above(bd, obd);
6545 ecore_x_window_configure(bd->win,
6546 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6547 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6549 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6550 /* FIXME: need to rebuiuld border list from current stacking */
6553 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6555 obd = e_border_find_by_client_window(e->abovewin);
6558 e_border_stack_below(bd, obd);
6562 ecore_x_window_configure(bd->win,
6563 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6564 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6566 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6567 /* FIXME: need to rebuiuld border list from current stacking */
6570 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6574 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6578 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6583 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6585 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6589 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6593 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6597 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6601 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6608 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6609 _e_border_client_move_resize_send(bd);
6610 return ECORE_CALLBACK_PASS_ON;
6614 _e_border_cb_window_resize_request(void *data __UNUSED__,
6615 int ev_type __UNUSED__,
6619 Ecore_X_Event_Window_Resize_Request *e;
6622 bd = e_border_find_by_client_window(e->win);
6625 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6626 ecore_x_window_resize(e->win, e->w, e->h);
6627 return ECORE_CALLBACK_PASS_ON;
6632 w = e->w + bd->client_inset.l + bd->client_inset.r;
6633 h = e->h + bd->client_inset.t + bd->client_inset.b;
6634 if ((bd->shaded) || (bd->shading))
6640 if ((bd->shade.dir == E_DIRECTION_UP) ||
6641 (bd->shade.dir == E_DIRECTION_DOWN))
6643 e_border_resize(bd, w, bd->h);
6648 e_border_resize(bd, bd->w, h);
6653 e_border_resize(bd, w, h);
6656 _e_border_client_move_resize_send(bd);
6657 return ECORE_CALLBACK_PASS_ON;
6661 _e_border_cb_window_gravity(void *data __UNUSED__,
6662 int ev_type __UNUSED__,
6663 void *ev __UNUSED__)
6666 // Ecore_X_Event_Window_Gravity *e;
6669 // bd = e_border_find_by_client_window(e->win);
6670 // if (!bd) return 1;
6675 _e_border_cb_window_stack_request(void *data __UNUSED__,
6676 int ev_type __UNUSED__,
6680 Ecore_X_Event_Window_Stack_Request *e;
6683 bd = e_border_find_by_client_window(e->win);
6686 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6687 if (!e_util_container_window_find(e->win))
6689 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6690 ecore_x_window_raise(e->win);
6691 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6692 ecore_x_window_lower(e->win);
6694 return ECORE_CALLBACK_PASS_ON;
6696 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6698 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6700 return ECORE_CALLBACK_PASS_ON;
6704 _e_border_cb_window_property(void *data __UNUSED__,
6705 int ev_type __UNUSED__,
6709 Ecore_X_Event_Window_Property *e;
6712 bd = e_border_find_by_client_window(e->win);
6713 if (!bd) return ECORE_CALLBACK_PASS_ON;
6714 if (e->atom == ECORE_X_ATOM_WM_NAME)
6716 if ((!bd->client.netwm.name) &&
6717 (!bd->client.netwm.fetch.name))
6719 bd->client.icccm.fetch.title = 1;
6723 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6725 bd->client.netwm.fetch.name = 1;
6728 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6730 bd->client.icccm.fetch.name_class = 1;
6733 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6735 if ((!bd->client.netwm.icon_name) &&
6736 (!bd->client.netwm.fetch.icon_name))
6738 bd->client.icccm.fetch.icon_name = 1;
6742 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6744 bd->client.netwm.fetch.icon_name = 1;
6747 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6749 bd->client.icccm.fetch.machine = 1;
6752 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6754 bd->client.icccm.fetch.protocol = 1;
6757 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6759 bd->client.icccm.fetch.hints = 1;
6762 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6764 bd->client.icccm.fetch.size_pos_hints = 1;
6767 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6770 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6771 (!bd->client.netwm.fetch.type))
6774 bd->client.mwm.fetch.hints = 1;
6780 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6782 bd->client.icccm.fetch.transient_for = 1;
6785 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6787 bd->client.icccm.fetch.client_leader = 1;
6790 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6792 bd->client.icccm.fetch.window_role = 1;
6795 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6797 bd->client.netwm.fetch.icon = 1;
6800 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6802 bd->client.qtopia.fetch.soft_menu = 1;
6805 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6807 bd->client.qtopia.fetch.soft_menus = 1;
6810 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6812 bd->client.vkbd.fetch.state = 1;
6815 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6817 bd->client.vkbd.fetch.vkbd = 1;
6820 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6822 bd->client.illume.conformant.fetch.conformant = 1;
6825 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6827 bd->client.illume.quickpanel.fetch.state = 1;
6830 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6832 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6835 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6837 bd->client.illume.quickpanel.fetch.priority.major = 1;
6840 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6842 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6845 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6847 bd->client.illume.quickpanel.fetch.zone = 1;
6850 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6852 bd->client.illume.drag.fetch.locked = 1;
6855 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6857 bd->client.illume.drag.fetch.drag = 1;
6860 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6862 bd->client.illume.win_state.fetch.state = 1;
6866 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6868 bd->client.netwm.fetch.user_time = 1;
6871 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6873 bd->client.netwm.fetch.strut = 1;
6876 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6878 bd->client.netwm.fetch.strut = 1;
6882 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6884 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6886 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6888 bd->client.e.fetch.video_position = 1;
6891 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6893 bd->client.e.fetch.video_parent = 1;
6896 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6898 bd->client.netwm.fetch.state = 1;
6901 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6902 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6904 bd->client.e.fetch.profile_list = 1;
6908 #ifdef _F_ZONE_WINDOW_ROTATION_
6909 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6911 if (e_config->wm_win_rotation)
6913 bd->client.e.fetch.rot.support = 1;
6917 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6918 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6919 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6920 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6922 if (e_config->wm_win_rotation)
6924 bd->client.e.fetch.rot.geom_hint = 1;
6928 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6930 if (e_config->wm_win_rotation)
6932 bd->client.e.fetch.rot.app_set = 1;
6936 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6938 if (e_config->wm_win_rotation)
6940 bd->client.e.fetch.rot.preferred_rot = 1;
6944 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6946 if (e_config->wm_win_rotation)
6948 bd->client.e.fetch.rot.available_rots = 1;
6954 return ECORE_CALLBACK_PASS_ON;
6958 _e_border_cb_window_colormap(void *data __UNUSED__,
6959 int ev_type __UNUSED__,
6963 Ecore_X_Event_Window_Colormap *e;
6966 bd = e_border_find_by_client_window(e->win);
6967 if (!bd) return ECORE_CALLBACK_PASS_ON;
6968 return ECORE_CALLBACK_PASS_ON;
6972 _e_border_cb_window_shape(void *data __UNUSED__,
6973 int ev_type __UNUSED__,
6977 Ecore_X_Event_Window_Shape *e;
6980 bd = e_border_find_by_client_window(e->win);
6982 if (e->type == ECORE_X_SHAPE_INPUT)
6986 bd->need_shape_merge = 1;
6987 // YYY bd->shaped_input = 1;
6988 bd->changes.shape_input = 1;
6992 return ECORE_CALLBACK_PASS_ON;
6997 bd->changes.shape = 1;
6999 return ECORE_CALLBACK_PASS_ON;
7001 bd = e_border_find_by_window(e->win);
7004 bd->need_shape_export = 1;
7006 return ECORE_CALLBACK_PASS_ON;
7008 bd = e_border_find_by_frame_window(e->win);
7011 bd->need_shape_merge = 1;
7013 return ECORE_CALLBACK_PASS_ON;
7015 return ECORE_CALLBACK_PASS_ON;
7019 _e_border_cb_window_focus_in(void *data __UNUSED__,
7020 int ev_type __UNUSED__,
7024 Ecore_X_Event_Window_Focus_In *e;
7027 bd = e_border_find_by_client_window(e->win);
7028 if (!bd) return ECORE_CALLBACK_PASS_ON;
7029 #ifdef INOUTDEBUG_FOCUS
7034 const char *modes[] = {
7036 "MODE_WHILE_GRABBED",
7040 const char *details[] = {
7044 "DETAIL_NON_LINEAR",
7045 "DETAIL_NON_LINEAR_VIRTUAL",
7047 "DETAIL_POINTER_ROOT",
7048 "DETAIL_DETAIL_NONE"
7052 ct[strlen(ct) - 1] = 0;
7053 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
7058 details[e->detail]);
7060 DBG("%s cb focus in %d %d\n",
7061 e_border_name_get(bd),
7062 bd->client.icccm.accepts_focus,
7063 bd->client.icccm.take_focus);
7066 _e_border_pri_raise(bd);
7067 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
7069 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
7071 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
7073 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
7076 /* ignore focus in from !take_focus windows, we just gave it em */
7077 /* if (!bd->client.icccm.take_focus)
7078 * return ECORE_CALLBACK_PASS_ON; */
7080 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
7081 if (e->time >= focus_time)
7082 e_border_focus_set(bd, 1, 0);
7083 return ECORE_CALLBACK_PASS_ON;
7087 _e_border_cb_window_focus_out(void *data __UNUSED__,
7088 int ev_type __UNUSED__,
7092 Ecore_X_Event_Window_Focus_Out *e;
7095 bd = e_border_find_by_client_window(e->win);
7096 if (!bd) return ECORE_CALLBACK_PASS_ON;
7097 #ifdef INOUTDEBUG_FOCUS
7102 const char *modes[] = {
7104 "MODE_WHILE_GRABBED",
7108 const char *details[] = {
7112 "DETAIL_NON_LINEAR",
7113 "DETAIL_NON_LINEAR_VIRTUAL",
7115 "DETAIL_POINTER_ROOT",
7116 "DETAIL_DETAIL_NONE"
7120 ct[strlen(ct) - 1] = 0;
7121 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
7126 details[e->detail]);
7128 DBG("%s cb focus out %d %d",
7129 e_border_name_get(bd),
7130 bd->client.icccm.accepts_focus,
7131 bd->client.icccm.take_focus);
7134 _e_border_pri_norm(bd);
7135 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
7137 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7138 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
7139 return ECORE_CALLBACK_PASS_ON;
7140 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
7141 return ECORE_CALLBACK_PASS_ON;
7143 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
7145 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
7146 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7147 return ECORE_CALLBACK_PASS_ON;
7148 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
7149 return ECORE_CALLBACK_PASS_ON;
7150 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
7151 return ECORE_CALLBACK_PASS_ON;
7152 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
7153 return ECORE_CALLBACK_PASS_ON;
7155 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
7157 /* for firefox/thunderbird (xul) menu walking */
7158 /* NB: why did i disable this before? */
7159 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7160 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
7161 return ECORE_CALLBACK_PASS_ON;
7163 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
7165 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
7166 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7167 return ECORE_CALLBACK_PASS_ON;
7169 e_border_focus_set(bd, 0, 0);
7170 return ECORE_CALLBACK_PASS_ON;
7173 #if _F_BORDER_CLIP_TO_ZONE_
7175 _e_border_shape_input_clip_to_zone(E_Border *bd)
7177 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
7181 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
7182 bd->zone->w, bd->zone->h,
7183 bd->x, bd->y, bd->w, bd->h)))
7186 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
7187 E_RECTS_CLIP_TO_RECT(x, y, w, h,
7188 bd->zone->x, bd->zone->y,
7189 bd->zone->w, bd->zone->h);
7192 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
7193 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
7197 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
7198 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
7201 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
7204 _e_border_cb_client_message(void *data __UNUSED__,
7205 int ev_type __UNUSED__,
7208 Ecore_X_Event_Client_Message *e;
7212 #ifdef _F_DEICONIFY_APPROVE_
7213 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
7215 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
7217 bd = e_border_find_by_client_window(e->win);
7220 if (bd->client.e.state.deiconify_approve.support)
7222 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
7223 bd->client.e.state.deiconify_approve.render_done = 1;
7225 E_Border *ancestor_bd;
7226 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
7229 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
7230 bd->client.e.state.deiconify_approve.ancestor = NULL;
7237 ELBF(ELBT_BD, 0, bd->client.win,
7238 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
7240 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
7241 (ancestor_bd->client.e.state.deiconify_approve.render_done))
7243 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7245 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7246 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7248 if (bd->client.e.state.deiconify_approve.wait_timer)
7250 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7251 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7254 e_border_uniconify(ancestor_bd);
7258 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7259 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7263 if (bd != ancestor_bd)
7265 if (bd->client.e.state.deiconify_approve.wait_timer)
7267 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7268 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7273 return ECORE_CALLBACK_PASS_ON;
7277 #ifdef _F_ZONE_WINDOW_ROTATION_
7278 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7280 bd = e_border_find_by_client_window(e->win);
7283 if (e_config->wm_win_rotation)
7285 Ecore_X_Event_Client_Message *msg = NULL;
7286 Ecore_X_Atom t = e->message_type;
7287 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7288 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7289 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7290 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7292 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7293 if (!msg) return ECORE_CALLBACK_PASS_ON;
7296 msg->message_type = e->message_type;
7297 msg->data.l[0] = e->data.l[0];
7298 msg->data.l[1] = e->data.l[1];
7299 msg->data.l[2] = e->data.l[2];
7300 msg->data.l[3] = e->data.l[3];
7301 msg->data.l[4] = e->data.l[4];
7302 rot.msgs = eina_list_append(rot.msgs, msg);
7304 rot.fetch = EINA_TRUE;
7307 return ECORE_CALLBACK_PASS_ON;
7310 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7312 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7313 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7315 if (e_config->wm_win_rotation)
7317 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7319 _e_border_rotation_list_remove(bd);
7320 if (bd->client.e.state.rot.pending_show)
7322 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7324 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7325 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
7326 _e_border_check_stack(bd);
7328 bd->client.e.state.rot.pending_show = 0;
7334 return ECORE_CALLBACK_PASS_ON;
7338 _e_border_cb_window_state_request(void *data __UNUSED__,
7339 int ev_type __UNUSED__,
7343 Ecore_X_Event_Window_State_Request *e;
7347 bd = e_border_find_by_client_window(e->win);
7348 if (!bd) return ECORE_CALLBACK_PASS_ON;
7350 for (i = 0; i < 2; i++)
7351 e_hints_window_state_update(bd, e->state[i], e->action);
7353 return ECORE_CALLBACK_PASS_ON;
7357 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7358 int ev_type __UNUSED__,
7362 Ecore_X_Event_Window_Move_Resize_Request *e;
7365 bd = e_border_find_by_client_window(e->win);
7366 if (!bd) return ECORE_CALLBACK_PASS_ON;
7368 if ((bd->shaded) || (bd->shading) ||
7369 (bd->fullscreen) || (bd->moving) ||
7370 (bd->resize_mode != RESIZE_NONE))
7371 return ECORE_CALLBACK_PASS_ON;
7373 if ((e->button >= 1) && (e->button <= 3))
7375 bd->mouse.last_down[e->button - 1].mx = e->x;
7376 bd->mouse.last_down[e->button - 1].my = e->y;
7377 bd->mouse.last_down[e->button - 1].x = bd->x;
7378 bd->mouse.last_down[e->button - 1].y = bd->y;
7379 bd->mouse.last_down[e->button - 1].w = bd->w;
7380 bd->mouse.last_down[e->button - 1].h = bd->h;
7384 bd->moveinfo.down.x = bd->x;
7385 bd->moveinfo.down.y = bd->y;
7386 bd->moveinfo.down.w = bd->w;
7387 bd->moveinfo.down.h = bd->h;
7389 bd->mouse.current.mx = e->x;
7390 bd->mouse.current.my = e->y;
7391 bd->moveinfo.down.button = e->button;
7392 bd->moveinfo.down.mx = e->x;
7393 bd->moveinfo.down.my = e->y;
7396 if (!bd->lock_user_stacking)
7399 if (e->direction == MOVE)
7401 bd->cur_mouse_action = e_action_find("window_move");
7402 if (bd->cur_mouse_action)
7404 if ((!bd->cur_mouse_action->func.end_mouse) &&
7405 (!bd->cur_mouse_action->func.end))
7406 bd->cur_mouse_action = NULL;
7407 if (bd->cur_mouse_action)
7409 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7410 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7413 return ECORE_CALLBACK_PASS_ON;
7416 if (!_e_border_resize_begin(bd))
7417 return ECORE_CALLBACK_PASS_ON;
7419 switch (e->direction)
7422 bd->resize_mode = RESIZE_TL;
7423 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7427 bd->resize_mode = RESIZE_T;
7428 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7432 bd->resize_mode = RESIZE_TR;
7433 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7437 bd->resize_mode = RESIZE_R;
7438 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7442 bd->resize_mode = RESIZE_BR;
7443 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7447 bd->resize_mode = RESIZE_B;
7448 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7452 bd->resize_mode = RESIZE_BL;
7453 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7457 bd->resize_mode = RESIZE_L;
7458 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7462 return ECORE_CALLBACK_PASS_ON;
7465 bd->cur_mouse_action = e_action_find("window_resize");
7466 if (bd->cur_mouse_action)
7468 if ((!bd->cur_mouse_action->func.end_mouse) &&
7469 (!bd->cur_mouse_action->func.end))
7470 bd->cur_mouse_action = NULL;
7472 if (bd->cur_mouse_action)
7473 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7475 return ECORE_CALLBACK_PASS_ON;
7479 _e_border_cb_desktop_change(void *data __UNUSED__,
7480 int ev_type __UNUSED__,
7484 Ecore_X_Event_Desktop_Change *e;
7487 bd = e_border_find_by_client_window(e->win);
7490 if (e->desk == 0xffffffff)
7492 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7496 desk = e_desk_at_pos_get(bd->zone, e->desk);
7498 e_border_desk_set(bd, desk);
7503 ecore_x_netwm_desktop_set(e->win, e->desk);
7505 return ECORE_CALLBACK_PASS_ON;
7509 _e_border_cb_sync_alarm(void *data __UNUSED__,
7510 int ev_type __UNUSED__,
7514 Ecore_X_Event_Sync_Alarm *e;
7515 unsigned int serial;
7518 bd = e_border_find_by_alarm(e->alarm);
7519 if (!bd) return ECORE_CALLBACK_PASS_ON;
7521 if (bd->client.netwm.sync.wait)
7522 bd->client.netwm.sync.wait--;
7524 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7526 E_Border_Pending_Move_Resize *pnd = NULL;
7528 /* skip pending for which we didn't get a reply */
7529 while (bd->pending_move_resize)
7531 pnd = bd->pending_move_resize->data;
7532 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7534 if (serial == pnd->serial)
7546 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7547 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7552 bd->changes.size = 1;
7553 bd->changes.pos = 1;
7556 evas_render(bd->bg_evas);
7558 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7559 &bd->mouse.current.mx,
7560 &bd->mouse.current.my);
7562 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7563 _e_border_resize_handle(bd);
7565 return ECORE_CALLBACK_PASS_ON;
7569 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7570 int ev_type __UNUSED__,
7571 void *ev __UNUSED__)
7576 /* mark all borders for desktop/icon updates */
7577 EINA_LIST_FOREACH(borders, l, bd)
7581 efreet_desktop_free(bd->desktop);
7584 bd->changes.icon = 1;
7588 e_init_status_set(_("Desktop files scan done"));
7591 return ECORE_CALLBACK_PASS_ON;
7595 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7596 int ev_type __UNUSED__,
7597 void *ev __UNUSED__)
7602 /* mark all borders for desktop/icon updates */
7603 EINA_LIST_FOREACH(borders, l, bd)
7605 bd->changes.icon = 1;
7608 return ECORE_CALLBACK_PASS_ON;
7612 _e_border_cb_pointer_warp(void *data __UNUSED__,
7613 int ev_type __UNUSED__,
7616 E_Event_Pointer_Warp *e;
7619 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7620 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7621 return ECORE_CALLBACK_PASS_ON;
7625 _e_border_cb_signal_bind(void *data,
7626 Evas_Object *obj __UNUSED__,
7627 const char *emission,
7633 if (e_dnd_active()) return;
7634 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7639 _e_border_cb_mouse_in(void *data,
7640 int type __UNUSED__,
7643 Ecore_X_Event_Mouse_In *ev;
7648 #ifdef INOUTDEBUG_MOUSE
7653 const char *modes[] = {
7655 "MODE_WHILE_GRABBED",
7659 const char *details[] = {
7663 "DETAIL_NON_LINEAR",
7664 "DETAIL_NON_LINEAR_VIRTUAL",
7666 "DETAIL_POINTER_ROOT",
7667 "DETAIL_DETAIL_NONE"
7671 ct[strlen(ct) - 1] = 0;
7672 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7673 ev->win, ev->event_win,
7676 details[ev->detail]);
7679 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7680 if (ev->event_win == bd->win)
7682 e_focus_event_mouse_in(bd);
7685 if ((ev->win != bd->win) &&
7686 (ev->win != bd->event_win) &&
7687 (ev->event_win != bd->win) &&
7688 (ev->event_win != bd->event_win))
7689 return ECORE_CALLBACK_PASS_ON;
7691 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7693 bd->mouse.current.mx = ev->root.x;
7694 bd->mouse.current.my = ev->root.y;
7695 if (!bd->bg_evas_in)
7697 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7698 bd->bg_evas_in = EINA_TRUE;
7700 return ECORE_CALLBACK_PASS_ON;
7704 _e_border_cb_mouse_out(void *data,
7705 int type __UNUSED__,
7708 Ecore_X_Event_Mouse_Out *ev;
7713 #ifdef INOUTDEBUG_MOUSE
7718 const char *modes[] = {
7720 "MODE_WHILE_GRABBED",
7724 const char *details[] = {
7728 "DETAIL_NON_LINEAR",
7729 "DETAIL_NON_LINEAR_VIRTUAL",
7731 "DETAIL_POINTER_ROOT",
7732 "DETAIL_DETAIL_NONE"
7736 ct[strlen(ct) - 1] = 0;
7737 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7738 ev->win, ev->event_win,
7741 details[ev->detail]);
7744 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7745 if (ev->event_win == bd->win)
7748 return ECORE_CALLBACK_PASS_ON;
7749 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7750 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7751 return ECORE_CALLBACK_PASS_ON;
7752 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7753 return ECORE_CALLBACK_PASS_ON;
7754 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7755 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7756 return ECORE_CALLBACK_PASS_ON;
7757 e_focus_event_mouse_out(bd);
7760 if ((ev->win != bd->win) &&
7761 (ev->win != bd->event_win) &&
7762 (ev->event_win != bd->win) &&
7763 (ev->event_win != bd->event_win))
7764 return ECORE_CALLBACK_PASS_ON;
7766 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7768 bd->mouse.current.mx = ev->root.x;
7769 bd->mouse.current.my = ev->root.y;
7772 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7773 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7774 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7776 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7777 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7778 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7779 bd->bg_evas_in = EINA_FALSE;
7782 return ECORE_CALLBACK_PASS_ON;
7786 _e_border_cb_mouse_wheel(void *data,
7787 int type __UNUSED__,
7790 Ecore_Event_Mouse_Wheel *ev;
7795 if ((ev->event_window == bd->win) ||
7796 (ev->event_window == bd->event_win))
7798 bd->mouse.current.mx = ev->root.x;
7799 bd->mouse.current.my = ev->root.y;
7800 if (!bd->cur_mouse_action)
7801 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7804 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7805 return ECORE_CALLBACK_PASS_ON;
7809 _e_border_cb_mouse_down(void *data,
7810 int type __UNUSED__,
7813 Ecore_Event_Mouse_Button *ev;
7818 if ((ev->event_window == bd->win) ||
7819 (ev->event_window == bd->event_win))
7821 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7823 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7824 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7825 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7826 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7827 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7828 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7832 bd->moveinfo.down.x = bd->x + bd->fx.x;
7833 bd->moveinfo.down.y = bd->y + bd->fx.y;
7834 bd->moveinfo.down.w = bd->w;
7835 bd->moveinfo.down.h = bd->h;
7837 bd->mouse.current.mx = ev->root.x;
7838 bd->mouse.current.my = ev->root.y;
7839 if (!bd->cur_mouse_action)
7841 bd->cur_mouse_action =
7842 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7844 if (bd->cur_mouse_action)
7846 if ((!bd->cur_mouse_action->func.end_mouse) &&
7847 (!bd->cur_mouse_action->func.end))
7848 bd->cur_mouse_action = NULL;
7849 if (bd->cur_mouse_action)
7850 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7853 e_focus_event_mouse_down(bd);
7855 if (ev->window != ev->event_window)
7859 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7863 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7865 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7866 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7867 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7868 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7869 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7870 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7874 bd->moveinfo.down.x = bd->x + bd->fx.x;
7875 bd->moveinfo.down.y = bd->y + bd->fx.y;
7876 bd->moveinfo.down.w = bd->w;
7877 bd->moveinfo.down.h = bd->h;
7879 bd->mouse.current.mx = ev->root.x;
7880 bd->mouse.current.my = ev->root.y;
7885 else if (bd->resize_mode != RESIZE_NONE)
7891 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7893 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7894 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7895 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7897 return ECORE_CALLBACK_PASS_ON;
7901 _e_border_cb_mouse_up(void *data,
7902 int type __UNUSED__,
7905 Ecore_Event_Mouse_Button *ev;
7910 if ((ev->event_window == bd->win) ||
7911 (ev->event_window == bd->event_win))
7913 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7915 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7916 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7917 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7918 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7920 bd->mouse.current.mx = ev->root.x;
7921 bd->mouse.current.my = ev->root.y;
7922 /* also we dont pass the same params that went in - then again that */
7923 /* should be ok as we are just ending the action if it has an end */
7924 if (bd->cur_mouse_action)
7926 if (bd->cur_mouse_action->func.end_mouse)
7927 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7928 else if (bd->cur_mouse_action->func.end)
7929 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7930 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7931 bd->cur_mouse_action = NULL;
7935 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7936 e_focus_event_mouse_up(bd);
7939 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7940 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7942 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7943 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7944 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7945 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7947 bd->mouse.current.mx = ev->root.x;
7948 bd->mouse.current.my = ev->root.y;
7952 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7953 return ECORE_CALLBACK_PASS_ON;
7957 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7959 #ifdef _F_BORDER_CLIP_TO_ZONE_
7960 int new_x_max, new_y_max;
7961 int new_x_min, new_y_min;
7962 int margin_x, margin_y;
7964 margin_x = bd->w - 100;
7965 margin_y = bd->h - 100;
7967 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7968 new_x_min = bd->zone->x - margin_x;
7969 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7970 new_y_min = bd->zone->y - margin_y;
7972 if (x >= new_x_max) *new_x = new_x_max;
7973 else if (x <= new_x_min) *new_x = new_x_min;
7975 if (y >= new_y_max) *new_y = new_y_max;
7976 else if (y <= new_y_min) *new_y = new_y_min;
7981 _e_border_cb_mouse_move(void *data,
7982 int type __UNUSED__,
7985 Ecore_Event_Mouse_Move *ev;
7990 if ((ev->window != bd->event_win) &&
7991 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7992 bd->mouse.current.mx = ev->root.x;
7993 bd->mouse.current.my = ev->root.y;
7996 int x, y, new_x, new_y;
7998 Eina_List *skiplist = NULL;
8000 // FIXME: remove? sync what for when only moving?
8001 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
8002 bd->client.netwm.sync.wait = 0;
8003 if ((bd->client.netwm.sync.request) &&
8004 (bd->client.netwm.sync.alarm) &&
8005 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
8007 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
8009 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
8010 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8011 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
8012 (bd->mouse.current.my - bd->moveinfo.down.my);
8016 x = bd->moveinfo.down.x +
8017 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8018 y = bd->moveinfo.down.y +
8019 (bd->mouse.current.my - bd->moveinfo.down.my);
8024 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
8025 skiplist = eina_list_append(skiplist, bd);
8026 e_resist_container_border_position(bd->zone->container, skiplist,
8027 bd->x, bd->y, bd->w, bd->h,
8029 &new_x, &new_y, &new_w, &new_h);
8030 eina_list_free(skiplist);
8032 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
8034 /* if (e_config->window_out_of_vscreen_limits_partly) */
8036 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
8039 skiplist = eina_list_append(skiplist, bd);
8040 e_resist_container_border_position(bd->zone->container, skiplist,
8041 bd->x, bd->y, bd->w, bd->h,
8043 &new_x, &new_y, &new_w, &new_h);
8044 eina_list_free(skiplist);
8047 bd->shelf_fix.x = 0;
8048 bd->shelf_fix.y = 0;
8049 bd->shelf_fix.modified = 0;
8050 e_border_move(bd, new_x, new_y);
8051 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
8053 else if (bd->resize_mode != RESIZE_NONE)
8055 if ((bd->client.netwm.sync.request) &&
8056 (bd->client.netwm.sync.alarm))
8058 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
8060 E_Border_Pending_Move_Resize *pnd;
8062 if (bd->pending_move_resize)
8064 bd->changes.pos = 1;
8065 bd->changes.size = 1;
8067 _e_border_client_move_resize_send(bd);
8069 EINA_LIST_FREE(bd->pending_move_resize, pnd)
8072 bd->client.netwm.sync.wait = 0;
8074 /* sync.wait is incremented when resize_handle sends
8075 * sync-request and decremented by sync-alarm cb. so
8076 * we resize here either on initial resize, timeout or
8077 * when no new resize-request was added by sync-alarm cb.
8079 if (!bd->client.netwm.sync.wait)
8080 _e_border_resize_handle(bd);
8083 _e_border_resize_handle(bd);
8089 if ((bd->drag.x == -1) && (bd->drag.y == -1))
8091 bd->drag.x = ev->root.x;
8092 bd->drag.y = ev->root.y;
8098 dx = bd->drag.x - ev->root.x;
8099 dy = bd->drag.y - ev->root.y;
8100 if (((dx * dx) + (dy * dy)) >
8101 (e_config->drag_resist * e_config->drag_resist))
8104 if (bd->icon_object)
8106 Evas_Object *o = NULL;
8107 Evas_Coord x, y, w, h;
8108 const char *drag_types[] = { "enlightenment/border" };
8110 e_object_ref(E_OBJECT(bd));
8111 evas_object_geometry_get(bd->icon_object,
8113 drag_border = e_drag_new(bd->zone->container,
8114 bd->x + bd->fx.x + x,
8115 bd->y + bd->fx.y + y,
8116 drag_types, 1, bd, -1,
8118 _e_border_cb_drag_finished);
8119 o = e_border_icon_add(bd, drag_border->evas);
8122 /* FIXME: fallback icon for drag */
8123 o = evas_object_rectangle_add(drag_border->evas);
8124 evas_object_color_set(o, 255, 255, 255, 255);
8126 e_drag_object_set(drag_border, o);
8128 e_drag_resize(drag_border, w, h);
8129 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
8135 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
8137 return ECORE_CALLBACK_PASS_ON;
8141 _e_border_cb_grab_replay(void *data __UNUSED__,
8145 Ecore_Event_Mouse_Button *ev;
8147 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
8149 if ((e_config->pass_click_on)
8150 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
8151 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
8156 bd = e_border_find_by_window(ev->event_window);
8159 if (bd->cur_mouse_action)
8160 return ECORE_CALLBACK_DONE;
8161 if (ev->event_window == bd->win)
8163 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
8164 E_OBJECT(bd), ev, NULL))
8165 return ECORE_CALLBACK_PASS_ON;
8169 return ECORE_CALLBACK_DONE;
8173 _e_border_cb_drag_finished(E_Drag *drag,
8174 int dropped __UNUSED__)
8179 e_object_unref(E_OBJECT(bd));
8183 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8185 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
8186 int ev_type __UNUSED__,
8189 E_Event_Desk_Window_Profile_Change *e;
8194 EINA_LIST_FOREACH(borders, l, bd)
8196 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
8198 bd->client.e.fetch.profile_list = 1;
8202 return ECORE_CALLBACK_PASS_ON;
8206 #ifdef _F_ZONE_WINDOW_ROTATION_
8208 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
8209 int ev_type __UNUSED__,
8212 E_Event_Zone_Rotation_Change_Begin *e = ev;
8214 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8215 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
8217 if (!_e_border_rotation_zone_set(e->zone))
8219 /* there is no border which supports window manager rotation */
8220 e_zone_rotation_update_cancel(e->zone);
8222 return ECORE_CALLBACK_PASS_ON;
8226 _e_border_cb_rotation_sync_job(void *data)
8228 E_Zone *zone = data;
8230 E_Border_Rotation_Info *info = NULL;
8232 ELBF(ELBT_ROT, 0, zone->id, "DO ROTATION SYNC_JOB rot.list:%p(%d) wait_prepare_done:%d zone_block_count:%d",
8233 rot.list, eina_list_count(rot.list), rot.wait_prepare_done, zone->rot.block_count);
8236 EINA_LIST_FOREACH(rot.list, l, info)
8237 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
8239 ELBF(ELBT_ROT, 0, zone->id, "SYNC_JOB list(%d) wait_prepare_done:%d zone_block_count:%d",
8240 eina_list_count(rot.list), rot.wait_prepare_done, zone->rot.block_count);
8242 if (!rot.wait_prepare_done)
8244 _e_border_rotation_change_request(zone);
8251 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
8252 ecore_job_del(rot.sync_job);
8253 rot.sync_job = NULL;
8258 _e_border_cb_rotation_async_job(void *data)
8260 E_Zone *zone = data;
8262 if (rot.list) goto end;
8264 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
8266 if (!rot.wait_prepare_done)
8268 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8269 rot.async_list = NULL;
8276 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8277 ecore_job_del(rot.async_job);
8278 rot.async_job = NULL;
8283 _e_border_rotation_change_prepare_timeout(void *data)
8285 E_Zone *zone = data;
8286 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8288 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8290 if ((zone) && (rot.wait_prepare_done))
8294 _e_border_rotation_change_request(zone);
8295 if (rot.prepare_timer)
8296 ecore_timer_del(rot.prepare_timer);
8297 rot.prepare_timer = NULL;
8298 rot.wait_prepare_done = EINA_FALSE;
8301 return ECORE_CALLBACK_CANCEL;
8305 _e_border_rotation_change_request(E_Zone *zone)
8307 if (!e_config->wm_win_rotation) return;
8308 if (!rot.list) return;
8309 if (eina_list_count(rot.list) <= 0) return;
8310 /* pending rotation problem occurred while launching app by the tray */
8311 //if (zone->rot.block_count) return;
8313 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8314 rot.prepare_timer = NULL;
8315 rot.wait_prepare_done = EINA_FALSE;
8317 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8320 ecore_timer_del(rot.done_timer);
8321 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8322 rot.done_timer = ecore_timer_add(5.0f,
8323 _e_border_rotation_change_done_timeout,
8328 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8331 E_Border_Rotation_Info *info =NULL;
8334 EINA_LIST_FOREACH (list, l, info)
8336 if (!info->bd) continue;
8337 if ((info->bd->client.e.state.rot.wait_for_done) &&
8338 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8340 _e_border_event_border_rotation_change_begin_send(info->bd);
8343 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8344 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8346 info->x = x; info->y = y;
8347 info->w = w; info->h = h;
8349 ELBF(ELBT_ROT, 1, info->bd->client.win,
8350 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8351 info->ang, info->win_resize, info->w, info->h);
8354 SECURE_SLOGD("[ROTATION] SEND PREP_ROT, win:0x%08x a%d resize%d %dx%d",
8355 info->bd->client.win, info->ang, info->win_resize,
8359 ecore_x_e_window_rotation_change_prepare_send
8360 (info->bd->client.win, info->ang,
8361 info->win_resize, info->w, info->h);
8363 if (!info->bd->client.e.state.rot.pending_change_request)
8365 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8367 SECURE_SLOGD("[ROTATION] SEND REQ_ROT, win:0x%08x, rot:%d",
8368 info->bd->client.win, info->ang);
8370 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8372 info->bd->client.e.state.rot.wait_for_done = 1;
8373 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8379 EINA_LIST_FREE(list, info)
8385 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8387 E_Border_Rotation_Info *info = NULL;
8389 if (send_request) _e_border_rotation_change_request(zone);
8392 EINA_LIST_FREE(rot.list, info)
8399 _e_border_rotation_list_remove(E_Border *bd)
8401 Eina_List *l = NULL;
8402 E_Border_Rotation_Info *info = NULL;
8403 E_Event_Border_Rotation_Change_End *ev = NULL;
8404 Eina_Bool found = EINA_FALSE;
8406 if (!e_config->wm_win_rotation) return;
8408 EINA_LIST_FOREACH(rot.list, l, info)
8412 rot.list = eina_list_remove(rot.list, info);
8418 if (bd->client.e.state.rot.wait_for_done)
8420 bd->client.e.state.rot.wait_for_done = 0;
8422 /* if we make the border event in the _e_border_free function,
8423 * then we may meet a crash problem, only work this at least e_border_hide.
8425 if (!e_object_is_del(E_OBJECT(bd)))
8427 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8431 e_object_ref(E_OBJECT(bd));
8432 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8434 _e_border_event_border_rotation_change_end_free,
8440 (eina_list_count(rot.list) == 0))
8442 _e_border_rotation_change_done();
8448 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8450 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8451 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8452 _e_border_rotation_change_done();
8453 return ECORE_CALLBACK_CANCEL;
8457 _e_border_rotation_change_done(void)
8459 E_Manager *m = NULL;
8460 E_Border_Rotation_Info *info = NULL;
8462 if (!e_config->wm_win_rotation) return;
8464 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8465 rot.prepare_timer = NULL;
8467 rot.wait_prepare_done = EINA_FALSE;
8469 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8470 rot.done_timer = NULL;
8472 EINA_LIST_FREE(rot.list, info)
8476 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8477 if (info->bd->client.e.state.rot.pending_show)
8479 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8480 e_border_show(info->bd);
8481 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8482 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8483 _e_border_check_stack(info->bd);
8485 info->bd->client.e.state.rot.pending_show = 0;
8487 info->bd->client.e.state.rot.wait_for_done = 0;
8492 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8495 rot.async_list = NULL;
8497 m = e_manager_current_get();
8498 e_manager_comp_screen_unlock(m);
8499 e_zone_rotation_update_done(e_util_zone_current_get(m));
8503 _prev_angle_get(Ecore_X_Window win)
8505 int ret, count = 0, ang = -1;
8506 unsigned char* data = NULL;
8508 ret = ecore_x_window_prop_property_get
8509 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8510 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8512 if ((ret) && (data) && (count))
8513 ang = ((int *)data)[0];
8514 if (data) free(data);
8518 /* get proper rotation value using preferred rotation and list of available rotations */
8520 _e_border_rotation_get(E_Border *bd,
8524 int current_ang = bd->client.e.state.rot.curr;
8526 Eina_Bool found = EINA_FALSE;
8527 Eina_Bool found_curr_ang = EINA_FALSE;
8529 if (!e_config->wm_win_rotation) return ang;
8530 if (!bd->client.e.state.rot.app_set) return ang;
8532 if (bd->client.e.state.rot.preferred_rot != -1)
8534 ang = bd->client.e.state.rot.preferred_rot;
8535 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8537 else if ((bd->client.e.state.rot.available_rots) &&
8538 (bd->client.e.state.rot.count))
8540 for (i = 0; i < bd->client.e.state.rot.count; i++)
8542 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8548 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8549 found_curr_ang = EINA_TRUE;
8552 /* do nothing. this window wants to maintain current state.
8553 * for example, window's available_rots: 0, 90, 270,
8554 * current zone rotation request: 180. the WM does nothing
8559 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8560 ang = bd->client.e.state.rot.curr;
8562 ang = bd->client.e.state.rot.available_rots[0];
8567 /* In this case, border doesn't have a list of
8568 * available rotations, thus WM should request
8569 * rotation with '0' degree to the application.
8578 _e_border_rotation_angle_get(E_Border *bd)
8580 E_Zone *zone = bd->zone;
8585 if (!e_config->wm_win_rotation) return ret;
8586 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8588 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8590 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8591 // should follow the state of rotation of zone.
8593 (bd->parent->visible) &&
8594 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8595 will_ang = bd->parent->client.e.state.rot.curr;
8596 else will_ang = zone->rot.curr;
8598 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8600 ELBF(ELBT_ROT, 1, bd->client.win,
8601 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8602 (rot.vkbd == bd) ? "vkbd" : "prediction",
8603 bd->parent ? bd->parent->client.win : 0,
8604 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8605 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8606 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8610 will_ang = bd->parent->client.e.state.rot.curr;
8611 if ((!bd->parent->client.e.state.rot.support) &&
8612 (!bd->parent->client.e.state.rot.app_set))
8619 if ((!bd->client.e.state.rot.app_set) &&
8620 (!bd->client.e.state.rot.support))
8622 /* hack for magnifier and keyboard popup */
8623 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8624 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8626 ELB(ELBT_BD, "MAG", bd->client.win);
8628 if ((rot.vkbd) && (rot.vkbd->visible))
8629 will_ang = rot.vkbd->client.e.state.rot.curr;
8633 if (bd->client.e.state.rot.app_set)
8635 /* utility type window should be rotated according to
8636 * rotation of the transient_for window.
8639 (bd->parent->visible) &&
8640 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8642 will_ang = bd->parent->client.e.state.rot.curr;
8643 if ((!bd->parent->client.e.state.rot.support) &&
8644 (!bd->parent->client.e.state.rot.app_set))
8646 /* if transient_for window doesn't support rotation feature,
8647 * then this window should't be rotated.
8648 * TODO: need to check whether window supports '0' degree or not.
8651 ELBF(ELBT_ROT, 0, bd->client.win,
8652 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8653 will_ang, bd->parent->client.win);
8657 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8658 ELBF(ELBT_ROT, 0, bd->client.win,
8659 "GET ROT ang:%d Transient_For:0x%08x",
8660 will_ang, bd->parent->client.win);
8665 will_ang = _e_border_rotation_get(bd, will_ang);
8666 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8667 will_ang, bd->parent ? bd->parent->client.win : 0,
8668 bd->client.netwm.type);
8674 _ang = _prev_angle_get(bd->client.win);
8676 bd->client.e.state.rot.curr = _ang;
8677 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8680 if (bd->client.e.state.rot.curr != will_ang)
8688 _e_border_rotation_zone_set(E_Zone *zone)
8690 E_Border_List *l = NULL;
8691 E_Border *bd = NULL;
8692 Eina_Bool ret = EINA_FALSE;
8694 if (!e_config->wm_win_rotation) return EINA_FALSE;
8696 l = e_container_border_list_last(zone->container);
8699 /* step 1. make the list needs to be rotated. */
8700 while ((bd = e_container_border_list_prev(l)))
8704 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8705 // it will be rotated when parent do rotate itself.
8708 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8710 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8711 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8712 // if it's not normal type window, will be rotated by illume.
8714 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8716 if ((!bd->visible) ||
8717 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8718 bd->x, bd->y, bd->w, bd->h))) continue;
8720 if (_e_border_rotatable_check(bd, zone->rot.curr))
8722 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8723 bd->client.e.state.rot.curr, zone->rot.curr);
8725 ret = e_border_rotation_set(bd, zone->rot.curr);
8728 if (l) e_container_border_list_free(l);
8734 _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
8736 E_Zone *zone = bd->zone;
8737 E_Border_Rotation_Info *info = NULL;
8738 Eina_List *list, *l;
8741 if (rotation < 0) return EINA_FALSE;
8742 if (pending) *pending = EINA_FALSE;
8744 /* step 1. check if rotation */
8745 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8747 /* step 2. add to async/sync list */
8748 if ((!zone->rot.block_count) &&
8749 (!bd->client.e.state.deiconify_approve.pending_bd) &&
8751 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8753 // send rotation change request later.
8754 // and no need to wait message of rotation done.
8757 info = E_NEW(E_Border_Rotation_Info, 1);
8758 if (!info) return EINA_FALSE;
8759 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8761 info->ang = rotation;
8762 rot.async_list = eina_list_append(rot.async_list, info);
8764 // add job for sending event.
8767 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8768 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8774 info = E_NEW(E_Border_Rotation_Info, 1);
8775 if (!info) return EINA_FALSE;
8776 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8778 info->ang = rotation;
8779 rot.list = eina_list_append(rot.list, info);
8781 // add job for sending event.
8784 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8785 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8788 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8790 // but, DO NOT lock the screen when rotation block state.
8791 if ((!zone->rot.block_count) &&
8792 ((eina_list_count(rot.list) == 2)))
8793 e_manager_comp_screen_lock(e_manager_current_get());
8796 if (pending) *pending = EINA_TRUE;
8798 /* step 3. search rotatable window in this window's child */
8799 list = _e_border_sub_borders_new(bd);
8800 EINA_LIST_FOREACH(list, l, child)
8802 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8803 // it shouldn't be rotated by rotation state of parent window.
8804 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8805 if (_e_border_rotatable_check(child, rotation))
8807 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8808 bd->client.e.state.rot.curr, rotation);
8809 e_border_rotation_set(child, rotation);
8813 /* step 4. if there is vkbd window, send message to prepare rotation */
8814 if (_e_border_is_vkbd(bd))
8816 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8817 if (rot.prepare_timer)
8818 ecore_timer_del(rot.prepare_timer);
8819 rot.prepare_timer = NULL;
8822 ecore_timer_del(rot.done_timer);
8823 rot.done_timer = NULL;
8825 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8826 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8829 rot.prepare_timer = ecore_timer_add(4.0f,
8830 _e_border_rotation_change_prepare_timeout,
8833 rot.wait_prepare_done = EINA_TRUE;
8836 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8837 bd->client.e.state.rot.curr = rotation;
8842 // check if border is rotatable in ang.
8844 _e_border_rotatable_check(E_Border *bd, int ang)
8846 Eina_Bool ret = EINA_FALSE;
8848 if (!bd) return ret;
8849 if (ang < 0) return ret;
8850 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8851 if (e_object_is_del(E_OBJECT(bd))) return ret;
8853 // same with current angle of window, then false return.
8854 if (ang == bd->client.e.state.rot.curr) return ret;
8856 /* basically WM allows only fullscreen window to rotate */
8857 if (bd->client.e.state.rot.preferred_rot == -1)
8861 if (bd->client.e.state.rot.app_set)
8863 if (bd->client.e.state.rot.available_rots &&
8864 bd->client.e.state.rot.count)
8866 Eina_Bool found = EINA_FALSE;
8867 for (i = 0; i < bd->client.e.state.rot.count; i++)
8869 if (bd->client.e.state.rot.available_rots[i] == ang)
8874 if (found) ret = EINA_TRUE;
8879 ELB(ELBT_ROT, "DO ROT", 0);
8883 // if it has preferred rotation angle,
8884 // it will be rotated at border's evaluation time.
8886 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8891 /* check whether virtual keyboard is visible on the zone */
8893 _e_border_is_vkbd(E_Border *bd)
8895 if (!e_config->wm_win_rotation) return EINA_FALSE;
8897 if ((rot.vkbd_ctrl_win) &&
8899 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8900 (rot.vkbd->zone == bd->zone) &&
8901 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8902 bd->zone->w, bd->zone->h,
8903 rot.vkbd->x, rot.vkbd->y,
8904 rot.vkbd->w, rot.vkbd->h)))
8912 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8915 int min_title_width=96;
8917 if (!bd) return EINA_FALSE;
8918 if (!x || !y) return EINA_FALSE;
8923 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8924 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8925 // guaranteeing the minimum size of titlebar shown, min_title_width
8926 // so user can initiate drag&drop action after rotation changed.
8927 if (bd->client.e.state.rot.curr == 0)
8929 if (bd->client.e.state.rot.prev == 90)
8931 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8934 else if (bd->client.e.state.rot.prev == 270)
8937 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8939 else if (bd->client.e.state.rot.prev == 180)
8941 new_x = bd->zone->w - bd->x - bd->w;
8942 new_y = bd->zone->h - bd->y - bd->h;
8945 if(new_x + bd->w < min_title_width)
8947 new_x = min_title_width - bd->w;
8949 else if(new_x > bd->zone->w - min_title_width)
8951 new_x = bd->zone->w - min_title_width;
8954 else if (bd->client.e.state.rot.curr == 90)
8956 if (bd->client.e.state.rot.prev == 0)
8959 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8961 else if (bd->client.e.state.rot.prev == 270)
8963 new_x = bd->zone->w - bd->x - bd->w;
8964 new_y = bd->zone->h - bd->y - bd->h;
8966 else if (bd->client.e.state.rot.prev == 180)
8968 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8969 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8972 if(new_y > bd->zone->h - min_title_width)
8974 new_y = bd->zone->h - min_title_width;
8976 else if(new_y < min_title_width - bd->w)
8978 new_y = min_title_width - bd->w;
8981 else if (bd->client.e.state.rot.curr == 270)
8983 if (bd->client.e.state.rot.prev == 0)
8985 new_x = bd->zone->w - bd->h - (bd->y / 2);
8988 else if (bd->client.e.state.rot.prev == 90)
8990 new_x = bd->zone->w - bd->x - bd->w;
8991 new_y = bd->zone->h - bd->y - bd->h;
8993 else if (bd->client.e.state.rot.prev == 180)
8995 new_x = bd->zone->w - bd->x - bd->w;
8996 new_y = bd->zone->h - bd->y - bd->h;
8998 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8999 new_y = (bd->zone->w - bd->x - bd->w) * 2;
9002 if(new_y > bd->zone->h - min_title_width)
9004 new_y = bd->zone->h - min_title_width;
9006 else if( new_y + bd->w < min_title_width)
9008 new_y = min_title_width - bd->w ;
9011 else if (bd->client.e.state.rot.curr == 180)
9013 if (bd->client.e.state.rot.prev == 0)
9015 new_x = bd->zone->w - bd->x - bd->w;
9016 new_y = bd->zone->h - bd->y - bd->h;
9018 else if (bd->client.e.state.rot.prev == 90)
9020 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
9021 new_y = bd->zone->h - (2 * bd->x) - bd->w;
9023 else if (bd->client.e.state.rot.prev == 270)
9025 new_x = bd->zone->w - (bd->y / 2) - bd->h;
9026 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
9029 if(new_x + bd->w < min_title_width)
9031 new_x = min_title_width - bd->w;
9033 else if(new_x > bd->zone->w - min_title_width)
9035 new_x = bd->zone->w - min_title_width;
9039 ELBF(ELBT_ROT, 0, bd->client.win,
9040 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
9041 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
9042 bd->x, bd->y, new_x, new_y);
9044 if ((new_x == *x) &&
9056 #define SIZE_EQUAL_TO_ZONE(a, z) \
9057 ((((a)->w) == ((z)->w)) && \
9058 (((a)->h) == ((z)->h)))
9060 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
9062 E_Zone *zone = bd->zone;
9065 Eina_Bool move = EINA_FALSE;
9066 Eina_Bool hint = EINA_FALSE;
9067 Eina_Bool resize = EINA_FALSE;
9074 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
9076 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
9077 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
9078 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
9080 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
9081 &_x, &_y, &_w, &_h, &move);
9084 if (((move) && ((bd->x !=_x) || (bd->y !=_y))) ||
9085 (bd->w != _w) || (bd->h != _h))
9088 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
9089 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d resize:%d",
9090 bd->client.icccm.name, _x, _y, _w, _h, resize);
9095 _x = bd->x; _y = bd->y;
9096 _w = bd->w; _h = bd->h;
9098 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
9099 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
9103 rot_dif = bd->client.e.state.rot.prev - rotation;
9104 if (rot_dif < 0) rot_dif = -rot_dif;
9113 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
9114 EINA_TRUE, EINA_TRUE);
9115 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
9116 bd->client.icccm.name, _x, _y, _w, _h);
9121 if (!resize && move)
9122 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
9137 _e_border_cb_window_configure(void *data __UNUSED__,
9138 int ev_type __UNUSED__,
9141 Ecore_X_Event_Window_Configure *e = ev;
9142 E_Border_Rotation_Info *info = NULL;
9144 Eina_Bool found = EINA_FALSE;
9146 if (!e) return ECORE_CALLBACK_PASS_ON;
9147 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
9149 E_Border *bd = e_border_find_by_client_window(e->win);
9150 if (!bd) return ECORE_CALLBACK_PASS_ON;
9152 if (bd->client.e.state.rot.pending_change_request)
9154 if ((e->w == bd->w) && (e->h == bd->h))
9156 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
9157 bd->client.e.state.rot.pending_change_request = 0;
9159 if ((bd->client.e.state.rot.wait_for_done) &&
9160 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
9162 EINA_LIST_FOREACH(rot.list, l, info)
9163 if (info->bd == bd) found = EINA_TRUE;
9164 // send request message if it's async rotation window,
9165 // even if wait prepare done.
9166 if ((found) && (rot.wait_prepare_done)) goto end;
9168 ELBF(ELBT_ROT, 0, bd->client.win,
9169 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
9170 bd->client.e.state.rot.curr,
9173 SECURE_SLOGD("[ROTATION] SEND REQ_ROT(CONFIGURE_NOTI), win:0x%08x, rot:%d",
9174 bd->client.win, bd->client.e.state.rot.curr);
9176 ecore_x_e_window_rotation_change_request_send(bd->client.win,
9177 bd->client.e.state.rot.curr);
9178 bd->client.e.state.rot.wait_for_done = 1;
9179 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
9184 return ECORE_CALLBACK_PASS_ON;
9188 _e_border_rotation_geom_get(E_Border *bd,
9197 if (!e_config->wm_win_rotation) return EINA_FALSE;
9199 Eina_Bool res = EINA_FALSE;
9200 Eina_Bool _move = EINA_TRUE;
9210 if (move) *move = EINA_TRUE;
9212 if (bd->client.e.state.rot.geom_hint)
9217 _w = bd->client.e.state.rot.geom[0].w;
9218 _h = bd->client.e.state.rot.geom[0].h;
9219 if (_w == 0) _w = bd->w;
9220 if (_h == 0) _h = bd->h;
9221 _x = 0; _y = zone->h - _h;
9224 _w = bd->client.e.state.rot.geom[1].w;
9225 _h = bd->client.e.state.rot.geom[1].h;
9226 if (_w == 0) _w = bd->w;
9227 if (_h == 0) _h = bd->h;
9228 _x = zone->w - _w; _y = 0;
9231 _w = bd->client.e.state.rot.geom[2].w;
9232 _h = bd->client.e.state.rot.geom[2].h;
9233 if (_w == 0) _w = bd->w;
9234 if (_h == 0) _h = bd->h;
9238 _w = bd->client.e.state.rot.geom[3].w;
9239 _h = bd->client.e.state.rot.geom[3].h;
9240 if (_w == 0) _w = bd->w;
9241 if (_h == 0) _h = bd->h;
9251 if (!((rot.vkbd) && (rot.vkbd == bd)))
9255 if (move) *move = EINA_FALSE;
9263 _x = 0; _y = 0; _w = 0; _h = 0;
9268 if (move) _move = *move;
9270 ELBF(ELBT_ROT, 1, bd->client.win,
9271 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
9272 ang, _x, _y, _w, _h, _move);
9280 _e_border_post_move_resize_job(void *data)
9284 bd = (E_Border *)data;
9290 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9291 ecore_x_window_move(tmp->win,
9293 bd->client_inset.l +
9295 tmp->client.e.state.video_position.x,
9297 bd->client_inset.t +
9299 tmp->client.e.state.video_position.y);
9301 if (bd->client.e.state.video)
9305 parent = bd->client.e.state.video_parent_border;
9306 ecore_x_window_move(bd->win,
9308 parent->client_inset.l +
9310 bd->client.e.state.video_position.x,
9312 parent->client_inset.t +
9314 bd->client.e.state.video_position.y);
9316 else if ((bd->post_move) && (bd->post_resize))
9318 ecore_x_window_move_resize(bd->win,
9323 else if (bd->post_move)
9325 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9327 else if (bd->post_resize)
9329 ecore_x_window_resize(bd->win, bd->w, bd->h);
9332 if (bd->client.e.state.video)
9334 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9336 bd->client.e.state.video_parent_border->x +
9337 bd->client.e.state.video_parent_border->client_inset.l +
9338 bd->client.e.state.video_parent_border->fx.x +
9339 bd->client.e.state.video_position.x,
9340 bd->client.e.state.video_parent_border->y +
9341 bd->client.e.state.video_parent_border->client_inset.t +
9342 bd->client.e.state.video_parent_border->fx.y +
9343 bd->client.e.state.video_position.y,
9351 bd->post_job = NULL;
9357 bd->post_resize = 0;
9358 bd->post_job = NULL;
9359 return ECORE_CALLBACK_CANCEL;
9363 _e_border_container_layout_hook(E_Container *con)
9365 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9369 _e_border_eval0(E_Border *bd)
9371 int change_urgent = 0;
9373 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9374 Eina_Bool need_desk_set = EINA_FALSE;
9376 #ifdef _F_ZONE_WINDOW_ROTATION_
9377 Eina_Bool need_rotation_set = EINA_FALSE;
9379 if ((e_config->wm_win_rotation) &&
9380 (bd->client.icccm.fetch.transient_for))
9382 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9383 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9385 need_rotation_set = EINA_TRUE;
9386 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9391 if (e_object_is_del(E_OBJECT(bd)))
9393 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9398 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9400 bd->changes.border = 0;
9402 /* fetch any info queued to be fetched */
9403 if (bd->client.netwm.fetch.state)
9405 e_hints_window_state_get(bd);
9406 bd->client.netwm.fetch.state = 0;
9409 if (bd->client.icccm.fetch.client_leader)
9411 /* TODO: What do to if the client leader isn't mapped yet? */
9412 E_Border *bd_leader = NULL;
9414 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9415 if (bd->client.icccm.client_leader)
9416 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9419 if (bd->leader != bd_leader)
9421 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9422 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9428 /* If this border is the leader of the group, don't register itself */
9429 if ((bd_leader) && (bd_leader != bd))
9431 bd_leader->group = eina_list_append(bd_leader->group, bd);
9432 bd->leader = bd_leader;
9433 /* Only set the window modal to the leader it there is no parent */
9434 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9435 ((!bd->parent) || (bd->parent->modal != bd)))
9437 bd->leader->modal = bd;
9438 if (bd->leader->focused)
9439 e_border_focus_set(bd, 1, 1);
9445 EINA_LIST_FOREACH(bd->leader->group, l, child)
9447 if ((child != bd) && (child->focused))
9448 e_border_focus_set(bd, 1, 1);
9453 bd->client.icccm.fetch.client_leader = 0;
9456 if (bd->client.icccm.fetch.title)
9458 char *title = ecore_x_icccm_title_get(bd->client.win);
9459 eina_stringshare_replace(&bd->client.icccm.title, title);
9460 if (title) free(title);
9463 edje_object_part_text_set(bd->bg_object, "e.text.title",
9464 bd->client.icccm.title);
9465 bd->client.icccm.fetch.title = 0;
9468 if (bd->client.netwm.fetch.name)
9471 ecore_x_netwm_name_get(bd->client.win, &name);
9472 eina_stringshare_replace(&bd->client.netwm.name, name);
9473 if (name) free(name);
9476 edje_object_part_text_set(bd->bg_object, "e.text.title",
9477 bd->client.netwm.name);
9478 bd->client.netwm.fetch.name = 0;
9481 if (bd->client.icccm.fetch.name_class)
9483 const char *pname, *pclass;
9484 char *nname, *nclass;
9486 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9487 pname = bd->client.icccm.name;
9488 pclass = bd->client.icccm.class;
9489 bd->client.icccm.name = eina_stringshare_add(nname);
9490 bd->client.icccm.class = eina_stringshare_add(nclass);
9491 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9492 e_bindings_mapping_change_enable(EINA_FALSE);
9493 #ifdef _F_ZONE_WINDOW_ROTATION_
9494 if (e_config->wm_win_rotation)
9496 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9498 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9499 (!strcmp(bd->client.icccm.class, "ISF")))
9501 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9502 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9505 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9506 (!strcmp(bd->client.icccm.class, "ISF")))
9508 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9509 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9510 rot.vkbd_prediction = bd;
9512 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9513 (!strcmp(bd->client.icccm.class, "ISF")))
9515 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9516 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9518 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9519 (!strcmp(bd->client.icccm.class, "ISF")))
9521 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9522 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9527 if (nname) free(nname);
9528 if (nclass) free(nclass);
9530 if (!((bd->client.icccm.name == pname) &&
9531 (bd->client.icccm.class == pclass)))
9532 bd->changes.icon = 1;
9534 if (pname) eina_stringshare_del(pname);
9535 if (pclass) eina_stringshare_del(pclass);
9536 bd->client.icccm.fetch.name_class = 0;
9537 bd->changes.icon = 1;
9540 if (bd->client.icccm.fetch.state)
9542 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9543 bd->client.icccm.fetch.state = 0;
9546 if (bd->client.e.fetch.state)
9548 e_hints_window_e_state_get(bd);
9549 bd->client.e.fetch.state = 0;
9552 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9553 if (bd->client.e.fetch.profile_list)
9555 const char **profiles = NULL;
9559 if (bd->client.e.state.profile)
9560 eina_stringshare_del(bd->client.e.state.profile);
9561 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9563 if (str) eina_stringshare_del(str);
9565 bd->client.e.state.profile = NULL;
9566 bd->client.e.state.profiles = NULL;
9567 bd->client.e.state.profile_list = 0;
9569 if (ecore_x_e_window_profile_list_get(bd->client.win,
9572 bd->client.e.state.profile_list = 1;
9573 for (i = 0; i < num; i++)
9575 str = eina_stringshare_add(profiles[i]);
9576 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9579 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9580 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9582 need_desk_set = EINA_TRUE;
9586 if (strcmp(bd->desk->window_profile,
9587 e_config->desktop_default_window_profile) != 0)
9589 ecore_x_e_window_profile_set(bd->client.win,
9590 bd->desk->window_profile);
9596 for (i = 0; i < num; i++)
9597 if (profiles[i]) free(profiles[i]);
9601 bd->client.e.fetch.profile_list = 0;
9604 #ifdef _F_ZONE_WINDOW_ROTATION_
9605 if ((e_config->wm_win_rotation) &&
9606 (bd->client.e.fetch.rot.support))
9609 unsigned int support = 0;
9611 ret = ecore_x_window_prop_card32_get
9613 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9616 bd->client.e.state.rot.support = 0;
9617 if ((ret == 1) && (support == 1))
9618 bd->client.e.state.rot.support = 1;
9620 if (bd->client.e.state.rot.support)
9621 need_rotation_set = EINA_TRUE;
9623 bd->client.e.fetch.rot.support = 0;
9625 if ((e_config->wm_win_rotation) &&
9626 (bd->client.e.fetch.rot.geom_hint))
9628 Eina_Rectangle r[4];
9630 bd->client.e.state.rot.geom_hint = 0;
9631 for (i = 0; i < 4; i++)
9633 r[i].x = bd->client.e.state.rot.geom[i].x;
9634 r[i].y = bd->client.e.state.rot.geom[i].y;
9635 r[i].w = bd->client.e.state.rot.geom[i].w;
9636 r[i].h = bd->client.e.state.rot.geom[i].h;
9638 bd->client.e.state.rot.geom[i].x = 0;
9639 bd->client.e.state.rot.geom[i].y = 0;
9640 bd->client.e.state.rot.geom[i].w = 0;
9641 bd->client.e.state.rot.geom[i].h = 0;
9644 for (i = 0; i < 4; i++)
9646 x = 0; y = 0; w = 0; h = 0;
9647 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9649 bd->client.e.state.rot.geom_hint = 1;
9650 bd->client.e.state.rot.geom[i].x = x;
9651 bd->client.e.state.rot.geom[i].y = y;
9652 bd->client.e.state.rot.geom[i].w = w;
9653 bd->client.e.state.rot.geom[i].h = h;
9655 if (!((r[i].x == x) && (r[i].y == y) &&
9656 (r[i].w == w) && (r[i].h == h)))
9658 need_rotation_set = EINA_TRUE;
9662 bd->client.e.fetch.rot.geom_hint = 0;
9664 if ((e_config->wm_win_rotation) &&
9665 (bd->client.e.fetch.rot.app_set))
9667 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9668 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9669 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9671 if (_prev_app_set != bd->client.e.state.rot.app_set)
9672 need_rotation_set = EINA_TRUE;
9674 bd->client.e.fetch.rot.app_set = 0;
9676 if ((e_config->wm_win_rotation) &&
9677 (bd->client.e.fetch.rot.preferred_rot))
9679 int r = 0, _prev_preferred_rot;
9680 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9681 bd->client.e.state.rot.preferred_rot = -1;
9682 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9684 bd->client.e.state.rot.preferred_rot = r;
9685 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9689 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9692 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9693 need_rotation_set = EINA_TRUE;
9695 bd->client.e.fetch.rot.preferred_rot = 0;
9697 if ((e_config->wm_win_rotation) &&
9698 (bd->client.e.fetch.rot.available_rots))
9700 Eina_Bool res, diff = EINA_FALSE;
9702 unsigned int count = 0, i = 0;
9703 int _prev_rots[4] = { -1, };
9705 if (bd->client.e.state.rot.available_rots)
9708 bd->client.e.state.rot.available_rots,
9709 (sizeof(int) * bd->client.e.state.rot.count));
9711 E_FREE(bd->client.e.state.rot.available_rots);
9714 bd->client.e.state.rot.count = 0;
9716 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9718 if ((res) && (count > 0) && (rots))
9720 bd->client.e.state.rot.available_rots = rots;
9721 bd->client.e.state.rot.count = count;
9723 for (i = 0; i < count; i++)
9725 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9726 if ((!diff) && (_prev_rots[i] != rots[i]))
9728 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9729 count, i, _prev_rots[i], rots[i]);
9736 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9740 if (diff) need_rotation_set = EINA_TRUE;
9741 bd->client.e.fetch.rot.available_rots = 0;
9744 if (bd->client.netwm.fetch.type)
9746 e_hints_window_type_get(bd);
9747 if ((!bd->lock_border) || (!bd->client.border.name))
9748 bd->client.border.changed = 1;
9750 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9752 if (!bd->client.netwm.state.skip_pager)
9754 bd->client.netwm.state.skip_pager = 1;
9755 bd->client.netwm.update.state = 1;
9757 if (!bd->client.netwm.state.skip_taskbar)
9759 bd->client.netwm.state.skip_taskbar = 1;
9760 bd->client.netwm.update.state = 1;
9763 bd->client.netwm.fetch.type = 0;
9765 if (bd->client.icccm.fetch.machine)
9767 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9769 if ((!machine) && (bd->client.icccm.client_leader))
9770 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9772 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9773 if (machine) free(machine);
9775 bd->client.icccm.fetch.machine = 0;
9778 if (bd->client.icccm.fetch.command)
9780 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9784 for (i = 0; i < bd->client.icccm.command.argc; i++)
9785 free(bd->client.icccm.command.argv[i]);
9786 free(bd->client.icccm.command.argv);
9788 bd->client.icccm.command.argc = 0;
9789 bd->client.icccm.command.argv = NULL;
9790 ecore_x_icccm_command_get(bd->client.win,
9791 &(bd->client.icccm.command.argc),
9792 &(bd->client.icccm.command.argv));
9793 if ((bd->client.icccm.client_leader) &&
9794 (!bd->client.icccm.command.argv))
9795 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9796 &(bd->client.icccm.command.argc),
9797 &(bd->client.icccm.command.argv));
9798 bd->client.icccm.fetch.command = 0;
9801 if (bd->client.icccm.fetch.hints)
9803 Eina_Bool accepts_focus, is_urgent;
9805 accepts_focus = EINA_TRUE;
9806 is_urgent = EINA_FALSE;
9807 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9808 if (ecore_x_icccm_hints_get(bd->client.win,
9810 &bd->client.icccm.initial_state,
9811 &bd->client.icccm.icon_pixmap,
9812 &bd->client.icccm.icon_mask,
9813 &bd->client.icccm.icon_window,
9814 &bd->client.icccm.window_group,
9817 bd->client.icccm.accepts_focus = accepts_focus;
9818 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9820 bd->client.icccm.urgent = is_urgent;
9822 /* If this is a new window, set the state as requested. */
9823 if ((bd->new_client) &&
9824 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9826 e_border_iconify(bd);
9827 e_border_hide(bd, 1);
9830 bd->client.icccm.fetch.hints = 0;
9833 if (bd->client.icccm.fetch.size_pos_hints)
9835 Eina_Bool request_pos;
9837 request_pos = EINA_FALSE;
9838 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9840 &bd->client.icccm.gravity,
9841 &bd->client.icccm.min_w,
9842 &bd->client.icccm.min_h,
9843 &bd->client.icccm.max_w,
9844 &bd->client.icccm.max_h,
9845 &bd->client.icccm.base_w,
9846 &bd->client.icccm.base_h,
9847 &bd->client.icccm.step_w,
9848 &bd->client.icccm.step_h,
9849 &bd->client.icccm.min_aspect,
9850 &bd->client.icccm.max_aspect))
9852 bd->client.icccm.request_pos = request_pos;
9857 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9858 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9859 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9860 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9861 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9862 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9863 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9864 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9865 // if doing a resize, fix it up
9866 if (bd->resize_mode != RESIZE_NONE)
9868 int x, y, w, h, new_w, new_h;
9876 e_border_resize_limit(bd, &new_w, &new_h);
9877 if ((bd->resize_mode == RESIZE_TL) ||
9878 (bd->resize_mode == RESIZE_L) ||
9879 (bd->resize_mode == RESIZE_BL))
9881 if ((bd->resize_mode == RESIZE_TL) ||
9882 (bd->resize_mode == RESIZE_T) ||
9883 (bd->resize_mode == RESIZE_TR))
9885 e_border_move_resize(bd, x, y, new_w, new_h);
9887 bd->client.icccm.fetch.size_pos_hints = 0;
9890 if (bd->client.icccm.fetch.protocol)
9893 Ecore_X_WM_Protocol *proto;
9895 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9898 for (i = 0; i < num; i++)
9900 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9901 bd->client.icccm.delete_request = 1;
9902 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9903 bd->client.icccm.take_focus = 1;
9904 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9905 bd->client.netwm.ping = 1;
9906 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9908 bd->client.netwm.sync.request = 1;
9909 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9910 &bd->client.netwm.sync.counter))
9911 bd->client.netwm.sync.request = 0;
9916 if (bd->client.netwm.ping)
9920 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9921 bd->ping_poller = NULL;
9923 bd->client.icccm.fetch.protocol = 0;
9925 if (bd->client.icccm.fetch.transient_for)
9927 /* TODO: What do to if the transient for isn't mapped yet? */
9928 E_Border *bd_parent = NULL;
9929 #ifdef _F_DEICONIFY_APPROVE_
9930 Eina_Bool change_parent = EINA_FALSE;
9933 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9934 if (bd->client.icccm.transient_for)
9935 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9936 /* If we already have a parent, remove it */
9939 if (bd_parent != bd->parent)
9941 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9942 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9948 if ((bd_parent) && (bd_parent != bd) &&
9949 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9951 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9952 bd->parent = bd_parent;
9953 #ifdef _F_DEICONIFY_APPROVE_
9954 change_parent = EINA_TRUE;
9959 e_border_layer_set(bd, bd->parent->layer);
9960 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9962 Ecore_X_Window_Attributes attr;
9963 bd->parent->modal = bd;
9964 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9965 bd->parent->saved.event_mask = attr.event_mask.mine;
9966 bd->parent->lock_close = 1;
9967 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9968 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9971 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9972 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9976 #ifdef _F_DEICONIFY_APPROVE_
9979 bd->client.e.state.deiconify_approve.render_done = 0;
9981 E_Border *ancestor_bd;
9982 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9983 if ((ancestor_bd) &&
9984 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9986 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9987 bd->client.e.state.deiconify_approve.ancestor = NULL;
9989 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9990 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9992 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9994 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9995 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9996 e_border_uniconify(ancestor_bd);
10002 bd->client.icccm.fetch.transient_for = 0;
10005 if (bd->client.icccm.fetch.window_role)
10007 char *role = ecore_x_icccm_window_role_get(bd->client.win);
10008 eina_stringshare_replace(&bd->client.icccm.window_role, role);
10009 if (role) free(role);
10011 bd->client.icccm.fetch.window_role = 0;
10014 if (bd->client.icccm.fetch.icon_name)
10016 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
10017 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
10018 if (icon_name) free(icon_name);
10020 bd->client.icccm.fetch.icon_name = 0;
10023 if (bd->client.netwm.fetch.icon_name)
10026 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
10027 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
10028 if (icon_name) free(icon_name);
10030 bd->client.netwm.fetch.icon_name = 0;
10033 if (bd->client.netwm.fetch.icon)
10036 if (bd->client.netwm.icons)
10038 for (i = 0; i < bd->client.netwm.num_icons; i++)
10040 free(bd->client.netwm.icons[i].data);
10041 bd->client.netwm.icons[i].data = NULL;
10043 free(bd->client.netwm.icons);
10045 bd->client.netwm.icons = NULL;
10046 bd->client.netwm.num_icons = 0;
10047 if (ecore_x_netwm_icons_get(bd->client.win,
10048 &bd->client.netwm.icons,
10049 &bd->client.netwm.num_icons))
10051 // unless the rest of e17 uses border icons OTHER than icon #0
10052 // then free the rest that we don't need anymore.
10053 for (i = 1; i < bd->client.netwm.num_icons; i++)
10055 free(bd->client.netwm.icons[i].data);
10056 bd->client.netwm.icons[i].data = NULL;
10058 bd->client.netwm.num_icons = 1;
10059 bd->changes.icon = 1;
10061 bd->client.netwm.fetch.icon = 0;
10063 if (bd->client.netwm.fetch.user_time)
10065 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
10066 bd->client.netwm.fetch.user_time = 0;
10068 if (bd->client.netwm.fetch.strut)
10070 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
10071 &bd->client.netwm.strut.left,
10072 &bd->client.netwm.strut.right,
10073 &bd->client.netwm.strut.top,
10074 &bd->client.netwm.strut.bottom,
10075 &bd->client.netwm.strut.left_start_y,
10076 &bd->client.netwm.strut.left_end_y,
10077 &bd->client.netwm.strut.right_start_y,
10078 &bd->client.netwm.strut.right_end_y,
10079 &bd->client.netwm.strut.top_start_x,
10080 &bd->client.netwm.strut.top_end_x,
10081 &bd->client.netwm.strut.bottom_start_x,
10082 &bd->client.netwm.strut.bottom_end_x))
10084 ecore_x_netwm_strut_get(bd->client.win,
10085 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
10086 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
10088 bd->client.netwm.strut.left_start_y = 0;
10089 bd->client.netwm.strut.left_end_y = 0;
10090 bd->client.netwm.strut.right_start_y = 0;
10091 bd->client.netwm.strut.right_end_y = 0;
10092 bd->client.netwm.strut.top_start_x = 0;
10093 bd->client.netwm.strut.top_end_x = 0;
10094 bd->client.netwm.strut.bottom_start_x = 0;
10095 bd->client.netwm.strut.bottom_end_x = 0;
10097 bd->client.netwm.fetch.strut = 0;
10099 if (bd->client.qtopia.fetch.soft_menu)
10101 e_hints_window_qtopia_soft_menu_get(bd);
10102 bd->client.qtopia.fetch.soft_menu = 0;
10105 if (bd->client.qtopia.fetch.soft_menus)
10107 e_hints_window_qtopia_soft_menus_get(bd);
10108 bd->client.qtopia.fetch.soft_menus = 0;
10111 if (bd->client.vkbd.fetch.state)
10113 e_hints_window_virtual_keyboard_state_get(bd);
10114 bd->client.vkbd.fetch.state = 0;
10117 if (bd->client.vkbd.fetch.vkbd)
10119 e_hints_window_virtual_keyboard_get(bd);
10120 bd->client.vkbd.fetch.vkbd = 0;
10123 if (bd->client.illume.conformant.fetch.conformant)
10125 bd->client.illume.conformant.conformant =
10126 ecore_x_e_illume_conformant_get(bd->client.win);
10127 bd->client.illume.conformant.fetch.conformant = 0;
10129 if (bd->client.illume.quickpanel.fetch.state)
10131 bd->client.illume.quickpanel.state =
10132 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
10133 bd->client.illume.quickpanel.fetch.state = 0;
10135 if (bd->client.illume.quickpanel.fetch.quickpanel)
10137 bd->client.illume.quickpanel.quickpanel =
10138 ecore_x_e_illume_quickpanel_get(bd->client.win);
10139 bd->client.illume.quickpanel.fetch.quickpanel = 0;
10141 if (bd->client.illume.quickpanel.fetch.priority.major)
10143 bd->client.illume.quickpanel.priority.major =
10144 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
10145 bd->client.illume.quickpanel.fetch.priority.major = 0;
10147 if (bd->client.illume.quickpanel.fetch.priority.minor)
10149 bd->client.illume.quickpanel.priority.minor =
10150 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
10151 bd->client.illume.quickpanel.fetch.priority.minor = 0;
10153 if (bd->client.illume.quickpanel.fetch.zone)
10155 bd->client.illume.quickpanel.zone =
10156 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
10157 bd->client.illume.quickpanel.fetch.zone = 0;
10159 if (bd->client.illume.drag.fetch.drag)
10161 bd->client.illume.drag.drag =
10162 ecore_x_e_illume_drag_get(bd->client.win);
10163 bd->client.illume.drag.fetch.drag = 0;
10165 if (bd->client.illume.drag.fetch.locked)
10167 bd->client.illume.drag.locked =
10168 ecore_x_e_illume_drag_locked_get(bd->client.win);
10169 bd->client.illume.drag.fetch.locked = 0;
10171 if (bd->client.illume.win_state.fetch.state)
10173 bd->client.illume.win_state.state =
10174 ecore_x_e_illume_window_state_get(bd->client.win);
10175 bd->client.illume.win_state.fetch.state = 0;
10176 #ifdef _F_ZONE_WINDOW_ROTATION_
10177 /* E should rotate the window if the property "win_state" of window is
10178 * changed to "ECORE_X_ILLUME_WINDOW_STATE_NORMAL".
10179 * FIXME: To move below code into illume seems to better.
10181 if (e_config->wm_win_rotation)
10183 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_NORMAL)
10185 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
10186 need_rotation_set = EINA_TRUE;
10191 if (bd->changes.shape)
10193 Ecore_X_Rectangle *rects;
10196 bd->changes.shape = 0;
10197 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
10200 int cw = 0, ch = 0;
10202 /* This doesn't fix the race, but makes it smaller. we detect
10203 * this and if cw and ch != client w/h then mark this as needing
10204 * a shape change again to fixup next event loop.
10206 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10207 if ((cw != bd->client.w) || (ch != bd->client.h))
10208 bd->changes.shape = 1;
10210 (rects[0].x == 0) &&
10211 (rects[0].y == 0) &&
10212 ((int)rects[0].width == cw) &&
10213 ((int)rects[0].height == ch))
10215 if (bd->client.shaped)
10217 bd->client.shaped = 0;
10218 if (!bd->bordername)
10219 bd->client.border.changed = 1;
10224 if (!bd->client.shaped)
10226 bd->client.shaped = 1;
10227 if (!bd->bordername)
10228 bd->client.border.changed = 1;
10235 // FIXME: no rects i think can mean... totally empty window
10236 bd->client.shaped = 0;
10237 if (!bd->bordername)
10238 bd->client.border.changed = 1;
10240 bd->need_shape_merge = 1;
10242 if (bd->changes.shape_input)
10244 Ecore_X_Rectangle *rects;
10247 bd->changes.shape_input = 0;
10248 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
10251 int cw = 0, ch = 0;
10253 /* This doesn't fix the race, but makes it smaller. we detect
10254 * this and if cw and ch != client w/h then mark this as needing
10255 * a shape change again to fixup next event loop.
10257 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10258 if ((cw != bd->client.w) || (ch != bd->client.h))
10259 bd->changes.shape_input = 1;
10261 (rects[0].x == 0) &&
10262 (rects[0].y == 0) &&
10263 ((int)rects[0].width == cw) &&
10264 ((int)rects[0].height == ch))
10266 if (bd->shaped_input)
10268 bd->shaped_input = 0;
10269 if (!bd->bordername)
10270 bd->client.border.changed = 1;
10275 if (!bd->shaped_input)
10277 bd->shaped_input = 1;
10278 if (!bd->bordername)
10279 bd->client.border.changed = 1;
10286 bd->shaped_input = 1;
10287 if (!bd->bordername)
10288 bd->client.border.changed = 1;
10290 bd->need_shape_merge = 1;
10292 if (bd->client.mwm.fetch.hints)
10296 bd->client.mwm.exists =
10297 ecore_x_mwm_hints_get(bd->client.win,
10298 &bd->client.mwm.func,
10299 &bd->client.mwm.decor,
10300 &bd->client.mwm.input);
10301 pb = bd->client.mwm.borderless;
10302 bd->client.mwm.borderless = 0;
10303 if (bd->client.mwm.exists)
10305 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
10306 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10307 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10308 bd->client.mwm.borderless = 1;
10310 if (bd->client.mwm.borderless != pb)
10312 if ((!bd->lock_border) || (!bd->client.border.name))
10313 bd->client.border.changed = 1;
10315 bd->client.mwm.fetch.hints = 0;
10318 if (bd->client.e.fetch.video_parent)
10320 /* unlinking child/parent */
10321 if (bd->client.e.state.video_parent_border != NULL)
10323 bd->client.e.state.video_parent_border->client.e.state.video_child =
10325 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10329 ecore_x_window_prop_card32_get(bd->client.win,
10330 ECORE_X_ATOM_E_VIDEO_PARENT,
10331 &bd->client.e.state.video_parent,
10334 /* linking child/parent */
10335 if (bd->client.e.state.video_parent != 0)
10340 EINA_LIST_FOREACH(borders, l, tmp)
10341 if (tmp->client.win == bd->client.e.state.video_parent)
10343 /* fprintf(stderr, "child added to parent \\o/\n"); */
10344 bd->client.e.state.video_parent_border = tmp;
10345 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10347 if (bd->desk != tmp->desk)
10348 e_border_desk_set(bd, tmp->desk);
10353 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10355 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10358 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10360 unsigned int xy[2];
10362 ecore_x_window_prop_card32_get(bd->client.win,
10363 ECORE_X_ATOM_E_VIDEO_POSITION,
10366 bd->client.e.state.video_position.x = xy[0];
10367 bd->client.e.state.video_position.y = xy[1];
10368 bd->client.e.state.video_position.updated = 1;
10369 bd->client.e.fetch.video_position = 0;
10370 bd->x = bd->client.e.state.video_position.x;
10371 bd->y = bd->client.e.state.video_position.y;
10373 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10375 if (bd->client.netwm.update.state)
10377 e_hints_window_state_set(bd);
10378 /* Some stats might change the border, like modal */
10379 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10380 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10382 bd->client.border.changed = 1;
10386 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10388 bd->parent->modal = bd;
10389 if (bd->parent->focused)
10390 e_border_focus_set(bd, 1, 1);
10393 else if (bd->leader)
10395 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10397 bd->leader->modal = bd;
10398 if (bd->leader->focused)
10399 e_border_focus_set(bd, 1, 1);
10405 EINA_LIST_FOREACH(bd->leader->group, l, child)
10407 if ((child != bd) && (child->focused))
10408 e_border_focus_set(bd, 1, 1);
10413 bd->client.netwm.update.state = 0;
10416 if (bd->new_client)
10418 E_Event_Border_Add *ev;
10419 E_Exec_Instance *inst;
10421 ev = E_NEW(E_Event_Border_Add, 1);
10423 e_object_ref(E_OBJECT(bd));
10424 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10425 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10427 if ((!bd->lock_border) || (!bd->client.border.name))
10428 bd->client.border.changed = 1;
10433 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10434 ((bd->client.icccm.client_leader > 0) &&
10435 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10438 if (!strncmp(str, "E_START|", 8))
10442 id = atoi(str + 8);
10443 if (id > 0) bd->client.netwm.startup_id = id;
10448 /* It's ok not to have fetch flag, should only be set on startup
10449 * * and not changed. */
10450 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10452 if (bd->client.icccm.client_leader)
10454 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10455 bd->client.netwm.pid = -1;
10458 bd->client.netwm.pid = -1;
10461 if (!bd->re_manage)
10463 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10464 bd->client.netwm.pid);
10465 if ((inst) && (inst->used == 0))
10471 zone = e_container_zone_number_get(bd->zone->container,
10473 if (zone) e_border_zone_set(bd, zone);
10474 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10476 if (desk) e_border_desk_set(bd, desk);
10477 e_exec_instance_found(inst);
10480 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10482 E_Border *bdl = NULL;
10487 if (bd->leader) bdl = bd->leader;
10494 bl = e_container_border_list_first(bd->zone->container);
10495 while ((child = e_container_border_list_next(bl)))
10497 if (child == bd) continue;
10498 if (e_object_is_del(E_OBJECT(child))) continue;
10499 if ((bd->client.icccm.client_leader) &&
10500 (child->client.icccm.client_leader ==
10501 bd->client.icccm.client_leader))
10507 e_container_border_list_free(bl);
10512 e_border_zone_set(bd, bdl->zone);
10514 e_border_desk_set(bd, bdl->desk);
10516 e_border_stick(bd);
10522 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10525 E_Container *con = bd->zone->container;
10526 E_Desk *desk = NULL;
10529 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10531 desk = e_container_desk_window_profile_get(con, str);
10534 if (bd->desk != desk)
10536 bd->client.e.state.profile = eina_stringshare_add(str);
10537 if (bd->zone != desk->zone)
10538 e_border_zone_set(bd, desk->zone);
10539 e_border_desk_set(bd, desk);
10547 /* PRE_POST_FETCH calls e_remember apply for new client */
10548 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10549 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10550 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10552 #ifdef _F_ZONE_WINDOW_ROTATION_
10553 if (e_config->wm_win_rotation)
10555 if ((need_rotation_set) &&
10556 (bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_NORMAL))
10558 Eina_Bool hint = EINA_FALSE;
10560 int x, y, w, h, move;
10562 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10563 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10565 if (bd->client.e.state.rot.changes == -1)
10567 ang = bd->client.e.state.rot.curr;
10569 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10572 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10573 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10574 bd->client.icccm.name, x, y, w, h);
10577 else bd->changed = 1;
10582 if (bd->need_reparent)
10585 ecore_x_window_save_set_add(bd->client.win);
10586 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10589 if ((bd->new_client) && (bd->internal) &&
10590 (bd->internal_ecore_evas))
10591 ecore_evas_show(bd->internal_ecore_evas);
10592 ecore_x_window_show(bd->client.win);
10594 bd->need_reparent = 0;
10597 if ((bd->client.border.changed) && (!bd->shaded) &&
10598 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10600 const char *bordername;
10602 if (bd->fullscreen)
10603 bordername = "borderless";
10604 else if (bd->bordername)
10605 bordername = bd->bordername;
10606 else if ((bd->client.mwm.borderless) || (bd->borderless))
10607 bordername = "borderless";
10608 else if (((bd->client.icccm.transient_for != 0) ||
10609 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10610 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10611 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10612 bordername = "noresize_dialog";
10613 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10614 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10615 bordername = "noresize";
10616 else if (bd->client.shaped)
10617 bordername = "shaped";
10618 else if ((!bd->client.icccm.accepts_focus) &&
10619 (!bd->client.icccm.take_focus))
10620 bordername = "nofocus";
10621 else if (bd->client.icccm.urgent)
10622 bordername = "urgent";
10623 else if ((bd->client.icccm.transient_for != 0) ||
10624 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10625 bordername = "dialog";
10626 else if (bd->client.netwm.state.modal)
10627 bordername = "modal";
10628 else if ((bd->client.netwm.state.skip_taskbar) ||
10629 (bd->client.netwm.state.skip_pager))
10630 bordername = "skipped";
10631 else if ((bd->internal) && (bd->client.icccm.class) &&
10632 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10633 bordername = "internal_fileman";
10635 bordername = e_config->theme_default_border_style;
10636 if (!bordername) bordername = "default";
10638 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10644 bd->changes.border = 1;
10645 eina_stringshare_replace(&bd->client.border.name, bordername);
10649 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10650 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10651 bd->changes.size = 1;
10652 evas_object_del(bd->bg_object);
10654 o = edje_object_add(bd->bg_evas);
10655 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10656 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10657 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10659 if (bd->client.border.name != e_config->theme_default_border_style)
10661 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10662 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10666 ok = e_theme_edje_object_set(o, "base/theme/borders",
10667 "e/widgets/border/default/border");
10670 /* Reset default border style to default */
10671 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10672 e_config_save_queue();
10680 const char *shape_option, *argb_option;
10685 if ((e_config->use_composite) && (!bd->client.argb))
10687 argb_option = edje_object_data_get(o, "argb");
10688 if ((argb_option) && (!strcmp(argb_option, "1")))
10691 if (use_argb != bd->argb)
10692 _e_border_frame_replace(bd, use_argb);
10699 shape_option = edje_object_data_get(o, "shaped");
10700 if ((shape_option) && (!strcmp(shape_option, "1")))
10704 if (bd->client.netwm.name)
10705 edje_object_part_text_set(o, "e.text.title",
10706 bd->client.netwm.name);
10707 else if (bd->client.icccm.title)
10708 edje_object_part_text_set(o, "e.text.title",
10709 bd->client.icccm.title);
10713 evas_object_del(o);
10714 bd->bg_object = NULL;
10717 _e_border_client_inset_calc(bd);
10719 bd->w += (bd->client_inset.l + bd->client_inset.r);
10720 bd->h += (bd->client_inset.t + bd->client_inset.b);
10721 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10722 bd->changes.size = 1;
10723 /* really needed ? */
10724 ecore_x_window_move(bd->client.shell_win,
10725 bd->client_inset.l,
10726 bd->client_inset.t);
10728 if (bd->maximized != E_MAXIMIZE_NONE)
10730 E_Maximize maximized = bd->maximized;
10732 /* to force possible resizes */
10733 bd->maximized = E_MAXIMIZE_NONE;
10735 _e_border_maximize(bd, maximized);
10737 /* restore maximized state */
10738 bd->maximized = maximized;
10740 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10741 bd->maximized & E_MAXIMIZE_VERTICAL);
10745 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10746 _e_border_cb_signal_bind, bd);
10749 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10750 if (bd->icon_object)
10751 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10754 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10756 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10758 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10759 // FIXME: in eval -do differently
10760 // edje_object_message_signal_process(bd->bg_object);
10761 // e_border_frame_recalc(bd);
10763 evas_object_move(bd->bg_object, 0, 0);
10764 evas_object_resize(bd->bg_object, bd->w, bd->h);
10765 evas_object_show(bd->bg_object);
10768 bd->client.border.changed = 0;
10770 if (bd->icon_object)
10774 evas_object_show(bd->icon_object);
10775 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10778 evas_object_hide(bd->icon_object);
10782 if (rem_change) e_remember_update(bd);
10786 E_Event_Border_Urgent_Change *ev;
10788 if (bd->client.icccm.urgent)
10789 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10791 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10793 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10795 e_object_ref(E_OBJECT(bd));
10796 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10797 _e_border_event_border_urgent_change_free, NULL);
10800 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10803 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10805 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10807 E_Border* temp_bd = NULL;
10808 E_Border* top_focusable_bd = NULL;
10809 Eina_Bool is_fully_obscured = EINA_FALSE;
10810 Ecore_X_XRegion *visible_region = NULL;
10811 Ecore_X_XRegion *win_region = NULL;
10812 Ecore_X_Rectangle visible_rect, win_rect;
10815 // set the entire visible region as a root geometry
10816 visible_rect.x = bd->zone->x;
10817 visible_rect.y = bd->zone->y;
10818 visible_rect.width = bd->zone->w;
10819 visible_rect.height = bd->zone->h;
10821 visible_region = ecore_x_xregion_new();
10822 if (!visible_region) return;
10824 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10826 bl = e_container_border_list_last(bd->zone->container);
10827 while ((temp_bd = e_container_border_list_prev(bl)))
10829 if (temp_bd == bd) break;
10831 if (temp_bd == focused) continue;
10832 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10833 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10834 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10835 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10836 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10837 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10838 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10839 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10840 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10842 if (!top_focusable_bd)
10844 top_focusable_bd = temp_bd;
10847 win_rect.x = temp_bd->x;
10848 win_rect.y = temp_bd->y;
10849 win_rect.width = temp_bd->w;
10850 win_rect.height = temp_bd->h;
10852 // if it stick out or is bigger than the entire visible region,
10853 // clip it by the entire visible's geometry.
10854 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10855 win_rect.width, win_rect.height,
10856 visible_rect.x, visible_rect.y,
10857 (int)(visible_rect.width), (int)(visible_rect.height));
10859 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10861 win_region = ecore_x_xregion_new();
10864 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10865 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10866 ecore_x_xregion_free(win_region);
10869 if (ecore_x_xregion_is_empty(visible_region))
10871 is_fully_obscured = EINA_TRUE;
10879 if (is_fully_obscured == EINA_TRUE)
10881 e_border_focus_set(top_focusable_bd, 1, 1);
10885 e_border_focus_set(bd, 1, 1);
10888 if (visible_region) ecore_x_xregion_free(visible_region);
10889 e_container_border_list_free(bl);
10893 _e_border_latest_stacked_focus(E_Border *bd)
10896 int root_w, root_h;
10898 root_w = bd->zone->w;
10899 root_h = bd->zone->h;
10902 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10904 if (bd == temp_bd) continue;
10905 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10906 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10908 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10909 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10910 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10911 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10912 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10913 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10914 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10916 _e_border_latest_stacked_focus_check_set(temp_bd);
10923 _e_border_check_stack (E_Border *bd)
10925 E_Border* temp_bd = NULL;
10926 E_Border* top_bd = NULL;
10927 int passed_focus = 0;
10929 int root_w = bd->zone->w;
10930 int root_h = bd->zone->h;
10933 bl = e_container_border_list_last(bd->zone->container);
10934 while ((temp_bd = e_container_border_list_prev(bl)))
10936 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10937 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10938 if ((temp_bd != bd) &&
10939 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10941 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10942 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10943 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10944 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10945 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10946 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10947 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10953 e_border_focus_set_with_pointer(bd);
10960 e_border_focus_set_with_pointer(top_bd);
10969 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10971 if (!bd->lock_focus_out)
10973 e_border_focus_latest_set(bd);
10985 if (temp_bd == focused)
10991 e_container_border_list_free(bl);
10995 _e_border_focus_top_stack_set(E_Border* bd)
10998 int root_w, root_h;
11000 root_w = bd->zone->w;
11001 root_h = bd->zone->h;
11004 bl = e_container_border_list_last(bd->zone->container);
11005 while ((temp_bd = e_container_border_list_prev(bl)))
11007 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
11008 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
11009 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
11011 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
11012 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
11013 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
11014 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
11015 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
11016 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
11017 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
11019 if (!temp_bd->focused)
11021 /* this border is the top of the latest stack */
11022 e_border_focus_set (temp_bd, 1, 1);
11027 e_container_border_list_free(bl);
11032 _e_border_eval(E_Border *bd)
11034 E_Event_Border_Property *event;
11035 E_Border_Pending_Move_Resize *pnd;
11036 int rem_change = 0;
11037 int send_event = 1;
11039 if (e_object_is_del(E_OBJECT(bd)))
11041 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
11046 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
11048 if (bd->new_client)
11050 int zx = 0, zy = 0, zw = 0, zh = 0;
11053 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
11056 * Limit maximum size of windows to useful geometry
11058 // TODO: temoporary limited maximize algorithm
11070 if ((rw != bd->w) || (rh != bd->h))
11074 e_border_resize (bd, bd->w, bd->h);
11080 bd->x -= bd->client_inset.l;
11081 bd->y -= bd->client_inset.t;
11082 bd->changes.pos = 1;
11085 else if ((!bd->placed) && (bd->client.icccm.request_pos))
11088 Ecore_X_Window_Attributes *att;
11091 att = &bd->client.initial_attributes;
11092 bw = att->border * 2;
11093 switch (bd->client.icccm.gravity)
11095 case ECORE_X_GRAVITY_N:
11096 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11100 case ECORE_X_GRAVITY_NE:
11101 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11105 case ECORE_X_GRAVITY_E:
11106 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11107 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
11110 case ECORE_X_GRAVITY_SE:
11111 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11112 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11115 case ECORE_X_GRAVITY_S:
11116 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11117 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11120 case ECORE_X_GRAVITY_SW:
11122 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11125 case ECORE_X_GRAVITY_W:
11127 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11130 case ECORE_X_GRAVITY_CENTER:
11131 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11132 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
11135 case ECORE_X_GRAVITY_NW:
11142 * This ensures that windows that like to open with a x/y
11143 * position smaller than returned by e_zone_useful_geometry_get()
11144 * are moved to useful positions.
11147 if (e_config->geometry_auto_move)
11155 if (bd->x + bd->w > zx + zw)
11156 bd->x = zx + zw - bd->w;
11158 if (bd->y + bd->h > zy + zh)
11159 bd->y = zy + zh - bd->h;
11162 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
11164 bd->changes.pos = 1;
11170 bd->changes.pos = 1;
11176 /* FIXME: special placement for dialogs etc. etc. etc goes
11178 /* FIXME: what if parent is not on this desktop - or zone? */
11179 if ((bd->parent) && (bd->parent->visible))
11181 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
11182 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
11183 bd->changes.pos = 1;
11187 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
11189 /* TODO: Place in center of group */
11192 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11194 bd->x = zx + ((zw - bd->w) / 2);
11195 bd->y = zy + ((zh - bd->h) / 2);
11196 bd->changes.pos = 1;
11202 Eina_List *skiplist = NULL;
11206 new_x = zx + (rand() % (zw - bd->w));
11210 new_y = zy + (rand() % (zh - bd->h));
11214 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
11216 skiplist = eina_list_append(skiplist, bd);
11218 e_place_desk_region_smart(bd->desk, skiplist,
11219 bd->x, bd->y, bd->w, bd->h,
11222 e_place_zone_region_smart(bd->zone, skiplist,
11223 bd->x, bd->y, bd->w, bd->h,
11225 eina_list_free(skiplist);
11227 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
11229 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
11234 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
11235 bd->client_inset.t, &new_x, &new_y);
11239 bd->changes.pos = 1;
11242 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11244 if ((!bd->lock_client_location) && (pnd->move))
11248 bd->changes.pos = 1;
11250 if (pnd->without_border)
11252 bd->x -= bd->client_inset.l;
11253 bd->y -= bd->client_inset.t;
11256 if ((!bd->lock_client_size) && (pnd->resize))
11258 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
11259 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
11260 bd->client.w = pnd->w;
11261 bd->client.h = pnd->h;
11262 bd->changes.size = 1;
11268 /* Recreate state */
11269 e_hints_window_init(bd);
11270 if ((bd->client.e.state.centered) &&
11271 ((!bd->remember) ||
11272 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
11274 bd->x = zx + (zw - bd->w) / 2;
11275 bd->y = zy + (zh - bd->h) / 2;
11276 bd->changes.pos = 1;
11280 _e_border_client_move_resize_send(bd);
11282 /* if the explicit geometry request asks for the app to be
11283 * in another zone - well move it there */
11287 zone = e_container_zone_at_point_get(bd->zone->container,
11288 bd->x + (bd->w / 2),
11289 bd->y + (bd->h / 2));
11291 zone = e_container_zone_at_point_get(bd->zone->container,
11295 zone = e_container_zone_at_point_get(bd->zone->container,
11299 zone = e_container_zone_at_point_get(bd->zone->container,
11301 bd->y + bd->h - 1);
11303 zone = e_container_zone_at_point_get(bd->zone->container,
11305 bd->y + bd->h - 1);
11306 if ((zone) && (zone != bd->zone))
11307 e_border_zone_set(bd, zone);
11311 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11313 /* effect changes to the window border itself */
11314 if ((bd->changes.shading))
11316 /* show at start of unshade (but don't hide until end of shade) */
11318 ecore_x_window_raise(bd->client.shell_win);
11319 bd->changes.shading = 0;
11322 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11325 ecore_x_window_lower(bd->client.shell_win);
11327 ecore_x_window_raise(bd->client.shell_win);
11328 bd->changes.shaded = 0;
11331 else if ((bd->changes.shaded) && (bd->changes.pos))
11334 ecore_x_window_lower(bd->client.shell_win);
11336 ecore_x_window_raise(bd->client.shell_win);
11337 bd->changes.size = 1;
11338 bd->changes.shaded = 0;
11341 else if ((bd->changes.shaded) && (bd->changes.size))
11344 ecore_x_window_lower(bd->client.shell_win);
11346 ecore_x_window_raise(bd->client.shell_win);
11347 bd->changes.shaded = 0;
11350 else if (bd->changes.shaded)
11353 ecore_x_window_lower(bd->client.shell_win);
11355 ecore_x_window_raise(bd->client.shell_win);
11356 bd->changes.size = 1;
11357 bd->changes.shaded = 0;
11361 if (bd->changes.size)
11363 int x = 0, y = 0, xx = 0, yy = 0;
11365 if ((bd->shaded) && (!bd->shading))
11367 evas_obscured_clear(bd->bg_evas);
11371 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11372 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11374 evas_obscured_clear(bd->bg_evas);
11375 evas_obscured_rectangle_add(bd->bg_evas,
11376 bd->client_inset.l, bd->client_inset.t, xx, yy);
11380 if (bd->shade.dir == E_DIRECTION_UP)
11382 y = yy - bd->client.h;
11384 else if (bd->shade.dir == E_DIRECTION_LEFT)
11386 x = xx - bd->client.w;
11391 if (bd->client.e.state.video)
11393 if (bd->client.e.state.video_position.updated)
11395 ecore_x_window_move(bd->win,
11396 bd->client.e.state.video_parent_border->x +
11397 bd->client.e.state.video_parent_border->client_inset.l +
11398 bd->client.e.state.video_parent_border->fx.x +
11399 bd->client.e.state.video_position.x,
11400 bd->client.e.state.video_parent_border->y +
11401 bd->client.e.state.video_parent_border->client_inset.t +
11402 bd->client.e.state.video_parent_border->fx.y +
11403 bd->client.e.state.video_position.y);
11404 bd->client.e.state.video_position.updated = 0;
11407 else if (!bd->changes.pos)
11409 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11410 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11411 bd->post_resize = 1;
11418 ecore_x_window_move_resize(bd->win,
11423 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11424 ecore_x_window_move(tmp->win,
11425 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11426 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11429 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11431 if ((!bd->shaded) || (bd->shading))
11432 ecore_x_window_move_resize(bd->client.shell_win,
11433 bd->client_inset.l, bd->client_inset.t, xx, yy);
11435 if (bd->internal_ecore_evas)
11436 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11437 else if (!bd->client.e.state.video)
11438 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11440 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11441 evas_object_resize(bd->bg_object, bd->w, bd->h);
11442 e_container_shape_resize(bd->shape, bd->w, bd->h);
11443 if (bd->changes.pos)
11444 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11446 _e_border_client_move_resize_send(bd);
11448 bd->changes.pos = 0;
11449 bd->changes.size = 0;
11452 else if (bd->changes.pos)
11454 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11455 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11458 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11460 _e_border_client_move_resize_send(bd);
11462 bd->changes.pos = 0;
11466 if (bd->changes.reset_gravity)
11468 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11469 bd->changes.reset_gravity = 0;
11473 if (bd->need_shape_merge)
11475 _e_border_shape_input_rectangle_set(bd);
11476 if ((bd->shaped) || (bd->client.shaped))
11478 Ecore_X_Window twin, twin2;
11481 twin = ecore_x_window_override_new
11482 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11484 ecore_x_window_shape_window_set(twin, bd->bg_win);
11487 Ecore_X_Rectangle rects[4];
11491 rects[0].width = bd->w;
11492 rects[0].height = bd->client_inset.t;
11494 rects[1].y = bd->client_inset.t;
11495 rects[1].width = bd->client_inset.l;
11496 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11497 rects[2].x = bd->w - bd->client_inset.r;
11498 rects[2].y = bd->client_inset.t;
11499 rects[2].width = bd->client_inset.r;
11500 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11502 rects[3].y = bd->h - bd->client_inset.b;
11503 rects[3].width = bd->w;
11504 rects[3].height = bd->client_inset.b;
11505 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11507 twin2 = ecore_x_window_override_new
11508 (bd->zone->container->scratch_win, 0, 0,
11509 bd->w - bd->client_inset.l - bd->client_inset.r,
11510 bd->h - bd->client_inset.t - bd->client_inset.b);
11513 if ((bd->shading) || (bd->shaded))
11515 if (bd->shade.dir == E_DIRECTION_UP)
11516 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11517 else if (bd->shade.dir == E_DIRECTION_LEFT)
11518 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11520 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11522 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11523 bd->w - bd->client_inset.l - bd->client_inset.r,
11524 bd->h - bd->client_inset.t - bd->client_inset.b);
11525 ecore_x_window_shape_window_add_xy(twin, twin2,
11526 bd->client_inset.l,
11527 bd->client_inset.t);
11528 ecore_x_window_free(twin2);
11529 ecore_x_window_shape_window_set(bd->win, twin);
11530 ecore_x_window_free(twin);
11533 ecore_x_window_shape_mask_set(bd->win, 0);
11534 // bd->need_shape_export = 1;
11535 bd->need_shape_merge = 0;
11538 if (bd->need_shape_export)
11540 Ecore_X_Rectangle *rects, *orects;
11543 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11549 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11553 orects = bd->shape_rects;
11555 for (i = 0; i < num; i++)
11557 if (rects[i].x < 0)
11559 rects[i].width -= rects[i].x;
11562 if ((rects[i].x + (int)rects[i].width) > bd->w)
11563 rects[i].width = rects[i].width - rects[i].x;
11564 if (rects[i].y < 0)
11566 rects[i].height -= rects[i].y;
11569 if ((rects[i].y + (int)rects[i].height) > bd->h)
11570 rects[i].height = rects[i].height - rects[i].y;
11572 if ((orects[i].x != rects[i].x) ||
11573 (orects[i].y != rects[i].y) ||
11574 (orects[i].width != rects[i].width) ||
11575 (orects[i].height != rects[i].height))
11584 if (bd->client.shaped)
11585 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11587 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11588 E_FREE(bd->shape_rects);
11589 bd->shape_rects = rects;
11590 bd->shape_rects_num = num;
11591 e_container_shape_rects_set(bd->shape, rects, num);
11598 E_FREE(bd->shape_rects);
11599 bd->shape_rects = NULL;
11600 bd->shape_rects_num = 0;
11601 e_container_shape_rects_set(bd->shape, NULL, 0);
11603 bd->need_shape_export = 0;
11606 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11610 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11611 if ((!bd->placed) && (!bd->re_manage) &&
11612 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11613 (!((bd->client.icccm.transient_for != 0) ||
11614 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11615 (!bdmove) && (!bdresize))
11617 /* Set this window into moving state */
11619 bd->cur_mouse_action = e_action_find("window_move");
11620 if (bd->cur_mouse_action)
11622 if ((!bd->cur_mouse_action->func.end_mouse) &&
11623 (!bd->cur_mouse_action->func.end))
11624 bd->cur_mouse_action = NULL;
11625 if (bd->cur_mouse_action)
11627 bd->x = x - (bd->w >> 1);
11628 bd->y = y - (bd->client_inset.t >> 1);
11630 bd->changes.pos = 1;
11632 _e_border_client_move_resize_send(bd);
11637 _e_border_show(bd);
11639 if (bd->cur_mouse_action)
11641 bd->moveinfo.down.x = bd->x + bd->fx.x;
11642 bd->moveinfo.down.y = bd->y + bd->fx.y;
11643 bd->moveinfo.down.w = bd->w;
11644 bd->moveinfo.down.h = bd->h;
11645 bd->mouse.current.mx = x;
11646 bd->mouse.current.my = y;
11647 bd->moveinfo.down.button = 0;
11648 bd->moveinfo.down.mx = x;
11649 bd->moveinfo.down.my = y;
11652 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11653 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11654 if (e_config->border_raise_on_mouse_action)
11655 e_border_raise(bd);
11656 e_border_focus_set(bd, 1, 1);
11658 bd->changes.visible = 0;
11662 if (bd->changes.icon)
11666 efreet_desktop_free(bd->desktop);
11667 bd->desktop = NULL;
11669 if (bd->icon_object)
11671 evas_object_del(bd->icon_object);
11672 bd->icon_object = NULL;
11674 if (bd->remember && bd->remember->prop.desktop_file)
11676 const char *desktop = bd->remember->prop.desktop_file;
11678 bd->desktop = efreet_desktop_get(desktop);
11680 bd->desktop = efreet_util_desktop_name_find(desktop);
11684 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11685 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11686 bd->client.icccm.class);
11690 /* libreoffice and maybe others match window class
11691 with .desktop file name */
11692 if (bd->client.icccm.class)
11695 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11696 bd->desktop = efreet_util_desktop_file_id_find(buf);
11701 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11702 bd->client.netwm.pid);
11703 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11705 if (!bd->desktop && bd->client.icccm.name)
11707 /* this works for most cases as fallback. useful when app is
11708 run from a shell */
11709 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11711 if (!bd->desktop && bd->client.icccm.transient_for)
11713 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11714 if (bd2 && bd2->desktop)
11716 efreet_desktop_ref(bd2->desktop);
11717 bd->desktop = bd2->desktop;
11722 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11723 bd->desktop->orig_path);
11726 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11727 if ((bd->focused) && (bd->icon_object))
11728 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11731 evas_object_show(bd->icon_object);
11732 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11735 evas_object_hide(bd->icon_object);
11738 E_Event_Border_Icon_Change *ev;
11740 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11742 e_object_ref(E_OBJECT(bd));
11743 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11744 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11745 _e_border_event_border_icon_change_free, NULL);
11747 bd->changes.icon = 0;
11750 bd->new_client = 0;
11752 bd->changes.stack = 0;
11753 bd->changes.prop = 0;
11755 #ifdef _F_ZONE_WINDOW_ROTATION_
11756 if (bd->client.e.state.rot.changes != -1)
11758 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11759 bd->client.e.state.rot.changes = -1;
11763 if ((bd->take_focus) || (bd->want_focus))
11765 bd->take_focus = 0;
11766 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11767 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11768 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11771 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11774 bd->want_focus = 0;
11775 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11776 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11777 _e_border_check_stack(bd);
11780 e_border_focus_set_with_pointer(bd);
11782 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11784 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11785 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11786 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11787 e_border_focused_get())))
11789 e_border_focus_set_with_pointer(bd);
11794 /* focus window by default when it is the only one on desk */
11795 E_Border *bd2 = NULL;
11797 EINA_LIST_FOREACH(focus_stack, l, bd2)
11799 if (bd == bd2) continue;
11800 if ((!bd2->iconic) && (bd2->visible) &&
11801 ((bd->desk == bd2->desk) || bd2->sticky))
11807 e_border_focus_set_with_pointer(bd);
11812 if (bd->need_maximize)
11815 max = bd->maximized;
11816 bd->maximized = E_MAXIMIZE_NONE;
11817 e_border_maximize(bd, max);
11818 bd->need_maximize = 0;
11821 if (bd->need_fullscreen)
11823 e_border_fullscreen(bd, e_config->fullscreen_policy);
11824 bd->need_fullscreen = 0;
11828 e_remember_update(bd);
11830 if (send_event) // FIXME: send only if a property changed - above need to
11831 { // check on that. for now - always send.
11832 event = E_NEW(E_Event_Border_Property, 1);
11833 event->border = bd;
11834 e_object_ref(E_OBJECT(bd));
11835 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11837 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11841 _e_border_moveinfo_gather(E_Border *bd,
11842 const char *source)
11844 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11845 else if (e_util_glob_match(source, "mouse,*,2"))
11846 bd->moveinfo.down.button = 2;
11847 else if (e_util_glob_match(source, "mouse,*,3"))
11848 bd->moveinfo.down.button = 3;
11849 else bd->moveinfo.down.button = 0;
11850 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11852 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11853 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11857 bd->moveinfo.down.mx = bd->mouse.current.mx;
11858 bd->moveinfo.down.my = bd->mouse.current.my;
11863 _e_border_resize_handle(E_Border *bd)
11866 int new_x, new_y, new_w, new_h;
11868 Eina_List *skiplist = NULL;
11875 if ((bd->resize_mode == RESIZE_TR) ||
11876 (bd->resize_mode == RESIZE_R) ||
11877 (bd->resize_mode == RESIZE_BR))
11879 if ((bd->moveinfo.down.button >= 1) &&
11880 (bd->moveinfo.down.button <= 3))
11881 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11882 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11884 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11886 else if ((bd->resize_mode == RESIZE_TL) ||
11887 (bd->resize_mode == RESIZE_L) ||
11888 (bd->resize_mode == RESIZE_BL))
11890 if ((bd->moveinfo.down.button >= 1) &&
11891 (bd->moveinfo.down.button <= 3))
11892 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11893 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11895 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11898 if ((bd->resize_mode == RESIZE_TL) ||
11899 (bd->resize_mode == RESIZE_T) ||
11900 (bd->resize_mode == RESIZE_TR))
11902 if ((bd->moveinfo.down.button >= 1) &&
11903 (bd->moveinfo.down.button <= 3))
11904 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11905 (bd->mouse.current.my - bd->moveinfo.down.my);
11907 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11909 else if ((bd->resize_mode == RESIZE_BL) ||
11910 (bd->resize_mode == RESIZE_B) ||
11911 (bd->resize_mode == RESIZE_BR))
11913 if ((bd->moveinfo.down.button >= 1) &&
11914 (bd->moveinfo.down.button <= 3))
11915 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11916 (bd->mouse.current.my - bd->moveinfo.down.my);
11918 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11924 if ((bd->resize_mode == RESIZE_TL) ||
11925 (bd->resize_mode == RESIZE_L) ||
11926 (bd->resize_mode == RESIZE_BL))
11928 if ((bd->resize_mode == RESIZE_TL) ||
11929 (bd->resize_mode == RESIZE_T) ||
11930 (bd->resize_mode == RESIZE_TR))
11933 skiplist = eina_list_append(skiplist, bd);
11934 e_resist_container_border_position(bd->zone->container, skiplist,
11935 bd->x, bd->y, bd->w, bd->h,
11937 &new_x, &new_y, &new_w, &new_h);
11938 eina_list_free(skiplist);
11942 e_border_resize_limit(bd, &new_w, &new_h);
11943 if ((bd->resize_mode == RESIZE_TL) ||
11944 (bd->resize_mode == RESIZE_L) ||
11945 (bd->resize_mode == RESIZE_BL))
11946 new_x += (w - new_w);
11947 if ((bd->resize_mode == RESIZE_TL) ||
11948 (bd->resize_mode == RESIZE_T) ||
11949 (bd->resize_mode == RESIZE_TR))
11950 new_y += (h - new_h);
11952 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11956 _e_border_shade_animator(void *data)
11958 E_Border *bd = data;
11960 double dur = bd->client.h / e_config->border_shade_speed;
11962 dt = ecore_loop_time_get() - bd->shade.start;
11965 if (val < 0.0) val = 0.0;
11966 else if (val > 1.0) val = 1.0;
11968 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11971 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11972 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11974 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11977 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11978 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11980 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11983 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11984 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11986 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11989 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11990 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11992 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11995 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11996 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11998 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
12001 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
12002 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12004 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
12007 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
12008 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12010 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
12013 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
12014 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12016 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
12019 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
12020 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12025 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
12026 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12029 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
12030 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
12031 else if (bd->shade.val > .999)
12032 bd->shade.val = 1.0;
12034 if (bd->shade.dir == E_DIRECTION_UP)
12035 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
12036 else if (bd->shade.dir == E_DIRECTION_DOWN)
12038 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
12039 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
12040 bd->changes.pos = 1;
12042 else if (bd->shade.dir == E_DIRECTION_LEFT)
12043 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
12044 else if (bd->shade.dir == E_DIRECTION_RIGHT)
12046 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
12047 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
12048 bd->changes.pos = 1;
12051 if ((bd->shaped) || (bd->client.shaped))
12053 bd->need_shape_merge = 1;
12054 bd->need_shape_export = 1;
12056 if (bd->shaped_input)
12058 bd->need_shape_merge = 1;
12060 bd->changes.size = 1;
12066 E_Event_Border_Resize *ev;
12069 bd->shaded = !(bd->shaded);
12070 bd->changes.size = 1;
12071 bd->changes.shaded = 1;
12072 bd->changes.shading = 1;
12074 bd->shade.anim = NULL;
12077 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
12079 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
12080 edje_object_message_signal_process(bd->bg_object);
12081 e_border_frame_recalc(bd);
12083 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
12084 ev = E_NEW(E_Event_Border_Resize, 1);
12086 e_object_ref(E_OBJECT(bd));
12087 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
12088 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
12089 return ECORE_CALLBACK_CANCEL;
12091 return ECORE_CALLBACK_RENEW;
12095 _e_border_event_border_resize_free(void *data __UNUSED__,
12098 E_Event_Border_Resize *e;
12101 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
12102 e_object_unref(E_OBJECT(e->border));
12107 _e_border_event_border_move_free(void *data __UNUSED__,
12110 E_Event_Border_Move *e;
12113 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
12114 e_object_unref(E_OBJECT(e->border));
12119 _e_border_event_border_add_free(void *data __UNUSED__,
12122 E_Event_Border_Add *e;
12125 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
12126 e_object_unref(E_OBJECT(e->border));
12131 _e_border_event_border_remove_free(void *data __UNUSED__,
12134 E_Event_Border_Remove *e;
12137 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
12138 e_object_unref(E_OBJECT(e->border));
12143 _e_border_event_border_show_free(void *data __UNUSED__,
12146 E_Event_Border_Show *e;
12149 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
12150 e_object_unref(E_OBJECT(e->border));
12155 _e_border_event_border_hide_free(void *data __UNUSED__,
12158 E_Event_Border_Hide *e;
12161 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
12162 e_object_unref(E_OBJECT(e->border));
12167 _e_border_event_border_iconify_free(void *data __UNUSED__,
12170 E_Event_Border_Iconify *e;
12173 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
12174 e_object_unref(E_OBJECT(e->border));
12179 _e_border_event_border_uniconify_free(void *data __UNUSED__,
12182 E_Event_Border_Uniconify *e;
12185 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
12186 e_object_unref(E_OBJECT(e->border));
12191 _e_border_event_border_stick_free(void *data __UNUSED__,
12194 E_Event_Border_Stick *e;
12197 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
12198 e_object_unref(E_OBJECT(e->border));
12203 _e_border_event_border_unstick_free(void *data __UNUSED__,
12206 E_Event_Border_Unstick *e;
12209 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
12210 e_object_unref(E_OBJECT(e->border));
12215 _e_border_event_border_zone_set_free(void *data __UNUSED__,
12218 E_Event_Border_Zone_Set *e;
12221 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
12222 e_object_unref(E_OBJECT(e->border));
12223 e_object_unref(E_OBJECT(e->zone));
12228 _e_border_event_border_desk_set_free(void *data __UNUSED__,
12231 E_Event_Border_Desk_Set *e;
12234 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
12235 e_object_unref(E_OBJECT(e->border));
12236 e_object_unref(E_OBJECT(e->desk));
12241 _e_border_event_border_stack_free(void *data __UNUSED__,
12244 E_Event_Border_Stack *e;
12247 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
12248 e_object_unref(E_OBJECT(e->border));
12251 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
12252 e_object_unref(E_OBJECT(e->stack));
12258 _e_border_event_border_icon_change_free(void *data __UNUSED__,
12261 E_Event_Border_Icon_Change *e;
12264 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
12265 e_object_unref(E_OBJECT(e->border));
12270 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
12273 E_Event_Border_Urgent_Change *e;
12276 e_object_unref(E_OBJECT(e->border));
12281 _e_border_event_border_focus_in_free(void *data __UNUSED__,
12284 E_Event_Border_Focus_In *e;
12287 e_object_unref(E_OBJECT(e->border));
12292 _e_border_event_border_focus_out_free(void *data __UNUSED__,
12295 E_Event_Border_Focus_Out *e;
12298 e_object_unref(E_OBJECT(e->border));
12303 _e_border_event_border_property_free(void *data __UNUSED__,
12306 E_Event_Border_Property *e;
12309 e_object_unref(E_OBJECT(e->border));
12314 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12317 E_Event_Border_Fullscreen *e;
12320 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12321 e_object_unref(E_OBJECT(e->border));
12326 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12329 E_Event_Border_Unfullscreen *e;
12332 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12333 e_object_unref(E_OBJECT(e->border));
12337 #ifdef _F_ZONE_WINDOW_ROTATION_
12339 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12342 E_Event_Border_Rotation_Change_Begin *e;
12344 e_object_unref(E_OBJECT(e->border));
12349 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12352 E_Event_Border_Rotation_Change_Cancel *e;
12354 e_object_unref(E_OBJECT(e->border));
12359 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12362 E_Event_Border_Rotation_Change_End *e;
12364 e_object_unref(E_OBJECT(e->border));
12369 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12371 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12372 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12376 e_object_ref(E_OBJECT(bd));
12377 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12379 _e_border_event_border_rotation_change_begin_free,
12386 _e_border_zone_update(E_Border *bd)
12392 /* still within old zone - leave it there */
12393 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12394 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12395 #if _F_BORDER_CLIP_TO_ZONE_
12397 _e_border_shape_input_clip_to_zone(bd);
12402 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12403 /* find a new zone */
12404 con = bd->zone->container;
12405 EINA_LIST_FOREACH(con->zones, l, zone)
12407 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12408 zone->x, zone->y, zone->w, zone->h))
12410 e_border_zone_set(bd, zone);
12411 #if _F_BORDER_CLIP_TO_ZONE_
12412 _e_border_shape_input_clip_to_zone(bd);
12413 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12420 _e_border_resize_begin(E_Border *bd)
12424 if (!bd->lock_user_stacking)
12426 if (e_config->border_raise_on_mouse_action)
12427 e_border_raise(bd);
12429 if ((bd->shaded) || (bd->shading) ||
12430 (bd->fullscreen) || (bd->lock_user_size))
12433 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12434 ret = e_grabinput_get(bd->win, 0, bd->win);
12436 ret = e_grabinput_get(bd->win, 0, 0);
12438 if (grabbed && !ret)
12444 if (bd->client.netwm.sync.request)
12446 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12447 bd->client.netwm.sync.serial = 1;
12448 bd->client.netwm.sync.wait = 0;
12449 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12452 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12459 _e_border_resize_end(E_Border *bd)
12463 e_grabinput_release(bd->win, bd->win);
12466 if (bd->client.netwm.sync.alarm)
12468 E_Border_Pending_Move_Resize *pnd;
12470 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12471 bd->client.netwm.sync.alarm = 0;
12472 /* resize to last geometry if sync alarm for it was not yet handled */
12473 if (bd->pending_move_resize)
12476 bd->changes.pos = 1;
12477 bd->changes.size = 1;
12478 _e_border_client_move_resize_send(bd);
12481 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12485 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12489 /* If this border was maximized, we need to unset Maximized state or
12490 * on restart, E still thinks it's maximized */
12491 if (bd->maximized != E_MAXIMIZE_NONE)
12492 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12493 bd->maximized & E_MAXIMIZE_NONE);
12498 _e_border_resize_update(E_Border *bd)
12500 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12504 _e_border_move_begin(E_Border *bd)
12507 if (!bd->lock_user_stacking)
12509 if (e_config->border_raise_on_mouse_action)
12510 e_border_raise(bd);
12512 if ((bd->fullscreen) || (bd->lock_user_location))
12515 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12516 ret = e_grabinput_get(bd->win, 0, bd->win);
12518 ret = e_grabinput_get(bd->win, 0, 0);
12520 if (grabbed && !ret)
12526 if (bd->client.netwm.sync.request)
12528 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12529 bd->client.netwm.sync.serial = 0;
12530 bd->client.netwm.sync.wait = 0;
12531 bd->client.netwm.sync.time = ecore_loop_time_get();
12534 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12541 _e_border_move_end(E_Border *bd)
12545 e_grabinput_release(bd->win, bd->win);
12549 if (bd->client.netwm.sync.alarm)
12551 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12552 bd->client.netwm.sync.alarm = 0;
12555 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12562 _e_border_move_update(E_Border *bd)
12564 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12568 _e_border_cb_ping_poller(void *data)
12578 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12579 if (bd->kill_timer)
12581 ecore_timer_del(bd->kill_timer);
12582 bd->kill_timer = NULL;
12588 /* if time between last ping and now is greater
12589 * than half the ping interval... */
12590 if ((ecore_loop_time_get() - bd->ping) >
12591 ((e_config->ping_clients_interval *
12592 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12597 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12598 /* FIXME: if below dialog is up - hide it now */
12600 if (bd->delete_requested)
12602 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12603 e_border_act_kill_begin(bd);
12607 bd->ping_poller = NULL;
12609 return ECORE_CALLBACK_CANCEL;
12613 _e_border_cb_kill_timer(void *data)
12618 // dont wait until it's hung -
12621 if (bd->client.netwm.pid > 1)
12622 kill(bd->client.netwm.pid, SIGKILL);
12624 bd->kill_timer = NULL;
12625 return ECORE_CALLBACK_CANCEL;
12629 _e_border_pointer_resize_begin(E_Border *bd)
12631 switch (bd->resize_mode)
12634 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12638 e_pointer_type_push(bd->pointer, bd, "resize_t");
12642 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12646 e_pointer_type_push(bd->pointer, bd, "resize_r");
12650 e_pointer_type_push(bd->pointer, bd, "resize_br");
12654 e_pointer_type_push(bd->pointer, bd, "resize_b");
12658 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12662 e_pointer_type_push(bd->pointer, bd, "resize_l");
12668 _e_border_pointer_resize_end(E_Border *bd)
12670 switch (bd->resize_mode)
12673 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12677 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12681 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12685 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12689 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12693 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12697 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12701 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12707 _e_border_pointer_move_begin(E_Border *bd)
12709 e_pointer_type_push(bd->pointer, bd, "move");
12713 _e_border_pointer_move_end(E_Border *bd)
12715 e_pointer_type_pop(bd->pointer, bd, "move");
12718 static Eina_List *_e_border_hooks = NULL;
12719 static int _e_border_hooks_delete = 0;
12720 static int _e_border_hooks_walking = 0;
12723 _e_border_hooks_clean(void)
12728 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12732 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12739 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12745 _e_border_hooks_walking++;
12746 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12748 if (bh->delete_me) continue;
12749 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12751 _e_border_hooks_walking--;
12752 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12753 _e_border_hooks_clean();
12756 EAPI E_Border_Hook *
12757 e_border_hook_add(E_Border_Hook_Point hookpoint,
12758 void (*func)(void *data,
12764 bh = E_NEW(E_Border_Hook, 1);
12765 if (!bh) return NULL;
12766 bh->hookpoint = hookpoint;
12769 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12774 e_border_hook_del(E_Border_Hook *bh)
12777 if (_e_border_hooks_walking == 0)
12779 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12783 _e_border_hooks_delete++;
12787 e_border_focus_track_freeze(void)
12789 focus_track_frozen++;
12793 e_border_focus_track_thaw(void)
12795 focus_track_frozen--;
12799 e_border_under_pointer_get(E_Desk *desk,
12802 E_Border *bd = NULL, *cbd;
12806 /* We need to ensure that we can get the container window for the
12807 * zone of either the given desk or the desk of the excluded
12808 * window, so return if neither is given */
12810 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12812 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12816 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12818 if (!cbd) continue;
12819 /* If a border was specified which should be excluded from the list
12820 * (because it will be closed shortly for example), skip */
12821 if ((exclude) && (cbd == exclude)) continue;
12822 if ((desk) && (cbd->desk != desk)) continue;
12823 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12825 /* If the layer is higher, the position of the window is higher
12826 * (always on top vs always below) */
12827 if (!bd || (cbd->layer > bd->layer))
12837 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12844 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12845 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12846 (y - warp_y) > 5 || (y - warp_y) < -5)
12848 /* User moved the mouse, so stop warping */
12853 /* We just use the same warp speed as configured
12854 * for the windowlist */
12855 spd = e_config->winlist_warp_speed;
12858 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12859 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12860 if (warp_x == x && warp_y == y)
12862 warp_x = warp_to_x;
12863 warp_y = warp_to_y;
12867 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12868 return ECORE_CALLBACK_RENEW;
12871 ecore_timer_del(warp_timer);
12873 return ECORE_CALLBACK_CANCEL;
12877 e_border_pointer_warp_to_center(E_Border *bd)
12881 /* Do not slide pointer when disabled (probably breaks focus
12882 * on sloppy/mouse focus but requested by users). */
12883 if (!e_config->pointer_slide) return 0;
12884 /* Only warp the pointer if it is not already in the area of
12885 * the given border */
12886 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12887 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12888 (y >= bd->y) && (y <= (bd->y + bd->h)))
12891 warp_to_x = bd->x + (bd->w / 2);
12892 if (warp_to_x < (bd->zone->x + 1))
12893 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12894 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12895 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12897 warp_to_y = bd->y + (bd->h / 2);
12898 if (warp_to_y < (bd->zone->y + 1))
12899 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12900 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12901 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12904 warp_to_win = bd->zone->container->win;
12905 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12907 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12912 e_border_comp_hidden_set(E_Border *bd,
12918 E_OBJECT_CHECK(bd);
12919 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12921 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12924 ecore_x_window_hide(tmp->win);
12926 ecore_x_window_show(tmp->win);
12929 if (bd->comp_hidden == hidden) return;
12931 bd->comp_hidden = hidden;
12933 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12935 ecore_x_composite_window_events_disable(bd->win);
12936 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12940 _e_border_shape_input_rectangle_set(bd);
12941 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12946 e_border_tmp_input_hidden_push(E_Border *bd)
12951 E_OBJECT_CHECK(bd);
12952 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12954 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12955 e_border_tmp_input_hidden_push(tmp);
12957 bd->tmp_input_hidden++;
12958 if (bd->tmp_input_hidden != 1) return;
12960 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12962 ecore_x_composite_window_events_disable(bd->win);
12963 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12967 _e_border_shape_input_rectangle_set(bd);
12968 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12973 e_border_tmp_input_hidden_pop(E_Border *bd)
12978 E_OBJECT_CHECK(bd);
12979 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12981 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12982 e_border_tmp_input_hidden_pop(tmp);
12984 bd->tmp_input_hidden--;
12985 if (bd->tmp_input_hidden != 0) return;
12987 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12989 ecore_x_composite_window_events_disable(bd->win);
12990 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12994 _e_border_shape_input_rectangle_set(bd);
12995 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
13000 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
13002 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
13004 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
13005 ((bd->parent->focused) &&
13006 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
13011 if (e_config->clientlist_warp_to_iconified_desktop == 1)
13012 e_desk_show(bd->desk);
13014 if (!bd->lock_user_iconify)
13015 e_border_uniconify(bd);
13017 if ((!bd->iconic) && (!bd->sticky))
13018 e_desk_show(bd->desk);
13019 if (!bd->lock_user_stacking) e_border_raise(bd);
13020 if (!bd->lock_focus_out)
13022 /* XXX ooffice does send this request for
13023 config dialogs when the main window gets focus.
13024 causing the pointer to jump back and forth. */
13025 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
13026 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
13027 ecore_x_pointer_warp(bd->zone->container->win,
13028 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
13029 e_border_focus_set(bd, 1, 1);
13034 #ifdef _F_DEICONIFY_APPROVE_
13036 _e_border_window_pending_destroy_event_free(void *data __UNUSED__,
13039 Ecore_X_Event_Window_Destroy *e;
13046 _e_border_window_pending_hide_event_free(void *data __UNUSED__,
13049 Ecore_X_Event_Window_Hide *e;
13056 _e_border_window_pending_hide_event_send(E_Border *bd)
13058 Ecore_X_Event_Window_Hide *e;
13062 e = E_NEW(Ecore_X_Event_Window_Hide, 1);
13065 e->win = bd->client.e.state.pending_event.hide.win;
13066 e->event_win = bd->client.e.state.pending_event.hide.event_win;
13067 e->time = ecore_x_current_time_get();
13068 e->send_event = bd->client.e.state.pending_event.hide.send_event;
13070 ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e,
13071 _e_border_window_pending_hide_event_free, NULL);
13073 ELB(ELBT_BD, "Send pended HIDE event", e->win);
13078 _e_border_window_pending_destroy_event_send(E_Border *bd)
13080 Ecore_X_Event_Window_Destroy *e;
13084 e = E_NEW(Ecore_X_Event_Window_Destroy, 1);
13087 e->win = bd->client.e.state.pending_event.destroy.win;
13088 e->event_win = bd->client.e.state.pending_event.destroy.event_win;
13089 e->time = ecore_x_current_time_get();
13091 ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e,
13092 _e_border_window_pending_destroy_event_free, NULL);
13094 ELB(ELBT_BD, "Send pended DESTROY event", e->win);
13099 _e_border_msg_handler(void *data,
13106 E_Manager *man = (E_Manager *)obj;
13107 E_Manager_Comp_Source *src = (E_Manager_Comp_Source *)msgdata;
13109 // handle only comp.manager msg
13110 if (strncmp(name, "comp.manager", sizeof("comp.manager"))) return;
13112 if (!strncmp(info, "visibility.src", sizeof("visibility.src")))
13114 Ecore_X_Window win;
13118 win = e_manager_comp_src_window_get(man, src);
13119 bd = e_border_find_by_window(win);
13122 if (!bd->client.e.state.deiconify_approve.pending_bd) return;
13124 visible = e_manager_comp_src_visible_get(man, src);
13127 E_Border *pending_bd = bd->client.e.state.deiconify_approve.pending_bd;
13128 if (!pending_bd->client.e.state.pending_event.pending)
13130 bd->client.e.state.deiconify_approve.pending_bd = NULL;
13134 pending_bd->client.e.state.pending_event.done = 1;
13135 pending_bd->client.e.state.pending_event.hold_bd = NULL;
13137 if (pending_bd->client.e.state.pending_event.hide.pending)
13139 _e_border_window_pending_hide_event_send(pending_bd);
13141 // clear hide event data
13142 pending_bd->client.e.state.pending_event.hide.pending = 0;
13143 pending_bd->client.e.state.pending_event.hide.win = 0;
13144 pending_bd->client.e.state.pending_event.hide.event_win = 0;
13145 pending_bd->client.e.state.pending_event.hide.send_event = 0;
13148 if (pending_bd->client.e.state.pending_event.destroy.pending)
13150 _e_border_window_pending_destroy_event_send(pending_bd);
13152 // clear destroy event data
13153 pending_bd->client.e.state.pending_event.destroy.pending = 0;
13154 pending_bd->client.e.state.pending_event.destroy.win = 0;
13155 pending_bd->client.e.state.pending_event.destroy.event_win = 0;
13158 bd->client.e.state.deiconify_approve.pending_bd = NULL;
13159 ELBF(ELBT_ROT, 0, bd->client.win, "RESET pending_bd:%x", bd->client.e.state.deiconify_approve.pending_bd);
13164 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/